/* ICP Incident Response — same palette contract as digital-twin/item_view: the status slots
   (ok/warn/serious/critical/unknown) are reserved for state and never reused for identity.

   Colour is rationed here. It carries three things and nothing else:
     - reply status (the replied / no-reply pills and the passed / failed drill chips)
     - the OK / Not OK verdict on the lookup card
     - the penalty state
   Panels, headings, helper text and buttons are neutral, and no card has a coloured rail. A
   page where everything is coloured is a page where nothing is.

   Two slots, not three, on a drill record: a drill is passed or it is failed. There was an
   amber "late" tier here and it has been removed, because a reply after the window earns no
   partial credit and a colour between green and red said it did. Lateness survives as the
   *reason* on a failed chip — a dashed edge and an annotation, never a rank. */
.viz-root {
  --plane:          #f9f9f7;
  --surface-1:      #fcfcfb;
  --surface-2:      #f2f1ed;
  --surface-3:      #eceae4;
  --text-primary:   #0b0b0b;
  --text-secondary: #52514e;
  --text-muted:     #898781;
  --grid:           #e1e0d9;
  --axis:           #c3c2b7;
  --border:         rgba(11, 11, 11, .10);

  --st-ok:       #0ca30c;
  --st-warn:     #fab219;
  --st-serious:  #ec835a;
  --st-critical: #d03b3b;
  --st-unknown:  #898781;

  --focus: #3987e5;

  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  .viz-root {
    --plane:          #0d0d0d;
    --surface-1:      #1a1a19;
    --surface-2:      #222221;
    --surface-3:      #2b2b29;
    --text-primary:   #ffffff;
    --text-secondary: #c3c2b7;
    --text-muted:     #898781;
    --grid:           #2c2c2a;
    --axis:           #383835;
    --border:         rgba(255, 255, 255, .10);
    --st-ok:          #35c035;
  }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* ---------- the audience switch ----------
   `body.op` is set from the payload's `operator` flag, never from the URL, so a page that
   failed to authenticate degrades to the visitor's view rather than to a broken one. Cosmetic
   reinforcement only: in public mode the operator payload was never sent. */
body:not(.op) .op-only { display: none !important; }
body.op .pub-only { display: none !important; }
/* `body.static` is set from the payload's `static` flag. There is no operator half of a
   published build to reveal — no key is held, no write would reach anything — so the
   surfaces are struck out here as well as by the payload that never contained them. */
body.static .op-only { display: none !important; }

body {
  margin: 0 auto; padding: 16px 24px 40px; max-width: 1180px;
  background: var(--plane); color: var(--text-primary);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}
h1 { font-size: 18px; font-weight: 600; margin: 0; letter-spacing: -.01em; }
h2 { font-size: 13px; font-weight: 600; margin: 0 0 10px; }
code { font: 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text-muted); }
.muted { color: var(--text-muted); font-weight: 400; }
.small { font-size: 11px; }
p { margin: 0; }

/* ---------- 0. header ---------- */
.topbar {
  display: flex; justify-content: space-between; align-items: baseline; gap: 20px;
  margin-bottom: 12px;
}
.topmeta { display: flex; align-items: baseline; gap: 10px; font-size: 11.5px; color: var(--text-secondary); }
.sync { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; cursor: help; }
/* a heartbeat, not a status light: it says the page is still watching, so it stays neutral —
   green here would read as a verdict on the drill */
.pulse {
  width: 7px; height: 7px; border-radius: 50%; align-self: center;
  background: var(--text-muted); animation: beat 2.6s ease-in-out infinite;
}
.pulse[data-state="off"] {
  animation: none; background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--text-muted); opacity: .6;
}
/* a published snapshot is not watching anything, so the heartbeat stops. A beating dot over
   the words "Updated 14 Aug" would be the page contradicting itself once every 2.6 seconds. */
