/*
 * Investigations work queue (ticket 006) — the analyst-facing session list from the report's
 * Activity screen. The table itself, its scroll wrapper, row hover/focus, and the section head
 * all reuse console.css's existing `table.data` / `.section*` rules (the sort-button reset moved
 * there too, ticket 020 — every table using `.sort-btn` needs it, not just this one); this file
 * only adds what is new here: the Agentic/Severity classification chips.
 *
 * Deliberately its own small palette (--inv-agentic-* / --inv-severity-*), not a reuse of
 * console.css's --st- and --rstatus- tokens — those are each already a fixed, documented five-value
 * mapping for a *different* axis (HTTP-response-class hue, or a single generic OK/caution/danger
 * "traffic light"). Agentic confidence and threat severity are two independent five-step ladders
 * of their own (see investigation_rank.js (AGENTIC_ORDER / SEVERITY_ORDER)), so each gets its own
 * ramp rather than borrowing meaning from an unrelated one.
 */

:root {
  --inv-agentic-confirmed: var(--gold-bright);
  --inv-agentic-high: #58a6ff;
  --inv-agentic-medium: var(--st-4xx);
  --inv-agentic-low: #8b8b93;
  --inv-agentic-none: #5a5a62;

  --inv-severity-critical: #f85149;
  --inv-severity-high: var(--st-4xx);
  --inv-severity-medium: #58a6ff;
  --inv-severity-low: #8b8b93;
  --inv-severity-info: #5a5a62;
}

.chip {
  display: inline-flex;
  align-items: center;
  border-radius: 9999px;
  padding: 0.2rem 0.65rem;
  font-size: var(--fs-2xs);
  font-family: var(--font-mono);
  font-weight: 600;
  border: 1px solid var(--border-strong);
  white-space: nowrap;
}

.chip--agentic-confirmed { color: var(--inv-agentic-confirmed); border-color: var(--inv-agentic-confirmed); }
.chip--agentic-high { color: var(--inv-agentic-high); border-color: var(--inv-agentic-high); }
.chip--agentic-medium { color: var(--inv-agentic-medium); border-color: var(--inv-agentic-medium); }
.chip--agentic-low { color: var(--inv-agentic-low); border-color: var(--inv-agentic-low); }
.chip--agentic-none { color: var(--inv-agentic-none); border-color: var(--border); }

.chip--severity-critical { color: var(--inv-severity-critical); border-color: var(--inv-severity-critical); }
.chip--severity-high { color: var(--inv-severity-high); border-color: var(--inv-severity-high); }
.chip--severity-medium { color: var(--inv-severity-medium); border-color: var(--inv-severity-medium); }
.chip--severity-low { color: var(--inv-severity-low); border-color: var(--inv-severity-low); }
.chip--severity-info { color: var(--inv-severity-info); border-color: var(--border); }

/*
 * Investigation detail (ticket 007) — the header/story/fingerprint-rail screen the work-queue
 * table above routes into. `.chip--lg` scales the header's conclusion chip up from the work
 * queue's compact row chips (reusing the same `.chip--agentic-*` color ramp); `.chip--outcome` is
 * flat (deception outcome has nine possible labels with no severity-style ramp of its own).
 * `.prov*` is the fingerprint rail's four-value OBSERVED/SELF-REPORTED/ENRICHED/INFERRED
 * provenance chip (investigation_story.js's provenanceClass()) — its own small palette, distinct
 * from the agentic/severity ramps above since provenance is a trust axis, not a severity one.
 */

.chip--lg {
  padding: 0.35rem 0.9rem;
  font-size: var(--fs-sm);
}

.chip--outcome {
  color: var(--ink);
  border-color: var(--border-strong);
}

.investigation-header {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.2rem;
}

.investigation-back {
  color: var(--gold-2);
  font-size: var(--fs-sm);
  text-decoration: none;
}

.investigation-back:hover {
  text-decoration: underline;
}

.investigation-header__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  flex-wrap: wrap;
}

.investigation-header__id {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
}

.investigation-header__title {
  font-family: var(--font-mono);
  font-size: var(--fs-lg);
  margin: 0;
}

.investigation-header__exports {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* The compact meta strip (ticket 012) replacing the old chip row + facts table: severity,
   agentic conclusion, deception outcome, duration, source IP (still an entity link), and the
   last-activity clock time, joined with " · ". The severity item borrows its color straight from
   the chip--severity-* rule above rather than rendering as a full chip. */
.investigation-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-dim);
}

