/* MixOps schematic register — PNW palette · v13 (production canonical)
   Mirror of .superpowers/brainstorm/49061-1778279370/content/_shared.css.
   Rules, declare-before-code gate, and anti-patterns:
   .claude/skills/mixops-ui-register/SKILL.md */

/* ────────────────────────────────────────────────────────────────────
   Font · JetBrains Mono (free, OFL, self-hosted in assets/fonts/)
   Replaces the ui-monospace fallback chain · taller x-height + heavier
   stems give the dark-bg secondary text the legibility we were losing.
   Fallback chain to ui-monospace is preserved for first-paint and
   offline.
   ──────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'JetBrains Mono';
  font-style:  normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/JetBrainsMono-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style:  normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/JetBrainsMono-Medium.woff2') format('woff2');
}

/* ────────────────────────────────────────────────────────────────────
   Body weight bump 400 → 500 (2026-05-18 · typography critique wave 2).
   JetBrains Mono Medium is loaded via @font-face above. Single rule lifts
   perceived legibility across the entire site at 11px without changing
   size or color. The Regular weight stays available for inline <code>
   blocks or any element that EXPLICITLY wants "lighter than body."
   ──────────────────────────────────────────────────────────────────── */
html, body { font-weight: 500; }

:root {
  /* Canonical font stacks · use these everywhere, never inline the chain.
   * --font-sans: mixed register adopted 2026-05-27 — Inter for body / labels /
   * chrome, JetBrains Mono for data (IDs, timestamps, hex, paths). Pages opt in
   * via a per-page Google Fonts <link>; non-linking pages fall back to the
   * system sans chain. */
  --font-mono: 'JetBrains Mono', ui-monospace, Menlo, Consolas, "SF Mono", monospace;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  /* ────────────────────────────────────────────────────────────────────
   * SURFACE STACK · 5-tier depth (added 2026-05-18)
   *
   * The v13 register was originally flat-on-bg by deliberate choice.
   * That worked for tabular reports but read as "monochrome rectangle"
   * for workflow editors (knobmap, layout). This 5-tier stack gives
   * cards a tonal lift WITHOUT abandoning the schematic register —
   * still hairline borders, still mono font, still zero radius.
   *
   * Borrowed from the external-portal register's --p-* stack (see
   * docs/design/external-portal-register.md §"Token reference") but
   * namespaced as v13 tokens so brk-* primitives consume them.
   * NEVER reach into .portal-* primitives from a v13 surface — adopt
   * the technique, not the prefix.
   *
   *   Depth recipe for .brk-section / .brk-card:
   *     background: var(--surface);
   *     box-shadow: var(--elev-1), var(--rim);
   *     border: 1px solid var(--rule-strong);
   *
   *   Depth recipe for inputs sitting INSIDE a card:
   *     background: var(--bg-sunk);
   *
   * dark → light progression:
   *   --bg-sunk    sunk     inputs inside cards
   *   --bg-deep    recessed page background
   *   --bg         default fallback
   *   --surface    LIFTED   card background
   *   --surface-soft         hover / nested surface
   * ──────────────────────────────────────────────────────────────────── */
  --bg-sunk:      #0d0f10;   /* NEW · inputs sunk into card surfaces */
  --bg-deep:      #131517;   /* page background · recessed */
  --bg:           #181a1c;   /* default fallback (rare now) */
  --surface:      #1c1e20;   /* NEW · cards · .brk-section lifted off bg */
  --surface-soft: #202224;   /* alias of --bg-row · hover state · nested */
  --bg-row:       #202224;
  --bg-row-alt:   #1c1e20;
  --bg-sel:       #2a2c2e;

  /* Rim-light + elevation primitives (added 2026-05-18) · pairs with
   * --surface to create rim-lit card depth. Used as a stack:
   *   box-shadow: var(--elev-1), var(--rim);
   */
  --rim-light:    rgba(255, 255, 255, 0.04);
  --rim:          inset 0 1px 0 var(--rim-light);
  --elev-1:       0 1px 2px rgba(0, 0, 0, 0.30), 0 1px 4px rgba(0, 0, 0, 0.18);
  --elev-2:       0 2px 4px rgba(0, 0, 0, 0.35), 0 8px 24px rgba(0, 0, 0, 0.28);
  --elev-pressed: 0 1px 2px rgba(0, 0, 0, 0.4);

  /* Spacing scale (added 2026-05-18) · 8pt-adjacent. Use these instead
   * of ad-hoc inline padding/margin values. Mirrors the external-portal
   * scale (--p-s-N) so the two registers stay synchronized.
   */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 14px;
  --s-5: 18px;
  --s-6: 22px;
  --s-7: 32px;
  --s-8: 48px;

  --ink:          #c9bfb1;
  /* --ink-faint lifted #928a7c → #a39888 (2026-05-17) · gives secondary
   * text ~15% more legibility headroom at 11px on the dark bg. */
  --ink-faint:    #a39888;
  --ink-very-faint: #4a4842;

  /* Whisper-alpha rules (2026-05-18 · wave 8 · depth pass)
   * Borrowed from external-portal's --p-rule pattern · 6% / 12% alpha on
   * cream ink. On --surface (lifted card) bg they read as soft tonal
   * dividers; on --bg-deep (page canvas) they almost vanish. The point
   * is for rules to be FELT, not SEEN — whitespace + tonal contrast
   * carries the structure, lines only confirm boundaries where needed.
   *
   * Legacy solid values kept under --rule-solid / --rule-strong-solid
   * for the few places that genuinely need a visible separator on flat
   * (un-lifted) backgrounds. Default --rule / --rule-strong now alpha. */
  --rule:         rgba(201, 191, 177, 0.06);
  --rule-strong:  rgba(201, 191, 177, 0.12);
  --rule-solid:        #2c2e30;
  --rule-strong-solid: #3a4044;

  /* PNW / Downeast palette · 2-tier system (2026-05-18 lift)
   *
   *   DEFAULT (4.5+:1 AA at 11px body text) — used everywhere by default.
   *   RAISED  (5.8-7.1:1)                   — opt-in via .is-raised modifier
   *                                            or var(--*-raised) for elements
   *                                            that should read LOUDER than
   *                                            the surrounding context
   *                                            (active alarms, live indicators,
   *                                            primary CTAs in empty states,
   *                                            in-flight operations).
   *
   *   Standard ramp is C-base from raised-token-candidates.html with --ok
   *   bumped one tick brighter per user pick (lichen sage → spruce sage).
   *
   *   Color character: lichen sage / salish slate / madrona cedar /
   *   muddy amber — same family on both tiers, only luminance changes. */

  /* DEFAULT tier · just-AA */
  --alarm:        #b06d4f;    /* madrona · 4.50:1 */
  --alarm-tint:   rgba(176, 109, 79, 0.20);
  --alarm-row-tint: rgba(176, 109, 79, 0.10);
  --warn:         #b07c1f;    /* amber   · 4.71:1 */
  --warn-tint:    rgba(176, 124, 31, 0.18);
  --ok:           #728a70;    /* sage    · 4.62:1 */
  --ok-tint:      rgba(114, 138, 112, 0.18);
  --info:         #6d8da0;    /* slate   · 4.95:1 */
  --info-tint:    rgba(109, 141, 160, 0.16);

  /* RAISED tier · opt-in lift for contextual emphasis */
  --ok-raised:    #89a787;    /* sage    · ~6.45:1 */
  --info-raised:  #94b3c8;    /* slate   · ~6.85:1 */
  --alarm-raised: #d39576;    /* madrona · ~7.10:1 */
  --warn-raised:  #c89537;    /* amber   · ~5.80:1 */
  --ok-raised-tint:    rgba(137, 167, 135, 0.20);
  --info-raised-tint:  rgba(148, 179, 200, 0.18);
  --alarm-raised-tint: rgba(211, 149, 118, 0.20);
  --warn-raised-tint:  rgba(200, 149, 55, 0.18);

  --stem-dx:      #4a93ad;
  --stem-fx:      #c89638;
  --stem-mx:      #6c9266;
  --stem-bg:      #8a6da9;
  --stem-fol:     #b35649;
  --stem-pm:      #aaa295;
  --stem-grp:     #928a7c;
  --stem-vca:     #5a6a78;
  --stem-frn:     #b3805e;
  --stem-other:   #7a766f;

  --mono:         ui-monospace, Menlo, Consolas, "SF Mono", monospace;

  /* per-page accent — set by .role-* body class so the user can tell at
     a glance which page they're on. Surfaces only on the page-mark
     glyph, the active-nav underline, and the action-rail go-button.
     Defaults to --ink-faint when no role class is set. */
  --page-accent: var(--ink-faint);
}

