/* AXIOM :: Mission Control
 *
 * An instrument panel, not a marketing page. The operator is on an incident bridge at
 * 03:00 and needs to answer one question fast: did the agent do the irreversible thing
 * twice? Everything here is subordinate to that.
 *
 * Rules held throughout:
 *   - One alarm colour (--alarm). It is spent ONLY on duplicate effects, FAILED,
 *     DEAD_LETTER and dead workers. If red is on screen, something is actually wrong.
 *   - All data is monospace with tabular figures so columns of numbers line up and a
 *     digit changing does not reflow the row.
 *   - Headings are Charter, a screen serif. The contrast against all-mono data is what
 *     makes the crash-window table read as a specification rather than as UI chrome.
 *   - Hairlines are 1px at low contrast. Structure comes from alignment, not from boxes.
 */

/* ──────────────────────────────────────────────────────────────────── tokens ── */
:root {
  /* Type. Everything must resolve from system fonts — no network at runtime. */
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, "JetBrains Mono",
          "IBM Plex Mono", "DejaVu Sans Mono", Consolas, monospace;
  --serif: Charter, "Iowan Old Style", "Bitstream Charter", "Source Serif Pro",
           Georgia, "Times New Roman", serif;

  /* Ground. Near-black with a faint green cast; pure #000 bands badly on video. */
  --bg:       #0a0c0b;
  --panel:    #0e1110;
  --panel-2:  #121614;
  --raised:   #161b19;

  --rule:     #1d2220;
  --rule-2:   #2a302d;
  --rule-3:   #3a423e;

  --text:     #dadfda;
  --dim:      #8e958f;
  --faint:    #5c635e;
  --ghost:    #3d4441;

  /* Signals. Hue is never the only difference — fill and shape carry it too. */
  --alarm:    #ff4a35;   /* reserved: duplicates, FAILED, DEAD_LETTER, dead worker */
  --hot:      #e07b30;   /* ACTION_PREPARED — a receipt exists, an effect may exist */
  --warn:     #d3a53f;   /* LEASED, stale heartbeat */
  --ok:       #4fb98b;   /* SUCCEEDED, healthy */
  --hold:     #6f9bb5;   /* AWAITING_APPROVAL — a human owns it */
  --slate:    #79837e;   /* READY */

  --alarm-bg: #24100d;
  --hot-bg:   #201409;
  --ok-bg:    #0d1a15;
  --hold-bg:  #0e1619;

  --focus:    #7fb0c9;

  --h-top:    44px;
  --h-mission: 104px;
}

/* ───────────────────────────────────────────────────────────────────── reset ── */
*, *::before, *::after { box-sizing: border-box; }
/* Author styles beat the UA sheet, so any `display` set on a class would otherwise
 * defeat the `hidden` attribute. Everything here is toggled by `hidden`; assert it once. */
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
h1, h2, h3, h4 { margin: 0; font-weight: 400; }
p { margin: 0; }
button, input, select { font: inherit; color: inherit; }
table { border-collapse: collapse; width: 100%; }

::selection { background: #2b3a35; }

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--rule-2); }
::-webkit-scrollbar-thumb:hover { background: var(--rule-3); }

:focus-visible { outline: 1px solid var(--focus); outline-offset: 1px; }

/* Shared micro-label. Used for every field name in the interface. */
.lbl, .panel-note, .view-sub, .kv b, .fld > span {
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
}

#app {
  height: 100%;
  display: grid;
  /* The mission row sizes to its content: with every task state occupied the count strip
   * runs to three lines, and a fixed height clipped it. The third row is the guided-proof
   * strip — one line idle, three once a run brings the step rail in. The last row is the
   * receipts footer. The body row takes what is left. */
  grid-template-rows: var(--h-top) auto auto minmax(0, 1fr) auto;
}

/* ──────────────────────────────────────────────────────────────────── topbar ── */
.topbar {
  display: flex; align-items: center; gap: 24px;
  padding: 0 14px;
  border-bottom: 1px solid var(--rule-2);
  background: var(--panel);
}
.brand { display: flex; align-items: baseline; gap: 9px; }
.brand-mark {
  font-family: var(--serif);
  font-size: 19px;
  letter-spacing: 0.16em;
  color: var(--text);
}
.brand-sub {
  font-size: 9.5px; letter-spacing: 0.22em; color: var(--faint);
  border-left: 1px solid var(--rule-2); padding-left: 9px;
}

