/* =================================================================================================
   EXIGUUS DESIGN SYSTEM v1 (CC96b)

   THE NA, ON THE REAL PHONE, 2026-09-02: "non-responsive, misaligned, no homogeneous design system
   - standardise the interface; even if we go stupid simple it must not be boring; colour-code each
   subdivision of content, especially since the content is long and rich".

   FOUR RULES, AND EVERYTHING BELOW IS ONE OF THEM.

   1. ONE SCALE. Every px value in this file lives in :root and nowhere else. A literal outside the
      token block is a value nobody chose twice the same way, and `test_shell.mjs` fails the build
      for it rather than trusting review to catch it.
   2. ONE CARD. Header (title + one status chip), body, footer. Every panel is that shape. Before
      this, `.screen` gave a border to the board - a container of cards - so the detail rail was a
      card inside a card, and the status strip was six identical grey boxes with no grouping.
   3. COLOUR IS A SECOND SIGNAL, NEVER THE ONLY ONE. Five content classes, each a left rail plus a
      header tint, and every one of them ALSO carries its words. A reader who cannot see the hue
      loses nothing; a reader who can, navigates a long page at a glance. Contrast measured, in the
      return, at AA on both the tint and the panel.
   4. HIERARCHY FROM WEIGHT AND RAIL, NOT ORNAMENT. Three type sizes. No gradients, no ornament, no
      second UI. "Stupid simple, not boring" is a colour system doing the work decoration usually
      does badly.

   WHAT THIS FILE DOES NOT DO: it says nothing new. No field, no vocabulary, no ranking and no
   state was added, removed or renamed by it, and it reads no result. The state chips keep their
   exact colours - they were already a system and replacing them would have been redecoration.
   ================================================================================================= */

:root {
  color-scheme: light;

  /* ---- SPACING: the 4-step scale, and there is no fifth value ------------------------------- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;

  /* ---- TYPE: three sizes and one mono. h2 is body size at weight 800 - a fourth size would be
     hierarchy by ornament, which rule 4 spends the colour rail to avoid. ---------------------- */
  --fs-label: 12px;
  --fs-body: 15px;
  --fs-title: 22px;
  --font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "SFMono-Regular", Consolas, ui-monospace, monospace;
  --lh: 1.45;
  --lh-tight: 1.2;

  /* ---- SHAPE -------------------------------------------------------------------------------- */
  --radius: 8px;
  --radius-sm: 6px;
  --border-w: 1px;
  --rail-w: 4px;
  --shadow: 0 1px 2px rgba(24, 32, 42, 0.06);

  /* ---- SIZES: touch targets and the grid's own minimums ------------------------------------- */
  --tap: 40px;          /* every control and link a thumb must hit */
  --tap-sm: 32px;
  --chip-h: 24px;
  --stat-min: 150px;    /* status strip column */
  --field-min: 180px;   /* search field column */
  --rail-min: 300px;    /* detail rail column */
  --rail-max: 380px;
  --measure: 560px;     /* the longest line of prose we let happen */
  --empty-h: 180px;
  --clip: 1px;          /* the a11y clip: 1px box, moved off-canvas, never display:none */
  --clip-off: -10000px;

  /* ---- NEUTRALS ----------------------------------------------------------------------------- */
  --ink: #18202a;
  --muted: #586477;
  --line: #c7d0dc;
  --panel: #ffffff;
  --page: #f5f7fa;
  --accent: #0f766e;
  --topbar-bg: #102526;
  --topbar-line: #0f3d3a;
  --topbar-ink: #f8fafc;
  --topbar-eyebrow: #9ee7dd;

  /* ---- THE FIVE CONTENT CLASSES ------------------------------------------------------------
     Five hues, one neutral. Each is a RAIL (a graphical edge) and a TINT (a header wash) with a
     TEXT colour measured against both. GOVERNANCE is deliberately in the violet family: the gate
     chip REFUSED_BY_GATE already lives there, so the class and the state agree instead of
     competing. NEUTRAL HAS NO RAIL - a hue that fails 3:1 as a signal should not pretend to be
     one, and "no class" is honestly the absence of a mark. */
  --alerts-rail: #0f766e;
  --alerts-text: #0b4a45;
  --alerts-tint: #e8f5f3;
  --evidence-rail: #3730a3;
  --evidence-text: #2a2578;
  --evidence-tint: #eceafb;
  --governance-rail: #6d28d9;
  --governance-text: #4c1d95;
  --governance-tint: #f2ebfd;
  --states-rail: #475569;
  --states-text: #293241;
  --states-tint: #eef1f5;
  --custody-rail: #92400e;
  --custody-text: #6b2f08;
  --custody-tint: #fbeee1;
  --neutral-text: #3d4757;
  --neutral-tint: #f4f6f9;

  /* the class currently in scope; every card reads these two and nothing else */
  --class-rail: transparent;
  --class-text: var(--neutral-text);
  --class-tint: var(--neutral-tint);

  /* ---- STATE CHIPS: UNCHANGED. They were already a system. --------------------------------- */
  --state-unknown-bg: #fff2bf;
  --state-unknown-border: #a36a00;
  --state-unknown-text: #533400;
  --state-not-captured-bg: #dbeafe;
  --state-not-captured-border: #2563eb;
  --state-not-captured-text: #153e75;
  --state-negative-bg: #ffe0e0;
  --state-negative-border: #b83232;
  --state-negative-text: #63171b;
  --state-unobservable-bg: #eef2f7;
  --state-unobservable-border: #64748b;
  --state-unobservable-text: #334155;
  --state-refused-bg: #ede9fe;
  --state-refused-border: #7c3aed;
  --state-refused-text: #3b0764;
  --state-satisfied-bg: #dcfce7;
  --state-satisfied-border: #15803d;
  --state-satisfied-text: #14532d;
  --state-neutral-bg: #f8fafc;
  --state-neutral-border: #94a3b8;
  --state-neutral-text: #334155;
  --state-frozen-bg: #ecfeff;
  --state-frozen-border: #0891b2;
  --state-frozen-text: #164e63;
  --marker-bg: #fff7ed;
  --marker-border: #ea580c;
  --marker-text: #7c2d12;
}