body.role-edit    { --page-accent: var(--warn); }
body.role-monitor { --page-accent: var(--alarm); }
body.role-archive { --page-accent: var(--info); }
body.role-build   { --page-accent: var(--ok); }
/* console-page roles — config-editor family, distinct from the
   user-tool family above */
body.role-hub     { --page-accent: var(--stem-dx); }
body.role-session { --page-accent: var(--stem-mx); }
body.role-spatial { --page-accent: var(--stem-bg); }
body.role-layout  { --page-accent: var(--stem-vca); }
body.role-keys    { --page-accent: var(--stem-frn); }
body.role-knob    { --page-accent: var(--stem-fol); }
body.role-strip   { --page-accent: var(--stem-fx); }
body.role-prefs   { --page-accent: var(--stem-pm); }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.5;
}

a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
a:hover { border-bottom-color: var(--ink-faint); }

button, input, select, textarea {
  font: inherit;
  color: inherit;
  background: transparent;
  border: 1px solid var(--rule);
  padding: 2px 6px;
}
button { cursor: pointer; }
button:hover { border-color: var(--ink-faint); }
button[disabled] { color: var(--ink-very-faint); cursor: not-allowed; border-color: var(--rule); }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--ink-faint); }

/* ─── chrome bar — two-line ──────────────────────────────────── */