.pulse[data-state="still"] { animation: none; background: var(--axis); opacity: .8; }
@keyframes beat {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .3; transform: scale(.72); }
}
@media (prefers-reduced-motion: reduce) { .pulse { animation: none; } }
.opbadge {
  font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-secondary); border: 1px solid var(--axis);
  border-radius: 4px; padding: 1px 6px; cursor: help;
}

/* ---------- banner ---------- */
.banner {
  border: 1px solid var(--axis); background: var(--surface-2);
  border-radius: 8px; padding: 8px 12px; margin-bottom: 12px;
  font-size: 12px; line-height: 1.45; color: var(--text-secondary);
}
.banner strong { color: var(--text-primary); }

/* ---------- panels ---------- */
.panel {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px 14px; min-width: 0;
}
.tile-label { font-size: 11px; color: var(--text-muted); margin-bottom: 3px; }
.tile-foot { font-size: 11.5px; color: var(--text-secondary); margin-top: 7px; }

/* ---------- 1. incident status ---------- */
.incident {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin-bottom: 12px;
}
.inc-main { min-width: 0; }
.inc-side { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
/* one hero: the time left, because every other number is measured against it */
.hero {
  font-size: 40px; font-weight: 600; line-height: 1.05; letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
}
.hero.calm { font-size: 26px; font-weight: 500; color: var(--text-secondary); letter-spacing: -.01em; }
.hero.urgent { color: var(--st-warn); }
.hero.overdue { font-size: 30px; color: var(--st-critical); }

/* the consequence line under the hero. Sized between the foot and the hero: it is the second
   thing read in this module, not the fourth. Neutral — the money is the emphasis, and a red
   line here would read as an alarm about a drill that is already over. */
.inc-outcome { margin-top: 8px; max-width: 54ch; }
.inc-outline {
  font-size: 12.5px; font-weight: 600; color: var(--text-primary);
  font-variant-numeric: tabular-nums; line-height: 1.4;
}
details.outcome > summary.inc-outline { cursor: pointer; list-style: none; display: inline; }
details.outcome > summary::-webkit-details-marker { display: none; }
details.outcome > summary::after {
  content: '?'; font-size: 9px; font-weight: 700; opacity: .7; margin-left: 5px;
  border: 1px solid var(--axis); border-radius: 3px; padding: 0 3px;
}
details.outcome[open] > summary::after { content: '×'; }
.outcome-why {
  margin-top: 6px; font-size: 11.5px; line-height: 1.5; color: var(--text-secondary);
  max-width: 54ch;
}
.outcome-facts { margin: 5px 0 0; padding-left: 16px; color: var(--text-muted); }

/* ---------- count chips ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.chip {
  display: inline-flex; align-items: baseline; gap: 6px;
  border: 1px solid var(--border); border-radius: 999px; padding: 4px 11px 4px 9px;
  background: var(--surface-2); font-size: 11.5px; color: var(--text-secondary);
}
.chip .dot { width: 7px; height: 7px; border-radius: 50%; align-self: center; }
.chip b { font-size: 17px; font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.chip.zero b { color: var(--text-muted); font-weight: 600; }

/* ---------- operator: feed freshness ----------
   The one place an alarm is warranted: only the operator can act on it. Text and dot carry
   the level; the panel itself stays neutral. */
.feedbar {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  border: 1px solid var(--border); border-radius: 10px; padding: 9px 14px; margin-bottom: 12px;
  background: var(--surface-1);
}
.feed-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--st-unknown); align-self: center; }
.feed-main { font-size: 15px; font-weight: 600; }
.feed-sub { font-size: 11.5px; color: var(--text-secondary); flex: 1 1 auto; min-width: 0; }
.feedbar .btn { flex: 0 0 auto; }
.feedbar[data-level="warn"] .feed-main { color: var(--st-warn); }
.feedbar[data-level="bad"] .feed-main,
.feedbar[data-level="never"] .feed-main { color: var(--st-critical); }
.feedbar[data-level="idle"] .feed-main { color: var(--text-muted); font-weight: 500; }