.investigation-synopsis {
  color: var(--ink-body);
  line-height: 1.5;
  max-width: 68ch;
}

.investigation-why__title {
  font: var(--type-footnote);
  font-weight: 600;
  color: var(--gold-2);
  margin: 0.8rem 0 0.4rem;
}

.investigation-why__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.investigation-why__reason {
  color: var(--ink-body);
}

.investigation-why__unverified {
  color: var(--inv-severity-high);
}

/* Ticket 426: the investigation's lure links (views/investigation.js lureLinksPanel), outside the
   tabs, one line per replayed or issued minted lure value with links to both exchanges. */
.investigation-lure-links__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.investigation-lure-links__item {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.8rem;
  color: var(--ink-body);
}

.investigation-lure-links__ref {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  overflow-wrap: anywhere;
}

.investigation-lure-links__truncated {
  margin: 0.4rem 0 0;
}

/* Ticket 955: the Bottom line block (js/investigation_bottom_line.js) under the header, three plain
   columns (what it was after, AI agent?, what to do) that stack to one at phone width, and the
   closed "Technical detail" disclosure that holds the synopsis, the reasons and the lure links.
   Every column and every long line (an example path, a block rule) wraps inside its own box, so
   the block never widens the page. */
.investigation-bottom-line {
  margin-bottom: 1rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel-deep);
}

.investigation-bottom-line__title {
  font: var(--type-footnote);
  font-weight: 600;
  color: var(--gold-2);
  margin: 0 0 0.6rem;
}

.investigation-bottom-line__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem 1.4rem;
  align-items: start;
}

.investigation-bottom-line__col {
  min-width: 0;
  overflow-wrap: anywhere;
}

.investigation-bottom-line__label {
  font: var(--type-footnote);
  font-weight: 600;
  color: var(--ink-dim);
  margin: 0 0 0.4rem;
}

.investigation-bottom-line__col .investigation-bottom-line__label:not(:first-child) {
  margin-top: 0.8rem;
}

.investigation-bottom-line__text,
.investigation-bottom-line__verdict {
  color: var(--ink-body);
  line-height: 1.5;
  margin: 0 0 0.4rem;
}

.investigation-bottom-line__verdict {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.investigation-bottom-line__families,
.investigation-bottom-line__examples,
.investigation-bottom-line__checks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.investigation-bottom-line__examples {
  gap: 0.1rem;
  margin-top: 0.2rem;
}

.investigation-bottom-line__example {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-dim);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.investigation-bottom-line__check {
  color: var(--ink-body);
  line-height: 1.45;
}

.investigation-bottom-line .response-panel__rule-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-width: 100%;
}

.investigation-technical {
  margin-bottom: 1rem;
}

.investigation-technical__summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--ink-dim);
}

.investigation-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
  gap: 1.2rem;
  align-items: start;
  margin-top: 1rem;
}

.investigation-rail {
  position: sticky;
  top: 1rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}

.fingerprint-group__title {
  font: var(--type-footnote);
  font-weight: 600;
  color: var(--ink-dim);
  margin: 0 0 0.3rem;
}

.fingerprint-table__prov {
  text-align: right;
}

.investigation-rail__footnote {
  margin-top: 0.2rem;
}

.prov {
  display: inline-flex;
  align-items: center;
  border-radius: 9999px;
  padding: 0.1rem 0.5rem;
  font: var(--type-footnote);
  border: 1px solid var(--border);
  color: var(--ink-dim);
  white-space: nowrap;
}

.prov--self-reported { color: var(--inv-agentic-medium); border-color: var(--inv-agentic-medium); }
.prov--enriched { color: var(--inv-agentic-high); border-color: var(--inv-agentic-high); }
.prov--inferred { color: var(--inv-severity-medium); border-color: var(--inv-severity-medium); }

/*
 * Ticket 013 — one line per story item on a continuous timeline rail (the report's story
 * vocabulary, deep-research-report.md lines 1032-1040) instead of the old three-line 100px card:
 * a 2rem `.story-item__glyph` column (a CSS-drawn dot/diamond, or the ★ character for a validated
 * callback) sits in front of a 1px rail line that runs the height of every item, then time, stage
 * label, request line, and a right-aligned "+0.1s" gap label share one row. `.story-item--diamond`/
 * `--star` color the label gold (a milestone or evidence item), `--star` also gets a soft gold
 * head background, and `--induced` (the callback end of a lure's causal edge) adds a caption
 * under the row — the only two modifiers allowed to grow past one line.
 */