.chrome {
  border-bottom: 1px solid var(--rule);
  padding: 10px 16px 8px 16px;
  background: var(--bg-deep);
  display: grid;
  grid-template-columns: auto 1fr auto;
  column-gap: 24px;
  row-gap: 2px;
  align-items: baseline;
}
.chrome .brand {
  grid-row: 1 / 3;
  align-self: center;
  color: var(--ink);
  font-size: 13px;
  border-right: 1px solid var(--rule);
  padding-right: 16px;
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}
/* page mark — small filled square in --page-accent, left of brand text.
   Single source of "which page am I on" at the brand level. */
.chrome .brand::before {
  content: "";
  display: inline-block;
  width: 8px; height: 8px;
  background: var(--page-accent);
  align-self: center;
}
.chrome .session { color: var(--ink); font-size: 13px; }
.chrome .meta    { color: var(--ink-faint); font-size: 11px; }
.chrome .nav {
  grid-row: 1 / 3;
  align-self: center;
  display: flex;
  gap: 16px;
}
.chrome .nav a {
  color: var(--ink-faint);
  border: none;
  border-bottom: 2px solid transparent;
  padding-bottom: 2px;
  font-size: 11px;
}
.chrome .nav a.on {
  color: var(--ink);
  border-bottom-color: var(--page-accent);
}
.chrome .nav a:hover { color: var(--ink); }

/* ─── alarm rail (top-rail alert/status) ────────────────────── */

.alarm-rail {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--alarm);
  background: var(--bg);
}
.alarm-rail.ok { border-bottom-color: var(--ok); }
.alarm-rail.warn { border-bottom-color: var(--warn); }
.alarm-rail .icon {
  width: 22px; height: 22px;
  border: 1px solid var(--alarm);
  color: var(--alarm);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px;
}
.alarm-rail.ok .icon { border-color: var(--ok); color: var(--ok); }
.alarm-rail.warn .icon { border-color: var(--warn); color: var(--warn); }
.alarm-rail .body { flex: 1; min-width: 0; }
.alarm-rail .ttl {
  color: var(--alarm);
  font-size: 12px;
}
.alarm-rail.ok .ttl { color: var(--ok); }
.alarm-rail.warn .ttl { color: var(--warn); }
.alarm-rail .det { color: var(--ink-faint); }
.alarm-rail .actions { display: flex; gap: 0; }

/* ─── stats strip ───────────────────────────────────────────── */

.stats {
  padding: 8px 16px;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
}
.stats .group { display: inline-flex; gap: 10px; }
.stats .group + .group::before { content: "·"; color: var(--ink-very-faint); margin-right: 8px; }
.stats .v { color: var(--ink); }
.stats .v.alarm { color: var(--alarm); }
.stats .v.warn  { color: var(--warn); }
.stats .v.ok    { color: var(--ok); }

/* ─── filterbar (tabs across content sections) ─────────────── */