/* =================================================================================================
   BASE
   ================================================================================================= */

* {
  box-sizing: border-box;
}

body {
  background: var(--page);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh);
  margin: 0;
}

code {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
}

/* LONG AND RICH IS THE CONTENT, SO WRAPPING IS A BASE RULE, NOT A BREAKPOINT RULE.
   CC93 repaired wrapping below 760px and CC95 repaired the detail rail below 760px. Measured at
   1280 on this branch's own base, the SAME two defects were still there - a 38-character alert id
   ran 139px past its heading box and the deep-link path 4px past its cell - because both repairs
   were inside the mobile media block. An identifier that cannot break is not a phone problem. */
h1,
h2,
h3,
p,
dt,
dd,
li,
td,
th,
code,
a,
span,
strong {
  /* `anywhere` is a LAST RESORT, not a policy: it breaks a token only when no other break point
     exists. That is why it can be applied this widely without producing the per-character
     shredding CC93 removed - the two are opposite settings, and the one that shreds is
     `word-break: break-word`, which nothing in this file sets and a test forbids.
     SPAN AND STRONG ARE ON THIS LIST BECAUSE MEASUREMENT PUT THEM THERE: the count strip's own
     values - ROCKETSHIP_BOARD_JSON_v0, UNKNOWN_NOT_RATIFIED - are spans, and they ran 74px and
     17px past their cells at 390px and 66px past at 1280px. */
  overflow-wrap: anywhere;
  word-break: normal;
}

[hidden] {
  display: none !important;
}

.booting,
.rocketship-shell {
  min-height: 100vh;
}

.rocketship-shell {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-4);
}

/* =================================================================================================
   THE CARD - ONE SHAPE, USED BY EVERY PANEL
   header (title + one chip) / body / footer, a left rail carrying the content class.
   ================================================================================================= */

.card,
.screen,
.table-panel,
.detail-rail,
.status-cell,
.population-zero-line,
.search-panel,
.state-catalog li,
.source-list li {
  background: var(--panel);
  border: var(--border-w) solid var(--line);
  border-left: var(--rail-w) solid var(--class-rail);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  max-width: 100%;
  min-width: 0;
  padding: var(--sp-3);
}

/* A CONTAINER IS NOT A CARD. The board screen holds cards; giving it a card's chrome is what put
   the detail rail inside a second border and made the whole page read as boxes-in-boxes. */
.board-screen,
.detail-screen,
.evidence-screen {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
}