.investigation-story {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.story-item {
  /* Review fix for ticket 032: the first cut forced `display: block` here, blaming
     `align-self: flex-start` on the `.story-item__glyph` descendant for mis-measuring the
     `<li>`'s default `display: list-item` height. The real cause was the missing
     `.story-item__run-items { list-style: none; }` rule (defined further down, next to
     `.story-item__label`) — that nested `<ol>`'s items
     (reusing this same class) showed UA decimal markers once expanded, inflating their own
     height. With that rule in place, `display: list-item` measures correctly on its own, so
     `display: block` is gone — this also restores each row's native list-item semantics
     instead of needing an explicit `role="listitem"`. */
  position: relative;
  padding: 0.15rem 0;
  /* The rail's vertical center within the head row: this item's own top padding, plus the
     head's top padding, plus half the head's text line-height (body's line-height 1.55 at
     --fs-sm). Review round 2 FIX 1: the rail used to live on .story-item__glyph and assumed
     the glyph sat at the item's own vertical center, which broke once an induced row's
     .story-item__induced-caption or an expanded .story-item__panel added height below the
     head — the rail stopped short of the row's real bottom. Anchoring it to the item box
     itself (top: 0 / bottom: 0, below) instead keeps it continuous regardless of what the row
     grows by, and first-/last-child only need to clip back to the head's own center, computed
     here rather than from the item's (now variable) total height. */
  --story-glyph-center: calc(0.3rem + var(--fs-sm) * 1.55 / 2);
}

.story-item::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(0.4rem + 1rem); /* .story-item__head's left padding (0.4rem) plus the
    horizontal center of the 2rem glyph column, so the rail lines up with the glyph column
    as it actually sits inset inside the head row (review round 3 BLOCK). */
  width: 1px;
  background: var(--border);
  z-index: 0;
}

/* Ticket 033: keyed off `.story-item--first`/`--last` (set by storyColumn() on the actual first/
   last story row) instead of `:first-child`/`:last-child`, since a causal connector `<li>` — never
   a `.story-item` — can occupy the literal first or last slot in `.investigation-story` and those
   positional pseudo-classes would then clip nothing, leaving the rail to overhang past the real
   first/last glyph. */
.story-item--first::before {
  top: var(--story-glyph-center);
}

.story-item--last:not(.story-item--first)::before {
  bottom: auto;
  height: var(--story-glyph-center);
}

.story-item--first.story-item--last::before {
  /* A single-item story: no adjacent glyph to connect to, so no rail. */
  top: var(--story-glyph-center);
  bottom: auto;
  height: 0;
}

.story-item__head {
  position: relative;
  z-index: 1; /* paint above the item-level ::before rail (a positioned sibling) */
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  background: none;
  border: none;
  padding: 0.15rem 0.4rem;
  margin: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.story-item__glyph {
  /* Ticket 032: `.story-item__head` centers its flex children against the row's full height,
     which is fine while every child is one line tall but puts the glyph between the lines once
     a long milestone label wraps at narrow widths. Pin the column to the row's top edge instead
     and place the shape with an explicit offset (below) equal to half the first line's
     line-height, so it always lands on that first line regardless of how tall the row grows. */
  position: relative;
  flex: 0 0 2rem;
  align-self: flex-start;
}

.story-item__glyph::after {
  content: "";
  position: absolute;
  top: calc(var(--fs-sm) * 1.55 / 2);
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 9999px;
  background: var(--ink-dim);
}

.story-item__glyph--diamond::after {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--gold);
  transform: translate(-50%, -50%) rotate(45deg);
}

.story-item__glyph--star::after {
  content: "★";
  width: auto;
  height: auto;
  background: none;
  border-radius: 0;
  font-size: 12px;
  line-height: 1;
  color: var(--gold-bright);
}

.story-item__time {
  font-family: var(--font-mono);
  color: var(--ink-dim);
  font-size: var(--fs-sm);
}