.filterbar {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--rule);
  padding: 0 16px;
  background: var(--bg-deep);
  font-size: 11px;
}
.filterbar .f {
  padding: 6px 12px;
  color: var(--ink-faint);
  cursor: pointer;
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid transparent;
  margin-bottom: -1px;
  user-select: none;
}
.filterbar .f:hover { color: var(--ink); }
.filterbar .f.active {
  color: var(--ink);
  border-bottom-color: var(--ink);
  background: var(--bg);
}
.filterbar .f .n {
  color: var(--ink-faint);
  margin-left: 6px;
}
.filterbar .right {
  margin-left: auto;
  align-self: center;
  color: var(--ink-faint);
  padding-right: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.filterbar input[type="text"],
.filterbar input[type="search"] {
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--rule);
  padding: 2px 8px;
  width: 220px;
}

/* ─── notched-legend section frame ─────────────────────────── */

.sec {
  position: relative;
  margin: 18px 16px 12px 16px;
  padding: 14px 14px 10px 14px;
  background: var(--bg-row-alt);
  border: 1px solid var(--rule-strong);
}
.sec > .ttl {
  position: absolute;
  top: -8px;
  left: 12px;
  background: var(--bg);
  padding: 0 8px;
  color: var(--ink);
  font-size: 12px;
  line-height: 1;
}
.sec > .ttl .meta {
  color: var(--ink-faint);
  margin-left: 8px;
  font-size: 11px;
}
.sec .scroll {
  max-height: 460px;
  overflow-y: auto;
  overflow-x: auto;
}
.sec table thead th {
  position: sticky;
  top: 0;
  background: var(--bg-row-alt);
  z-index: 1;
}

/* ─── tables ────────────────────────────────────────────────── */

table {
  border-collapse: collapse;
  width: 100%;
  font: inherit;
}
th, td {
  text-align: left;
  padding: 0 12px 0 0;
  color: var(--ink);
  white-space: nowrap;
  font-weight: 400;
  vertical-align: top;
}
th {
  color: var(--ink-faint);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 3px;
  padding-top: 2px;
  font-size: 11px;
  text-transform: none;
}
td.f { color: var(--ink-faint); }
td.num, th.num { font-variant-numeric: tabular-nums; text-align: right; padding-right: 12px; }

.sec tbody tr:nth-child(even) td { background: var(--bg); }
.sec tbody tr.alarm-row td,
.sec tbody tr.alarm-row:nth-child(even) td { background: var(--alarm-row-tint); }
.sec tbody tr.warn-row td,
.sec tbody tr.warn-row:nth-child(even) td { background: var(--warn-tint); }
.sec tbody tr.ok-row td { color: var(--ink); }
.sec tbody tr.dim-row td { color: var(--ink-faint); }

/* ─── MOTable — shared data-table primitive (sourced from v4) ───────
   Apply class="mo-table zebra" to any data table (including those
   outside notched-section frames). Sticky thead inside .mo-scroll
   containers, ellipsis on overflow, gutter selection marker, alarm
   tint layer, sep rows, separators that match the chrome bg. */

.mo-table {
  table-layout: auto;
  border-collapse: collapse;
  width: 100%;
  font: inherit;
}
.mo-table th, .mo-table td {
  text-align: left;
  padding: 0 12px 0 0;
  color: var(--ink);
  white-space: nowrap;
  font-weight: 400;
  vertical-align: middle;
  font-size: 11px;
}
.mo-table th {
  color: var(--ink-faint);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 3px;
  padding-top: 2px;
  user-select: none;
  text-transform: none;
}
.mo-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-row-alt);
}
.mo-table tbody tr td { background: var(--bg-row-alt); }

/* zebra — every other row drops back to page bg */
.mo-table.zebra tbody tr:nth-child(even) td { background: var(--bg); }

/* row state tints — alarm / warn / sel / hover / dirty layer over zebra */
.mo-table tbody tr.alarm-row td,
.mo-table.zebra tbody tr.alarm-row:nth-child(even) td { background: var(--alarm-row-tint); }
.mo-table tbody tr.warn-row td,
.mo-table.zebra tbody tr.warn-row:nth-child(even) td { background: var(--warn-tint); }
.mo-table tbody tr.sel td,
.mo-table.zebra tbody tr.sel:nth-child(even) td { background: var(--bg-sel); }
.mo-table tbody tr.dirty td,
.mo-table.zebra tbody tr.dirty:nth-child(even) td { background: var(--warn-tint); }
.mo-table tbody tr.row, .mo-table tbody tr[data-ix] { cursor: pointer; }
.mo-table tbody tr:hover td,
.mo-table.zebra tbody tr:hover:nth-child(even) td { background: var(--bg-row); }