.board-screen {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

/* THE CARD HEADER. `.section-heading` already paired a title with one chip; every other panel had
   a bare h2 doing the same job with none of the same styling. Both are the header band now. */
.section-heading,
.screen > h2,
.split-grid > section > h2,
.detail-rail > h2 {
  align-items: center;
  background: var(--class-tint);
  border-bottom: var(--border-w) solid var(--line);
  color: var(--class-text);
  display: flex;
  font-size: var(--fs-body);
  font-weight: 800;
  gap: var(--sp-2);
  justify-content: space-between;
  letter-spacing: 0.02em;
  margin: calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)) 0;
  padding: var(--sp-2) var(--sp-3);
}

/* THE HEADER BAND IS THE TOP OF THE CARD, whatever the markup order says. The standing
   OBSERVATION ONLY marker is emitted before the heading, so the band was landing UNDER it and the
   card read as two stacked things instead of one. Ordering it in CSS keeps the marker exactly
   where it is in the document - it is a standing declaration and this act removes nothing. */
.screen,
.split-grid > section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.screen > h2,
.split-grid > section > h2,
.detail-rail > h2,
.section-heading {
  order: -1;
}

.section-heading h2 {
  font-size: var(--fs-body);
  font-weight: 800;
  margin: 0;
}

h1,
h2,
h3 {
  letter-spacing: 0;
  margin: 0;
}

h3 {
  color: var(--class-text);
  font-size: var(--fs-body);
}

/* =================================================================================================
   THE FIVE CONTENT CLASSES
   Every card declares its class in the markup. Colour is the SECOND signal; the header words are
   the first, and they are always there.
   ================================================================================================= */

[data-content-class="alerts"] {
  --class-rail: var(--alerts-rail);
  --class-text: var(--alerts-text);
  --class-tint: var(--alerts-tint);
}

[data-content-class="evidence"] {
  --class-rail: var(--evidence-rail);
  --class-text: var(--evidence-text);
  --class-tint: var(--evidence-tint);
}

[data-content-class="governance"] {
  --class-rail: var(--governance-rail);
  --class-text: var(--governance-text);
  --class-tint: var(--governance-tint);
}

[data-content-class="states"] {
  --class-rail: var(--states-rail);
  --class-text: var(--states-text);
  --class-tint: var(--states-tint);
}

[data-content-class="custody"] {
  --class-rail: var(--custody-rail);
  --class-text: var(--custody-text);
  --class-tint: var(--custody-tint);
}

/* =================================================================================================
   TOPBAR AND NAV
   ================================================================================================= */

.topbar {
  align-items: center;
  background: var(--topbar-bg);
  border: var(--border-w) solid var(--topbar-line);
  border-radius: var(--radius);
  color: var(--topbar-ink);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  justify-content: space-between;
  padding: var(--sp-3) var(--sp-4);
}

.topbar h1 {
  font-size: var(--fs-title);
  line-height: var(--lh-tight);
}

.eyebrow {
  color: var(--topbar-eyebrow);
  font-size: var(--fs-label);
  font-weight: 700;
  margin: 0 0 var(--sp-1);
  text-transform: uppercase;
}

.board-identity {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  margin: var(--sp-2) 0 0;
}

.observation-marker {
  background: var(--marker-bg);
  border: var(--border-w) solid var(--marker-border);
  border-radius: var(--radius-sm);
  color: var(--marker-text);
  display: inline-flex;
  font-size: var(--fs-label);
  font-weight: 800;
  justify-content: center;
  line-height: var(--lh-tight);
  padding: var(--sp-2) var(--sp-3);
  text-align: center;
}

.mobile-stack-nav {
  display: none;
}

/* =================================================================================================
   BOARD LAYOUT - one column on the phone, one grid on desktop, panels never wider than the column
   ================================================================================================= */

.board-layout {
  align-items: start;
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: minmax(0, 1fr) minmax(var(--rail-min), var(--rail-max));
}

.split-grid {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(var(--rail-min), 1fr));
}

.search-panel {
  align-items: end;
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(var(--field-min), 1fr));
}

.search-panel label {
  display: grid;
  gap: var(--sp-1);
  min-width: 0;
}

.search-panel span {
  color: var(--muted);
  font-size: var(--fs-label);
  font-weight: 800;
  text-transform: uppercase;
}