.ingest { margin-bottom: 12px; }
.ingest textarea {
  width: 100%; resize: vertical; min-height: 74px;
  font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--surface-2);
}
.row-inline { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.flash { font-size: 11.5px; color: var(--text-secondary); }
.flash.good { color: var(--st-ok); font-weight: 600; }
.flash.bad { color: var(--st-critical); font-weight: 600; }

.queue { margin-bottom: 12px; }
.queue-why { margin: 0 0 10px; }
.queue-list { display: flex; flex-direction: column; gap: 8px; }
.qitem { background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 9px 11px; }
.qhead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.qhead .sender { font-weight: 600; font-size: 12.5px; }
.qhead .key { margin-left: auto; }
.qitem .excerpt {
  margin: 5px 0 8px; font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text-secondary); white-space: pre-wrap; word-break: break-word;
  max-height: 6.5em; overflow: auto;
}
.qctl { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.qctl select { max-width: 320px; }

/* ---------- 2 + 3. the answer, and the nudge beside it ---------- */
.pair {
  display: grid; grid-template-columns: minmax(0, 2.3fr) minmax(0, 1fr);
  gap: 12px; align-items: start; margin-bottom: 16px;
}

.lookup h2 { font-size: 14px; }
.lk-controls { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-end; }

/* ---------- the provider combobox ----------
   The list is absolutely positioned so opening it never reflows the card underneath: the
   answer a reader is already looking at must not jump down the page while they refine the
   query that produced it. */
.lk-combo { position: relative; width: 100%; max-width: 340px; }
.combo-in { position: relative; display: block; width: 100%; }
#lk-input { width: 100%; min-width: 0; padding-right: 26px; }
.lk-toggle {
  position: absolute; right: 1px; top: 1px; bottom: 1px; width: 24px;
  display: flex; align-items: center; justify-content: center;
  font: inherit; font-size: 10px; line-height: 1; cursor: pointer;
  color: var(--text-muted); background: none; border: 0; border-radius: 0 6px 6px 0;
}
.lk-toggle:hover { color: var(--text-primary); background: var(--surface-2); }
.lk-listbox {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
  margin: 0; padding: 4px; list-style: none;
  max-height: 264px; overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface-1); border: 1px solid var(--axis); border-radius: 8px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .16);
}
.lk-opt {
  padding: 5px 9px; border-radius: 5px; cursor: pointer; font-size: 12.5px;
  color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lk-opt:hover { background: var(--surface-2); }
/* the keyboard highlight has to be legible next to the hover tint, so it takes an edge too */
.lk-opt.on { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--axis); font-weight: 600; }

.lk-suggest { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.lk-suggest:empty { margin-top: 0; }
.lk-none { margin-top: 10px; font-size: 12px; }

.lk-card { margin-top: 12px; }
.lk-pname { font-size: 16px; font-weight: 700; margin-bottom: 8px; }

/* the verdict: one word, readable in greyscale and out loud, with colour as reinforcement */
.lk-verdict {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px;
  background: var(--surface-2);
}
/* The verdict exists only while a drill is running. Between drills the card carries no
   banner at all — there is no question outstanding, and a calm panel saying so would be
   read as an all-clear the page has no standing to give a provider under penalty. */
.lk-big { font-size: 34px; font-weight: 700; letter-spacing: -.02em; line-height: 1.05; white-space: nowrap; }
.lk-vbody { flex: 1 1 260px; min-width: 0; }
.lk-vline { font-size: 13px; font-weight: 600; display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; }
.lk-verdict.ok .lk-big   { color: var(--st-ok); }
.lk-verdict.warn .lk-big { color: var(--st-warn); }
.lk-verdict.bad .lk-big  { color: var(--st-critical); }

.lk-countdown { margin-top: 5px; font-size: 12.5px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.lk-countdown.urgent { color: var(--st-warn); font-weight: 700; }
.lk-countdown.overdue { color: var(--st-critical); font-weight: 600; }

.lk-note { margin-top: 6px; font-size: 11.5px; color: var(--text-secondary); line-height: 1.45; max-width: 72ch; }
.lk-h { font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 6px; }
.lk-block { margin-top: 14px; }

/* the record in the card: most recent first, dates spelled out. The board's three anonymous
   chips are for scanning 79 rows; this is for reading one. */
.lk-hist { display: flex; gap: 8px; flex-wrap: wrap; }
.lk-hchip {
  display: inline-flex; align-items: baseline; gap: 7px;
  border: 1px solid var(--border); border-radius: 6px; padding: 4px 10px;
}
.lk-hchip b { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; }
.lk-hdate { font-size: 11.5px; color: var(--text-secondary); }
.lk-hchip.lk-fail { border-width: 1.5px; }
/* A late reply is a failure — same colour, same word. The dashed edge carries only the
   reason, and it is deliberately the quietest signal on the chip: this is an annotation on
   a miss, not a third grade between passing and missing. */
.lk-hchip.is-late { border-style: dashed; }
.lk-hwhy {
  font-size: 9.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-muted); cursor: help;
}
.lk-hnote { margin-top: 6px; line-height: 1.45; }

/* the call to action: only when a drill is running and this provider has not replied */
.lk-cta {
  margin-top: 12px; padding: 11px 12px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2);
}
.lk-say { font-size: 12px; font-weight: 600; margin-bottom: 6px; }
.lk-open { text-decoration: none; display: inline-flex; align-items: center; }
/* the line to post, assembled from live parts: the provider half is fixed and exact, the name
   half is an input because it is the only bit they supply */