/* separator rows (e.g. day-breaks, group headers) — chrome bg */
.mo-table tbody tr.sep td,
.mo-table.zebra tbody tr.sep:nth-child(even) td {
  background: var(--bg-deep);
  color: var(--ink-faint);
  padding-top: 4px;
  padding-bottom: 4px;
}

/* hidden by filter — keep DOM, hide visually so col widths don't reflow */
.mo-table tbody tr.h { display: none; }

/* tabular numerics inside mo-table */
.mo-table .num, .mo-table th.num, .mo-table td.num { font-variant-numeric: tabular-nums; }

/* generic scroll container for tables (pairs with sticky thead above) */
.mo-scroll {
  overflow-y: auto;
  overflow-x: auto;
  height: 100%;
}

/* ─── zebra for div-row lists (non-table layouts) ────────────────
   Pages where rows are <div class="row-foo"> instead of <tr>; apply
   class="zebra-rows" to the parent container and the EVEN children
   matching the row class drop to page bg. */
.zebra-rows > .save-row:nth-of-type(even),
.zebra-rows > .job-row:nth-of-type(even),
.zebra-rows > .recipe-row:nth-of-type(even),
.zebra-rows > .reel-row:nth-of-type(even),
.zebra-rows > .ev-row:nth-of-type(even),
.zebra-rows > .auto-row:nth-of-type(even),
.zebra-rows > .plug-row:nth-of-type(even),
.zebra-rows > .lane-row:nth-of-type(even),
.zebra-rows > li:nth-of-type(even) { background: var(--bg); }
.zebra-rows > .save-row:nth-of-type(odd),
.zebra-rows > .job-row:nth-of-type(odd),
.zebra-rows > .recipe-row:nth-of-type(odd),
.zebra-rows > .reel-row:nth-of-type(odd),
.zebra-rows > .ev-row:nth-of-type(odd),
.zebra-rows > .auto-row:nth-of-type(odd),
.zebra-rows > .plug-row:nth-of-type(odd),
.zebra-rows > .lane-row:nth-of-type(odd),
.zebra-rows > li:nth-of-type(odd) { background: var(--bg-row-alt); }

td.gutter, th.gutter {
  width: 14px;
  padding-right: 2px;
  color: var(--ink-faint);
}
tr td.gutter::before { content: " "; }
tr.sel td.gutter { color: var(--ink); box-shadow: inset 2px 0 0 var(--ink); }
tr.sel td.gutter::before { content: "▸"; }
tr.alarm-row td.gutter { color: var(--alarm); box-shadow: inset 2px 0 0 var(--alarm); }
tr.alarm-row td.gutter::before { content: "▸"; }
tr.warn-row td.gutter { color: var(--warn); box-shadow: inset 2px 0 0 var(--warn); }
tr.warn-row td.gutter::before { content: "▸"; }

/* edited / dirty-row signal — left rule, faint amber inset */
tr.dirty td { background: var(--warn-tint) !important; }
tr.dirty td.gutter { color: var(--warn); box-shadow: inset 2px 0 0 var(--warn); }
tr.dirty td.gutter::before { content: "●"; }

/* ─── stem identity ─────────────────────────────────────────── */

.stem-dx    { color: var(--stem-dx); }
.stem-fx    { color: var(--stem-fx); }
.stem-mx    { color: var(--stem-mx); }
.stem-bg    { color: var(--stem-bg); }
.stem-fol   { color: var(--stem-fol); }
.stem-pm    { color: var(--stem-pm); }
.stem-grp   { color: var(--stem-grp); }
.stem-vca   { color: var(--stem-vca); }
.stem-frn   { color: var(--stem-frn); }
.stem-other { color: var(--stem-other); }

/* ─── slot boxes (chain inserts) ────────────────────────────── */