.search-panel input,
.search-panel select {
  appearance: none;
  background: var(--panel);
  border: var(--border-w) solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font: inherit;
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-3);
  width: 100%;
}

/* =================================================================================================
   STATUS STRIP - counts, and counts get tabular figures so columns of digits line up
   ================================================================================================= */

.status-strip {
  display: grid;
  gap: var(--sp-2);
  grid-template-columns: repeat(auto-fit, minmax(var(--stat-min), 1fr));
}

.status-cell {
  padding: var(--sp-2) var(--sp-3);
}

.status-cell span:first-child {
  color: var(--muted);
  display: block;
  font-size: var(--fs-label);
  font-weight: 700;
  margin-bottom: var(--sp-1);
  text-transform: uppercase;
}

.status-cell span:not(:first-child),
.status-cell strong {
  font-variant-numeric: tabular-nums;
  font-weight: 800;
}

/* THE DAY'S HEADLINE. Nothing reached the floor, and that is the sentence the board exists to say
   today - so it carries the ALERTS rail and reads as the headline rather than as a footnote. */
.population-zero-line {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
}

.population-zero-line strong {
  color: var(--class-text);
  font-size: var(--fs-body);
}

.population-zero-line span {
  color: var(--muted);
  font-size: var(--fs-label);
  font-variant-numeric: tabular-nums;
  font-weight: 800;
}

/* =================================================================================================
   TABLES
   ================================================================================================= */

table {
  border-collapse: collapse;
  width: 100%;
}

th,
td {
  border-bottom: var(--border-w) solid var(--line);
  padding: var(--sp-2);
  text-align: left;
  vertical-align: top;
}