.replybox {
  display: inline-flex; align-items: center; flex-wrap: wrap;
  border: 1px solid var(--border); border-radius: 7px; padding: 7px 10px;
  background: var(--surface-1);
  font: 13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
  max-width: 100%;
}
.rb-lit { color: var(--text-secondary); white-space: pre; }
.rb-np { color: var(--text-primary); font-weight: 700; }
.rb-name {
  font: inherit; min-height: 0; padding: 1px 4px; min-width: 8ch; max-width: 100%;
  color: var(--text-primary); font-weight: 700;
  background: var(--surface-2);
  border: 0; border-bottom: 2px dashed var(--axis); border-radius: 3px;
}

/* the penalty disclosure — the same component on the board and in the card. The percentage is
   the whole headline; the wording behind it is the server's. */
.pen { display: inline-block; }
.pen > summary {
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer; list-style: none;
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
  color: var(--st-critical);
  border: 1px solid color-mix(in srgb, var(--st-critical) 45%, transparent);
  border-radius: 4px; padding: 1px 6px;
}
.pen > summary::-webkit-details-marker { display: none; }
.pen > summary::after { content: '?'; font-size: 9px; opacity: .75; }
.pen[open] > summary::after { content: '×'; }
.penwhy {
  white-space: normal; max-width: 48ch; margin-top: 6px;
  font-size: 11.5px; line-height: 1.5; color: var(--text-secondary);
}
.penrounds { margin: 5px 0 0; padding-left: 16px; color: var(--text-muted); }

/* the good-news case. Same slot as the penalty chip, same reserved colour, opposite sign —
   it is a statement about the penalty, which is one of the three things colour is for here. */
.lk-clear {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600; color: var(--st-ok);
  border: 1px solid color-mix(in srgb, var(--st-ok) 40%, transparent);
  border-radius: 6px; padding: 4px 10px; background: var(--surface-2);
}

.lk-rule { margin-top: 12px; font-size: 11.5px; color: var(--text-muted); }
.lk-rule summary { cursor: pointer; }
.lk-rule p { margin-top: 5px; max-width: 72ch; }

/* ---------- 3. the nudge ---------- */
.signup .su-line { font-size: 12.5px; color: var(--text-secondary); margin-bottom: 10px; }
.signup .field { width: 100%; }
.signup .field input { width: 100%; min-width: 0; }
.su-terms {
  margin-top: 10px; padding: 10px 11px; border: 1px solid var(--axis);
  border-radius: 8px; background: var(--surface-3);
}
.su-promise { font-size: 11.5px; line-height: 1.45; color: var(--text-secondary); }
/* Checkbox and its label are one line of reading, not two columns. `display: flex` (not
   inline-flex) so the label wraps under itself on a narrow screen instead of pushing the
   box around, and the box keeps a fixed size so it cannot stretch with the text. */