.slot {
  border: 1px solid var(--rule);
  padding: 0 4px;
  margin-right: 2px;
  display: inline-block;
  color: var(--ink-faint);
  min-width: 56px;
  text-align: center;
  font-size: 11px;
}
.slot.on    { color: var(--ink); border-color: var(--ink-faint); }
.slot.x, .slot.missing {
  color: var(--alarm);
  border-color: var(--alarm);
  background: var(--alarm-tint);
}
.slot.empty  { border-style: dashed; color: var(--ink-very-faint); }
.slot.bypass { color: var(--ink-faint); border-color: var(--ink-faint); text-decoration: line-through; }
.slot.unused { color: var(--warn); border-color: var(--warn); }
.slot.stock  { color: var(--ok); border-color: var(--ok); }
.slot.active { color: var(--info); border-color: var(--info); }
.slot.sel    { background: var(--bg-sel); border-color: var(--ink); color: var(--ink); }

/* ─── v4 layout — top row (65/35 master | inspector) + bottom pane ─
   Pages opt in via class="page-v4" on body. Rows:
     row1 chrome  · row2 stats  · row3 filterbar  · row4 alarm-rail (opt) ·
     row5 top-row 1fr  · row6 bot-pane 320px (opt). */

/* Page shell. Children expected, in order:
     <header.chrome> <div.stats> <div.filterbar> <div.layout> <footer.alarm-rail?>
   .layout itself splits into top-row + bot-pane (or top-row only if .no-bot). */
body.page-v4 {
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  height: 100vh;
  overflow: hidden;
}
/* with-rail = there is an alarm-rail BETWEEN filterbar and .layout */
body.page-v4.with-rail { grid-template-rows: auto auto auto auto 1fr auto; }
body.page-v4.no-footer { grid-template-rows: auto auto auto 1fr; }

.layout {
  display: grid;
  grid-template-rows: 1fr 320px;
  overflow: hidden;
  min-height: 0;
}
.layout.no-bot { grid-template-rows: 1fr; }

.top-row {
  display: grid;
  grid-template-columns: 65fr 35fr;
  overflow: hidden;
  min-height: 0;
}
.main-pane {
  overflow-y: auto;
  border-right: 1px solid var(--rule);
  min-width: 0;
}
.right-col {
  display: grid;
  grid-template-rows: 65fr 35fr;
  overflow: hidden;
  min-height: 0;
  background: var(--bg-deep);
}
.right-col.single { grid-template-rows: 1fr; }

.bot-pane {
  border-top: 1px solid var(--rule-strong);
  background: var(--bg-deep);
  overflow: hidden;
  display: grid;
  grid-template-rows: auto 1fr;
  min-height: 0;
}
.bot-pane > .insp-body { background: var(--bg-deep); padding: 0; }

.insp-pane {
  overflow: hidden;
  display: grid;
  grid-template-rows: auto auto 1fr;   /* meta · tabs · body */
  min-height: 0;
}
.insp-pane.no-meta { grid-template-rows: auto 1fr; }
.insp-pane + .insp-pane { border-top: 1px solid var(--rule); }

/* meta sits ABOVE the tabs, full pane width — long entity names never
   truncate, tabs stay on the bottom edge so v13 active-tab-attaches-to-
   body trick keeps working. */
.insp-meta {
  background: var(--bg-deep);
  color: var(--ink);
  padding: 5px 10px 4px 10px;
  font-size: 11px;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 22px;
}
.insp-meta .f { color: var(--ink-faint); }
.insp-meta:empty::before { content: " "; }

.insp-tabs {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--rule-strong);
  background: var(--bg-deep);
  padding: 0 8px;
  height: 28px;
  font-variant-numeric: tabular-nums;
}
.insp-tabs .tab {
  padding: 6px 10px;
  color: var(--ink-faint);
  cursor: pointer;
  height: 28px;
  line-height: 16px;
  margin-bottom: -1px;
  border-left: 1px solid transparent;
  border-right: 1px solid transparent;
  user-select: none;
}
.insp-tabs .tab:hover { color: var(--ink); }
.insp-tabs .tab.on {
  color: var(--ink);
  background: var(--bg-row-alt);
  border-left: 1px solid var(--rule-strong);
  border-right: 1px solid var(--rule-strong);
  border-bottom: 1px solid var(--bg-row-alt);
}
.insp-tabs .meta { margin-left: auto; color: var(--ink-faint); padding-right: 4px; align-self: center; }