/* Ticket 035 — the folded-run summary row (runItem() in investigation.js) shared only the
   generic `.story-item__head` flex/padding rules with an ordinary dot row: the toggle below
   already got its own chrome reset and type-scale rule (ticket 018), but the summary text
   itself still rendered at the browser's inherited body size and full-ink color, reading like
   an ordinary label instead of a compact, secondary "N × METHOD path status" line. `--fs-sm`
   matches the rest of the timeline's body copy; `--ink-dim` is the same "muted" tone the run
   toggle and timestamps already use. */
.story-item__run-summary {
  font-size: var(--fs-sm);
  color: var(--ink-dim);
}

/* Ticket 018 (normalize type scale) — a plain <button> with no rule of its own inherits the
   browser's UA default button font (Chrome: 13.3333px) instead of the type scale, which is what
   the Story tab's 9th, off-scale size traced back to. Indented to 2.6rem like
   .story-item__induced-caption below so it lines up under the run summary text, past the glyph
   column, rather than under the rail. */
.story-item__run-toggle {
  display: block;
  margin: 0.15rem 0 0 2.6rem;
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  font-size: var(--fs-2xs);
  color: var(--ink-dim);
  cursor: pointer;
}

.story-item__run-toggle:hover,
.story-item__run-toggle:focus-visible {
  color: var(--ink);
}

/* Review fix for ticket 032: this nested `<ol>` (js/views/investigation.js's runItem()) is not a
   descendant of `.investigation-story` for cascade purposes — it's its own `ol` element, and the
   UA stylesheet sets `list-style-type: decimal` directly on every `ol`, which beats any inherited
   `list-style: none` from an ancestor. Without this rule the folded run's individual events showed
   numbered markers once expanded. */
.story-item__run-items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.story-item__label {
  font-weight: 600;
}

.story-item--diamond .story-item__label,
.story-item--star .story-item__label {
  color: var(--gold);
}

.story-item__line {
  font-family: var(--font-mono);
  color: var(--ink-dim);
}

.story-item__gap {
  margin-left: auto;
  padding-left: 0.6rem;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-dim);
  white-space: nowrap;
}

.story-item--star .story-item__head {
  background: var(--gold-soft);
  border-radius: var(--radius);
}

.story-item__induced-caption {
  margin: 0.1rem 0 0.15rem 2.6rem;
  font-size: var(--fs-2xs);
  color: var(--ink-dim);
  font-style: italic;
}

.story-item__panel {
  margin-top: 0.6rem;
  border-top: 1px solid var(--border);
  padding-top: 0.6rem;
}

.story-item__tabs {
  display: flex;
  gap: 0.8rem;
  margin-bottom: 0.5rem;
}

.story-item__tab {
  background: none;
  border: none;
  padding: 0;
  color: var(--ink-dim);
  font: var(--type-footnote);
  cursor: pointer;
}

.story-item__tab.is-active {
  color: var(--gold);
}

.investigation-connector {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.4rem 0.9rem;
  margin-left: 1.4rem;
  border-left: 2px dashed var(--border-gold);
}

.investigation-connector__box {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0.6rem;
  flex: 1 1 auto;
}

.investigation-connector__edge {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--gold-2);
  white-space: nowrap;
}

.investigation-connector__note {
  list-style: none;
  margin: -0.4rem 0 0 2.2rem;
  padding: 0 0.9rem 0.4rem;
  font-size: var(--fs-2xs);
  font-style: italic;
}

.investigation-story__truncated-note {
  margin: 0 0 0.6rem;
}

.investigation-tabbar {
  display: flex;
  gap: 1rem;
  margin-bottom: 1.4rem;
  border-bottom: 1px solid var(--border);
  /* Six tabs need ~436 px; a 390 px phone column is 358 px. Scroll the row inside its column
     rather than widening the page (ticket 950). */
  overflow-x: auto;
}

.investigation-tabbar__tab {
  background: none;
  border: none;
  padding: 0.2rem 0 0.6rem;
  color: var(--ink-dim);
  font: inherit;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  letter-spacing: 0.04em;
  cursor: pointer;
  flex: 0 0 auto;
  white-space: nowrap;
}

.investigation-tabbar__tab.is-active {
  color: var(--gold);
  border-bottom: 2px solid var(--gold);
}

@media (max-width: 900px) {
  .investigation-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .investigation-rail {
    position: static;
  }
}