th {
  color: var(--muted);
  font-size: var(--fs-label);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.operations-table {
  table-layout: fixed;
}

.row-link {
  align-items: center;
  background: var(--alerts-rail);
  border: var(--border-w) solid var(--alerts-text);
  border-radius: var(--radius-sm);
  color: var(--panel);
  display: inline-flex;
  font-size: var(--fs-label);
  font-weight: 800;
  justify-content: center;
  min-height: var(--tap-sm);
  padding: var(--sp-2) var(--sp-3);
  text-decoration: none;
}

.empty-row td {
  background: var(--neutral-tint);
  height: var(--empty-h);
  text-align: center;
}

.empty-row p {
  color: var(--muted);
  margin: var(--sp-3) auto 0;
  max-width: var(--measure);
}

/* =================================================================================================
   DETAIL RAIL, HISTORY, LISTS
   ================================================================================================= */

.detail-rail {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.detail-rail p {
  color: var(--muted);
  margin: 0;
}

.detail-rail dl,
.history-summary {
  display: grid;
  gap: var(--sp-2) var(--sp-3);
  grid-template-columns: max-content minmax(0, 1fr);
  margin: 0;
}

.detail-rail dt,
.history-summary dt {
  color: var(--muted);
  font-size: var(--fs-label);
  font-weight: 800;
  text-transform: uppercase;
}

.detail-rail dd,
.history-summary dd {
  margin: 0;
  min-width: 0;
}

.detail-block {
  border-top: var(--border-w) solid var(--line);
  padding-top: var(--sp-3);
}

.state-catalog,
.source-list {
  display: grid;
  gap: var(--sp-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.state-catalog li,
.source-list li {
  align-items: flex-start;
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
}

.source-list li {
  flex-direction: column;
}

.source-list span {
  color: var(--muted);
  font-size: var(--fs-label);
}

.history-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}

.history-tabs button {
  background: var(--panel);
  border: var(--border-w) solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  font-size: var(--fs-label);
  font-weight: 800;
  min-height: var(--tap-sm);
  padding: var(--sp-2) var(--sp-3);
}

.history-tabs button[aria-pressed="true"] {
  background: var(--class-tint);
  border-color: var(--class-rail);
  color: var(--class-text);
}

/* =================================================================================================
   THE ALERT CARD, AT EVERY WIDTH - CC93's mechanism, promoted out of the phone

   CC93 turned each table row into a card below 760px and fixed the phone. Rendered at 1280 the
   table was still nine fixed columns in an 790px panel, about 88px each, and every chip in the
   board broke across three lines: OUT_OF_ / POPULA / TION. Not per-character, so it passed that
   gate, and unreadable anyway.

   THE MANDATE NAMES "Alert card" AS ONE OF THE PANELS THAT MUST USE THE CARD SHAPE, so the shape
   is not a phone workaround - it is the grammar. The same rules now apply at every width and the
   rows lay out as an auto-fill grid: two cards to a row in the board panel on a desktop, one on a
   phone, and no width at which nine columns have to share 88px each.

   Consequences worth naming rather than discovering: the header row is the per-cell labels at
   every width now (clipped, kept for assistive technology, never deleted), and the labels come
   from :nth-of-type - so if a column is added or moved in app.mjs they must move with it. That was
   CC93's cost and it is unchanged, not newly incurred.
   ================================================================================================= */
.operations-table,
.operations-table tbody,
.operations-table tr,
.operations-table td,
.compact-table,
.compact-table tbody,
.compact-table tr,
.compact-table td {
  display: block;
  width: 100%;
}

.operations-table {
  border-collapse: separate;
  overflow-x: visible;
  table-layout: auto;
}

/* The rows are a grid of cards, not a stack. `auto-fill` is what makes one set of rules serve
   both viewports: it lands on two columns in the board panel at 1280 and one at 390. */
.operations-table tbody,
.compact-table tbody {
  display: grid;
  gap: var(--sp-2);
  grid-template-columns: repeat(auto-fill, minmax(var(--rail-min), 1fr));
}

.operations-table thead,
.compact-table thead {
  height: var(--clip);
  left: var(--clip-off);
  overflow: hidden;
  position: absolute;
  width: var(--clip);
}

.operations-table tbody tr,
.compact-table tbody tr {
  background: var(--panel);
  border: var(--border-w) solid var(--line);
  border-left: var(--rail-w) solid var(--class-rail);
  border-radius: var(--radius);
  padding: var(--sp-2) var(--sp-3);
}

.operations-table td {
  border: 0;
  display: grid;
  gap: var(--sp-1) var(--sp-3);
  grid-template-columns: minmax(0, 9ch) minmax(0, 1fr);
  padding: var(--sp-1) 0;
}

.compact-table td {
  border: 0;
  display: grid;
  gap: var(--sp-1) var(--sp-3);
  grid-template-columns: minmax(0, 9ch) minmax(0, 1fr);
  padding: var(--sp-1) 0;
}

/* THE LABEL IS THE COLUMN'S OWN HEADER WORD, carried on the cell. The alert table supplied
   `data-label` and the compact tables did not, so the moment their rows became cards they lost
   their headers entirely - measured, on the rendered page: Predicate States read as an unlabelled
   run of V1 / VETO / UNKNOWN / BLOCKS. That was ALREADY TRUE ON THE PHONE under CC93 and is
   repaired here for both. */
.operations-table td::before,
.compact-table td::before {
  color: var(--muted);
  content: attr(data-label);
  font-size: var(--fs-label);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* A CHIP IS NOT A BUTTON. Inside the card's grid a chip stretched to the full value column and
   read as a second tappable control beside Open - on a touch surface that is a usability defect,
   not a stylistic one. It takes its own width instead. */
.operations-table td .state-pill,
.compact-table td .state-pill {
  justify-self: start;
}

.operations-table td:nth-of-type(1)::before { content: "Open"; }
.operations-table td:nth-of-type(2)::before { content: "Alert ID"; }
.operations-table td:nth-of-type(3)::before { content: "Symbol"; }
.operations-table td:nth-of-type(4)::before { content: "Population"; }
.operations-table td:nth-of-type(5)::before { content: "Date Minute"; }
.operations-table td:nth-of-type(6)::before { content: "Capture"; }
.operations-table td:nth-of-type(7)::before { content: "Market Facts"; }
.operations-table td:nth-of-type(8)::before { content: "Catalyst"; }
.operations-table td:nth-of-type(9)::before { content: "Delivery"; }

/* Open is the action, so it spans the card rather than sitting in a label column. */
.operations-table td:nth-of-type(1) {
  grid-template-columns: minmax(0, 1fr);
  padding-bottom: var(--sp-2);
}

.operations-table td:nth-of-type(1)::before {
  display: none;
}

.operations-table .row-link {
  display: flex;
  min-height: var(--tap);
  text-align: center;
}

/* =================================================================================================
   STATE CHIPS - the colours are untouched; only the box uses the token scale
   ================================================================================================= */

.state-pill {
  align-items: center;
  border: var(--border-w) solid;
  border-radius: var(--radius-sm);
  display: inline-flex;
  font-size: var(--fs-label);
  font-weight: 800;
  justify-content: center;
  line-height: var(--lh-tight);
  min-height: var(--chip-h);
  padding: var(--sp-1) var(--sp-2);
  /* NOT `nowrap`. Measured at 1280 on this branch's base: `OUT_OF_POPULATION` in a fixed-layout
     column forced 120 table cells past their width and the whole page 76px past the viewport.
     A chip that cannot wrap is a chip that decides the page width. */
  text-align: center;
  white-space: normal;
}

.state-unknown {
  background: var(--state-unknown-bg);
  border-color: var(--state-unknown-border);
  color: var(--state-unknown-text);
}

.state-not-captured {
  background: var(--state-not-captured-bg);
  border-color: var(--state-not-captured-border);
  color: var(--state-not-captured-text);
}

.state-negative {
  background: var(--state-negative-bg);
  border-color: var(--state-negative-border);
  color: var(--state-negative-text);
}

.state-unobservable {
  background: var(--state-unobservable-bg);
  border-color: var(--state-unobservable-border);
  color: var(--state-unobservable-text);
}

.state-refused {
  background: var(--state-refused-bg);
  border-color: var(--state-refused-border);
  color: var(--state-refused-text);
}

.state-satisfied {
  background: var(--state-satisfied-bg);
  border-color: var(--state-satisfied-border);
  color: var(--state-satisfied-text);
}

.state-neutral {
  background: var(--state-neutral-bg);
  border-color: var(--state-neutral-border);
  color: var(--state-neutral-text);
}

.state-frozen {
  background: var(--state-frozen-bg);
  border-color: var(--state-frozen-border);
  color: var(--state-frozen-text);
}

/* =================================================================================================
   THE PHONE - CC93's stacked cards and CC95's rail wrapping, kept, on the token scale
   ================================================================================================= */

@media (max-width: 760px) {
  .rocketship-shell {
    gap: var(--sp-3);
    padding: var(--sp-2);
  }

  .topbar {
    align-items: flex-start;
    flex-direction: column;
  }

  .observation-marker {
    width: 100%;
  }

  .mobile-stack-nav {
    background: var(--panel);
    border: var(--border-w) solid var(--line);
    border-radius: var(--radius);
    display: grid;
    gap: var(--sp-2);
    grid-template-columns: repeat(3, 1fr);
    padding: var(--sp-2);
    position: sticky;
    top: 0;
    z-index: 2;
  }

  .mobile-stack-nav a {
    align-items: center;
    background: var(--alerts-tint);
    border: var(--border-w) solid var(--alerts-rail);
    border-radius: var(--radius-sm);
    color: var(--alerts-text);
    display: flex;
    font-size: var(--fs-label);
    font-weight: 800;
    justify-content: center;
    min-height: var(--tap);
    text-decoration: none;
  }

  /* ONE CONTENT COLUMN - which is a statement about PANELS, not about every grid inside one.
     The board, the rails and the form stack. THE COUNT STRIP DOES NOT: rendered at 390px it was
     nine full-width cells, roughly 600px of scrolling before the first alert, and a column of
     single numbers is the least useful thing a phone screen can spend itself on. It keeps the
     auto-fit grid, which lands on two columns at this width, so the counts stay a block a reader
     takes in at once - which is also the only place ALIGNMENT means anything for numbers. */
  .board-layout,
  .split-grid,
  .search-panel {
    grid-template-columns: 1fr;
  }

  /* Below the breakpoint the card grid is ONE column - see the base rules above, which now own
     the card shape itself. */
  .operations-table tbody,
  .compact-table tbody {
    grid-template-columns: 1fr;
  }

  /* CC95 - the detail rail wraps too. The rule is now global (see the base block); this keeps the
     rail's own minimum so an empty rail does not collapse to nothing. */
  .detail-rail {
    min-height: auto;
  }

  .state-catalog li {
    align-items: stretch;
    flex-direction: column;
  }

  /* THE RULE THE CC93 ADDENDUM STATES: no panel may exceed its card at 390px. */
  .card,
  .table-panel,
  .screen {
    max-width: 100%;
    overflow-x: hidden;
  }
}