.insp-body {
  overflow-y: auto;
  padding: 12px 14px;
  background: var(--bg-row-alt);
}
.insp-body h2, .insp-body h3 {
  font: inherit;
  color: var(--ink-faint);
  margin: 0 0 6px 0;
  font-weight: 400;
}
.insp-body .insp-section {
  background: var(--bg);
  border: 1px solid var(--rule);
  padding: 8px 10px;
  margin-bottom: 8px;
}
.insp-body .insp-section:last-child { margin-bottom: 0; }
.insp-body .empty {
  color: var(--ink-faint);
  padding: 24px 0;
  text-align: center;
}

/* ─── x-block — collapsible cross-cut group, used in bot-pane ─── */
.x-block { border-top: 1px solid var(--rule); margin-top: 0; }
.x-block:first-child { border-top: none; }
.x-block > summary {
  padding: 8px 16px;
  background: var(--bg-deep);
  color: var(--ink);
  font-size: 12px;
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.x-block > summary::before {
  content: "\25B8";
  color: var(--ink-faint);
  font-size: 9px;
  width: 10px;
  display: inline-block;
}
.x-block[open] > summary::before { content: "\25BE"; }
.x-block > summary .n {
  color: var(--ink-faint);
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
}
.x-block > .body { padding: 0; }

/* ─── tbl-ctl — small button that lives in section titles ────── */
.tbl-ctl {
  color: var(--ink-faint);
  cursor: pointer;
  margin-left: 12px;
  border: 1px solid var(--rule);
  padding: 0 6px;
  font-size: 11px;
  user-select: none;
}
.tbl-ctl:hover, .tbl-ctl.on { color: var(--ink); border-color: var(--ink-faint); }

/* ─── chain cell — count + small dot summary, alarm if any miss ─ */
td.chain { cursor: pointer; }
td.chain .summary-dot {
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
}
td.chain .summary-dot .count {
  color: var(--ink); font-variant-numeric: tabular-nums; min-width: 16px; text-align: right;
}
td.chain .summary-dot .dot {
  width: 7px; height: 7px; background: var(--ink-faint); display: inline-block;
}
td.chain.has-missing .summary-dot .dot { background: var(--alarm); }

.chain-cell {
  display: flex;
  gap: 2px;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule-strong) transparent;
  white-space: nowrap;
  max-width: 720px;
}
.chain-cell::-webkit-scrollbar { height: 4px; }
.chain-cell::-webkit-scrollbar-thumb { background: var(--rule-strong); }

/* ─── slot-table (inspector listing of slots) ────────────────── */
.slot-table {
  width: 100%;
  border-collapse: collapse;
}
.slot-table td {
  padding: 1px 8px 1px 0;
  color: var(--ink);
}
.slot-table td.ix  { color: var(--ink-faint); width: 18px; }
.slot-table td.ven { color: var(--ink-faint); width: 90px; }
.slot-table td.ver { color: var(--ink-faint); width: 60px; text-align: right; }
.slot-table tr.miss td.name { color: var(--alarm); }
.slot-table tr.bypass td.name { color: var(--ink-faint); text-decoration: line-through; }
.slot-table tbody tr:nth-child(even) td { background: var(--bg-row-alt); }
.slot-table tbody tr:nth-child(even):hover td { background: var(--bg-row); }
.slot-table tbody tr.sel td { background: var(--bg-sel); }

/* ─── kv lists ──────────────────────────────────────────────── */

.kv {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 2px 12px;
  font-size: 11px;
}
.kv dt { color: var(--ink-faint); margin: 0; }
.kv dd { margin: 0; color: var(--ink); }
.kv dd.alarm { color: var(--alarm); }
.kv dd.warn  { color: var(--warn); }
.kv dd.ok    { color: var(--ok); }
.kv dd.f     { color: var(--ink-faint); }

/* ─── action / status footer (sticky bottom rail) ──────────── */

.action-rail {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  border-top: 1px solid var(--rule);
  background: var(--bg-deep);
}
.action-rail .left  { display: flex; align-items: center; gap: 10px; }
.action-rail .right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.action-rail .count { color: var(--ink-faint); }
.action-rail .count .v { color: var(--ink); }
.action-rail .kbd {
  color: var(--ink-faint);
  font-size: 10px;
}
.action-rail .kbd .k {
  color: var(--ink);
  border: 1px solid var(--rule);
  padding: 0 4px;
  margin-right: 3px;
}