/*
 * EVIDENCE tab, HTTP tab, and the persistent bottom evidence drawer (ticket 008 —
 * z/notes/deep-research-report.md lines 322-362/600-649). `.evidence-item*` is shared by the
 * EVIDENCE tab's list and the drawer's own list (js/views/investigation.js's evidenceListItem()),
 * so both read identically. `.http-*` reuses console.css's `table.data`, `.wire*`, `.toggle-group`,
 * and `.btn*` rules rather than redefining them.
 */

.investigation-evidence-pane {
  padding-bottom: 1rem;
}

.evidence-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.evidence-item {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.6rem 0.8rem;
  background: var(--panel);
}

.evidence-item__head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.evidence-item__marker {
  font-family: var(--font-mono);
  color: var(--gold);
}

.evidence-item__title {
  font-weight: 600;
}

.evidence-item__summary {
  margin-left: auto;
  white-space: nowrap;
}

.evidence-item__detail {
  margin-top: 0.6rem;
  border-top: 1px solid var(--border);
  padding-top: 0.6rem;
}

.evidence-drawer {
  position: sticky;
  bottom: 0;
  margin-top: 1.4rem;
  border-top: 1px solid var(--border-strong);
  background: var(--panel);
}

.evidence-drawer__toggle {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  background: none;
  border: none;
  padding: 0.6rem 0.2rem;
  color: var(--ink);
  font: inherit;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  letter-spacing: 0.06em;
  cursor: pointer;
}

.evidence-drawer__label {
  color: var(--gold-2);
}

.evidence-drawer__count {
  color: var(--ink-dim);
}

.evidence-drawer__panel {
  max-height: 40vh;
  overflow-y: auto;
  padding: 0.2rem 0.2rem 0.8rem;
}

.http-tab {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.http-row {
  cursor: pointer;
}

.http-row.is-selected {
  background: var(--glass);
  box-shadow: inset 3px 0 0 var(--gold);
}

.http-row__time,
.http-row__path {
  font-family: var(--font-mono);
}

.http-row__size {
  text-align: right;
  font-family: var(--font-mono);
  color: var(--ink-dim);
}

.http-detail__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}

.http-detail__panes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem;
}

.http-detail__body-title {
  margin: 0.6rem 0 0.3rem;
}

@media (max-width: 900px) {
  .http-detail__panes {
    grid-template-columns: minmax(0, 1fr);
  }
}

/*
 * RELATED tab (ticket 005 — z/notes/deep-research-report.md lines 846-876): a table of the most
 * similar other investigations, each match a `.chip` variant distinguishing a deterministic match
 * (same solid border as the agentic/severity chips above) from a probabilistic one (dashed, to
 * read as "similarity" rather than "fact") at a glance.
 */

.related-row {
  cursor: pointer;
}

.related-row__id,
.related-row__similarity {
  font-family: var(--font-mono);
}

.related-row__matches {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.chip--match-deterministic {
  color: var(--gold-2);
  border-color: var(--gold-2);
}

.chip--match-probabilistic {
  color: var(--ink-dim);
  border-style: dashed;
}

/*
 * Column filter row (tickets 511 and 512): the second header row of the work queue, one cell per
 * column under the sort buttons. Every cell but Time holds a control: a text box, a select (the
 * triage status select keeps its older `.investigations-status-filter` class) or the Evidence
 * number box. The cells are plain `td`, so `table.data thead th`'s sort
 * header styling does not reach them. `.investigations-filter__error` is the inline message a
 * rejected filter value shows right under the row, and `.investigations-empty-row` the one body
 * row of a table whose filters matched nothing (a plain `td` inside `table.data tbody tr`, so it
 * opts out of the row hover and pointer cursor).
 */

table.data .investigations-filter-row td {
  padding: 0.35rem 0.8rem;
  border-bottom: 1px solid var(--border-strong);
  background: var(--panel-deep);
}

.investigations-filter__input {
  width: 100%;
  min-width: 9rem;
  padding: 0.28rem 0.6rem;
  border-radius: 0.45rem;
  border: 1px solid var(--border-strong);
  background: var(--glass);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
}

.investigations-filter__input::placeholder {
  color: var(--ink-muted);
}

.investigations-filter__input:focus-visible {
  outline: 2px solid var(--gold-2);
  outline-offset: 1px;
}

/* The Evidence box holds a few digits. A value the server would refuse (a minus sign, a decimal) is
   marked, and the filter stays what it was. */
.investigations-filter__input--number {
  min-width: 5rem;
}

.investigations-filter__input[aria-invalid="true"] {
  border-color: var(--st-5xx);
}

/* The filter selects share the text boxes' compact face; the base `select` rule paints the rest. */
.investigations-filter__select,
.investigations-status-filter {
  width: 100%;
  min-width: 7rem;
  min-height: 1.8rem;
  padding: 0.28rem 1.5rem 0.28rem 0.5rem;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
}

table.data .investigations-filter-message td {
  padding: 0.4rem 0.8rem;
  border-bottom: 1px solid var(--border-strong);
  background: var(--panel-deep);
}

.investigations-filter__error {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--st-5xx);
}