.consent {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 9px; line-height: 1.45; font-size: 11.5px;
  width: 100%;
}
.consent input[type=checkbox] {
  flex: 0 0 auto;
  width: 15px; height: 15px; min-height: 0;
  margin: 1px 0 0; padding: 0;
  accent-color: var(--st-ok);
}
.consent > span { flex: 1 1 auto; min-width: 0; }
.signup .flash { display: block; margin-top: 6px; }
/* the mailto affordance is a real link, so it needs to be told to look like the button it
   replaces rather than like body copy */
.su-mail { text-decoration: none; display: inline-flex; align-items: center; }

/* ---------- controls ---------- */
.ctl {
  display: inline-flex; align-items: center; gap: 6px; min-height: 30px;
  font-size: 12px; color: var(--text-secondary);
}
.field { flex-direction: column; align-items: flex-start; gap: 3px; font-size: 11px; color: var(--text-muted); }
.flabel { white-space: nowrap; }
.ctl input:not([type=checkbox]), .ctl select, .btn, select, textarea {
  font: inherit; font-size: 12px; color: var(--text-primary);
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 6px; padding: 5px 8px; min-height: 28px;
}
.btn { cursor: pointer; }
.btn:hover { background: var(--surface-2); }
.btn:disabled { opacity: .5; cursor: progress; }
/* emphasis without a brand colour: a solid edge and weight */
.btn.primary { border-color: var(--axis); background: var(--surface-2); font-weight: 600; }
.btn.primary:hover { border-color: var(--text-secondary); }
.checkbox { cursor: pointer; }

.board-head-h { margin: 0 0 8px; font-size: 13px; }
.filters { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 0 0 10px; }
.filters .spacer { flex: 1 1 auto; }
.segmented { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.seg {
  font: inherit; font-size: 12px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-1); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 10px; min-height: 28px;
}
.seg:hover { background: var(--surface-2); }
.seg.on { color: var(--text-primary); font-weight: 600; border-color: var(--axis); background: var(--surface-2); }
.segn {
  font-variant-numeric: tabular-nums; font-size: 11px; color: var(--text-muted);
  border-left: 1px solid var(--border); padding-left: 6px;
}
#query { min-width: 160px; }

/* ---------- 4. the roster ---------- */
.board { padding: 4px 14px 8px; }
.scroll { overflow-x: auto; max-height: 66vh; overflow-y: auto; }
table { border-collapse: collapse; width: 100%; font-size: 12px; }
th, td { text-align: left; padding: 6px 14px 6px 0; border-bottom: 1px solid var(--grid); white-space: nowrap; vertical-align: middle; }
th {
  color: var(--text-muted); font-weight: 600; position: sticky; top: 0; z-index: 1;
  background: var(--surface-1); padding-top: 9px; padding-bottom: 7px;
}
td.wrap { white-space: normal; min-width: 220px; }
td:last-child, th:last-child { padding-right: 0; }
.sortbtn {
  font: inherit; font-weight: 600; color: var(--text-muted); background: none; border: 0;
  padding: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 4px;
}
.sortbtn:hover { color: var(--text-primary); }
.sortbtn .arrow { font-size: 9px; color: var(--text-secondary); }

tbody tr:hover { background: var(--surface-2); }
.pname { font-weight: 600; }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600;
  border: 1px solid var(--border); background: var(--surface-2);
}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; }

.seen { display: inline-flex; align-items: baseline; gap: 4px; font-variant-numeric: tabular-nums; }
/* the "at or before" marker: a bound is not a timestamp and must not look like one */
.seen .bound { color: var(--text-muted); font-weight: 700; cursor: help; }
.seen-t { color: var(--text-primary); }
.tag {
  font-size: 9px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-muted); border: 1px solid var(--border); border-radius: 3px; padding: 0 4px;
  cursor: help;
}