/* ─── buttons ──────────────────────────────────────────────── */

.btn {
  font-family: var(--mono);
  font-size: 11px;
  background: transparent;
  color: var(--ink-faint);
  border: 1px solid var(--rule);
  padding: 3px 10px;
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { color: var(--ink); border-color: var(--ink-faint); }
.btn.primary { color: var(--ink); border-color: var(--ink-faint); }
.btn.primary.go {
  color: var(--bg);
  background: var(--page-accent);
  border-color: var(--page-accent);
  font-weight: 600;
}
.btn.primary.go:hover { filter: brightness(1.1); }
.btn.alarm { color: var(--alarm); border-color: var(--alarm); }
.btn.alarm:hover { background: var(--alarm-tint); }
.btn.warn { color: var(--warn); border-color: var(--warn); }
.btn.ok { color: var(--ok); border-color: var(--ok); }

/* button group — flush row, hairline shared edges */
.btn-group { display: inline-flex; }
.btn-group .btn { border-right-width: 0; }
.btn-group .btn:last-child { border-right-width: 1px; }

/* ─── details / summary ─────────────────────────────────────── */

details { margin: 0; }
summary {
  cursor: pointer;
  list-style: none;
  outline: none;
  user-select: none;
}
summary::-webkit-details-marker { display: none; }
summary::before {
  content: "▸";
  display: inline-block;
  width: 12px;
  color: var(--ink-faint);
  font-size: 9px;
}
details[open] > summary::before { content: "▾"; }

/* ─── helpers ──────────────────────────────────────────────── */

.alarm  { color: var(--alarm); }
.warn   { color: var(--warn); }
.ok     { color: var(--ok); }
.info   { color: var(--info); }
.f      { color: var(--ink-faint); }
.vf     { color: var(--ink-very-faint); }
.num    { font-variant-numeric: tabular-nums; }

/* preview / diff rows */
.diff-add  { color: var(--ok); }
.diff-del  { color: var(--alarm); text-decoration: line-through; }
.diff-mod  { color: var(--warn); }
.arrow     { color: var(--ink-very-faint); padding: 0 6px; }

/* coverage bar */
.bar {
  display: inline-block;
  width: 80px;
  height: 6px;
  background: var(--rule);
  vertical-align: middle;
  margin-right: 6px;
}
.bar > i {
  display: block;
  height: 100%;
  background: var(--ink-faint);
}
.bar.ok > i    { background: var(--ok); }
.bar.warn > i  { background: var(--warn); }
.bar.alarm > i { background: var(--alarm); }
.bar.info > i  { background: var(--info); }

/* timeline strip — shared by mix-recall + alert history */
.tl {
  position: relative;
  height: 18px;
  background: var(--bg);
  border: 1px solid var(--rule);
}
.tl .pip {
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: var(--ink-faint);
}
.tl .pip.alarm { background: var(--alarm); }
.tl .pip.warn  { background: var(--warn); }
.tl .pip.ok    { background: var(--ok); }
.tl .pip.sel   { background: var(--ink); width: 3px; }

/* drop-zone (file ingest) */
.dropzone {
  border: 1px dashed var(--rule-strong);
  padding: 36px 20px;
  text-align: center;
  color: var(--ink-faint);
  margin: 24px 16px;
}
.dropzone.over {
  border-color: var(--ink);
  color: var(--ink);
  background: var(--bg-row-alt);
}
.dropzone .ttl { color: var(--ink); font-size: 12px; }
.dropzone .sub { margin-top: 6px; }

/* tags / inline state markers (text, not chips) */
.tag {
  color: var(--ink-faint);
  border: 1px solid var(--rule);
  padding: 0 4px;
  margin-right: 4px;
}
.tag.alarm { color: var(--alarm); border-color: var(--alarm); }
.tag.warn  { color: var(--warn); border-color: var(--warn); }
.tag.ok    { color: var(--ok); border-color: var(--ok); }
.tag.info  { color: var(--info); border-color: var(--info); }

/* page shells */
.page { display: flex; flex-direction: column; min-height: 100vh; }
.page > main { flex: 1; min-height: 0; }
.page-grid { display: grid; grid-template-rows: auto auto auto 1fr auto; min-height: 100vh; }

/* utility — hide / show */
.hidden { display: none !important; }