/*
 * Both messages sit in a cell that spans every column, and on a narrow screen the table is far wider
 * than its scroller (about 1,600 px of columns in a 356 px scroller at 390 px wide). Left in the
 * cell's flow, the empty-table text (centred on the table) and the Source message (left of a Source
 * box the user has scrolled to) were off screen. Each is only as wide as its text and sticks to the
 * scroller's left edge, so it stays in view however far the table is scrolled sideways.
 */
.investigations-filter__error,
.investigations-empty-row__text {
  position: sticky;
  left: 0.8rem;
  display: block;
  width: max-content;
  max-width: calc(100vw - 5rem);
  white-space: normal;
}

table.data tbody tr.investigations-empty-row {
  cursor: default;
}

table.data tbody tr.investigations-empty-row:hover {
  background: none;
}

table.data .investigations-empty-row td {
  padding: 1.2rem 0.8rem;
  text-align: left;
  color: var(--ink-muted);
}

/*
 * The Investigations table at any width (ticket 928). Every rule below hangs under
 * `.investigations-scroll`, the wrapper views/investigations.js gives only its own table, so the
 * compact preview (which shares `table.data.investigations-table` and `.table-scroll`) and the
 * other lists keep their look. Cells carry `data-col` (the column key) and body and filter cells
 * `data-label` (the column name); the width bands target those, never a cell position, because the
 * checkbox column depends on the role and empty columns are left out of the markup.
 * Three bands: 1024 px and wider the table fits its wrapper and the header sticks under the navbar;
 * 641 to 1023 px it scrolls sideways with a pinned Time column; 640 px and narrower each row is a
 * card.
 */

/* States, all widths. The hover tint skips a ticked row so that row keeps its selected highlight
   (intrusion-groups.css). The focus ring sits inside the row: a ring drawn outside it would be cut
   by the wrapper. */
.investigations-scroll .investigations-row:hover:not(:has(.investigations-row__select input:checked)) {
  background: color-mix(in srgb, var(--gold) 8%, transparent);
}

.investigations-scroll .investigations-row:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: -2px;
  box-shadow: inset 3px 0 0 var(--gold);
}

/* An Agentic value of None carries no signal: muted text, no chip. Not scoped to the wrapper, so
   A compact preview, which shares the cell, reads the same. */
.investigations-row__none {
  color: var(--ink-muted);
}

/* The Filters disclosure (ticket 977), at every width: a bordered button in the list's head. The
   column filter row under the sort headers shows only while it is open, so a list opens with no
   filter control on screen. The row is a table row on wide screens and a stacked card on a phone. */
.investigations-filters > summary {
  display: inline-flex;
  list-style: none;
  cursor: pointer;
}

.investigations-filters > summary::-webkit-details-marker {
  display: none;
}

.investigations-scroll .investigations-filter-row {
  display: none;
}

.section:has(.investigations-filters[open]) .investigations-scroll .investigations-filter-row {
  display: table-row;
}

/* The head's count sits at the leading edge, the Filters and Select buttons at the trailing one. */
.section__head-meta:has(> .investigations-filters) {
  flex: 1 1 auto;
}

.section__head-meta:has(> .investigations-filters) > .section__hint {
  margin-right: auto;
}

/* "Show more" (js/paging.js, shared by the Investigations, Operations, Intrusion Groups and Entities
   lists): one bordered button, centred under the table; hidden once every row shows. */
.show-more-row {
  display: flex;
  justify-content: center;
  margin-top: 0.75rem;
}

.show-more-row:has(> .show-more[hidden]) {
  display: none;
}

/* The Operations list's search box and its claims header's ⓘ (ticket 977). */
.operations-search {
  flex: 1 1 12rem;
  min-width: 0;
  max-width: 18rem;
}