.hist { display: inline-flex; gap: 4px; }
.hchip {
  font-size: 9.5px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
  border: 1px solid var(--border); border-radius: 3px; padding: 1px 5px; cursor: help;
}
/* dashed = failed because the reply came after the window. Hover says so in words; on the
   board this is scanning texture, and the card spells it out. */
.hchip.is-late { border-style: dashed; }

.reply { display: inline-flex; align-items: baseline; gap: 8px; max-width: 46ch; }
.reply .sender { color: var(--text-primary); font-weight: 500; flex: 0 0 auto; }
.reply .excerpt { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.empty { color: var(--text-muted); font-size: 12px; padding: 18px 0 22px; text-align: center; }

/* ---------- 5. penalties total ---------- */
.totals { margin-top: 14px; }
.tot-num { font-size: 30px; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.tot-num b { font-weight: 700; }
.tot-unit { font-size: 15px; font-weight: 600; color: var(--text-secondary); }
.tot-usd { font-size: 15px; font-weight: 500; color: var(--text-muted); margin-left: 8px; }
.tot-sub { margin-top: 4px; }
.est-tag {
  font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-secondary); border: 1px solid var(--axis); border-radius: 4px; padding: 0 5px;
  margin-left: 4px;
}
.tot-why { margin-top: 8px; font-size: 11.5px; color: var(--text-muted); }
.tot-why summary { cursor: pointer; }
.tot-why p { margin-top: 5px; max-width: 90ch; line-height: 1.5; }

.foot { margin-top: 22px; font-size: 11px; color: var(--text-muted); border-top: 1px solid var(--grid); padding-top: 10px; max-width: 100ch; }

/* held-but-not-live: the last good state stays readable and stops looking current. The lookup
   card is in here because a stale "OK" is the most dangerous thing this page can show. */
body.offline .incident, body.offline .board, body.offline .queue, body.offline .feedbar,
body.offline .lookup, body.offline .totals {
  opacity: .5; filter: saturate(.55); transition: opacity .15s;
}

/* ---------- phone: providers check this away from a desk ---------- */
@media (max-width: 860px) {
  .pair { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  body { padding: 12px 14px 32px; }
  .topbar { flex-direction: column; align-items: flex-start; gap: 4px; }
  .incident { gap: 12px; }
  .inc-side { align-items: flex-start; width: 100%; }
  .chips { justify-content: flex-start; }
  .hero { font-size: 32px; }
  .feed-sub { flex-basis: 100%; }
  .ctl { width: 100%; }
  .ctl input, .ctl select, #query, #lk-input { width: 100%; min-width: 0; }
  .lk-combo { max-width: none; }
  .lk-listbox { max-height: 50vh; }
  .board { padding: 4px 10px 8px; }
  .scroll { max-height: none; }
  /* the operator's raw-source column is the one that cannot fit; the five public columns stay
     and the table scrolls inside its own box rather than pushing the page sideways. Keyed on
     the column name, because nth-child would hide the wrong thing in public mode. */
  .c-source { display: none; }
  .qhead .key { margin-left: 0; }
  .lk-big { font-size: 28px; }
  .replybox { font-size: 12px; }
  .penwhy { max-width: none; }
}


/* ---------- title breadcrumb ----------
   NODAO / Internet Computer (ICP) / Incident Response.
   The first two crumbs are context and recede; the last one is the page and carries the
   weight, so a provider arriving from a chat link sees where they are and what this is in
   a single line rather than a wordmark bar plus a heading repeating it. */
.crumbs {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .45rem;
  font-size: 1.02rem; font-weight: 400; margin: 0;
}
.crumb { color: var(--text-3); text-decoration: none; }
a.crumb:hover { color: var(--text-1); text-decoration: underline; }
.crumbsep { color: var(--text-3); opacity: .6; }
.crumb-now { color: var(--text-1); font-weight: 700; }