.health { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.hx {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 9.5px; letter-spacing: 0.12em; color: var(--dim);
}
.hver { font-size: 9.5px; color: var(--ghost); letter-spacing: 0.08em; }

/* The indicator lamp. Shape is a plain square-ish dot; state is carried by colour
 * AND by whether it is filled, so it survives a desaturated screen recording. */
.dot {
  width: 7px; height: 7px; display: inline-block;
  border: 1px solid var(--ghost); background: transparent;
}
.is-ok  .dot, .dot.is-ok  { background: var(--ok);    border-color: var(--ok); }
.is-bad .dot, .dot.is-bad { background: var(--alarm); border-color: var(--alarm); }
.is-warn .dot, .dot.is-warn { background: var(--warn); border-color: var(--warn); }
.hx.is-bad { color: var(--alarm); }

.topright { display: flex; align-items: center; gap: 14px; }
.demo { display: flex; gap: 6px; }
.clock { font-size: 11px; color: var(--dim); letter-spacing: 0.06em; }

/* ───────────────────────────────────────────────────────────────── buttons ── */
.btn {
  background: var(--raised);
  border: 1px solid var(--rule-2);
  border-radius: 0;
  color: var(--dim);
  font-size: 9.5px; letter-spacing: 0.12em;
  padding: 4px 9px;
  cursor: pointer;
  transition: color .12s, border-color .12s, background .12s;
}
.btn:hover { color: var(--text); border-color: var(--rule-3); background: #1b211e; }
.btn:active { background: #0f1412; }
.btn-danger:hover { color: var(--alarm); border-color: #4a2019; background: var(--alarm-bg); }
.btn-xs { padding: 3px 7px; }
.btn-go { padding: 4px 14px; color: var(--text); border-color: var(--rule-3); align-self: end; }
.btn-x { padding: 4px 10px; }
.btn.is-on { color: var(--text); border-color: var(--focus); }
.btn:disabled { opacity: .4; cursor: default; }

.btn-approve:hover { color: var(--ok); border-color: #1f4436; background: var(--ok-bg); }
.btn-reject:hover  { color: var(--alarm); border-color: #4a2019; background: var(--alarm-bg); }

/* ─────────────────────────────────────────────────────────────── mission ── */
.mission {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) 268px;
  gap: 22px;
  padding: 11px 14px 9px;
  border-bottom: 1px solid var(--rule-2);
  background: var(--panel);
  align-items: start;
}
.mission-title {
  font-family: var(--serif);
  font-size: 18px; line-height: 1.15;
  letter-spacing: 0.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mission-goal {
  color: var(--dim); font-size: 11px; margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mission-meta { display: flex; gap: 16px; margin-top: 7px; flex-wrap: wrap; }
.kv { display: inline-flex; align-items: baseline; gap: 6px; font-size: 10.5px; color: var(--dim); }
.uuid { color: var(--ghost); font-size: 10px; }

.mission-budget { display: flex; flex-direction: column; gap: 5px; padding-top: 2px; }
.lbl-row { display: flex; justify-content: space-between; align-items: baseline; }
.budget-nums { font-size: 11.5px; color: var(--text); }
.budget-nums .over { color: var(--alarm); }

.bar {
  position: relative; height: 7px;
  background: #090b0a; border: 1px solid var(--rule-2);
}
.bar-fill {
  height: 100%; width: 0%;
  background: var(--slate);
  transition: width .5s cubic-bezier(.22,.61,.36,1), background .3s;
}
.bar-fill.is-warn  { background: var(--warn); }
.bar-fill.is-alarm { background: var(--alarm); }
/* Quarter ticks — reading a proportion off a bare bar is guesswork. */
.bar-ticks {
  position: absolute; inset: 0; pointer-events: none;
  background-image: linear-gradient(90deg, transparent calc(25% - 1px), var(--rule-2) calc(25% - 1px), var(--rule-2) 25%, transparent 25%),
                    linear-gradient(90deg, transparent calc(50% - 1px), var(--rule-2) calc(50% - 1px), var(--rule-2) 50%, transparent 50%),
                    linear-gradient(90deg, transparent calc(75% - 1px), var(--rule-2) calc(75% - 1px), var(--rule-2) 75%, transparent 75%);
}

/* Swatch colours, shared by the legend, the mission state strip and the rewind diff.
 * Declared once here so the palette lives in exactly one file. */
.mark.m-PENDING           { background: var(--ghost); }
.mark.m-READY             { background: var(--slate); }
.mark.m-LEASED            { background: var(--warn); }
.mark.m-AWAITING_APPROVAL { background: var(--hold); }
.mark.m-ACTION_PREPARED   { background: var(--hot); }
.mark.m-SUCCEEDED         { background: var(--ok); }
.mark.m-FAILED            { background: var(--alarm); }
.mark.m-DEAD_LETTER       { background: var(--alarm); outline: 1px solid #6b2a20; outline-offset: 1px; }
.mark.m-CANCELLED         { background: transparent; box-shadow: inset 0 0 0 1px var(--ghost); }
.rw-row .mark { width: 7px; height: 7px; display: inline-block; }

.statestrip { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 2px; }
.sc { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; color: var(--dim); }
.sc b { color: var(--text); font-size: 11px; }
.sc .mark { width: 7px; height: 7px; display: inline-block; }

/* The money shot. Calm by construction: it is text-coloured, not green, and the only
 * thing that makes it alarm-red is the number ceasing to be zero. */
.moneyshot {
  border-left: 1px solid var(--rule-2);
  padding-left: 16px;
  display: flex; flex-direction: column; gap: 1px;
}
.bignum {
  font-family: var(--serif);
  font-size: 46px; line-height: 1;
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 1px 0 2px;
  font-variant-numeric: tabular-nums lining-nums;
}
.moneyshot.is-alarm .bignum { color: var(--alarm); }
.moneyshot.is-alarm .lbl { color: var(--alarm); }
.money-sub { display: flex; flex-direction: column; gap: 0; font-size: 10px; color: var(--faint); }
.money-sub b { color: var(--dim); font-weight: 400; }

/* ─────────────────────────────────────────────────────────────────── body ── */
.body {
  display: grid;
  grid-template-columns: 234px minmax(0, 1fr) 316px;
  min-height: 0;
}
.rail {
  border-right: 1px solid var(--rule-2);
  display: flex; flex-direction: column;
  min-height: 0; overflow-y: auto;
  background: var(--panel);
}
.center { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.stream {
  border-left: 1px solid var(--rule-2);
  display: flex; flex-direction: column; min-height: 0;
  background: var(--panel);
}

/* ────────────────────────────────────────────────────────────────── panels ── */
.panel { border-bottom: 1px solid var(--rule); display: flex; flex-direction: column; min-height: 0; }
.panel-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 8px 11px 6px;
  border-bottom: 1px solid var(--rule);
}
.panel-head h2 {
  font-size: 9.5px; letter-spacing: 0.16em; color: var(--dim); text-transform: uppercase;
}
.panel-body { padding: 7px 11px 9px; min-height: 0; overflow-y: auto; }
.panel-foot {
  padding: 5px 11px 8px;
  font-size: 9.5px; color: var(--ghost); line-height: 1.35;
}
.empty { color: var(--ghost); font-size: 10.5px; }

/* ── worker pool ── */
.worker {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 8px;
  padding: 6px 0; border-bottom: 1px solid var(--rule);
}
.worker:last-child { border-bottom: 0; }
.worker-ref { font-size: 11px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.worker-age { font-size: 11px; color: var(--ok); text-align: right; }
.worker.is-stale .worker-age { color: var(--warn); }
.worker.is-dead  .worker-age { color: var(--alarm); }
.worker.is-dead  .worker-ref { color: var(--faint); text-decoration: line-through; }
.worker-sub { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; }
.worker-status { font-size: 9px; letter-spacing: 0.1em; color: var(--faint); }
.worker-shards { font-size: 9px; letter-spacing: 0.08em; color: var(--ghost); }
.worker.is-stale .worker-status { color: var(--warn); }
.worker.is-dead  .worker-status { color: var(--alarm); }

/* 16 shard slots, lit for the shards this worker owns. A worker dying visibly
 * hands its lit slots to another row. */
.shardmap { display: flex; gap: 1px; margin-left: auto; }
.shardmap i { width: 4px; height: 8px; background: #171d1a; display: block; }
.shardmap i.on { background: var(--ok); }
.worker.is-stale .shardmap i.on { background: var(--warn); }
.worker.is-dead  .shardmap i.on { background: #3a1a15; }

/* ── unsettled receipts ── */
.receipt { padding: 5px 0; border-bottom: 1px solid var(--rule); font-size: 10.5px; }
.receipt:last-child { border-bottom: 0; }
.receipt .r-top { display: flex; justify-content: space-between; gap: 8px; }
.receipt .r-key { color: var(--hot); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.receipt .r-amt { color: var(--text); }
.receipt .r-sub { color: var(--ghost); font-size: 9.5px; }

/* ── rewind ── */
.rewind-ctl { display: flex; gap: 4px; margin-bottom: 7px; }
.rewind-out { font-size: 10.5px; }
.rw-at { color: var(--ghost); font-size: 9.5px; margin-bottom: 4px; }
.rw-row { display: flex; justify-content: space-between; gap: 8px; padding: 1.5px 0; }
.rw-row span { color: var(--dim); }
.rw-row b { color: var(--text); font-weight: 400; }
.rw-row .delta { color: var(--ok); }
.rw-row .delta.neg { color: var(--hot); }

/* ───────────────────────────────────────────────────────────────────── tabs ── */
.tabs {
  display: flex; gap: 0;
  border-bottom: 1px solid var(--rule-2);
  background: var(--panel);
  flex: 0 0 auto;
  /* Scroll rather than spill into the event journal once the labels stop fitting. */
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { height: 0; }
.tab {
  position: relative;
  background: transparent; border: 0; border-right: 1px solid var(--rule);
  padding: 9px 15px 8px;
  color: var(--faint);
  font-size: 9.5px; letter-spacing: 0.14em;
  cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 7px;
  transition: color .12s, background .12s;
}
.tab:hover { color: var(--dim); background: var(--panel-2); }
.tab.is-on { color: var(--text); background: var(--bg); }
.tab.is-on::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--text);
}
.tab-n {
  font-size: 8.5px; color: var(--ghost);
  border: 1px solid var(--rule-2); padding: 0 3px; line-height: 1.35;
}
.tab.is-on .tab-n { color: var(--dim); border-color: var(--rule-3); }
.badge {
  font-style: normal; font-size: 9px;
  background: var(--hold); color: #06110f; padding: 0 4px; line-height: 1.5;
}

.views { flex: 1 1 auto; min-height: 0; position: relative; }
.view { display: none; height: 100%; flex-direction: column; min-height: 0; }
.view.is-on { display: flex; }

.view-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 8px 14px 7px; border-bottom: 1px solid var(--rule);
  flex: 0 0 auto;
}
.view-title { font-family: var(--serif); font-size: 13px; letter-spacing: 0.02em; color: var(--text); white-space: nowrap; }
.view-sub { text-align: right; }
.view-foot {
  display: flex; justify-content: space-between; align-items: center; gap: 14px;
  padding: 6px 14px 7px; border-top: 1px solid var(--rule);
  font-size: 9.5px; color: var(--ghost); flex: 0 0 auto;
}
.view-foot b { color: var(--faint); font-weight: 400; }
.foot-key { white-space: nowrap; }
.foot-key b { margin-left: 8px; margin-right: 3px; color: var(--dim); }
.head-l { display: flex; align-items: baseline; gap: 10px; }
.scroller { overflow: auto; min-height: 0; flex: 1 1 auto; }

/* ── legend + fence meter ── */
.legend { display: flex; flex-wrap: wrap; gap: 2px 11px; }
.lg { display: inline-flex; align-items: center; gap: 5px; font-size: 9px; color: var(--faint); letter-spacing: 0.05em; }
.lg .mark { width: 6px; height: 6px; }

.fence-meter { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.fence-meter b { font-size: 17px; color: var(--text); font-weight: 400; }
.fence-meter.is-live b { color: var(--hot); }
.fence-delta { font-size: 11px; color: var(--hot); min-width: 20px; }

/* ────────────────────────────────────────────────────────────── task grid ── */
.taskgrid {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  /* Rows absorb spare height instead of leaving a dead slab under the grid — a 30-task
   * mission fills its panel, and a 300-task one still packs to the 56px floor and
   * scrolls. The demo is recorded on a 30-task mission, so the small case is the one
   * that has to look composed. */
  grid-auto-rows: minmax(56px, 1fr);
  gap: 1px;
  padding: 1px;
  background: var(--rule);          /* the gap IS the hairline grid */
  align-content: stretch;
}
.cell {
  position: relative;
  background: var(--panel-2);
  border-left: 2px solid var(--ghost);
  padding: 6px 8px 6px 7px;
  cursor: pointer;
  min-height: 56px;
  display: flex; flex-direction: column; gap: 2px;
  transition: background .15s;
}
.cell:hover { background: var(--raised); }
.cell-key {
  font-size: 11px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cell-state { font-size: 9px; letter-spacing: 0.08em; color: var(--dim); }
.cell-meta {
  margin-top: auto; display: flex; gap: 7px;
  font-size: 9.5px; color: var(--ghost);
}
.cell-meta .ep { color: var(--faint); }
.cell-meta .ep.bumped { color: var(--hot); }
.cell-meta .at.retry { color: var(--warn); }

/* State skins. Colour + left rule weight + background tint, three cues not one. */
.cell.s-PENDING           { border-left-color: var(--ghost); }
.cell.s-PENDING .cell-state { color: var(--faint); }
.cell.s-READY             { border-left-color: var(--slate); }
.cell.s-READY .cell-state { color: var(--slate); }
.cell.s-LEASED            { border-left-color: var(--warn); background: #14140d; }
.cell.s-LEASED .cell-state { color: var(--warn); }
.cell.s-ACTION_PREPARED   { border-left-color: var(--hot); background: var(--hot-bg); }
.cell.s-ACTION_PREPARED .cell-state { color: var(--hot); }
.cell.s-AWAITING_APPROVAL { border-left-color: var(--hold); background: var(--hold-bg); }
.cell.s-AWAITING_APPROVAL .cell-state { color: var(--hold); }
/* Success is the boring case and must not compete for attention with the two states
 * that mean something is at stake. Dimmed on purpose — 27 bright green labels would
 * drown the one orange cell that an operator actually needs to find. */
.cell.s-SUCCEEDED         { border-left-color: #2f6e53; }
.cell.s-SUCCEEDED .cell-state { color: #3f8867; }
.cell.s-SUCCEEDED .cell-key { color: var(--dim); }
.cell.s-FAILED            { border-left-color: var(--alarm); background: var(--alarm-bg); }
.cell.s-FAILED .cell-state { color: var(--alarm); }
.cell.s-CANCELLED         { border-left-color: var(--ghost); }
.cell.s-CANCELLED .cell-key { color: var(--faint); text-decoration: line-through; }
.cell.s-DEAD_LETTER       { border-left-color: var(--alarm); background: var(--alarm-bg); }
.cell.s-DEAD_LETTER .cell-state { color: var(--alarm); }
/* DEAD_LETTER also gets a hatch so it separates from FAILED without relying on hue. */
.cell.s-DEAD_LETTER::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .3;
  background: repeating-linear-gradient(-45deg, transparent 0 5px, #4a2019 5px 6px);
}

/* Transitions. A short flash, not a bounce — motion here means "look", nothing else. */
@keyframes flash-state {
  0%   { background: #2b332f; }
  100% { background: inherit; }
}
@keyframes flash-fence {
  0%, 55% { background: #4a2a10; border-left-color: var(--hot); }
  100%    { background: inherit; }
}
.cell.did-change { animation: flash-state .7s ease-out; }
.cell.did-fence  { animation: flash-fence 1.5s ease-out; }

/* The epoch chip is the fence made visible. It stays marked after the flash decays so
 * an operator arriving late can still see which tasks were fenced. */
.cell .fencemark {
  position: absolute; top: 0; right: 0;
  width: 0; height: 0;
  border-top: 8px solid var(--hot);
  border-left: 8px solid transparent;
}

/* ─────────────────────────────────────────────────────────────────── tables ── */
.tbl { font-size: 11px; }
.tbl th {
  position: sticky; top: 0; z-index: 1;
  background: var(--panel);
  text-align: left; font-weight: 400;
  font-size: 9.5px; letter-spacing: 0.1em; color: var(--faint); text-transform: uppercase;
  padding: 7px 10px 6px;
  border-bottom: 1px solid var(--rule-2);
  white-space: nowrap;
}
.tbl td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
  color: var(--dim);
}
.tbl tbody tr:hover td { background: var(--panel-2); }
.tbl .num { text-align: right; color: var(--text); white-space: nowrap; }
.tbl .strong { color: var(--text); }
.tbl .mut { color: var(--ghost); }
.tbl .alarm { color: var(--alarm); }
.tbl .ok { color: var(--ok); }
.tbl .warn { color: var(--warn); }
.tbl .wrap { white-space: normal; line-height: 1.4; }
/* Ledger: every column is nowrap so nothing breaks mid-token, and the 52-character
 * idempotency key absorbs the remaining width and ellipsizes rather than shoving the
 * CREATED column off the right edge. max-width:0 is what makes that work in a table. */
#ledger-tbl td, #ledger-tbl th { white-space: nowrap; }
#ledger-tbl .c-key {
  width: 100%; max-width: 0; overflow: hidden; text-overflow: ellipsis;
}

/* ── crash-window spec ── */
.spec-head { padding: 14px 18px 12px; border-bottom: 1px solid var(--rule); flex: 0 0 auto; max-width: 74ch; }
.spec-title { font-family: var(--serif); font-size: 20px; letter-spacing: 0.01em; }
.spec-lede {
  font-family: var(--serif); font-size: 13px; line-height: 1.55;
  color: var(--dim); margin-top: 5px;
}
.spec-lede em { color: var(--text); font-style: italic; }
.spec-list { padding: 2px 0 20px; }
.cw {
  display: grid; grid-template-columns: 56px minmax(0, 1fr);
  border-bottom: 1px solid var(--rule);
  padding: 11px 18px 12px 0;
}
.cw-id {
  font-family: var(--serif); font-size: 17px; color: var(--dim);
  letter-spacing: 0.04em; text-align: center; padding-top: 1px;
  border-left: 2px solid var(--rule-2); margin-right: 12px;
}
.cw-YES .cw-id { border-left-color: var(--alarm); color: var(--text); }
.cw-UNKNOWN .cw-id { border-left-color: var(--hot); color: var(--text); }
.cw-NO .cw-id { border-left-color: var(--ok); }
.cw-top { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 6px; }
.cw-when { font-family: var(--serif); font-size: 14.5px; color: var(--text); font-weight: 400; }
.cw-row { display: grid; grid-template-columns: 82px minmax(0, 1fr); gap: 10px; padding: 1.5px 0; }
.cw-row > span {
  font-size: 9px; letter-spacing: 0.12em; color: var(--ghost);
  text-transform: uppercase; padding-top: 2px;
}
.cw-row p { font-size: 11px; color: var(--dim); line-height: 1.45; }
.cw-guar { font-family: var(--serif); font-size: 12.5px; font-style: italic; color: var(--text); }
.eff { font-size: 9.5px; letter-spacing: 0.1em; white-space: nowrap; }
.eff-YES { color: var(--alarm); }
.eff-UNKNOWN { color: var(--hot); }
.eff-NO { color: var(--ok); }
.testref { font-size: 9.5px; color: var(--ghost); }

/* ─────────────────────────────────────────────────────────────────── memory ── */
.recall { padding: 9px 14px 8px; border-bottom: 1px solid var(--rule); flex: 0 0 auto; }
.recall-row { display: flex; gap: 9px; align-items: end; }
.fld { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.fld.grow { flex: 1 1 auto; }
.fld-k { width: 52px; }
.fld input, .fld select {
  background: #090b0a; border: 1px solid var(--rule-2); border-radius: 0;
  padding: 4px 7px; font-size: 11px; color: var(--text); width: 100%;
}
.fld input:focus, .fld select:focus { border-color: var(--focus); outline: none; }

.recall-status { display: flex; align-items: center; gap: 16px; margin-top: 7px; }
.idx { display: inline-flex; align-items: center; gap: 6px; font-size: 9.5px; letter-spacing: 0.1em; color: var(--faint); }
.idx.is-ok  { color: var(--ok); }
.idx.is-bad { color: var(--alarm); }
.recall-delta { font-size: 10.5px; color: var(--hot); }

.recall-hits { padding: 0 14px; flex: 0 0 auto; max-height: 232px; overflow-y: auto; }
.hit {
  display: grid; grid-template-columns: 46px 1fr auto;
  gap: 10px; align-items: start;
  padding: 7px 0; border-bottom: 1px solid var(--rule);
}
.hit-sim { font-size: 11px; color: var(--text); }
.simbar { height: 3px; background: #161b19; margin-top: 3px; }
.simbar i { display: block; height: 100%; background: var(--slate); }
.hit-body { min-width: 0; }
.hit-content { font-size: 11px; color: var(--text); line-height: 1.4; }
.hit-meta { font-size: 9.5px; color: var(--ghost); margin-top: 2px; display: flex; gap: 10px; flex-wrap: wrap; }
.hit.is-gone { opacity: .3; }
.hit.is-gone .hit-content { text-decoration: line-through; color: var(--alarm); }

.mem-head { border-top: 1px solid var(--rule-2); }
.chk { display: inline-flex; align-items: center; gap: 6px; font-size: 9.5px; letter-spacing: 0.1em; color: var(--faint); text-transform: uppercase; cursor: pointer; }
.chk input { accent-color: var(--slate); }

.rc { font-size: 9px; letter-spacing: 0.1em; padding: 1px 5px; border: 1px solid; white-space: nowrap; }
.rc-ACTIONABLE  { color: var(--ok);    border-color: #1f4436; }
.rc-ADVISORY    { color: var(--slate); border-color: var(--rule-2); }
.rc-SUPERSEDED  { color: var(--faint); border-color: var(--rule-2); }
.rc-QUARANTINED { color: var(--alarm); border-color: #4a2019; background: var(--alarm-bg); }

/* Trust as a 4-slot meter — a level is a position on a scale, not a word. */
.trust { display: inline-flex; gap: 2px; align-items: center; }
.trust i { width: 4px; height: 9px; background: #1b211e; display: block; }
.trust i.on { background: var(--slate); }
.trust.t3 i.on { background: var(--ok); }
.trust.t0 i.on { background: var(--warn); }

/* Fixed layout: auto layout kept sizing columns from their max-content and pushed the
 * QUARANTINE button off the right edge. Fixed gives each column exactly what is declared
 * here and wraps the prose inside it. */
.tbl-mem { table-layout: fixed; }
.tbl-mem td { font-size: 10.5px; padding: 7px 10px; }
.tbl-mem .m-content { color: var(--text); line-height: 1.45; }
.tbl-mem .c-ctx { width: 22%; }
.tbl-mem .c-adm { width: 18%; }
.tbl-mem .c-act { width: 106px; }
.tbl-mem .c-ctx, .tbl-mem .c-adm, .tbl-mem .c-act { vertical-align: top; }
.tbl-mem .m-key { overflow-wrap: anywhere; }
.tbl-mem .m-key { color: var(--dim); }
.tbl-mem .m-cls { font-size: 9px; letter-spacing: 0.1em; color: var(--ghost); }
.tbl-mem .m-qr { font-size: 9.5px; color: var(--alarm); margin-top: 3px; }
.tbl-mem tr.is-q .m-content { color: var(--faint); }
.tbl-mem .c-n .mut { margin-bottom: 3px; }
.tbl-mem .m-out { margin-top: 4px; font-size: 9.5px; letter-spacing: 0.08em; }
.tbl-mem .m-prov { font-size: 9.5px; color: var(--ghost); margin: 4px 0 3px; }
.tbl-mem .c-n { vertical-align: top; }
.recall-hits { max-height: 244px; }

/* ──────────────────────────────────────────────────────────────── approvals ── */
.approvals { padding: 12px 14px; overflow-y: auto; min-height: 0; flex: 1 1 auto;
             display: flex; flex-direction: column; gap: 10px; }
.appr {
  border: 1px solid var(--rule-2); border-left: 2px solid var(--hold);
  background: var(--panel-2);
  padding: 11px 13px;
}
.appr-top { display: flex; justify-content: space-between; gap: 14px; align-items: baseline; }
.appr-action { font-family: var(--serif); font-size: 15px; color: var(--text); }
.appr-amt { font-size: 17px; color: var(--text); white-space: nowrap; }
.appr-reason { color: var(--dim); font-size: 11px; margin-top: 4px; line-height: 1.45; }
.appr-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 4px 16px; margin-top: 9px;
  border-top: 1px solid var(--rule); padding-top: 8px;
}
.appr-f { display: flex; flex-direction: column; gap: 1px; }
.appr-f span { font-size: 9px; letter-spacing: 0.1em; color: var(--ghost); text-transform: uppercase; }
/* break-word, not break-all: the evidence ids are separated by spaces, so wrapping
 * should happen at the separators rather than slicing a uuid across two lines. */
.appr-f b { font-size: 10.5px; color: var(--dim); font-weight: 400; overflow-wrap: break-word; }
.appr-acts { display: flex; gap: 6px; margin-top: 10px; align-items: center; }
.appr-acts .who {
  background: #090b0a; border: 1px solid var(--rule-2); padding: 4px 7px;
  font-size: 10.5px; color: var(--dim); width: 200px;
}
.appr-expiry { margin-left: auto; font-size: 10px; color: var(--faint); }
.appr-expiry.is-soon { color: var(--warn); }

/* ────────────────────────────────────────────────────────────── event stream ── */
.events { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.ev {
  display: grid; grid-template-columns: 58px 1fr;
  gap: 8px; padding: 5px 11px 5px 9px;
  border-bottom: 1px solid var(--rule);
  border-left: 2px solid transparent;
  font-size: 10.5px;
}
.ev-time { color: var(--ghost); font-size: 9.5px; padding-top: 1px; }
.ev-main { min-width: 0; }
.ev-type { color: var(--text); }
.ev-trans { color: var(--faint); font-size: 9.5px; }
.ev-trans b { color: var(--dim); font-weight: 400; }
.ev-actor { color: var(--ghost); font-size: 9.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-act {
  display: inline-block; font-size: 9px; letter-spacing: 0.1em;
  border: 1px solid var(--rule-2); padding: 0 4px; margin: 2px 0 1px; color: var(--dim);
}
.ev.e-recovered .ev-act { color: var(--hot); border-color: #5a3315; }
/* The recovery rationale. Deliberately given real leading and near-body colour: it is
 * the system explaining, in its own words, why re-sending a $300 refund was safe. */
.ev-why {
  display: block; font-size: 10px; line-height: 1.4; color: var(--dim);
  margin: 1px 0 2px; word-break: break-word;
}
.ev.e-recovered .ev-why { color: #bfa588; }

/* The four event types an operator actually cares about get a coloured left rule.
 * Everything else stays quiet so these read at a glance. */
.ev.e-recovered  { border-left-color: var(--hot);   background: #17110a; }
.ev.e-recovered .ev-type { color: var(--hot); letter-spacing: 0.04em; }
.ev.e-dead       { border-left-color: var(--alarm); background: var(--alarm-bg); }
.ev.e-dead .ev-type { color: var(--alarm); }
.ev.e-approval   { border-left-color: var(--hold); }
.ev.e-approval .ev-type { color: var(--hold); }
.ev.e-quarantine { border-left-color: var(--alarm); }
.ev.e-quarantine .ev-type { color: var(--alarm); }
.ev.e-settled .ev-type { color: var(--ok); }

@keyframes ev-in { from { background: #232b28; } to { background: inherit; } }
.ev.is-new { animation: ev-in 1s ease-out; }

/* ────────────────────────────────────────────────────────────────── drawer ── */
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 520px; max-width: 92vw;
  background: var(--panel); border-left: 1px solid var(--rule-3);
  box-shadow: -1px 0 0 var(--rule), -24px 0 48px rgba(0,0,0,.5);
  display: flex; flex-direction: column;
  z-index: 40;
}
.drawer-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 12px;
  padding: 11px 14px 10px; border-bottom: 1px solid var(--rule-2);
}
.drawer-head h2 { font-family: var(--serif); font-size: 16px; }
.drawer-body { overflow-y: auto; padding: 0 0 24px; min-height: 0; }
.d-sec { border-bottom: 1px solid var(--rule); padding: 10px 14px 12px; }
.d-sec > h3 {
  font-size: 9.5px; letter-spacing: 0.14em; color: var(--faint);
  text-transform: uppercase; margin-bottom: 7px;
}
.d-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 5px 14px; }
.d-f { display: flex; flex-direction: column; }
.d-f span { font-size: 9px; letter-spacing: 0.1em; color: var(--ghost); text-transform: uppercase; }
.d-f b { font-size: 11px; color: var(--text); font-weight: 400; word-break: break-all; }
pre.json {
  margin: 0; padding: 8px 10px; background: #090b0a; border: 1px solid var(--rule);
  font-size: 10.5px; color: var(--dim); overflow-x: auto; line-height: 1.45;
  white-space: pre-wrap; word-break: break-word;
}
.att {
  border: 1px solid var(--rule-2); border-left: 2px solid var(--hot);
  padding: 8px 10px; margin-bottom: 7px; background: var(--panel-2);
}
.att.a-SUCCEEDED { border-left-color: var(--ok); }
.att.a-ABANDONED { border-left-color: var(--ghost); }
.att.a-FAILED_TERMINAL, .att.a-FAILED_RETRYABLE { border-left-color: var(--alarm); }
.att-top { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.att-state { font-size: 10px; letter-spacing: 0.08em; color: var(--hot); }
.att.a-SUCCEEDED .att-state { color: var(--ok); }
.att.a-FAILED_TERMINAL .att-state, .att.a-FAILED_RETRYABLE .att-state { color: var(--alarm); }
.att-kv { display: grid; grid-template-columns: 88px 1fr; gap: 1px 8px; margin-top: 5px; font-size: 10px; }
.att-kv span { color: var(--ghost); letter-spacing: 0.06em; }
.att-kv b { color: var(--dim); font-weight: 400; word-break: break-all; }
.att-kv b.key { color: var(--hot); }

.d-ev { display: grid; grid-template-columns: 26px 1fr auto; gap: 8px;
        padding: 4px 0; border-bottom: 1px solid var(--rule); font-size: 10.5px; }
.d-ev:last-child { border-bottom: 0; }
.d-ev .sq { color: var(--ghost); font-size: 9.5px; }
.d-ev .ty { color: var(--text); }
.d-ev .tr { color: var(--faint); font-size: 9.5px; }
.d-ev .ep { color: var(--hot); font-size: 9.5px; }

/* ─────────────────────────────────────────────────────────────────── toast ── */
.toast {
  position: fixed; bottom: 14px; left: 50%; transform: translateX(-50%);
  background: var(--raised); border: 1px solid var(--rule-3);
  padding: 7px 14px; font-size: 11px; color: var(--text);
  z-index: 60; max-width: 60ch;
}
.toast.is-bad { border-color: #4a2019; color: var(--alarm); background: var(--alarm-bg); }

/* ───────────────────────────────────────────────────────────────── narrower ── */
@media (max-width: 1180px) {
  .body { grid-template-columns: 206px minmax(0, 1fr) 268px; }
  .mission { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 232px; gap: 16px; }
  .bignum { font-size: 38px; }
  .tab { padding: 9px 9px 8px; gap: 5px; letter-spacing: 0.08em; }
  .tab-n { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ══════════════════════════════════════════════════ poll meter + chaos control ══
 *
 * Added for the Lambda deployment, where a request is a metered resource rather than a
 * free local socket. Nothing above this line is restyled; these are new elements only.
 */

/* The poll readout sits inside the existing .hx lamp, so it inherits its colour and its
 * OK/BAD state. Bright enough to read at 720p, quiet enough not to compete with DB. */
.hx b { font-weight: 400; color: var(--dim); letter-spacing: 0.04em; min-width: 34px; }
.hx b.is-paused { color: var(--faint); }
.reqs { font-size: 9px; letter-spacing: 0.1em; color: var(--ghost); }

/* KILL A WORKER is not an error, so it does not get --alarm. It gets --hot, the colour
 * this interface already uses for "a receipt exists and an effect may exist" — which is
 * precisely the state the button creates. */
.btn-chaos:hover { color: var(--hot); border-color: #4a3016; background: var(--hot-bg); }

/* ── the recovery banner ──
 * Full grid width, 12px type, one line. It is the only narration on the page and it is
 * sized so that a viewer reading a 720p recording can take it in without pausing. */
.chaosbar {
  display: flex; align-items: baseline; gap: 12px;
  padding: 7px 10px; margin-bottom: 1px;
  border: 1px solid var(--rule-2); border-left-width: 2px;
  background: var(--panel-2);
  font-size: 11px; color: var(--dim);
}
.chaosbar .cb-lbl {
  font-size: 10px; letter-spacing: 0.16em; color: var(--dim); white-space: nowrap;
}
.chaosbar .cb-txt { color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.chaosbar.is-armed { border-color: #4a3016; border-left-color: var(--hot); background: var(--hot-bg); }
.chaosbar.is-armed .cb-lbl { color: var(--hot); animation: cb-pulse 1.4s ease-in-out infinite; }

/* .chaosbar.is-expired has NO rule on purpose. "No takeover observed" is not an alarm and
 * not a success, so it inherits the neutral base above — the bar goes quiet rather than
 * changing colour, which is the whole point of having exactly one alarm colour. */

.chaosbar.is-fenced { border-color: var(--hot); border-left-color: var(--hot); background: var(--hot-bg); }
.chaosbar.is-fenced .cb-lbl { color: var(--hot); font-size: 12px; letter-spacing: 0.14em; }
.chaosbar.is-fenced .cb-txt { color: var(--text); }

@keyframes cb-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* The epoch transition, shown for 20s after a takeover. Larger than the chip it replaces
 * because "e1 → e2" appearing is legible on video where "1" becoming "2" is not. */
.cell-meta .ep.is-callout {
  font-size: 11px; color: var(--hot);
  border-bottom: 1px solid #4a3016; padding-bottom: 1px;
}
.cell-meta .ep.is-callout b { font-weight: 400; color: var(--hot); margin: 0 2px; }

/* ═══════════════════════════════════════════ the entry, explained to a stranger ══
 *
 * Everything below this line was added for one reason: a judge lands here knowing
 * nothing and has ninety seconds. The console above is correct and dense and assumes you
 * already know what AXIOM is. These are the surfaces that answer "what am I looking at",
 * "what am I about to watch" and "which number is the proof" — under exactly the rules
 * the header of this file already sets. No new fonts, no gradients, no glow, one alarm
 * colour, structure from alignment.
 */

/* ─────────────────────────────────────────────────────── the two entry buttons ── */

/* BRIEFING sits inside .brand so it reads as part of the identity block rather than as
 * one more control in a row of four. Quiet, because it is the second thing you press. */
.btn-brief {
  margin-left: 4px;
  border-color: var(--rule);
  color: var(--faint);
  font-size: 9px;
}
.btn-brief:hover { color: var(--text); border-color: var(--rule-3); }

/* RUN THE PROOF is the one control a stranger should press, so it is the only button on
 * the page carrying body-text colour and a full-contrast rule. It earns that by being
 * separated from the manual group with a hairline rather than by being made bigger or
 * rounder or a different hue. */
.btn-proof {
  color: var(--text);
  border-color: var(--rule-3);
  padding: 4px 13px;
  letter-spacing: 0.16em;
}
.btn-proof:hover { border-color: var(--focus); background: #1b211e; }
.btn-proof:disabled { opacity: 1; color: var(--faint); border-color: var(--rule); }
.topright > .demo { border-left: 1px solid var(--rule-2); padding-left: 14px; margin-left: 2px; }

/* ───────────────────────────────────────────── the verdict under the money shot ── */

/* Reserved space so the strip does not reflow when the verdict changes length. */
.money-verdict {
  margin-top: 5px;
  font-size: 9.5px; letter-spacing: 0.06em; line-height: 1.35;
  color: var(--ghost);
  border-top: 1px solid var(--rule);
  padding-top: 4px;
}
/* "0 duplicates, but nothing was retried" is not an alarm and not a success. It is the
 * honest middle, and it gets the neutral colour on purpose. */
.money-verdict.is-unproven { color: var(--warn); }
.money-verdict.is-proven   { color: var(--ok); letter-spacing: 0.08em; }
.money-verdict.is-alarm    { color: var(--alarm); }

/* ═══════════════════════════════════════════════════════════════ the guided proof ══ */

.proof {
  border-bottom: 1px solid var(--rule-2);
  background: var(--panel-2);
  padding: 8px 14px 9px;
}

/* The step rail is seven top rules, not seven boxes. A step is "done" when its rule goes
 * green and "now" when its rule goes to body colour — position on a line, which is what
 * progress actually is. */
.pf-rail { display: flex; list-style: none; margin: 0 0 8px; padding: 0; gap: 0; }
.pfs {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: baseline; gap: 6px;
  border-top: 2px solid var(--rule-2);
  padding: 5px 10px 0 0;
  font-size: 9px; letter-spacing: 0.1em; color: var(--ghost);
}
.pfs b { font-weight: 400; color: var(--ghost); }
.pfs span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pfs.is-done { border-top-color: #2f6e53; color: var(--faint); }
.pfs.is-done b { color: #3f8867; }
.pfs.is-now { border-top-color: var(--text); color: var(--text); }
.pfs.is-now b { color: var(--text); }

.pf-line {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto auto;
  grid-template-areas: 'n step . ev stop' 'say say say say say';
  gap: 3px 12px;
  align-items: baseline;
}
.pf-n    { grid-area: n; font-size: 10px; color: var(--faint); }
.pf-step { grid-area: step; font-family: var(--serif); font-size: 14.5px; color: var(--text); white-space: nowrap; }
.pf-ev   { grid-area: ev; display: flex; gap: 16px; align-items: baseline; }
#pf-stop { grid-area: stop; }

/* Two lines, wrapping, full width. The narration is up to ~150 characters and ellipsising
 * it on one line cut it exactly where the meaning was. */
.pf-say {
  grid-area: say;
  font-size: 11px; line-height: 1.4; color: var(--dim);
  max-height: 2.85em; overflow: hidden;
}
.pf-say.is-hot  { color: var(--hot); }
.pf-say.is-miss { color: var(--warn); }

.pev { display: inline-flex; align-items: baseline; gap: 6px; }
.pev b { font-size: 15px; font-weight: 400; color: var(--text); }
.pev span { font-size: 9px; letter-spacing: 0.1em; color: var(--faint); }
.pev.is-alarm b, .pev.is-alarm span { color: var(--alarm); }

/* ══════════════════════════════════════════════════════ the fence, made legible ══
 *
 * The proof of this whole system is one integer incrementing inside one 132px cell. That
 * is true and it is unwatchable. The cell keeps its chip and its corner tick for the
 * operator; this block restates the same fact at a size that survives a 720p screen
 * recording. It appears — it does not glow, pulse or slide, because it is a readout.
 */
.fenceproof {
  border: 1px solid #4a3016; border-left-width: 2px; border-left-color: var(--hot);
  background: var(--hot-bg);
  margin-bottom: 1px;
}
.fp-row {
  display: grid; grid-template-columns: 132px minmax(0, 1fr);
  gap: 0 14px; padding: 9px 12px 10px;
  border-top: 1px solid #3a2611;
}
.fp-row:first-child { border-top: 0; }
.fp-lbl {
  font-size: 9.5px; letter-spacing: 0.14em; color: var(--hot);
  padding-top: 5px;
}
.fp-big { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.fp-task { font-size: 15px; color: var(--text); }
.fp-ep { font-size: 20px; color: var(--hot); line-height: 1.1; }
.fp-ep b { font-weight: 400; }
.fp-ep i { font-style: normal; color: #8a6236; margin: 0 5px; }
.fp-mono { font-size: 12px; color: var(--text); word-break: break-all; }
.fp-same {
  font-size: 9px; letter-spacing: 0.16em; color: var(--hot);
  border: 1px solid #5a3315; padding: 1px 5px; white-space: nowrap;
}
.fp-note { font-size: 10.5px; line-height: 1.45; color: #bfa588; margin-top: 3px; }
.fp-note b { font-weight: 400; color: var(--hot); }

/* ────────────────────────────────────────────────────────── ESCALATED, not DEAD ── */

/* An escalation is not a failure: nothing was sent, no money moved, and a human now owns
 * the case. It gets --hold, the colour this panel already spends on "a human owns it".
 * A DASHED left rule rather than a solid one is what separates it from
 * AWAITING_APPROVAL, so the two do not rely on being different shades of the same blue —
 * one is blocked and live, the other is handed off and finished. */
.mark.m-ESCALATED { background: transparent; box-shadow: inset 0 0 0 1.5px var(--hold); }
.cell.s-ESCALATED { border-left-color: var(--hold); border-left-style: dashed; }
.cell.s-ESCALATED .cell-state { color: var(--hold); }
.cell.s-ESCALATED .cell-key { color: var(--dim); }

/* ─────────────────────────────────────────────────────────────── worker outcomes ── */

/* A worker that drained its queue and exited wrote stopped_at on the way out. That is a
 * normal end, so it is grey. Red stays for the worker that stopped heartbeating without
 * ever saying so, which is the exact condition the fencing token exists for. */
.worker.is-exited .worker-ref { color: var(--faint); }
.worker.is-exited .worker-age, .worker.is-exited .worker-status { color: var(--ghost); }
.worker.is-exited .shardmap i.on { background: #232926; }
.worker-more {
  padding: 6px 0 1px; font-size: 9.5px; letter-spacing: 0.06em; color: var(--ghost);
}
/* /api/agents has no LIMIT, so this panel is the one that grows without bound. Cap its
 * height so it can never squeeze UNSETTLED RECEIPTS and REWIND off the rail. */
#panel-workers .panel-body { max-height: 232px; }

/* ══════════════════════════════════════════════════════════ the memory classes ══ */

.classes { padding: 11px 14px 12px; border-bottom: 1px solid var(--rule); flex: 0 0 auto; }
.classes-head { display: flex; align-items: baseline; justify-content: space-between; gap: 18px; }
.classes-head h4 { font-size: 9.5px; letter-spacing: 0.14em; color: var(--dim); }
.classes-head > span { font-size: 10px; color: var(--faint); text-align: right; }
.classes-head em { color: var(--dim); font-style: italic; }

.classes-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; margin-top: 8px;
  background: var(--rule);            /* the gap is the hairline, as in the task grid */
  border: 1px solid var(--rule);
}
.mc { background: var(--panel); padding: 7px 9px 8px; border-left: 2px solid var(--ghost); }
.mc-n { font-size: 10.5px; color: var(--text); letter-spacing: 0.06em; display: block; }
.mc-a { font-size: 9px; letter-spacing: 0.14em; display: block; margin-top: 1px; }
.mc p { font-size: 10px; line-height: 1.4; color: var(--faint); margin-top: 5px; }
/* Authority as three levels, coloured by what they can actually do: advisory memory is
 * the neutral READY grey, procedural memory is the colour of a human decision, and
 * execution state is the colour this panel already uses for "an effect is at stake". */
.mc-advise    { border-left-color: var(--slate); }
.mc-advise .mc-a { color: var(--slate); }
.mc-auth      { border-left-color: var(--hold); }
.mc-auth .mc-a { color: var(--hold); }
.mc-constrain { border-left-color: var(--hot); }
.mc-constrain .mc-a { color: var(--hot); }

/* ═══════════════════════════════════════════════ the crash-window timeline ══ */

.tl { padding: 15px 18px 14px; border-bottom: 1px solid var(--rule); max-width: 92ch; }
.tl-r {
  position: relative; padding: 3px 0 3px 24px;
  font-size: 11px; color: var(--faint); line-height: 1.5;
}
.tl-r::before {
  content: ''; position: absolute; left: 6px; top: 0; bottom: 0;
  width: 1px; background: var(--rule-3);
}
.tl-r:first-child::before { top: 9px; }
.tl-dot {
  position: absolute; left: 3px; top: 8px; width: 7px; height: 7px;
  background: var(--rule-3); border: 1px solid var(--rule-3);
}
.tl-op { color: var(--dim); }
.tl-op b { font-weight: 400; color: var(--text); }
.tl-op span { color: var(--faint); margin-left: 8px; }
.tl-commit .tl-dot { background: var(--ok); border-color: var(--ok); }
.tl-c {
  font-size: 8.5px; letter-spacing: 0.16em; color: var(--ok);
  border: 1px solid #1f4436; padding: 0 4px; margin: 0 8px 0 8px !important;
}
.tl-irrev { padding-top: 6px; padding-bottom: 6px; }
.tl-irrev b { font-weight: 400; color: var(--text); }
.tl-irrev .tl-dot { background: var(--alarm); border-color: var(--alarm); }
.tl-mark {
  font-size: 9px; letter-spacing: 0.16em; color: var(--alarm); margin-left: 12px;
}
.tl-w .tl-id {
  font-family: var(--serif); font-size: 12px; color: var(--faint);
  border: 1px solid var(--rule-2); padding: 0 5px; margin-right: 10px;
}
.tl-w-hot { color: var(--dim); }
.tl-w-hot .tl-id { color: var(--hot); border-color: #4a3016; }
.tl-w-hot em { color: var(--text); font-style: italic; }
.tl-foot {
  margin-top: 9px; padding-left: 24px;
  font-size: 10px; color: var(--ghost);
}

/* The one window this browser session can witness first-hand — and only once BOTH a
 * fence advance and a provider replay have been seen. */
.cw-live { background: #12100c; }
.cw-obs {
  font-size: 9px; letter-spacing: 0.14em; color: var(--hot);
  border: 1px solid #4a3016; padding: 1px 5px; white-space: nowrap; margin-left: auto;
}
.cw-top { align-items: baseline; }

/* The replayed row IS the crash, in the provider's own book. */
#ledger-tbl tr.is-replay td { background: #16120b; }
#ledger-tbl tr.is-replay td:first-child { box-shadow: inset 2px 0 0 var(--hot); }

/* ══════════════════════════════════════════════════════════ the counterexample ══ */

.ce { padding: 16px 20px 30px; }
.ce-lede {
  font-family: var(--serif); font-size: 13px; line-height: 1.6;
  color: var(--dim); max-width: 80ch;
}
.ce-lede em { color: var(--text); font-style: italic; }
.ce-setup {
  display: flex; gap: 12px; align-items: baseline;
  margin: 14px 0 2px; font-size: 11px; color: var(--dim);
}
.ce-tbl { width: 100%; max-width: 108ch; font-size: 11.5px; }
.ce-tbl th, .ce-tbl td {
  text-align: left; padding: 6px 14px; vertical-align: baseline;
  border-bottom: 1px solid var(--rule);
}
.ce-h {
  font-weight: 400; font-family: var(--serif); font-size: 15px; color: var(--dim);
  border-bottom: 1px solid var(--rule-2); padding-top: 10px;
}
.ce-h span {
  display: block; font-family: var(--mono); font-size: 9px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ghost); margin-top: 1px;
}
.ce-h-b { color: var(--text); }
/* One hairline down the middle. The comparison is carried by alignment, not by two
 * boxes sitting next to each other. */
.ce-h-b, .ce-b { border-left: 1px solid var(--rule-2); }
.ce-k {
  color: var(--faint); font-size: 9.5px; letter-spacing: 0.1em;
  text-transform: uppercase; width: 22%;
}
.ce-a { color: var(--dim); width: 38%; }
.ce-b { color: var(--text); width: 40%; }
.ce-tbl tbody tr:hover td { background: var(--panel-2); }

.ce-total td { padding-top: 9px; padding-bottom: 9px; font-size: 13px; }
.ce-total .ce-k { color: var(--dim); font-size: 10px; }
.ce-bad .ce-a { color: var(--alarm); }
.ce-good .ce-b { color: var(--ok); }
/* The only 22px numbers on the page after the money shot, and the only other place the
 * alarm colour is spent: a real customer is $300 down in the left column. */
.ce-money td { padding-top: 12px; padding-bottom: 12px; }
.ce-money .ce-a, .ce-money .ce-b {
  font-family: var(--serif); font-size: 24px; line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
}
.ce-money .ce-a { color: var(--alarm); }
.ce-money .ce-b { color: var(--text); }

.ce-say {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1px; margin-top: 18px; max-width: 108ch;
  background: var(--rule); border: 1px solid var(--rule);
}
.ce-q { background: var(--panel); padding: 9px 12px 11px; border-left: 2px solid var(--rule-3); }
.ce-q-b { border-left-color: var(--hot); }
.ce-q p { font-size: 11px; line-height: 1.5; color: var(--dim); margin-top: 5px; }
.ce-q-b p { color: var(--text); }

.ce-verdict {
  font-family: var(--serif); font-size: 15px; color: var(--text);
  margin: 18px 0 0; max-width: 80ch;
}
.ce-prov {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px 28px; margin-top: 20px; padding-top: 14px;
  border-top: 1px solid var(--rule); max-width: 108ch;
}
.ce-prov p { font-size: 10.5px; line-height: 1.5; color: var(--faint); margin-top: 5px; max-width: 62ch; }
.ce-prov pre.json { margin-top: 7px; }

/* ══════════════════════════════════════════════════════════════════ the briefing ══
 *
 * It has to answer "what am I looking at" in the first three seconds and then get out of
 * the way. Built out of the same parts as everything else — hairlines, one serif for the
 * argument, mono for anything that is data — so that dismissing it feels like closing a
 * panel of the instrument rather than closing an ad.
 */
.brief {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(5, 7, 6, 0.88);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.brief-card {
  width: min(980px, 100%); max-height: min(860px, 92vh);
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--rule-3);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .6);
}
.brief-top {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 20px;
  padding: 16px 22px 15px; border-bottom: 1px solid var(--rule-2);
}
.brief-eyebrow { font-size: 9.5px; letter-spacing: 0.22em; color: var(--faint); }
.brief-setup {
  font-family: var(--serif); font-size: 16px; line-height: 1.4;
  color: var(--dim); margin-top: 8px; max-width: 70ch;
}
.brief-q {
  font-family: var(--serif); font-size: 31px; line-height: 1.15;
  font-style: italic; color: var(--text); margin-top: 3px;
}

/* Multi-column rather than grid: the four sections have very different heights, and a
 * two-track grid leaves a slab of dead space under whichever one is shorter. Columns
 * balance the flow, and column-width (not column-count) means the card falls to one
 * column on a narrow window without a second media query. */
.brief-body {
  overflow-y: auto; min-height: 0;
  padding: 4px 22px 18px;
  column-width: 380px; column-gap: 32px;
}
.bsec { padding: 14px 0 4px; break-inside: avoid; -webkit-column-break-inside: avoid; }
.bsec > h3 {
  font-size: 9.5px; letter-spacing: 0.16em; color: var(--faint);
  border-bottom: 1px solid var(--rule); padding-bottom: 6px; margin-bottom: 9px;
}
.blead {
  font-family: var(--serif); font-size: 13px; line-height: 1.6; color: var(--dim);
}
.blead em { color: var(--text); font-style: italic; }
.blead b { font-weight: 400; }
.bnote { font-size: 10.5px; line-height: 1.5; color: var(--faint); margin-top: 9px; }
.bnote em { color: var(--dim); font-style: italic; }
.hot { color: var(--hot); }

.btbl { width: 100%; font-size: 10.5px; }
.btbl td { padding: 4px 10px 4px 0; border-bottom: 1px solid var(--rule); vertical-align: baseline; }
.btbl tr:last-child td { border-bottom: 0; }
.bt-n { color: var(--text); white-space: nowrap; }
.bt-a { font-size: 9px; letter-spacing: 0.14em; white-space: nowrap; }
.a-adv  { color: var(--slate); }
.a-auth { color: var(--hold); }
.a-con  { color: var(--hot); }
.btbl td:last-child { color: var(--faint); line-height: 1.45; }

.bsteps { margin: 0; padding-left: 0; list-style: none; counter-reset: bs; }
.bsteps li {
  position: relative; padding: 5px 0 6px 26px;
  font-size: 11px; line-height: 1.5; color: var(--faint);
  border-bottom: 1px solid var(--rule);
  counter-increment: bs;
}
.bsteps li:last-child { border-bottom: 0; }
.bsteps li::before {
  content: counter(bs);
  position: absolute; left: 0; top: 5px;
  font-family: var(--serif); font-size: 12px; color: var(--ghost);
}
.bsteps b { font-weight: 400; color: var(--text); }
.bsteps em { color: var(--dim); font-style: italic; }

.brief-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 12px 22px 13px; border-top: 1px solid var(--rule-2);
  background: var(--panel-2);
}
.brief-acts { display: flex; gap: 8px; }
.brief-hint { font-size: 10px; color: var(--ghost); }
.brief-hint b { color: var(--faint); font-weight: 400; border: 1px solid var(--rule-2); padding: 0 4px; }

/* ─────────────────────────────────────────────────────────────────── narrower ── */

/* Six tabs do not fit alongside their index numbers until about 1400px, and a tab that
 * has scrolled out of a hidden-scrollbar strip is a tab a judge will never find. Drop
 * the numbers first; they are a shortcut hint, not information. */
@media (max-width: 1400px) {
  .tab-n { display: none; }
  .tab { padding: 9px 12px 8px; }
}
@media (max-width: 1180px) {
  .brief-q { font-size: 25px; }
  .brief-setup { font-size: 14px; }
  .pf-step { font-size: 13px; }
  .fp-ep { font-size: 17px; }
}

/* A footnote under the AXIOM value, for the two rows where the number needs an
 * explanation and leaving it unexplained would read as a discrepancy. */
.ce-note { font-size: 9.5px; line-height: 1.45; color: var(--ghost); margin-top: 3px; max-width: 46ch; }

/* ══════════════════════════════════ the evidence that was only in the terminal ══
 *
 * Everything below was added for one reason: the strongest results in this repository
 * lived in CLI scripts, where a judge with three minutes never looks. Same rules as the
 * rest of this file — hairlines, one alarm colour, structure from alignment, system
 * fonts, no gradients and no glow. Nothing above this line is restyled; every selector
 * here is either a new element or a variant class on one.
 */

/* ─────────────────────────────────────────────────────── the proof strip, idle ── */

/* The strip is on screen from the first frame now, so an untouched page still states the
 * procedure and prints the three counters out of the database. Idle it is one line; a run
 * brings the rail in above it. */
.proof.is-idle { background: var(--panel); }
.proof.is-idle .pf-n {
  font-size: 9px; letter-spacing: 0.16em; color: var(--ghost);
  border: 1px solid var(--rule-2); padding: 1px 5px;
}
.proof.is-idle .pf-step { color: var(--dim); }
.proof.is-idle .pf-say  { color: var(--faint); }
.proof.is-idle .pev b   { color: var(--dim); }

/* The tour's optional eighth step. Offered only at the verdict, so it is allowed to carry
 * body colour without competing with RUN THE PROOF — by then that button is spent. */
.btn-more { color: var(--text); border-color: var(--rule-3); letter-spacing: 0.1em; }
.btn-more:hover { border-color: var(--focus); background: #1b211e; }

/* ──────────────────────────────────────────────────────────── the receipts strip ── */

/* A spec sheet, not a row of badges: label in the micro-label style, value in data mono,
 * hairline separators, and every item carries its provenance in its title. It wraps
 * rather than scrolls — a receipt that has scrolled out of view is a receipt nobody
 * reads, and one extra 17px line is a cheap price for that. */
.receipts {
  display: flex; align-items: baseline; gap: 12px;
  padding: 5px 14px 6px;
  border-top: 1px solid var(--rule-2);
  background: var(--panel);
}
.rc-lbl {
  font-size: 9px; letter-spacing: 0.2em; color: var(--faint);
  white-space: nowrap; flex: 0 0 auto;
}
.rc-items { display: flex; flex-wrap: wrap; gap: 2px 0; min-width: 0; }
.rc-i {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 0 11px; border-left: 1px solid var(--rule-2);
  font-size: 9.5px; white-space: nowrap;
}
.rc-i:first-child { border-left: 0; padding-left: 0; }
.rc-k { font-size: 8.5px; letter-spacing: 0.14em; color: var(--ghost); }
.rc-v { color: var(--dim); }
.rc-v b { font-weight: 400; color: var(--text); }
.rc-v b.is-alarm { color: var(--alarm); }

/* ──────────────────────────────────────────────────────── the recorded-run flag ── */

/* Worn by any panel showing a transcript instead of a live call. Deliberately the
 * loudest label in the interface after the alarm colour, because a recorded result
 * rendered as a live one is the one mistake this project cannot make. */
.rec {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  border: 1px solid var(--rule-3); border-left: 2px solid var(--warn);
  background: var(--panel-2);
  padding: 7px 11px 8px; margin-bottom: 14px;
}
.rec-tag {
  font-size: 9px; letter-spacing: 0.2em; color: var(--warn); white-space: nowrap;
}
.rec-why { font-size: 10px; color: var(--faint); }
.rec-cmd {
  font-family: var(--mono); font-size: 10px; color: var(--dim);
  background: #090b0a; border: 1px solid var(--rule); padding: 1px 6px;
}

/* ═══════════════════════════════════════════════════════════════ MEMORY DECIDES ══ */

.md { padding: 14px 18px 30px; }
.md-lede {
  font-family: var(--serif); font-size: 13px; line-height: 1.6;
  color: var(--dim); max-width: 84ch;
}
.md-lede em { color: var(--text); font-style: italic; }
.md-lede-2 { margin-top: 9px; color: var(--faint); }
.md-wait { font-size: 11px; color: var(--faint); margin-top: 16px; }

/* The track. Three slots side by side, because the claim is a value CHANGING and a
 * change is only legible against the thing it changed from. The decision is set in the
 * serif at 30px — the second-largest type on the page after the money shot — and the
 * cause sits directly beneath it, so the eye reads down a column rather than hunting. */
.md-track {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr);
  margin-top: 16px; max-width: 112ch;
  border: 1px solid var(--rule-2);
  background: var(--panel-2);
}
.mdt { padding: 11px 15px 13px; border-left: 2px solid var(--rule-2); min-width: 0; }
.mdt-n { display: block; font-size: 8.5px; letter-spacing: 0.18em; color: var(--ghost); }
.mdt-act {
  display: block; margin-top: 1px;
  font-family: var(--serif); font-size: 30px; line-height: 1.05;
  letter-spacing: 0.01em; color: var(--ghost);
}
.mdt-because {
  display: block; margin-top: 6px;
  font-size: 10px; line-height: 1.45; color: var(--faint);
}
.mdt-arrow {
  align-self: center; font-style: normal;
  color: var(--rule-3); font-size: 15px; padding: 0 2px;
}

/* Colour is the ACTION, never the position — an escalation in slot 1 would be the same
 * blue. RESEND is body colour because it is the safe default, not a success; ESCALATE is
 * --hold, which is what this panel already spends on "a human owns it". Neither is a
 * value judgement, and neither gets the alarm colour, because neither is a failure. */
.mdt.is-set .mdt-act.a-RESEND   { color: var(--text); }
.mdt.is-set .mdt-act.a-ESCALATE { color: var(--hold); }
.mdt.is-set .mdt-act.a-REPLAN   { color: var(--warn); }
.mdt.is-set.a-RESEND   { border-left-color: var(--rule-3); }
.mdt.is-set.a-ESCALATE { border-left-color: var(--hold); background: var(--hold-bg); }
.mdt.is-set.a-REPLAN   { border-left-color: var(--warn); }

@keyframes md-land { 0% { background: #262e2b; } 100% { background: inherit; } }
.mdt.is-fresh, .mdx.is-fresh { animation: md-land .75s ease-out; }

.md-flip {
  font-family: var(--serif); font-size: 15px; color: var(--text);
  margin-top: 12px; max-width: 84ch;
}
.md-flip.is-miss { color: var(--warn); font-size: 13px; }

/* One run: what it decided, why, and every memory it decided on. */
.mdx { margin-top: 20px; border-top: 1px solid var(--rule); padding-top: 11px; max-width: 112ch; }
.mdx-head { display: flex; align-items: baseline; gap: 12px; }
.mdx-n {
  font-size: 9px; letter-spacing: 0.16em; color: var(--ghost);
  border: 1px solid var(--rule-2); padding: 1px 5px;
}
.mdx-label { font-size: 12px; color: var(--text); }
.mdx-act {
  margin-left: auto; font-size: 11px; letter-spacing: 0.18em;
  border: 1px solid var(--rule-2); padding: 2px 8px; color: var(--dim);
}
.mdx-act.a-RESEND   { color: var(--text); border-color: var(--rule-3); }
.mdx-act.a-ESCALATE { color: var(--hold); border-color: #24404e; background: var(--hold-bg); }
.mdx-act.a-REPLAN   { color: var(--warn); border-color: #4a3d16; }
.mdx-why { font-size: 11px; line-height: 1.5; color: var(--dim); margin-top: 6px; max-width: 96ch; }
.mdx-delta {
  font-size: 10.5px; line-height: 1.5; color: var(--faint);
  margin-top: 6px; border-left: 2px solid var(--rule-2); padding-left: 9px;
}
.mdx-delta.is-moved { color: var(--text); border-left-color: var(--hold); }
.mdx-delta b { font-weight: 400; color: var(--hold); }
.mdx-hits { margin-top: 8px; }

/* The recalled memories reuse .hit from the recall panel unchanged. Two variants are
 * added: the memories that CAN move a decision, and the ones that have just left the
 * candidate set. */
.hit.is-adverse .hit-content { color: var(--text); }
.hit.is-adverse .simbar i { background: var(--hot); }
.hit-tag {
  font-size: 8.5px; letter-spacing: 0.14em; color: var(--hot);
  border: 1px solid #4a3016; padding: 1px 5px; white-space: nowrap;
}
.hit-tag.is-gone-tag { color: var(--faint); border-color: var(--rule-2); }
.mo { font-size: 9px; letter-spacing: 0.1em; }
.mo-DUPLICATE_EFFECT { color: var(--hot); }
.mo-HUMAN_REQUIRED   { color: var(--hold); }
.mo-RESOLVED         { color: #3f8867; }

.md-plan { margin-top: 22px; border-top: 1px solid var(--rule-2); padding-top: 11px; max-width: 112ch; }
.md-plan-top { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.md-plan-note { font-size: 10px; line-height: 1.5; color: var(--faint); max-width: 76ch; }
.md-plan pre.json { margin-top: 8px; font-size: 10px; color: var(--faint); }

.md-verdict {
  font-family: var(--serif); font-size: 14px; line-height: 1.55;
  margin-top: 16px; max-width: 84ch; color: var(--dim);
}
.md-verdict.is-proven   { color: var(--ok); }
.md-verdict.is-unproven { color: var(--warn); }

/* ═════════════════════════════════════════════════════════ STRIPE, IN THE LEDGER ══
 *
 * A band above the simulated ledger rather than a tab of its own: this tab is already
 * about a provider's own books, and the argument is that the same crash survives against
 * a book nobody here wrote. Capped in height so it can never push the ledger table it is
 * introducing off the screen.
 */
.sp {
  flex: 0 0 auto; max-height: 52%; overflow-y: auto;
  border-bottom: 1px solid var(--rule-2);
  background: var(--panel);
}
.sp-head {
  display: flex; align-items: baseline; gap: 14px;
  padding: 9px 14px 8px; border-bottom: 1px solid var(--rule);
}
.sp-id { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-width: 0; }
.sp-id h4 { font-size: 10px; letter-spacing: 0.18em; color: var(--text); }
.sp-sub { font-size: 9.5px; letter-spacing: 0.06em; color: var(--faint); }
.sp-flag {
  margin-left: auto; font-size: 9px; letter-spacing: 0.16em;
  border: 1px solid var(--rule-2); padding: 1px 6px; white-space: nowrap;
}
.sp-flag.is-live { color: var(--ok); border-color: #1f4436; }
.sp-flag.is-rec  { color: var(--warn); border-color: #4a3d16; }
.sp-head .btn-go { margin-left: auto; align-self: center; }
.sp-flag + .btn-go { margin-left: 0; }
.sp-body { padding: 11px 14px 14px; }
.sp-lede {
  font-family: var(--serif); font-size: 12.5px; line-height: 1.6;
  color: var(--dim); max-width: 92ch;
}
.sp-lede em { color: var(--text); font-style: italic; }

/* The six beats, as a wrapped rail rather than a list: it is a sequence, and a sequence
 * reads left to right in a band this short. */
.sp-steps {
  list-style: none; margin: 0 0 12px; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
.spx { background: var(--panel-2); padding: 6px 9px 7px; display: grid;
       grid-template-columns: 16px minmax(0, 1fr); gap: 0 6px; }
.spx b { grid-row: span 2; font-weight: 400; font-size: 10px; color: var(--ghost); padding-top: 1px; }
.spx-l { font-size: 10.5px; color: var(--text); line-height: 1.35; }
.spx-d { font-size: 9.5px; color: var(--faint); line-height: 1.4; word-break: break-word; }

.sp-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
  gap: 7px 20px; padding: 10px 0 2px; border-top: 1px solid var(--rule);
}
.spf { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.spf span { font-size: 8.5px; letter-spacing: 0.14em; color: var(--ghost); text-transform: uppercase; }
.spf b { font-size: 12px; font-weight: 400; color: var(--text); overflow-wrap: anywhere; }
.spf b.mono { font-size: 11px; color: var(--dim); }
.spf b.is-hot { color: var(--hot); }
.spf b.is-warn { color: var(--warn); }
.spf b.is-alarm { color: var(--alarm); }

.sp-verdict {
  font-family: var(--serif); font-size: 13px; line-height: 1.55;
  margin-top: 12px; max-width: 88ch; color: var(--dim);
}
.sp-verdict em { color: var(--text); font-style: italic; }
.sp-verdict.is-proven { color: var(--ok); }
.sp-verdict.is-unproven { color: var(--warn); }
.sp-foot { margin-top: 9px; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.sp-link { font-size: 10.5px; color: var(--hold); text-decoration: none; border-bottom: 1px solid #24404e; }
.sp-link:hover { color: var(--text); border-bottom-color: var(--rule-3); }
.sp-link-note { font-size: 9.5px; color: var(--ghost); }

/* ═══════════════════════════════════════════════════════════════ BEYOND REFUNDS ══ */

.dm { padding: 14px 18px 30px; }
.dm-tbl { margin-top: 16px; max-width: 118ch; font-size: 11px; }
.dm-tbl .dm-t { color: var(--text); white-space: nowrap; }
.dm-tbl .dm-n { color: var(--dim); white-space: nowrap; }
.dm-tbl .dm-u code { font-family: var(--mono); font-size: 10.5px; color: var(--hold); }
/* The ceiling is the whole point of the table, so it is the only column set larger than
 * the body — a number in the action's own unit, sitting where dollars would be. */
.dm-tbl .dm-c { font-size: 14px; color: var(--text); white-space: nowrap; }
.dm-tbl .dm-d { color: var(--faint); line-height: 1.45; }
.dm-src { margin-top: 7px; font-size: 9.5px; color: var(--ghost); }

/* The second domain's money shot, built out of the first one's parts: same .bignum, same
 * .money-sub, same .money-verdict. The unit under the number is the only difference, and
 * that is exactly the claim. */
.dm-shot {
  margin-top: 22px; padding: 14px 16px 15px; max-width: 118ch;
  border: 1px solid var(--rule-2); border-left: 2px solid var(--rule-3);
  background: var(--panel-2);
  display: grid; grid-template-columns: minmax(0, 210px) minmax(0, 1fr);
  gap: 4px 26px; align-items: start;
}
.dm-shot.is-alarm { border-left-color: var(--alarm); }
.dm-shot.is-alarm .bignum, .dm-shot.is-alarm .lbl { color: var(--alarm); }
.dm-shot .bignum { font-size: 42px; }
.dm-shot .money-sub { font-size: 11px; gap: 2px; padding-top: 4px; }
.dm-shot .money-verdict { grid-column: 1 / -1; margin-top: 8px; }

/* ─────────────────────────────────────────────────────────── eight tabs, not six ── */

/* Two tabs were added, and a tab that has scrolled out of a hidden-scrollbar strip is a
 * tab a judge will never find. The numbers go first (they are a shortcut hint, not
 * information), then the tracking tightens. Measured at 1280 and 1440, which are the two
 * widths this is recorded at. */
@media (max-width: 1520px) {
  .tab-n { display: none; }
  .tab { padding: 9px 11px 8px; letter-spacing: 0.1em; }
}
@media (max-width: 1340px) {
  .tab { padding: 9px 8px 8px; letter-spacing: 0.06em; }
}

@media (max-width: 1180px) {
  .md-track { grid-template-columns: minmax(0, 1fr); }
  .mdt-arrow { display: none; }
  .mdt { border-left-width: 2px; border-top: 1px solid var(--rule); }
  .dm-shot { grid-template-columns: minmax(0, 1fr); }
}

/* ───────────────────────────────────────── second pass, after looking at it ──
 *
 * Every rule below fixes something a screenshot showed rather than something the markup
 * suggested: a placeholder em dash rendering as a 30px rule, a button wrapping onto two
 * lines behind its own flag, a description column crushed to five words a line at 1280.
 */

/* An unfilled slot must read as "not answered yet", and an em dash set in a 30px serif
 * reads as a horizontal rule. Shrink it and take it down to the ghost weight. */
.mdt:not(.is-set) .mdt-act { font-size: 17px; color: var(--ghost); }

/* Buttons never wrap. RUN IT AGAIN broke across two lines once the LIVE flag appeared
 * beside it, which moved the whole Stripe header down half a line. */
.btn { white-space: nowrap; }

/* The Stripe band shares the ledger's scroller, so it sizes to its content and the table
 * follows it down. Its own max-height is gone with the same rule that clipped a verdict. */
.sp { max-height: none; overflow: visible; }
/* Five facts, one row at 1280 and up: the replay flag, the two ids and the two counts
 * belong on the same line — they are one sentence about one refund. */
.sp-facts { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); }
/* Sticky above a sibling section inside a shared scroller: the header must paint over the
 * band's own background when the table scrolls up under it. */
#ledger-tbl th { background: var(--panel); }

/* Fixed layout so the prose column keeps the width it needs. Auto layout gave RISK UNIT
 * and CEILING their max-content and crushed WHAT THE CEILING MEANS to four words a line. */
.dm-tbl { table-layout: fixed; }
.dm-tbl th:nth-child(1), .dm-tbl td:nth-child(1) { width: 11%; }
.dm-tbl th:nth-child(2), .dm-tbl td:nth-child(2) { width: 20%; }
.dm-tbl th:nth-child(3), .dm-tbl td:nth-child(3) { width: 17%; }
.dm-tbl th:nth-child(4), .dm-tbl td:nth-child(4) { width: 19%; }
.dm-tbl .dm-n { white-space: normal; }

/* The receipts strip is one line at 1280 with these tighter gutters, which is the width
 * this demo is recorded at. It still wraps rather than scrolls below that. */
@media (max-width: 1400px) {
  .rc-i { padding: 0 8px; gap: 5px; }
  .receipts { gap: 9px; }
}

/* The one string in the Stripe panel a judge has to leave with. It is Stripe's own
 * response header and it does not get to break across two lines to save 30px. */
.sp-facts .spf:first-child { grid-column: span 2; }
.spf b.is-hot { white-space: nowrap; }

/* The two Stripe ids need the same width for the same reason. A refund id is 27 characters
 * with no break opportunity in it, which needs 195px and was being handed a 161px column —
 * so `overflow-wrap: anywhere` snapped the last character onto a line of its own. These are
 * the ids a judge copies into the Stripe dashboard to check the claim in the other party's
 * UI; an id that ends in a hanging character reads as a rendering fault at exactly the
 * moment the panel is asking to be believed. */
.sp-facts .spf:has(b.mono) { grid-column: span 2; }

/* ─────────────────────────────────────────── against the endpoints as shipped ──
 *
 * The API returns more than the drafted contract promised: the memory proof carries the
 * receipt's key and the whole EXPLAIN, the broadcast carries a per-campaign rail, and
 * /api/proofs reports whether this deployment can reach Stripe at all. These style what
 * arrived.
 */

/* The key, printed once under the three runs. It is the quiet half of this panel's claim:
 * the decision moved twice and the key on the receipt never moved at all. */
.md-key {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin-top: 20px; padding: 9px 12px 10px;
  border: 1px solid #4a3016; border-left-width: 2px; border-left-color: var(--hot);
  background: var(--hot-bg); max-width: 112ch;
}
.md-key b { font-size: 12px; font-weight: 400; color: var(--text); word-break: break-all; }
.md-same {
  font-size: 9px; letter-spacing: 0.16em; color: var(--hot);
  border: 1px solid #5a3315; padding: 1px 5px; white-space: nowrap;
}
.md-plan-src { font-size: 9.5px; color: var(--ghost); margin-top: 5px; }

/* The campaign that crashed is the one to look at, so the relay's replay verdict gets the
 * same --hot left rule the refund receipt gets. */
.dm-steps { margin-top: 20px; }
.spx.is-replay { border-left: 2px solid var(--hot); background: var(--hot-bg); }
.spx.is-replay .spx-d { color: #bfa588; }

.sp-note {
  font-size: 11px; line-height: 1.5; color: var(--warn);
  border-left: 2px solid #4a3d16; padding-left: 10px; margin-bottom: 11px; max-width: 88ch;
}
.sp-note b { font-weight: 400; color: var(--text); }

/* Sub-facts inside the domains table: the operation a ceiling governs, the reversibility
 * it assumes, and whether the number came from a live policy row or the proof's default. */
.dm-op { font-size: 9px; letter-spacing: 0.06em; color: var(--ghost); margin-top: 2px; }

/* The toast was pinned 14px off the bottom, which is now where the receipts strip lives.
 * 46px clears the strip at its two-line height and is invisible at its one-line one. */
.toast { bottom: 46px; }

/* A Stripe id is 27 characters and belongs on one line: at 11px it wrapped after
 * "re_3U47WUAwRnm0fQgO3ku7", which turns an identifier into two half-identifiers. */
.spf b.mono { font-size: 10px; }

/* The public receipt is the one link in this panel a stranger can actually open, and it
 * used to sit at the same weight as the dashboard link that shows them a login screen.
 * Sized and coloured to win that pairing outright: it is the evidence, the other is a
 * convenience for the one person who already has the account. */
.sp-link.is-pub { font-size: 12px; color: var(--ok); border-bottom-color: #2b4a35; }
.sp-link.is-pub:hover { color: var(--text); border-bottom-color: var(--rule-3); }
/* The request-id pair reads as prose under its own facts row, not crushed against it. */
.sp-facts + .sp-lede { margin-top: 9px; }
/* nowrap for the same reason .spf b.mono is sized down: it broke after "original-", and a
 * header name split across two lines stops being a header name you can search Stripe for. */
.sp-lede .mono { font-family: var(--mono); font-size: 11px; color: var(--hold); white-space: nowrap; }

/* The memory view stacks four fixed-height blocks above its scroller, and their sum can
 * exceed the pane: the recall hit list was `flex: 0 0 auto`, so at 800px tall it pushed
 * the store table past the bottom of the body row and under the receipts strip. Letting
 * the hit list SHRINK is the whole fix — it already scrolls internally, so nothing is
 * lost, and the blocks above it keep the size they were given. */
.recall-hits { flex: 0 1 auto; min-height: 84px; }

/* At 720p the rail's panels were compressing instead of scrolling, so UNSETTLED RECEIPTS
 * printed its footnote on top of its own body. The rail already scrolls; the panels just
 * have to refuse to shrink. */
.rail > .panel { flex: 0 0 auto; }

/* The ceiling is the column the eye lands on, and at 1280 "2,000 RECIPIENTS" ended one
 * character away from the sentence in the next cell. Give it a real gutter. */
.dm-tbl .dm-c { padding-right: 22px; }

/* The gutter alone made it worse. The column is 19% of a fixed-layout table — 132px at
 * 1280 — and "2,000 RECIPIENTS" set at 14px is 145px wide; `white-space: nowrap` meant it
 * did not clip, it printed straight over the first word of the sentence beside it
 * (measured: scrollWidth 145 vs clientWidth 132). Let it wrap. The break falls between
 * the count and the unit, which is where a reader would put it anyway, and "$200.00" has
 * no space in it so the money row is unaffected. */
.dm-tbl .dm-c { white-space: normal; }