.section__head:has(> .operations-search) {
  flex-wrap: wrap;
}

/* The panel hangs from the header's right edge, so the table's scroller never clips it. */
.operations-table th .info-tip__panel {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 20;
  width: max-content;
  max-width: 18rem;
  border: 1px solid var(--border-strong);
  background: var(--panel);
  font-weight: normal;
  text-transform: none;
  letter-spacing: 0;
  box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 0.3);
}

.operations-table th[data-col="claims"] {
  position: relative;
}

/* 1024 px and wider. `overflow-x: clip` clips without making the wrapper a scroll container, which
   a sticky header needs: with `overflow-x: auto` the header sticks to the wrapper, not the page.
   The table has to fit, so its layout is fixed and the column widths are shares of it (they total
   about 97 percent with every column and the checkbox column shown; with columns hidden the browser
   spreads the unused share over the others in proportion). A cell that does not fit ends in an ellipsis,
   and its `title` holds the full text. The header sticks just under the navbar (`--navbar-h`,
   console.css) on a solid background with a shadow below it. */
@media (min-width: 1024px) {
  .investigations-scroll {
    overflow-x: clip;
  }

  .investigations-scroll .investigations-table {
    min-width: 0;
    table-layout: fixed;
  }

  .investigations-scroll .investigations-table thead th {
    top: var(--navbar-h);
    z-index: 2;
    padding: 0.6rem 0.4rem;
    letter-spacing: 0.04em;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: 0 6px 8px -6px rgba(0, 0, 0, 0.7);
  }

  .investigations-scroll .investigations-table td {
    padding: 0.5rem 0.4rem;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .investigations-scroll .investigations-table th[data-col="select"] { width: 3%; text-align: center; }
  .investigations-scroll .investigations-table [data-col="select"] {
    padding-left: 0;
    padding-right: 0;
  }
  .investigations-scroll .investigations-table th[data-col="time"] { width: 11%; }
  .investigations-scroll .investigations-table th[data-col="agentic"] { width: 6%; }
  .investigations-scroll .investigations-table th[data-col="severity"] { width: 6.5%; }
  .investigations-scroll .investigations-table th[data-col="status"] { width: 7%; }
  .investigations-scroll .investigations-table th[data-col="source"] { width: 9%; }
  .investigations-scroll .investigations-table th[data-col="group"] { width: 6.5%; }
  .investigations-scroll .investigations-table th[data-col="scenario"] { width: 7%; }
  .investigations-scroll .investigations-table th[data-col="stage"] { width: 12%; }
  .investigations-scroll .investigations-table th[data-col="agent_stack"] { width: 8%; }
  .investigations-scroll .investigations-table th[data-col="techniques"] { width: 15%; }
  .investigations-scroll .investigations-table th[data-col="evidence"] { width: 6%; }

  /* The filter controls fill their column instead of holding a minimum width of their own. */
  .investigations-scroll .investigations-filter__input,
  .investigations-scroll .investigations-filter__select,
  .investigations-scroll .investigations-status-filter {
    min-width: 0;
    width: 100%;
    box-sizing: border-box;
  }

  /* Chip cells wrap onto a second line rather than cut a chip off, and the deepest stage wraps onto a
     second line rather than end in an ellipsis (its `title` still holds the full text). */
  .investigations-scroll .investigations-table td[data-col="techniques"],
  .investigations-scroll .investigations-table td[data-col="group"],
  .investigations-scroll .investigations-table td[data-col="stage"] {
    white-space: normal;
    text-overflow: clip;
  }
}

/* 641 to 1023 px. The wrapper keeps `overflow-x: auto` from .table-scroll, so the table scrolls
   sideways and the header does NOT stick here (a sticky header inside a scrolling wrapper sticks to
   the wrapper). The Time column (and the checkbox before it) is pinned on the left, with a shadow
   edge, so a row stays identified while its far columns are read. */
@media (min-width: 641px) and (max-width: 1023px) {
  .investigations-scroll .investigations-table [data-col="select"],
  .investigations-scroll .investigations-table [data-col="time"] {
    position: sticky;
    left: 0;
    z-index: 3;
    background: var(--panel-deep);
  }

  .investigations-scroll .investigations-table [data-col="time"] {
    box-shadow: 6px 0 8px -6px rgba(0, 0, 0, 0.7);
  }

  .investigations-scroll .investigations-table:has([data-col="select"]) [data-col="time"] {
    left: 2.25rem;
  }

  .investigations-scroll .investigations-row:hover:not(:has(.investigations-row__select input:checked)) [data-col="time"],
  .investigations-scroll .investigations-row:hover:not(:has(.investigations-row__select input:checked)) [data-col="select"] {
    background: color-mix(in srgb, var(--gold) 8%, var(--panel-deep));
  }

  .investigations-scroll .investigations-row:has(.investigations-row__select input:checked) [data-col="time"],
  .investigations-scroll .investigations-row:has(.investigations-row__select input:checked) [data-col="select"] {
    background: color-mix(in srgb, var(--gold) 9%, var(--panel-deep));
  }
}

/* 640 px and narrower: each row is a card. The header row goes (the Filters disclosure above the
   cards opens the filter row instead), and a body cell is shown only for Time and Severity on line
   one, the source address on line two and the deepest stage on line three; the checkbox stays at
   the card's left. The source and stage lines say what they are with the cell's `data-label`. */
@media (max-width: 640px) {
  /* Ticket 955: the Bottom line columns stack to one. */
  .investigation-bottom-line {
    padding: 0.7rem 0.8rem;
  }

  .investigation-bottom-line__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .investigations-scroll {
    overflow-x: visible;
    border: 0;
    background: none;
  }

  .investigations-scroll .investigations-table,
  .investigations-scroll .investigations-table thead,
  .investigations-scroll .investigations-table tbody {
    display: block;
    min-width: 0;
    width: 100%;
  }

  .investigations-scroll .investigations-table thead tr:first-child {
    display: none;
  }

  /* The filter row shows only while the disclosure is open (the rule above the bands); its cells
     stack, each with its name. */
  .section:has(.investigations-filters[open]) .investigations-scroll .investigations-filter-row {
    display: grid;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
    padding: 0.6rem 0.8rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--panel-deep);
  }

  .investigations-scroll .investigations-filter-row td {
    display: grid;
    gap: 0.2rem;
    padding: 0;
    border: 0;
  }

  /* The Time cell holds no control, and the checkbox cell has nothing to filter. */
  .investigations-scroll .investigations-filter-row td[data-col="select"],
  .investigations-scroll .investigations-filter-row td:empty {
    display: none;
  }

  .investigations-scroll .investigations-filter-row td::before {
    content: attr(data-label);
    color: var(--ink-muted);
    font: var(--type-footnote);
  }

  .investigations-scroll .investigations-filter__input,
  .investigations-scroll .investigations-filter__select,
  .investigations-scroll .investigations-status-filter {
    min-width: 0;
    width: 100%;
    box-sizing: border-box;
  }

  .investigations-scroll .investigations-filter-message {
    display: block;
  }

  .investigations-scroll .investigations-filter-message td {
    display: block;
  }

  .investigations-scroll .investigations-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    margin-bottom: 0.6rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--panel);
  }

  .investigations-scroll .investigations-row > td {
    display: none;
    min-width: 0;
    padding: 0.35rem 0.8rem;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .investigations-scroll .investigations-row > td[data-col="select"] {
    display: block;
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: start;
    padding: 0.5rem 0 0 0.6rem;
  }

  .investigations-scroll .investigations-row > td[data-col="time"] {
    display: block;
    grid-column: 2;
    grid-row: 1;
    color: var(--ink-muted);
  }

  .investigations-scroll .investigations-row > td[data-col="severity"] {
    display: block;
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
  }

  .investigations-scroll .investigations-row > td[data-col="source"],
  .investigations-scroll .investigations-row > td[data-col="stage"] {
    display: block;
    grid-column: 2 / -1;
    white-space: normal;
  }

  .investigations-scroll .investigations-row > td[data-col="source"] {
    grid-row: 2;
    color: var(--ink);
    font-family: var(--font-mono);
  }

  .investigations-scroll .investigations-row > td[data-col="stage"] {
    grid-row: 3;
  }

  .investigations-scroll .investigations-row > td[data-col="source"]::before,
  .investigations-scroll .investigations-row > td[data-col="stage"]::before {
    content: attr(data-label) ": ";
    color: var(--ink-muted);
  }

  .investigations-scroll tr.investigations-empty-row {
    display: block;
  }

  .investigations-scroll .investigations-empty-row > td {
    display: block;
    padding: 1rem 0.8rem;
  }
}
