/* tokens.css — the complete design language. Palette per Lon 2026-08-25:
   very dark navy for dark mode; very light gray with navy print for light.
   (The first cut was warm cream — read as Claude's own branding, not the department's.) One file, linked, no injection.
   SEVEN COLORS, SIX NAMED TYPE FACES, FOUR SPACING STEPS. A token with no stated job
   gets deleted; adding a seventh color is a design decision to raise, not a
   variable to add.

   THEME FOLLOWS THE DEVICE (Lon, 2026-08-25): dark when the phone is dark,
   light otherwise. No in-app toggle on moment screens. */

*, *::before, *::after { box-sizing: border-box; }
/* ^ load-bearing: a width:100% control with padding overflows the viewport
   without it — found live on the front door's buttons. */

/* TOUCH HYGIENE (Lon, 2026-09-21): a control is a control, not text. A
   glove's long-press must never pop the selection callout mid-case, and a
   rapid double-tap — the MTP +1, a repeat dose — must never zoom the page.
   Buttons and the control-shaped anchors get all three; prose and inputs
   keep their selection (copying a dose into a chart is legitimate). The
   .ack pulse already answers every tap, so the UA's gray flash goes too. */
button, a.action-2, .dial, .bar .back {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* FOCUS — the keyboard/switch-access ring, one rule for the whole product
   (design session 2026-09-21; the operating layer had none). :focus-visible
   only, so a tap never draws it; a hardware keyboard, a switch user or a
   desktop reviewer gets one consistent ink ring sitting on the ground —
   strong in both themes, and never red (rule 8). Where a due-state outline
   already rings a control, its attribute rule outranks this one and the due
   ring keeps the slot; the landing's rocks carry their own treatment. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

:root {
  /* --paper   the ground everything sits on — tinted by section, see --secWash */
  --paper: var(--secWash);
  /* --ink     primary text and the strongest rules */
  --ink: #16233c;
  /* --soft    secondary text — context, sublines, timestamps */
  --soft: #4c5a70;
  /* --line    hairlines, borders, quiet separation */
  --line: #d3d8e0;
  /* --card    a raised surface (secondary actions, sheets) */
  --card: #ffffff;
  /* --act     THE action, and nothing else. Red is never decoration. */
  --act: #b3362f;
  /* the GREEN EXIT (Lon, 2026-08-29: "a green boxed ROSC button"). One
     semantic: the way OUT of the arrest, never a recommendation — so it is a
     box, not a fill, and nothing else in the vocabulary uses green. 4.5:1 on
     its ground in both themes. */
  --ok: #1e6b45;
  /* --act-ink text on the action. THE PAIR FLIPS BY THEME (design session
     2026-09-21, the --late precedent applied to the red): in dark mode no
     single red can carry BOTH white small text on its fill AND red text on
     the near-black ground at WCAG AA — the two jobs bound the red's
     lightness from opposite sides (≤L0.18 vs ≥L0.21). So dark lifts the
     red to #e0655c and sets navy ink on it, the exact move --late already
     makes: a deep fill under near-white ink in light, a light fill under
     dark ink in dark. Measured: 4.9:1 on the fill at every text size,
     5.4:1 as text on the ground — AA everywhere the red speaks. */
  --act-ink: #fdfcf9;
  /* --late / --late-ink   OVERDUE, and only overdue (Lon, 2026-09-14: "I
     would make the overdue blue not red"). Rule 8 reserves red for due-NOW —
     red means act, here, in this second. An overdue practice is not that: it
     is a fact to read on a quiet screen, and spending the alarm colour on
     something nobody acts on at 3am blunts it. Blue carries overdue instead,
     which leaves red meaning one thing only. Rule 8 still holds: it reserves
     red FOR due-now; it never required overdue to wear it.
     The pair flips by theme so the fill stays legible either way — a deep
     blue under near-white ink, a light blue under dark ink. */
  --late: #3f5f8f;
  --late-ink: #fdfcf9;
  /* --gap / --gap-ink   AN ASSERTED GAP, and only that (Lon, 2026-09-21:
     "the walk-state reds — make them yellow"). The seventh color, raised
     and ruled: a missing mark on a walk, a gap ring, an expired scan — the
     readiness layer's attention state, which is not a this-second action,
     so it stops spending the alarm color. Same theme-flip as --late: a
     deep amber under ink in light, a bright amber under navy in dark.
     Non-text marks ≥3:1 on card and wash in both themes; the ✕ and the
     EXPIRED words ride it only at bold sizes (large-text AA). Color is
     never the only carrier — every mark keeps its word. */
  --gap: #a87b00;
  --gap-ink: #16233c;

  /* --sec / --secWash   WHICH ROCK AM I UNDER.
     Lon, 2026-08-29: "Should the sections be color coded? Then the background
     can be tinted to match the rock?" — ruled yes, and ruled explicitly NOT
     red/yellow/green. The reason is the rule three lines above this one: red
     is THE action and nothing else. Tinting a whole section red would put red
     behind every screen in it, and red would stop meaning act on the screens
     where it has to. So the manual keeps its red ROCK on the front door, one
     place, and no clinical screen is ever washed in it.

     --secWash overrides --paper, because --paper IS "the ground" and the
     ground is exactly what is being tinted; every consumer follows for free.
     --sec is the section's own accent, used on the way back and nowhere that
     carries clinical meaning. Both default to the Emergency Manual, so a page
     that declares no section renders exactly as it did before.

     design/section-back.js stamps data-sec on <html>; it resolves the section
     from ?from= or the page's declared default, so the tint and the back caret
     can never disagree about which area you are in. */
  --sec: var(--soft);
  --secWash: #f7f5f2;

  /* THREE FAMILIES, one job each (typography pass, 2026-09-21 — the splash is
     the canon). Every font-family in the app goes through one of these. */
  --font-brand: 'Bitter', Georgia, serif;                 /* the Cairn wordmark; at most a top-level title. Never body text. */
  --font-ui: 'Space Grotesk', system-ui, sans-serif;      /* everything a person reads or taps */
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;  /* short uppercase labels, version strings, clocks & digits. Never a full sentence. */

  /* type — the scale. Each line has one job; one-off font values are the
     thing this scale exists to retire. Space Grotesk tops out at 700, so 700
     is the heaviest weight anywhere. */
  --t-meta: 500 0.8125rem/1.4 var(--font-mono);   /* clocks-in-margin, short labels, stamps & counts — never prose (the log's WORDS ride --t-help since 2026-09-21; the stamp stays mono) */
  --t-body: 400 1.0625rem/1.5 var(--font-ui);     /* sentences a clinician reads — 17px floor at default OS size (design session 2026-09-21: legibility under stress outranks density) */
  --t-help: 500 0.84375rem/1.45 var(--font-ui);   /* helper / description sentences — prose is never mono */
  --t-title: 700 1rem/1.2 var(--font-ui);         /* the bar title */
  --t-action: 700 1.75rem/1.15 var(--font-ui);    /* the action, and moment headlines */
  --t-clock: 600 4rem/1 var(--font-mono);         /* the one number the room runs on */
  --t-label: 600 0.6875rem/1.35 var(--font-mono); /* THE micro-label voice: section keys, eyebrows, card heads — uppercase, tracked by --ls-label. Controls keep their own tuned faces. */
  --ls-label: .1em;                           /* letterspacing for uppercase mono labels */

  /* spacing — four steps */
  --s1: 8px; --s2: 14px; --s3: 22px; --s4: 32px;

  /* COMPATIBILITY ALIASES for the frozen v1 icon registries. procedure-icons.js
     draws with var(--red) and var(--ink2); those files are clinically reviewed
     and carried VERBATIM (never edited, never redrawn), so the mapping lives
     here instead: */
  --red: var(--act);
  --ink2: var(--soft);

  /* one radius, one floor */
  --r: 12px;
  --tap: 44px; /* nothing tappable is smaller, ever */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --secWash: #0e1523; --sec: #97a4b8; --ink: #e8ecf3; --soft: #97a4b8;
    --line: #24334d; --card: #131e33; --act: #e0655c; --act-ink: #131e33; --ok: #4fbf8a;
    --late: #8fb0da; --late-ink: #131e33;
    --gap: #e0aa3e; --gap-ink: #131e33;
  }
}
[data-theme="dark"] {
  --secWash: #0e1523; --sec: #97a4b8; --ink: #e8ecf3; --soft: #97a4b8;
  --line: #24334d; --card: #131e33; --act: #e0655c; --act-ink: #131e33; --ok: #4fbf8a;
  --late: #8fb0da; --late-ink: #131e33;
  --gap: #e0aa3e; --gap-ink: #131e33;
}
[data-theme="light"] {
  --secWash: #f7f5f2; --sec: #4c5a70; --ink: #16233c; --soft: #4c5a70;
  --line: #d3d8e0; --card: #ffffff; --act: #b3362f; --act-ink: #fdfcf9; --ok: #1e6b45;
  --late: #3f5f8f; --late-ink: #fdfcf9;
  --gap: #a87b00; --gap-ink: #16233c;
}

/* ---- THE THREE SECTIONS ---------------------------------------------------
   The ground says which rock you are under. Faint on purpose: enough to know
   the area at a glance, never enough to compete with what is written on it —
   --ink on every wash below stays far above 4.5:1 in both themes.

   NO RED HERE, and that is the whole design (Lon's ruling, 2026-08-29). The
   Emergency Manual keeps the red rock on the front door and takes the warm
   NEUTRAL ground, so red survives as the one thing it means: the action.

   The dark rules carry the same :not([data-theme="light"]) guard the base
   theme uses — without it a section's dark wash outranks an explicit light
   choice, and a phone set to light renders one section dark. */
/* Each section's pair is a NAMED TOKEN, so the rocks on the front door and the
   ground under a section resolve from the same values — the cairn shows the
   color, the section wears it, one home. The first cut kept these anonymous
   inside [data-sec] rules and washed so faintly a phone in daylight showed
   nothing — Lon's screenshot ("Where are the colors?") is why they deepened.
   Ink stays well past 4.5:1 on every wash in both themes (the suite measures
   it), and the hub's warm wash keeps its hue >30° off the action red. */
:root {
  --sec-hub: #4c5a70;   --secWash-hub: #f5f0e3;
  --sec-sims: #3f5f8f;  --secWash-sims: #e4ecfa;
  --sec-equip: #2c6b4c; --secWash-equip: #e2f1e8;
  --sec-home: #4c5a70;  --secWash-home: #f4f5f7;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --sec-hub: #97a4b8;   --secWash-hub: #121620;
    --sec-sims: #8fb0da;  --secWash-sims: #0e1e3d;
    --sec-equip: #7fc0a1; --secWash-equip: #0c241b;
    --sec-home: #97a4b8;  --secWash-home: #0c1424;
  }
}
:root[data-theme="dark"] {
  --sec-hub: #97a4b8;   --secWash-hub: #121620;
  --sec-sims: #8fb0da;  --secWash-sims: #0e1e3d;
  --sec-equip: #7fc0a1; --secWash-equip: #0c241b;
  --sec-home: #97a4b8;  --secWash-home: #0c1424;
}
/* INCREASED CONTRAST (Lon, 2026-09-23, issue 155 item 4: "yes, additive").
   The OS increased-contrast setting raises the two quiet tokens and nothing
   else: hairlines 1.3:1 → 2.3:1 (light) / 1.4:1 → 2.75:1 (dark), the soft text
   6.4 → 8.8 / 7.2 → 10.3. Invisible to anyone without the setting. */
@media (prefers-contrast: more) {
  :root:not([data-theme="dark"]) { --line: #9aa4b3; --soft: #3a4659; }
}
@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --line: #4a5d80; --soft: #b8c3d4; }
}
@media (prefers-contrast: more) {
  :root[data-theme="dark"] { --line: #4a5d80; --soft: #b8c3d4; }
}
/* THE DARK-CONTRAST BENCH ARM (Lon, 2026-09-23, issue 155 item 1: A/B on /lab/).
   body[data-con="plus"] — set only by /lab/ or ?con=plus, device-sticky — lifts
   the dark hairline 1.44 → 1.76:1 and the card 1.10 → 1.20:1 over the ground,
   the ~0.3 of headroom the refinement session measured. Off = absent = shipped. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body[data-con="plus"] { --line: #2e4063; --card: #18253f; }
}
:root[data-theme="dark"] body[data-con="plus"] { --line: #2e4063; --card: #18253f; }
/* the aliases need no dark guard of their own — the per-section tokens above
   already flip with the theme, so a dark device honoring an explicit light
   choice keeps working (the suite drives that exact configuration) */
:root[data-sec="hub"]   { --secWash: var(--secWash-hub);   --sec: var(--sec-hub); }
:root[data-sec="sims"]  { --secWash: var(--secWash-sims);  --sec: var(--sec-sims); }
:root[data-sec="equip"] { --secWash: var(--secWash-equip); --sec: var(--sec-equip); }
:root[data-sec="home"]  { --secWash: var(--secWash-home);  --sec: var(--sec-home); }


/* ---- the eleven components ----------------------------------------------- */

/* 0 · TOP BAR — navigation + the heads-up facts. Always present, always the
   same: the way back, which case, the case clock, and the WEIGHT — visible on
   every screen because every pediatric dose hangs off it. Sticky in product. */
.bar {
  display: flex; align-items: center; gap: var(--s2);
  min-height: 56px; padding: 6px 0;
}
.bar .back {
  display: flex; align-items: center; justify-content: center; gap: 3px; flex: none;
  min-width: var(--tap); height: var(--tap); padding: 0 10px;
  border: 1.5px solid var(--line);
  border-radius: var(--r); background: var(--card); color: var(--ink); cursor: pointer;
  text-decoration: none;
  /* the CAIRN is the mark and the way back, everywhere: caret + stones. On the
     front door the stones stand alone and link to cairnready.org. */
}
/* THE WAY BACK WEARS THE SECTION'S COLOR — the one place --sec is allowed to
   show. "Where am I" and "the way out of here" are the same question, and the
   caret answers both for free: it costs no vertical space, which matters
   because the bar is already two lines. Declared AFTER the rule above on
   purpose — the component sets `border: … var(--line)` in shorthand, and a
   section rule placed earlier in the file loses to it silently. */
.bar .back { color: var(--sec); border-color: color-mix(in srgb, var(--sec) 70%, var(--line)); }
.bar .where { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.bar .tool { font: var(--t-title); color: var(--ink); }
.bar .caseclock { font: var(--t-meta); color: var(--soft); }
/* THE FLAT BAR (cleaned 2026-09-21, Lon: "that top row is so messy"): on a
   page that is not a running case, the bar is ONE row — back · title ·
   version · signed-in button, baseline-aligned. The sentence subtitle lives
   OUTSIDE the bar as .sub, the quiet line under it; the case screens keep
   the stacked where (title over the case clock), which this rule never
   touches. */
.bar.flat .where { flex-direction: row; align-items: baseline; gap: 9px; min-width: 0; }
.sub { display: block; font: var(--t-help); color: var(--soft); margin: 0 0 12px; }
/* the bar is TWO LINES, never three (Lon, 2026-09-16, the site page at phone
   width: "yours, on this phone only" wrapped under the title and the account
   line was cut mid-word). The name and the line under it each keep to one
   line and trail off; the account line trails off too — text-overflow needs a
   block, not a flex box, so the line is a block with the tap height as its
   line height. */
.bar .tool, .bar .caseclock { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* THE CASE BAR'S TITLE WRAPS; IT IS NEVER CUT MID-WORD (issue 253, audit
   F24 — "RSI — W…", "TOURNIQUET APPLI…" broke TESTING's "the bar is two
   lines, nothing cut mid-word"; the revamp's two-line title, yes 2026-09-25).
   On a stacked bar (a case screen: title over the case clock) the title takes
   up to two lines, breaking only between words (or after a hyphen), and a
   third line is not drawn — so any cut falls between two words, never inside
   one. No ellipsis: text-overflow cuts inside a word, and -webkit-line-clamp's
   "…" does too (measured: "HEMORRH…" in Chromium); and no break-word, which
   split "Induction" across the lines in s9's 74 px column and then hid the
   "n". Only the third LINE is clipped: sideways the title may run into the
   bar's gap, so a single word a few px wider than the column ("intubation"
   in s9's 78 px) is drawn whole instead of losing its last letter. The FLAT
   bar (a page that is not a running case) stays one row and trails off, as
   ruled on 2026-09-21 and pinned by check.mjs. */
.bar:not(.flat) .tool { white-space: normal; text-overflow: clip; overflow-wrap: normal;
  overflow-x: visible; overflow-y: clip;
  max-height: 2.4em; /* two lines of --t-title, whose line-height is 1.2 */ }
/* a clock that is secretly a BUTTON dresses as its own text — the case
   clock in every bar (tap → the timeline) and the tappable clockBlock the
   engine builds. One class, not twelve inline styles and a JS-written
   cssText (E39 + E40, retired 2026-09-21). */
button.caseclock, button.clocktap { background: none; border: none; padding: 0;
  cursor: pointer; text-align: left; color: inherit; }
/* THE CASE CLOCK IS A 44 px TARGET (issue 253, audit F36: it was 18 px tall
   against --tap, "nothing tappable is smaller, ever"). Padding grows the
   button to the floor and an equal negative margin gives the space back, so
   the text, the bar and everything under it sit exactly where they did. The
   extra height reaches up over the title (not a control) and down into the
   bar's own padding. 1.4em is --t-meta's line box. */
.bar button.caseclock { padding-block: calc((var(--tap) - 1.4em) / 2);
  margin-block: calc((1.4em - var(--tap)) / 2); }
/* the subtitle sits under the bar and wraps freely — never ellipsized
   mid-word (Lon, 2026-09-21) */
.sub { overflow-wrap: anywhere; }
/* who is signed in, at the right end of every bar (design/account-line.js) —
   THE ONE SIGNED-IN BUTTON (typography pass, 2026-09-21): the splash's
   .acct-go rendering, everywhere. Rounded rectangle, thin border, semibold
   UI face; the label is two short words, so it never truncates at 390px.
   DRAWN AT 44 px, the tap floor (Lon, 2026-09-28): the box is the target,
   so the 40 px box with a 44 px hit strip of issue 253 is gone. It fits the
   bar's 56 px row beside the 44 px back button, so the bar does not grow. */
.bar .acct-line { margin-left: auto; flex: none; display: inline-flex; align-items: center; justify-content: center;
                  min-height: var(--tap); padding: 0 14px; border: 1px solid var(--line); border-radius: 8px;
                  background: var(--card); color: var(--soft); font: 700 0.875rem/1 var(--font-ui);
                  text-decoration: none; white-space: nowrap; }
.bar .acct-line[data-signed-in] { color: var(--ink); }

/* the weight chip lives IN the bar. In a pediatric case it wears its Broselow
   band — the same hexes as the printed tape and the cart (frozen v1 values).
   Color is never the only carrier: the band NAME is in the text. */
.chip[data-band] {
  border-color: var(--band); border-width: 2px; font-weight: 600;
  background: color-mix(in srgb, var(--band) 18%, var(--card));
}
.chip .dot { width: 13px; height: 13px; border-radius: 50%; background: var(--band);
  border: 1px solid color-mix(in srgb, var(--ink) 30%, transparent); }
/* The band hex is the TAPE's color (v1 'mid' values) in BOTH themes — the
   bright value carries the recognition; a dimmed dark-pair hex read as mud on
   the dark ground and was dropped for chips after Lon's review. */


/* 1 · ACTION — verb + agent + dose + route, one line. Tap = do = log. */
.action {
  display: flex; align-items: center; justify-content: center; text-align: center;
  flex-wrap: wrap; align-content: center; /* the tapfx line below wraps to its own row; one-line content is unchanged */
  min-height: 108px; padding: 0 var(--s3);
  overflow-wrap: anywhere; text-wrap: balance; min-width: 0;
  background: var(--act); color: var(--act-ink);
  border: none; border-radius: var(--r); font: var(--t-action); cursor: pointer;
  width: 100%;
}
/* 1b · THE TAP'S EFFECT, STATED ON THE RED (S3 calibration, Lon 2026-09-09:
   "carry a small 'tap to log' line so the tap's effect is stated"; A/B/C
   bench 2026-09-21; RULED 2026-09-21: ARM A IS THE PRODUCT). Default = A,
   the effect as its own quiet line inside the button. The bench arms stay
   for comparison off body[data-ux] (?ux= or /lab/): B = a compact ✓ LOG
   pill after the label; C = off (engine tapfx renders no span in C, so the
   control DOM matches the pre-ruling product). The line is exempt from the
   moment budget BY NAME — see the budget's exemption list in probes/s1.mjs;
   it rides inside the red the way the DUE NOW tail does. */
.tapfx { display: inline; flex: 1 0 100%; margin-top: 4px;
         font: 500 0.6875rem/1.4 var(--font-mono);
         letter-spacing: .08em; text-transform: uppercase; opacity: .85; }
         /* .85, not .8: at .8 the line's effective contrast on the red fill
            fell to 4.3:1 (below AA); .85 measures 4.7 light / 5.1 dark and
            the line still reads quiet — size and case carry the hierarchy */
body[data-ux="b"] .tapfx { flex: 0 0 auto; font-size: 0; letter-spacing: 0; margin: 0 0 0 10px;
  border: 1.5px solid color-mix(in srgb, var(--act-ink) 55%, transparent); border-radius: 999px; padding: 3px 9px; }
body[data-ux="b"] .tapfx::after { content: attr(data-short);
  font: 700 0.625rem/1 var(--font-mono); letter-spacing: .08em; }
.action[data-long] { font: 700 1.3125rem/1.25 var(--font-ui); }
.action[data-due="true"] { outline: 3px solid color-mix(in srgb, var(--act) 45%, var(--paper)); outline-offset: 3px; }
/* a DUE med that is not holding the red slot: same due vocabulary, secondary
   weight. Color is never the only carrier — the label also says DUE NOW. */
.action-2[data-due="true"] { outline: 3px solid color-mix(in srgb, var(--act) 45%, var(--paper)); outline-offset: 2px; }
/* the GIVEN state — a dose with no published interval, given at least once:
   ink border (the acted-on family, same as data-done) with the time-since
   tail still live. Never red, never DUE — the drug's own printed repeat
   window is the reference (BRIEF rule 7 addendum, 2026-08-29). */
.action-2[data-given="true"] { border-color: var(--ink); }

/* THE RETIRED STATE — the other half of a single-select GIVEN group (BRIEF
   rule 7 carve-out): choosing one drug of a mutually exclusive set dims its
   siblings, but they STAY TAPPABLE — someone taps midazolam, then gets IV
   access and gives lorazepam anyway, and the log accepts both without the
   screen fighting them (Lon, 2026-08-29). Dim ≠ disabled: no pointer-events
   change, no aria-disabled — the visual says "not the plan", never "not
   allowed". */
.action-2[data-retired="true"] { opacity: 0.45; }

/* the pulse check is TEN SECONDS — counted down in red inside the sheet, so
   the room can see the hands-off time running out (Lon, 2026-08-29) */
.rcsec { font: var(--t-clock); font-size: 2.75rem; line-height: 1; color: var(--act);
         font-variant-numeric: tabular-nums; margin: 2px 0 10px; }
.rcsec[data-over="true"] { opacity: .55; }

/* the cadence line and its MUTE button share a row: the reading on the left,
   the control on the right, the control looking like one */
.cadence { display: flex; align-items: center; justify-content: space-between;
           gap: var(--s2); padding: 6px 0; }
.mutebtn { display: inline-flex; align-items: center; justify-content: center; gap: 6px;
           flex: none; min-height: var(--tap); padding: 0 14px;
           border: 1.5px solid var(--line); border-radius: var(--r);
           background: var(--card); color: var(--ink); cursor: pointer;
           font: 700 0.75rem/1 var(--font-mono); letter-spacing: .08em; }
.mutebtn[aria-pressed="true"] { color: var(--soft); }

/* a countdown riding on an action button: the dose reads first, the time
   reads second, and DUE NOW replaces the time when the algorithm calls for it */
.cd { font: var(--t-meta); opacity: .85; margin-left: 8px; font-variant-numeric: tabular-nums; }
.action .cd { opacity: .92; }

/* the running tally — what has actually gone in, above the buttons */
.tally { display: flex; flex-wrap: wrap; gap: 4px 14px; font: var(--t-meta);
         color: var(--soft); padding: 2px 0 8px; }
.tally b, .tally .cnt { color: var(--ink); font-weight: 700; }
/* given → it is not a button any more; it is .logline. not-applicable → absent. */

/* 2 · SECONDARY ACTION — same grammar, visibly subordinate, at most three */
/* the green boxed exit — same geometry as the option rows, green border and
   green text; never a fill, because the red recommendation owns the only
   solid color on a case screen */
.action-ok {
  display: block; width: 100%; min-height: 56px; padding: 14px 16px;
  border: 2px solid var(--ok); border-radius: var(--r); background: none;
  color: var(--ok); font: 700 1.0625rem/1.2 var(--font-ui);
  letter-spacing: .04em; cursor: pointer; text-align: center;
}
.action-2 {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 60px; padding: 0 var(--s3);
  background: var(--card); color: var(--ink);
  border: 1.5px solid var(--line); border-radius: var(--r);
  font: 600 1.0625rem/1.2 var(--font-ui); cursor: pointer; width: 100%; overflow-wrap: anywhere; min-width: 0;
}

/* 2a-top · THE CARD'S TOP ROW (issue A + ruling (b), 2026-09-01): the two
   supporting links side by side, so moving them OFF the walk does not cost
   the walk two rows of height — the point of the ruling was vertical space
   above the fold. Wraps to two lines on a narrow phone rather than shrinking
   below the tap floor. */
.toprow { display: flex; gap: var(--s1); flex-wrap: wrap; }
.toprow > * { flex: 1 1 46%; }

/* 2a-eq · THE EQUIPMENT LINK (issue A, ruled 2026-09-01). Same idiom as
   SOURCES \u25b8 — a \u25b8 opens a sheet (issue #71, one idiom per action) — but it
   sits in the card's TOP row, so it is the QUIET version of it: the tap
   floor is kept, everything above it is not. R5's supporting material is
   subordinate to the first act even when it comes before it on the page. */
.action-2.eqlink {
  min-height: var(--tap);
  font: 600 0.875rem/1.2 var(--font-ui);
  letter-spacing: .06em; color: var(--soft);
}

/* 2b · retired 2026-08-28 — the scene/sim-inject style is gone: scenario
   injections do not appear on the pathways; a patient-state transition is
   an ordinary secondary action. Sims live only in the training areas. */

/* 2d · CRITICAL SECONDARY — one tap that must not be missed while another
   action holds the red fill (the birth stamp under the delivery stepper) */
.action-crit {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 72px; padding: 0 var(--s3);
  background: var(--card); color: var(--act);
  border: 2px solid var(--act); border-radius: var(--r);
  font: 700 1.1875rem/1.2 var(--font-ui);
  cursor: pointer; width: 100%; overflow-wrap: anywhere; min-width: 0;
}

/* 2e · THE BUTTON KINDS (issue #74, Lon 2026-09-17 — piloted on S3 post-ROSC).
   The shape says what a row does; the colors stay where they were (red = do
   now, green = the exit). A header names each group. */
.kind-head { margin: var(--s3) 0 2px; font: var(--t-label);
             letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
.stack > .kind-head:first-child { margin-top: 0; }
/* check off — a light row with a box that becomes ✓ + the time */
.action-2[data-kind="check"] { justify-content: flex-start; text-align: left; gap: 12px; min-height: var(--tap);
  background: none; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; font-weight: 500; }
.action-2[data-kind="check"]:not([data-done]):not(.dial)::before { content: ''; flex: none; width: 20px; height: 20px;
  border: 2px solid var(--ink); border-radius: 3px; }
/* a done check RECEDES, as a done .ck row and a done .step do (Lon,
   2026-09-28, the audit's F11 finished): soft ink, a dashed rule, and no
   heavier than an open check (500), where it used to go bold at 700. The ✓
   and the wall time stay: they are the record. */
.action-2[data-kind="check"][data-done] { border-width: 0 0 1px; border-style: dashed; border-color: var(--line); color: var(--soft); font-weight: 500; }
.action-2[data-kind="check"][data-done]::before { content: '✓'; flex: none; width: 20px; text-align: center; color: var(--ok); }
/* the patient changed — the one heavy row besides the red: bar + arrow */
.action-2[data-kind="move"] { justify-content: space-between; text-align: left; gap: 12px;
  border: 2px solid var(--ink); border-left-width: 8px; border-radius: 0; font-weight: 800; }
.action-2[data-kind="move"]::after { content: '\2192'; flex: none; }
/* open over the case — dashed, comes back */
.action-2[data-kind="open"] { justify-content: flex-start; text-align: left; border-style: dashed; border-color: var(--ink); }
/* a dose — repeatable and counted (Lon, 2026-09-24, issue 235 D1): the GIVEN
   look from the first render, the count on the label, the time since on its
   tail. A done-once row is a check; a dose is never one. */
.action-2[data-kind="dose"] { justify-content: space-between; text-align: left; gap: 12px; border-color: var(--ink); }
/* leave for a card — a link, not a button */
a.action-2[data-kind="go"] { justify-content: space-between; text-align: left; gap: 12px; min-height: var(--tap);
  background: none; border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  font-weight: 600; }
a.action-2[data-kind="go"]::after { content: '\2197'; flex: none; }

/* option chips in sheets: a picked option says so, and groups sit two-up */
.optgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.action-2[data-done] { border-color: var(--ink); border-width: 2px; font-weight: 800; }
.action-2[data-done]::before { content: '✓ '; }

/* 2c · PAIR — two outcomes of equal standing; neither is "the" action */
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pair3 { grid-template-columns: 1fr 1fr 1fr; }
.pair .action-2 { min-height: 84px; font: 700 1.0625rem/1.25 var(--font-ui); }

/* 3 · CLOCK — the one number, with what it counts beneath it */
.clock { font: var(--t-clock); color: var(--ink); font-variant-numeric: tabular-nums; }
.clock-label { font: var(--t-meta); letter-spacing: 2px; text-transform: uppercase; color: var(--soft); }
/* THE LAST TEN SECONDS OF A CYCLE. Inside the window the number turns the
   action color and the instruction for those seconds appears beneath it —
   pre-charge in a shockable rhythm, dump the charge in one that is not.
   Both the number and the words are driven from one place in engine.js, so
   the color and the instruction can never disagree about whether the window
   is open. Colors are tokens, so this reads in both themes. */
.clockblock[data-warn="true"] .clock { color: var(--act); }
/* at zero a declared-due block drops its digits — the label carries the
   state and the red action below carries the instruction (cr#7 item 2) */
.clockblock[data-due="true"] .clock { display: none; }
.clock-warn:empty { display: none; }
/* THE TEXT VOCABULARY (BRIEF rules 8–9, Lon 2026-08-29). due-txt is the ONE
   inline-text claim on the alarm color — state-triggered due-now/overdue
   words only. warn-txt / warn-box are warnings: loud by weight and border,
   in ink, never red. Cards use these classes; element-level color or
   spacing values are a build failure (the inline-style ratchet in check.mjs). */
.due-txt { color: var(--act); font-weight: 700; }
/* the utility vocabulary for card- and sheet-built markup (BRIEF rule 9:
   no inline style attributes — everything is a class). Named by role. */
.soft { color: var(--soft); }
.bold { font-weight: 700; }
.inert { cursor: default; }
.tleft { text-align: left; }
.flex1 { flex: 1; }
.fmin { flex: 1 1 auto; min-width: 0; }
.iconrow { display: flex; align-items: center; gap: 10px; }
.sheet-note { font: var(--t-help); color: var(--soft); padding: 6px 0; }
.sheet-row { font: var(--t-body); padding: 6px 0; }
.sheet-big { min-height: 60px; font-size: 1.25rem; }
.sheet-x { min-width: 44px; min-height: 44px; background: none; border: 1.5px solid var(--line);
           border-radius: var(--r); color: var(--ink); font-size: 1.125rem; cursor: pointer; }
a.action-2 { text-decoration: none; }
/* a white row that states its tap (s1's cord countdown, issue 232) wraps the
   tapfx line to its own row, as .action does; rows without one are unchanged */
.action-2:has(> .tapfx) { flex-wrap: wrap; align-content: center; }
.kv { font: var(--t-meta); letter-spacing: 1px; color: var(--soft); }
.lane-head { font: var(--t-meta); letter-spacing: 2px; text-transform: uppercase; color: var(--soft); }
.mtp-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; }
.mtp-cell { padding: 8px 4px; text-align: center; border: 1px solid var(--line); }
.mtp-num { font: 800 1.875rem/1.2 var(--font-mono); }
.mtp-cal { margin-top: 10px; padding: 10px 12px; border: 2px solid var(--line); border-radius: var(--r); }
/* THE MTP LINE (BRIEF s8, Stop A candidate — the ONE new element kind):
   the running product tally as a wrapping row of counting chips, riding
   under the mode line as a single element. The chips are the bar's own
   .chip class — 44px floor, token colors — so this is the one new rule. */
.mtpline { display: flex; flex-wrap: wrap; gap: 6px; }
.mtp-cal[data-due="true"] { border-color: var(--act); }
.mtp-cal .h { font: 800 0.8125rem/1.3 var(--font-mono); letter-spacing: .04em; color: var(--soft); }
.mtp-cal[data-due="true"] .h { color: var(--act); }
.mtp-row { display: flex; gap: 4px; margin-top: 6px; }
.mtp-add { flex: 1; min-height: 44px; }
.sheet-body { font: var(--t-body); line-height: 1.55; padding: 2px 0 8px; }
.sheet-head { display: flex; align-items: center; gap: 8px; }
.sheet-sm { min-height: 52px; font-size: 0.8125rem; padding: 4px 8px; }
.dim { opacity: .55; }
.eyebrow { font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); padding: 8px 0 2px; }
.figwrap { border: 1.5px solid var(--line); border-radius: var(--r); background: var(--card); padding: 10px; }
.figcap { font: 700 0.6875rem/1.3 var(--font-ui); letter-spacing: .07em; margin-top: 8px; }
.figsub { font: var(--t-help); color: var(--soft); margin-top: 4px; }
.numbox { font: 700 0.875rem/1.35 var(--font-ui);
          border: 1.5px solid var(--ink); border-radius: var(--r); padding: 10px 12px; }
.rolecap { font: 700 0.75rem/1.3 var(--font-ui); letter-spacing: .05em; color: var(--soft); }
.opt-lead { border-width: 2px; font-weight: 800; }
.figimg { width: 100%; max-width: 300px; display: block; margin: 0 auto; }
.hflex { display: flex; gap: 8px; }
.hflex2 { display: flex; gap: 8px; align-items: stretch; }
.hflex6 { display: flex; gap: 6px; }
.logbtn { width: auto; min-width: 84px; flex: none; }
.wfield { flex: 2; min-width: 0; }
.due-note { font: var(--t-help); color: var(--act); font-weight: 800; padding: 0 0 6px; }
.mtp-note { font: var(--t-help); color: var(--soft); padding-top: 4px; }
.mtp-sub52 { flex: none; width: 52px; }
.in-meta { font: var(--t-meta); }
/* the visible beat — the speaker glyph swells on every scheduled tone, so a
   silent phone is diagnosable at a glance: pulse + no sound = the device is
   eating audio; no pulse = the app is */
@keyframes beat { 0% { transform: scale(1.35); } 100% { transform: scale(1); } }
.mutebtn svg.beat { animation: beat .28s ease-out; }
@media (prefers-reduced-motion: reduce) { .mutebtn svg.beat { animation: none; } }
.mtp-sub { flex: none; width: 44px; min-height: 44px; }
.warn-txt { font-weight: 800; }
.warn-box { border: 2px solid var(--ink); border-radius: var(--r);
            padding: 10px 12px; font: var(--t-help); font-weight: 700; }
.clock-warn {
  font: var(--t-meta); letter-spacing: 2px; text-transform: uppercase;
  color: var(--act); font-weight: 800; padding-top: 2px;
}

/* 4 · MOMENT HEADER — where am I; the top rule is the page's one heavy line */
.moment {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2);
  border-bottom: 2px solid var(--ink); padding-bottom: var(--s2);
}
.moment .name { font: 700 1.0625rem/1.2 var(--font-ui); color: var(--ink); }
.moment .case-clock { font: var(--t-meta); font-size: 0.9375rem; color: var(--ink); flex: none; }

/* 5 · STATE CHIP — a fact that travels (weight, phase). Set = quiet; unset = asks. */
.chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap);
  padding: 0 var(--s2); border: 1.5px solid var(--line); border-radius: 999px;
  background: var(--card); font: var(--t-meta); font-size: 0.875rem; color: var(--ink); cursor: pointer;
}
.chip[data-unset="true"] { border-color: var(--act); color: var(--act); font-weight: 600; }

/* 6 · LOG LINE — what a tap wrote; the timeline is made of these */
/* the log is SENTENCES a clinician reads back — the words wear the UI face
   (mono never carries a full sentence, per the three-family ruling); the
   wall stamp stays mono, so times still align down the column */
.logline { display: flex; gap: 10px; align-items: baseline; font: var(--t-help); color: var(--soft); min-height: 24px; }
.logline .t { font: var(--t-meta); color: var(--ink); }

/* 7 · REFERENCE LINK — the one tap to everything not needed this second */
.ref {
  display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap);
  font: var(--t-body); color: var(--ink); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-color: var(--line);
}
/* 7b · A PLAIN LINK — one themed link colour in both themes (issue 253,
   audit F33). A link with no class kept the browser's own blue: #0000EE on
   the dark card #131e33 is 1.77:1 (the drills' cross-links, the procedure
   section sheets, Equipment). It takes the ink of the text around it — --ink
   on the ground and the cards, the right ink on any filled surface — and the
   underline is what says "link". No blue: in this palette blue means
   overdue. Zero specificity, so any class that styles its own link wins. */
:where(a:not([class])) { color: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* 8 · CONFIRM (destructive) — two taps, and it says what it destroys */
.confirm {
  display: flex; align-items: center; justify-content: center; min-height: 60px;
  width: 100%; background: transparent; color: var(--act);
  border: 1.5px solid var(--act); border-radius: var(--r);
  font: 600 1.0625rem/1.2 var(--font-ui); cursor: pointer;
}
.confirm[data-armed="true"] { background: var(--act); color: var(--act-ink); }

/* 9 · PROCEDURE INLAY — a procedure card INTERPOSED into the case. The steps
   come from content/ (one home, never retyped); the case clock stays visible;
   tapping a step logs it done; RETURN puts you back on the moment you left. */
.proc-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  border-bottom: 2px solid var(--ink); padding-bottom: var(--s2);
}
.proc-head .name { font: 700 1.0625rem/1.2 var(--font-ui); color: var(--ink); }
.proc-return {
  display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap);
  padding: 0 var(--s2); border: 1.5px solid var(--line); border-radius: var(--r);
  background: var(--card); font: 600 0.875rem/1 var(--font-ui);
  color: var(--ink); cursor: pointer; white-space: nowrap;
}
.step {
  display: flex; gap: var(--s2); align-items: flex-start; width: 100%; text-align: left;
  min-height: var(--tap); padding: 10px var(--s2);
  background: var(--card); border: 1.5px solid var(--line); border-radius: var(--r);
  font: var(--t-body); color: var(--ink); cursor: pointer;
}
.step .n { font: var(--t-meta); color: var(--soft); flex: none; padding-top: 2px; }
.step[data-done="true"] { border-style: dashed; color: var(--soft); }
/* [data-lead] — a step the room must not skip (Lon, 2026-09-02: "Assign
   Roles and Start MTP need to be highlighted more"). Loud by weight and
   border, in ink — never red, which is reserved for due-now (rule 8).
   A procedure card's check row (.ck) wears the same lead when it is the NEXT
   step (issue 253 / audit F11; the card stamps the attribute). The #screen
   selector outranks the deck and pathways shells' own .ck rules, which sit
   later in the cascade; the ::before is the .ck row's gutter mark, its .n. */
.step[data-lead], .action-2.ck[data-lead], #screen .stack > .action-2.ck[data-lead] { border: 2px solid var(--ink); font-weight: 800; }
.step[data-lead] .n, #screen .stack > .action-2.ck[data-lead]::before { color: var(--ink); font-weight: 800; }
/* ONE DONE GRAMMAR: DONE RECEDES (issue 253, audit F11). A done check row
   on a procedure card used to get HEAVIER — a 2 px ink border and weight 800
   (the generic .action-2[data-done] of section 2, and the deck and pathways
   shells' own .ck rule) — so the finished steps were the loudest rows on the
   card, while an engine .step went quiet. Now a done .ck row does what
   .step[data-done] does: dashed, soft, no heavier than an open row (600 is
   .action-2's own weight; the shells set 400 and keep it). The ✓ and the
   wall time stay: they are the record. */
.action-2.ck[data-done] { border: 1.5px dashed var(--line); color: var(--soft); font-weight: 600; }
#screen .stack > .action-2.ck[data-done] { border: 1.5px dashed var(--line); }

/* 10 · THE LOG — one system, three faces. (a) every action tap writes a
   logline; (b) MAJOR moments render heavy, marked, so the timeline can be
   read back at a glance — ROSC, a pronouncement, a decision; (c) the
   quick-log sheet catches what has no button: common events as one-tap rows
   plus guarded free text. No names, no MRN — the log never leaves the phone. */
.logline[data-major="true"] { font-weight: 600; color: var(--ink); }
.logline[data-major="true"]::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--act); align-self: center; flex: none;
}
.log-input {
  width: 100%; box-sizing: border-box; min-height: var(--tap); padding: 10px var(--s2);
  border: 1.5px solid var(--line); border-radius: var(--r);
  background: var(--paper); color: var(--ink); font: var(--t-body);
}
.log-guard { font: var(--t-help); font-size: 0.75rem; color: var(--soft); }

/* 12 · NEXT-UP — scheduled, not yet due. THE distinction that keeps a screen
   honest: the ACTION control is only ever NOW; anything with time still on it
   sits in a quiet next-up row with its own countdown. When the countdown hits
   zero the row LEAVES this component and renders as the action (state: due).
   The big clock is the same idea at headline size — it always counts to the
   NEXT action BY NAME, never to an abstract zero.
   A scheduled action whose tap is compound (PULSE CHECK: pauses the metronome,
   stamps the time, opens the rhythm picker) still gets ONE control and ONE
   gesture — the compound is what the tap MEANS, never extra buttons.

   SEVERAL AT ONCE — three lanes, and every pending thing lives in exactly one:
     NOW      the action control. Only ever one primary.
     TIMED    sorted soonest-first; the SOONEST is the headline clock, the rest
              are .next rows beneath it. Epi in 2:30 never sits above a rhythm
              check in 1:15.
     STANDING untimed tasks (advanced airway, call OB) are SECONDARIES, not
              queue rows — a countdown row with no countdown is a lie. One with
              a procedure card carries its glyph and opens the inlay (the steps
              log themselves); one without is a plain tap-log. */
.next {
  display: flex; align-items: center; gap: var(--s2); width: 100%;
  min-height: var(--tap); padding: 0 var(--s2);
  border: 1.5px dashed var(--line); border-radius: var(--r);
  background: transparent; color: var(--soft); font: var(--t-body);
}
.next .k { font: var(--t-meta); font-size: 0.6875rem; letter-spacing: 2px; color: var(--soft); flex: none; }
.next .what { color: var(--ink); font-weight: 600; min-width: 0; flex: 1 1 auto; }
.next .in { font: var(--t-meta); color: var(--ink); flex: none; font-variant-numeric: tabular-nums; }

/* the TIMELINE STRIP — the log's front door, on every moment screen. It is
   the bottom edge of every screen: the newest entry plus the entry count.
   Tapping it — or the case clock in the bar — opens the timeline sheet:
   full log newest-first, major moments marked, quick-log at the top. Two
   handles, one destination; the thing that shows case time opens case times. */
.timeline-strip {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  width: 100%; min-height: var(--tap); padding: 0 var(--s2);
  border: 1.5px solid var(--line); border-radius: var(--r); background: var(--card);
  font: var(--t-help); color: var(--soft); cursor: pointer; text-align: left;
  /* chrome like the weight chip, after live review: a bare hairline did not
     read as tappable; the log's front door has to look like a door */
}
.timeline-strip .latest { display: flex; gap: 10px; align-items: baseline; min-width: 0; }
/* MONO AT 13 px, AND IT MAY TAKE TWO LINES (Lon, 2026-09-28, over issue
   253's one-line UI face). The time, the newest entry cut on a word at thirty
   characters, and LOG n, in --t-meta. The widest entry (29 capitals, LOG
   108) needs about 380 px, so on a narrow phone it wraps a whole word to a
   second line. Nothing clips it: the strip has a min-height, never a height,
   and two lines of --t-meta (36 px) sit inside the 44 px tap floor, so a
   wrapped strip is the same height as a one-line one; at a larger text size
   it grows, and the foot's inset grows with it. */
.timeline-strip .latest .t { font: var(--t-meta); color: var(--ink); }
.timeline-strip .count { font: var(--t-meta); flex: none; color: var(--soft); }
/* THE STRIP IS FIXED TO THE BOTTOM EDGE, AND NEVER A LID (Lon, 2026-09-28,
   replacing issue 253's strip in the flow). The foot is the last thing in
   the #app column and sticky at bottom 0: on every screen, scrolled or not,
   the strip is the bottom edge, and because a sticky box keeps its own place
   in the flow, the page always has the strip's real height (one line or two)
   left to scroll, so any row can be scrolled clear above it. On a moment
   that fits, nothing sits under it at all. On a moment taller than the
   screen the last rows pass under it until they are scrolled to: the
   newborn's red at 375×667 needs a scroll to clear it, which Lon accepted
   with the fixed strip. The scroll padding does the same for a row the
   browser scrolls to itself (focus, find in page): the strip's floor height
   plus the foot's 10 px. Onboarding's own #foot carries no strip and is not
   touched. */
#foot:has(> .timeline-strip) { position: sticky; bottom: 0; }
html:has(#foot > .timeline-strip) { scroll-padding-bottom: calc(var(--tap) + 10px); }

/* 11 · GLYPHS — two frozen v1 sets, carried verbatim (design/ICONOGRAPHY.md).
   procedure-icons.js draws anatomy + ONE red action idea, themed by the alias
   tokens above, so both themes work untouched. equipment-icons.js draws the
   drawer's objects as #111 silhouettes — those always sit on a white tile,
   because the drawing IS the printed label and must match the cart exactly. */
.proc-glyph { width: 44px; height: 44px; flex: none; }
.proc-detail { width: 100%; max-width: 320px; height: auto; }
.fig-caption { font: var(--t-help); font-size: 0.75rem; color: var(--soft); }
.eq-tile { display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; background: #ffffff; border: 1.5px solid var(--line);
  border-radius: 8px; padding: 6px; flex: none; }
.eq-tile svg { width: 100%; height: 100%; }

/* PICKER SHEET — a decision suspended, never resolved by the page */
.sheet { background: var(--card); border: 1.5px solid var(--line); border-radius: 16px; padding: var(--s3); display: flex; flex-direction: column; gap: var(--s1); }
/* a capped sheet SCROLLS — it never compresses its rows. Without this, iOS
   Safari shrinks flex children to fit max-height before overflowing, and long
   log lines render on top of each other and of END CASE. */
.sheet > * { flex: none; }

.sheet .q { font: 600 1.0625rem/1.3 var(--font-ui); color: var(--ink); margin-bottom: var(--s1); }

/* tap acknowledgment: every button answers back for half a second, so a
   log-only tap never looks dead (engine adds .ack on click) */
button.ack { animation: ack .5s ease-out; }
@keyframes ack { 0% { box-shadow: 0 0 0 3px var(--act); } 100% { box-shadow: 0 0 0 12px rgba(0, 0, 0, 0); } }
@media (prefers-reduced-motion: reduce) { button.ack { animation: none; } }

/* ---- THE DOLL — a treatment card open INSIDE a running case ---------------
   Ruled 2026-08-30 (Lon): B on the phone, C at width — and the card GATES
   the algorithm underneath, never just describes it. The doll lives outside
   #screen so the 1 s repaints pass through it; its taps log into the ONE
   case timeline; RETURN pops back to the case exactly as it stands.

   Phone: the card slides to ~⅔ height and the exposed case RE-RENDERS
   COMPRESSED ON PURPOSE (Lon, mid-review: "the info up top compressed when
   the card slides up") — moment · mode · clock · tally · rows the case marks
   [data-vital] — never a screen truncated wherever the panel landed.
   THE DOLL NEVER GROWS (Lon, 2026-09-22): scrolling inside it scrolls its
   content only — the body is its own scroll container and contains its
   overscroll — so the case's clock, counters and due-now action stay in
   view and live above it. (The 2026-08-30 scroll-pressure-to-full-screen
   is retired.) The handle: a tap or a drag down docks the card to its
   strip, which turns red when the rhythm check lands.

   Width ≥760px (the one breakpoint, engine.js WIDE): the same DOM lays out
   as two panes — the case keeps the left, the doll takes the right, nothing
   compresses and nothing punches through because nothing is covered. */
.doll { position: fixed; left: 0; right: 0; bottom: 0; top: 37%;
  background: var(--paper); border-top: 1.5px solid var(--line);
  border-radius: 18px 18px 0 0; box-shadow: 0 -10px 30px rgba(0,0,0,.18);
  transform: translateY(103%); transition: transform .28s ease, top .28s ease;
  display: flex; flex-direction: column;
  /* BELOW the sheet overlay (z-index 10 in every engine page): a sheet is a
     momentary question and always wins the screen; the doll is the standing
     layer under it */
  z-index: 9; }
.doll.open { transform: translateY(0); }
/* DOCKED (R6 item 4) — a state, not closed: the doll slides down until only
   its strip shows at the bottom edge; stack and scroll are kept, nothing is
   logged. The strip tap slides it back up where it was. */
.doll.open.docked { top: 0; border-radius: 0; transform: translateY(calc(100% - 48px)); box-shadow: none; }
.doll.docked .doll-strip { display: flex; }
.doll.docked .doll-grab { display: none; }
.doll-grab { flex: none; display: flex; justify-content: center; padding: 8px 0 2px; cursor: pointer; min-height: 20px; touch-action: none; }
.doll-grab i { width: 44px; height: 4px; border-radius: 2px; background: var(--line); }
.doll-strip { flex: none; display: none; align-items: center; gap: 10px; padding: 10px 14px;
  min-height: var(--tap); cursor: pointer; background: var(--card);
  border-bottom: 1.5px solid var(--line);
  font: 700 0.75rem/1.2 var(--font-mono); letter-spacing: .04em; color: var(--ink); }
.doll-strip .crumb { color: var(--soft); font-weight: 500; }
.doll-strip .live { margin-left: auto; font-variant-numeric: tabular-nums; }
.doll-strip[data-due="true"] { background: var(--act); color: var(--act-ink); border-color: var(--act); }
.doll-strip[data-due="true"] .crumb { color: var(--act-ink); opacity: .85; }
.doll-body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 8px 16px 16px; display: flex; flex-direction: column; gap: 9px; }
/* rows never shrink — content taller than the doll scrolls, it does not
   compress rows into each other (the WebKit long-log geometry class) */
.doll-body > * { flex: none; }
/* the log lines inside the log doll keep the timeline's own rhythm */
[data-dolllog] { display: flex; flex-direction: column; gap: 6px; }
.doll-title { display: flex; align-items: center; gap: 10px; font: 700 1.1875rem/1.2 var(--font-ui); }   /* the card's one glyph, then its name (INVARIANTS.md rule 3) */
.doll-src { font: var(--t-meta); font-size: 0.6875rem; color: var(--soft); }

/* the HELD state — the algorithm shifted this row out of play: same
   geometry, drained of red, dashed. STILL TAPPABLE — tapping logs an
   override, never fights the hands (the manual's undo rule). */
.action-2[data-held="true"] { border-style: dashed; color: var(--soft); font-weight: 700; }

/* the mode line — WHICH GATE THE CASE IS UNDER, stamped beneath the moment;
   tappable, and the tap reopens the card that set it. INK, not red (ruled,
   cr#7 item 5): red stays reserved for due-now and the primary action, and
   a standing state banner is neither. No warm/state token exists in this
   palette, and the ruling forbids inventing one. */
.mode-line { display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 2px 0; cursor: pointer;
  font: 700 0.75rem/1.4 var(--font-mono); letter-spacing: .05em; color: var(--ink); }

/* phone: the compressed case header while a doll is up — every element that
   survives must FIT ABOVE the doll's top edge, or it is decoration under
   glass. One line each: moment, mode, clock (label clipped to one line),
   tally, and the [data-vital] rows. A DOCKED doll lifts the compression:
   the case has its screen back while the card waits in its strip. */
@media (max-width: 759.9px) {
  body[data-doll]:not([data-doll-dock]) #screen { display: flex; flex-direction: column; gap: 4px; }
  body[data-doll]:not([data-doll-dock]) #screen .moment { font: 700 0.875rem/1.2 var(--font-ui); }
  body[data-doll]:not([data-doll-dock]) #screen .mode-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 0.6875rem; padding: 0; }
  body[data-doll]:not([data-doll-dock]) #screen .clockblock .lab { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 0.625rem; }
  body[data-doll]:not([data-doll-dock]) #screen .clock { font-size: 1.75rem; }
  body[data-doll]:not([data-doll-dock]) #screen .cadence { display: none; }
  body[data-doll]:not([data-doll-dock]) #screen .stack { gap: 6px; }
  body[data-doll]:not([data-doll-dock]) #screen .stack > * { display: none; }
  body[data-doll]:not([data-doll-dock]) #screen .stack > .tally { display: flex; padding: 0; }
  body[data-doll]:not([data-doll-dock]) #screen .stack > [data-vital] { display: flex; min-height: var(--tap); font-size: 0.8125rem; padding: 2px 10px; }
  /* THE PARENT'S DUE-NOW RIDES THE COMPRESSED HEADER (R6 item 5): when the
     case underneath comes due (epi, rhythm check), its red action surfaces
     above the doll — tappable, logging as if the doll were not there. The
     compressed-header budget is SIX: moment, mode, clock, tally, vitals,
     and the due-now action. */
  body[data-doll]:not([data-doll-dock]) #screen .stack > .action { display: flex; min-height: var(--tap); font-size: 0.9375rem; padding: 2px 10px; }
  /* the compressed case has no room for the effect line — the doll is on top */
  body[data-doll]:not([data-doll-dock]) #screen .stack > .action .tapfx { display: none; }
  /* the docked doll's strip is FIXED on the bottom edge (48 px): the sticky
     foot reserves that height under the timeline strip, so the log strip
     rides just above the dock and the last row still scrolls clear of both
     (the docked half of the strip inset; the scroll padding follows) */
  body[data-doll-dock] #foot { padding-bottom: 58px; }
  html:has(body[data-doll-dock] #foot > .timeline-strip) { scroll-padding-bottom: calc(var(--tap) + 58px); }
}
/* THE RIGHT PANE IS NEVER EMPTY (R6 item 7): at width, the pane a doll
   would take shows the TIMELINE when no doll is open — the log's front
   door, standing. The engine appends .tlpane and stamps body[data-engine];
   on the phone there is no pane. */
/* the procedure drawing fills its card — was a JS-written cssText in
   procedures/case.js (E40 debt), now the class it always should have been */
.figwrap svg { display: block; width: 100%; max-height: 220px; height: auto; }

.tlpane { display: none; }
/* the pane card (Lon, 2026-09-14): the case's own block above the log at width and
   under the log in the doll — the procedure's glyph, its poster, its sources */
.pane-card { display: flex; flex-direction: column; gap: var(--s1); flex: none; }
/* the reference block a doll ends with (INVARIANTS.md, rule 1): the same rhythm as the pane card */
.refblock { display: flex; flex-direction: column; gap: var(--s1); flex: none; }
.refblock:empty { display: none; }
.pane-card:empty { display: none; }
.doll .pane-card { margin-top: var(--s2); }
.pane-fig { display: flex; justify-content: center; padding: 4px 0 2px; color: var(--ink); }
.pane-fig .proc-glyph { width: 96px; height: 96px; }
/* END CASE sits at the pane's bottom edge — margin-top:auto in the flex
   column keeps the destructive control below everything else (cr#6) */
.tlpane .confirm { margin-top: auto; flex: none; }
.tlpane-head { flex: none; font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); padding-bottom: var(--s2); }
.tlpane-log { display: flex; flex-direction: column; gap: 6px; }

/* width: two panes — the case keeps the left; the right belongs to the doll
   when one is open, to the timeline otherwise.
   The app is a 430px CENTERED column, so the panel must not simply cover the
   right half of the window — Lon's desktop screenshot (2026-08-30) showed
   the case clipped UNDERNEATH it. At width an engine page pins LEFT and the
   pane takes what remains, never less than the case column needs (that
   floor is also why the breakpoint is 760px). */
@media (min-width: 760px) {
  body[data-engine] #app { margin-left: 16px; margin-right: auto; }
  /* a docked sheet takes the pane, not the room: opaque over the pane, the
     case stays live on the left. Modal (the ten-second questions) keeps the
     centered dimmed form everywhere. */
  .overlay:not(.modal) { left: auto; width: min(56%, calc(100% - 462px)); background: var(--paper);
    align-items: stretch; justify-content: stretch; border-left: 1.5px solid var(--line); }
  .overlay:not(.modal) .sheet { max-width: none; width: 100%; max-height: none; border-radius: 0; }
  .doll { left: auto; top: 0; border-radius: 0; border-left: 1.5px solid var(--line); border-top: none;
    width: min(56%, calc(100% - 462px)); }
  .doll-grab { display: none; }
  .doll-strip { display: flex; cursor: default; }
  body[data-engine]:not([data-doll]) .tlpane { display: flex; flex-direction: column; gap: 9px;
    position: fixed; right: 0; top: 0; bottom: 0; width: min(56%, calc(100% - 462px));
    border-left: 1.5px solid var(--line); background: var(--paper);
    padding: 14px 16px; box-sizing: border-box; overflow-y: auto; }
  /* the pane IS the log at width (cr#7 item 3) — the bottom strip would be
     the same door twice; the bar's clock stays the timeline sheet's door */
  body[data-engine] #foot { display: none; }
}

/* 2c · THE DIAL — every phone number is a tel: link with the glyph and the
   44 px floor (Lon, 2026-09-08, ruling 3; design/dial.js writes it). Inline
   in a sentence it is a chip; on a case screen it wears the ✓ row's own
   .action-2 geometry (CALL TRANSFER on post-ROSC). Ink, never red: a phone
   number is not a due-now state. */
.dial { display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap);
        padding: 0 10px; margin: 2px 0; border: 1.5px solid var(--line); border-radius: var(--r);
        background: var(--card); color: var(--ink); font-weight: 700; text-decoration: none;
        vertical-align: middle; overflow-wrap: anywhere; }
.dial-glyph { width: 18px; height: 18px; flex: none; }
.action-2.dial { display: flex; gap: 10px; justify-content: center; padding: 0 var(--s3); margin: 0; }
.action-2.dial > span { min-width: 0; }

/* the practice sheet (ruling 2): the privacy line rides the question, so the
   sheet is four elements — the question, REAL CASE, SIMULATION, NOT NOW */
.sheet .q[data-guard]::after { content: attr(data-guard); display: block; margin-top: 4px;
        font: var(--t-help); font-size: 0.75rem; font-weight: 400; color: var(--soft); }

/* ---- S9 · THE STEP INTERFACE (Lon's 2026-09-08 handoff) --------------------
   spec: docs/superpowers/specs/2026-09-08-rsi-step-interface-design.md.
   One vocabulary on top of the engine's: the kicker line, ONE primary block
   (.action.block = do now; .action-ok.block = the exit, a box, never a fill),
   reference cards, choose-1 rows, chips, the keypad, the Broselow tiles, the
   timer card. Colors are the six tokens; the band tokens are the tape's own
   values — the same hexes V.bands carries (frozen v1 values). */
:root {
  --band-grey: #5a6a78; --band-pink: #c96f8c; --band-red: #9b1c2e; --band-purple: #6f4fa8; --band-yellow: #8a6d1f;
  --band-white: #8a8578; --band-blue: #2f62a8; --band-orange: #b45a1f; --band-green: #2f7a3f;
}
.kicker { display: flex; align-items: center; gap: 10px; min-height: var(--tap);
  font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
.kicker .kicker-text { flex: 1 1 auto; min-width: 0; }
.kicker .kicker-n { flex: none; }
.kicker.sub { min-height: 0; justify-content: space-between; padding-top: 6px; }
.kicker-back { flex: none; width: var(--tap); height: var(--tap); padding: 0; border-radius: var(--r);
  background: var(--card); border: 1.5px solid var(--line); color: var(--ink);
  font: 400 1.5rem/1 var(--font-ui); cursor: pointer; }
/* THE BLOCK — red (.action) is the step to do now; green (.action-ok) is the
   exit, boxed. Declared after .action and .action-ok so its layout wins. */
.block { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 14px;
  width: 100%; min-height: 140px; padding: 20px 22px; border-radius: 18px; text-align: left;
  text-wrap: pretty; letter-spacing: 0; }
.block .block-title { font: 700 1.5rem/1.1 var(--font-ui); letter-spacing: -.02em; }
.block .lines { display: flex; flex-direction: column; gap: 10px; }
.block .line { display: flex; gap: 10px; align-items: baseline; font: 500 1rem/1.35 var(--font-ui); }
.block .line::before { content: ''; flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .85; position: relative; top: -2px; }
.block .hint { margin-top: auto; padding-top: 10px; font: var(--t-label); letter-spacing: var(--ls-label); opacity: .85; }
.block[data-dim="true"] { opacity: .45; }
.block.cta { min-height: 64px; padding: 0 22px; justify-content: center; }
.block.cta .block-title { font-size: 1.125rem; letter-spacing: .02em; }
.action-ok.block .block-title { color: var(--ok); }
/* a reference CARD — plain, never tappable as a whole */
.card { background: var(--card); border: 1.5px solid var(--line); border-radius: 16px; overflow: hidden; }
.card-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 15px;
  border-bottom: 1px solid var(--line); font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
.card-note { padding: 10px 15px; font: var(--t-help); color: var(--soft); border-bottom: 1px solid var(--line); }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 10px; align-items: start; }
.gear { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.gear-cell { padding: 12px 15px; border-top: 1px solid var(--line); min-width: 0; }
.gear-cell .k { font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }
.gear-cell .v { font: 600 1.0625rem/1.2 var(--font-ui); margin-top: 4px; text-wrap: pretty; }
.gear-cell .s { font: var(--t-meta); font-size: 0.6875rem; color: var(--soft); margin-top: 2px; }
.drawup-row { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: 12px; padding: 12px 15px; border-top: 1px solid var(--line); align-items: start; }
.drawup-row .k { font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); padding-top: 5px; }
.drawup-row .items { display: grid; gap: 6px; }
.drawup-row .item { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.drawup-row .n { font: 600 1rem/1.3 var(--font-ui); }
.drawup-row .per { font: var(--t-meta); font-size: 0.71875rem; color: var(--soft); margin-left: 4px; }
.drawup-row .d { font: 600 1rem/1.3 var(--font-mono); white-space: nowrap; }
/* a CHOOSE-1 row — the selected one is the ink fill with a ✓ */
.pick { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; min-height: 62px; padding: 12px 15px;
  background: none; border: none; border-top: 1px solid var(--line); color: var(--ink); cursor: pointer; font: var(--t-body); }
.pick .pick-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.pick .n { font: 600 1.0625rem/1.2 var(--font-ui); }
.pick .per, .pick .route { font: var(--t-meta); font-size: 0.71875rem; color: var(--soft); }
.pick .d { flex: none; max-width: 48%; text-align: right; font: 600 1rem/1.3 var(--font-mono); text-wrap: balance; }
.pick .mark { flex: none; width: 22px; text-align: right; font-size: 1.0625rem; }
.pick[data-on="true"] { background: var(--ink); color: var(--paper); }
.pick[data-on="true"] .per, .pick[data-on="true"] .route { color: var(--paper); opacity: .8; }
.card .action-2.sm, .card .pushed, .card a.action-2 { width: calc(100% - 20px); margin: 10px; }
/* PUSHED — three states: no drug picked (inert outline) → picked (the red
   .action, armed) → pushed ([data-done]: ink, ✓, the running timer) */
.pushed { display: flex; justify-content: space-between; align-items: center; gap: 12px; min-height: 56px; border-radius: 12px; padding: 0 16px;
  font: 600 0.8125rem/1.2 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; }
.pushed[data-inert="true"] { color: var(--soft); }
.pushed[data-done="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.pushed .cd { margin: 0; font-size: 0.9375rem; }
.timercard { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; }
.timercard .clockblock { background: var(--card); border: 1.5px solid var(--line); border-radius: 14px; padding: 10px 12px; min-width: 0; }
.timercard .clock-label { letter-spacing: .08em; font-size: 0.625rem; white-space: normal; }
.timercard .clock { font-size: 1.625rem; }
.chips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; padding: 10px 12px 12px; }
.chip-big { min-height: 48px; border-radius: 11px; padding: 0 4px; background: var(--paper); border: 1.5px solid var(--line); color: var(--ink);
  font: 600 0.9375rem/1.2 var(--font-mono); cursor: pointer; }
.chip-big[data-rec="true"] { border-color: var(--soft); }
.chip-big[data-on="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.readout { display: flex; align-items: baseline; gap: 8px; min-height: 74px; padding: 14px 18px; background: var(--card); border: 1.5px solid var(--line); border-radius: 16px; }
.readout .big { font: 600 2.375rem/1 var(--font-mono); letter-spacing: -.02em; }
.readout .big.empty { color: var(--soft); }
.readout .unit { font: var(--t-meta); font-size: 1rem; color: var(--soft); }
.keypad { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
.key { min-height: 62px; border-radius: 14px; background: var(--card); border: 1.5px solid var(--line); color: var(--ink);
  font: 600 1.5rem/1 var(--font-mono); cursor: pointer; }
/* the Broselow TILES — the band's color is a bar, the name is the carrier
   (color is never the only one); the chosen tile wears the ink border */
.bands { display: grid; grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: 7px; }
.band { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-height: 58px; padding: 8px 8px 8px 10px; border-radius: 12px;
  background: var(--card); border: 1.5px solid var(--line); border-left: 8px solid var(--band); color: var(--ink); cursor: pointer; text-align: left; }
.band .n { font: 700 0.75rem/1.2 var(--font-ui); letter-spacing: .02em; }
.band .kg { font: 600 0.65625rem/1.2 var(--font-mono); color: var(--soft); }
.band[data-on="true"] { border-color: var(--ink); border-left-color: var(--band); }
.band-grey { --band: var(--band-grey); } .band-pink { --band: var(--band-pink); } .band-red { --band: var(--band-red); }
.band-purple { --band: var(--band-purple); } .band-yellow { --band: var(--band-yellow); } .band-white { --band: var(--band-white); }
.band-blue { --band: var(--band-blue); } .band-orange { --band: var(--band-orange); } .band-green { --band: var(--band-green); }
/* an option TILE — title over a mono sub-line; ink, never red */
.tile { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; width: 100%; text-align: left; min-height: 64px; padding: 12px 16px;
  border-radius: 14px; background: var(--card); border: 1.5px solid var(--line); color: var(--ink); cursor: pointer; }
.tile .t { font: 700 1.0625rem/1.2 var(--font-ui); letter-spacing: -.01em; }
.tile .s { font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
.tile.wide { flex-direction: row; justify-content: space-between; align-items: center; }
.tile[data-on="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.tile[data-on="true"] .s { color: var(--paper); opacity: .8; }
/* the ink BUTTON — a step that is not the red (Post-intubation →, SET on a sheet) */
.ink-btn { display: flex; justify-content: space-between; align-items: center; gap: 12px; width: 100%; text-align: left; min-height: 64px; padding: 0 20px;
  border-radius: 16px; background: var(--ink); border: none; color: var(--paper); font: 700 1.125rem/1.2 var(--font-ui); letter-spacing: -.01em; cursor: pointer; }
.ink-btn .sub { font: var(--t-meta); font-size: 0.71875rem; opacity: .8; }
.ink-btn[data-dim="true"] { opacity: .45; }
/* the bar's CICO → FONA — one tap from every screen; ink, because red is due-now only */
.chip-cico { flex: none; min-height: var(--tap); padding: 0 11px; border-radius: 12px; background: var(--card); border: 1.5px solid var(--ink); color: var(--ink);
  font: 700 0.6875rem/1.15 var(--font-mono); letter-spacing: .08em; text-align: center; cursor: pointer; }
.chip-cico[data-done="true"] { background: var(--ink); color: var(--paper); }
.logged-note { display: flex; gap: 10px; align-items: baseline; padding: 10px 14px; border-radius: 12px; background: var(--card); border: 1px solid var(--line);
  font: var(--t-help); font-size: 0.75rem; color: var(--soft); }
.logged-note .t { font: 600 0.75rem/1.45 var(--font-mono); color: var(--ink); }
.soft-line { font: var(--t-body); font-size: 0.9375rem; color: var(--soft); text-wrap: pretty; }
.action-2.sm { min-height: 50px; font: 600 0.75rem/1.2 var(--font-mono); letter-spacing: .1em; text-transform: uppercase; }

/* THE ASK — AN OPTION IN STEPS (Lon, 2026-09-09: "we need a design language
   for options ... the option is in two steps"). One question at a time,
   standing in the flow where the decision is, never a sheet; its options are
   tiles, so a fork looks like every other fork in the manual. Answered, an ask
   collapses to its own line — the question, the answer, CHANGE — and the next
   question opens under it. Nothing is red until every ask is answered, because
   red is still only the thing to do now. Two asks is the ceiling: a third means
   it should be two screens. */
.ask { display: flex; flex-direction: column; gap: 8px; }
.ask-q { display: flex; align-items: baseline; gap: 8px; padding: 2px 2px 0;
  font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
.ask-q .n { flex: none; color: var(--ink); }
.ask-opts { display: flex; flex-direction: column; gap: 8px; }
.ask-note { padding: 0 2px; font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
/* the classically taught answer wears the heavier edge — the sheet's .opt-lead
   rule in tile form ("four options, and the default is the first") */
.tile[data-lead="true"] { border-color: var(--ink); border-width: 2px; }
/* an ANSWERED ask: one line, still a button, because changing it is a tap */
.asked { display: flex; align-items: center; gap: 10px; width: 100%; min-height: var(--tap); padding: 9px 14px; text-align: left;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 12px; color: var(--ink); cursor: pointer; }
.asked .main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.asked .q { font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
.asked .a { font: 700 1rem/1.25 var(--font-ui); letter-spacing: -.01em; text-wrap: pretty; }
.asked .change { flex: none; font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }

/* ---- THE REHEARSAL (design/rehearsal.js; Lon's onboarding addendum, 2026-09-10,
   rulings 2026-09-11). The same engine with a banner, a coach line and a muted
   ground: the ground is the TRAINING wash (a rehearsal is training), the coach
   bar is the section colour — no new token. The banner's line is fixed copy. */
html[data-rehearsal] { --secWash: var(--secWash-sims); --sec: var(--sec-sims); }
.reh-banner { display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 6px 0;
  border-bottom: 1.5px solid var(--line); font: var(--t-meta); font-size: 0.6875rem; color: var(--soft); }
.reh-banner .k { flex: none; font: var(--t-label); letter-spacing: var(--ls-label); color: var(--ink); }
.reh-banner .t { flex: 1 1 auto; min-width: 0; font: 500 0.71875rem/1.35 var(--font-ui); }
.reh-banner .n { flex: none; font-weight: 600; font-variant-numeric: tabular-nums; }
.reh-exit { flex: none; min-height: var(--tap); padding: 0 11px; border-radius: var(--r); background: var(--card);
  border: 1.5px solid var(--line); color: var(--ink); font: 600 0.65625rem/1 var(--font-mono); letter-spacing: .1em; cursor: pointer; }
.reh-coach { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border-radius: var(--r); background: var(--sec); color: var(--paper); }
.reh-coach .k { flex: none; font: var(--t-label); letter-spacing: var(--ls-label); opacity: .75; padding-top: 3px; }
.reh-coach .t { font: 600 1rem/1.35 var(--font-ui); letter-spacing: -.01em; text-wrap: pretty; }
.reh-doors { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.reh-preview[data-inert] { cursor: default; min-height: 0; }

/* ---- CARDS KEEP THEIR PLACE (issue 256, 2026-09-27) ----------------------
   n OF m DONE, the phase's count, is the card title's micro-label. RETURN
   also rides a card's grab line on the phone, left of the indicator, so a
   card opened in error is backed out of without a scroll; it goes wherever
   the line goes (docked and at width the line is hidden). The first
   unchecked .ck carries [data-lead]: its look belongs with the done and
   next grammar of the rows, not with this block. */
.ck-prog { font: var(--t-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--soft); }
[data-procwalk] > .ck-prog { margin-bottom: var(--s1); }
@media (max-width: 759.9px) {
  .doll-grab[data-ret] { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 4px 12px 0; }
  .doll-grab[data-ret] i { grid-column: 2; grid-row: 1; }
  .doll-grab[data-ret] .doll-ret { grid-column: 1; grid-row: 1; justify-self: start; }
  /* the deck's count is not one of the compressed header's six (R6 item 5) */
  body[data-doll]:not([data-doll-dock]) #screen > .ck-prog { display: none; }
}

/* ---- ONE WEIGHT SHEET (issue 255, lane C; decision 8, Lon 2026-09-25) ------
   The engines' weight sheet (design/engine.js weightSheet): the band swatch,
   the age row and the confirm. The swatch is the tape's colour beside the
   band's WORD and range, so colour is never the only carrier (R2). It is a
   bordered row and never a filled button, so the RED band cannot read as the
   action (rule 8); the band hex is the tape's in both themes (.band-* above).
   The confirm (swatch + SET WEIGHT) rides the sheet's bottom edge when the
   sheet scrolls, so SET is in reach from the tiles and the age row alike. */
.bandswatch { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 6px 12px 6px 6px;
  border: 1.5px solid var(--line); border-radius: var(--r); background: var(--card); color: var(--ink); }
.bandswatch .sw { flex: none; width: var(--tap); height: var(--tap); border-radius: 8px; background: var(--band);
  border: 1px solid color-mix(in srgb, var(--ink) 30%, transparent); }
.bandswatch .t { font: 700 1.25rem/1.2 var(--font-mono); letter-spacing: -.01em; }
.wconfirm { position: sticky; bottom: calc(-1 * var(--s3)); z-index: 1; display: flex; flex-direction: column; gap: var(--s1);
  padding: var(--s1) 0 var(--s3); background: var(--card); }
/* the sheet is 390 wide less its padding: five tiles to a row (s9's two rows,
   not three) and a keypad a notch shorter, so the tiles sit above the fold */
.sheet .bands { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.wpad .key { min-height: 52px; }
.wage { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
/* the age field is typed on the sheet's one keypad: tapping it moves the
   keypad there, and it wears a focused field's ink edge while it has it —
   an edge, not the fill, because the fill is the chosen unit (yr / mo) */
.wage button { min-height: var(--tap); padding: 0 12px; border-radius: 10px; background: var(--card);
  border: 1.5px solid var(--line); color: var(--ink); font: 700 0.8125rem/1 var(--font-mono); cursor: pointer; }
.wage .wage-in { min-width: 72px; text-align: left; }
.wage .wage-in[data-empty="true"] { color: var(--soft); }
.wage .wage-in[data-on="true"] { border: 2.5px solid var(--ink); }
.wage [data-wunit][data-on="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.wage-note { font: var(--t-meta); color: var(--soft); }
.wage-note[data-err] { color: var(--ink); font-weight: 700; }

/* ---- LON'S 2026-09-28 RULINGS, THE ENGINES' HALF (lane E2) ----------------
   One block, appended: the weight entry's shared parts (design/engine.js
   wTop / wNote / wSlot, drawn by the engines' weight sheet and s9's weight
   step), the swatch on the case screen's weight chip, and a done step that
   un-ticks. */
/* the chip's swatch (ruling: the band swatch "also on the case screen"): the
   tape's colour as a block beside "6.5 kg · PINK" — upright, the tiles' colour
   bar, so the chip is no wider than it was with its dot and the bar's clock
   keeps its room at 375; the band's WORD stays the carrier (R2) */
.chip[data-band] > .sw { flex: none; width: 14px; height: 28px; margin-left: -6px; border-radius: 4px; background: var(--band);
  border: 1px solid color-mix(in srgb, var(--ink) 30%, transparent); }
/* THE TOP ROW: the readout and the age side by side */
.wtop { display: flex; align-items: stretch; gap: 7px; }
.wtop .readout { flex: 1 1 auto; min-width: 0; min-height: 56px; padding: 10px 14px; cursor: pointer; }
.wtop .readout .big { font-size: 2rem; }
.wtop .wage { flex: none; flex-wrap: nowrap; gap: 6px; }
.wtop .wage button { padding: 0 11px; }
.wtop .wage .wage-in { min-width: 56px; }
/* the slot holds the swatch, or nothing, at one height: SET never moves */
.wslot { min-height: 56px; display: flex; flex-direction: column; }
.wslot .bandswatch { min-height: 56px; padding: 4px 12px 4px 4px; }
/* THE WHOLE SHEET IN ONE VIEW at 390×844 (ruling: "rework it") — nothing
   scrolls, so nothing rides over a tile: tighter padding and rhythm, a
   one-line note, lower tiles (keys stay 52 px), RETURN beside SET. s9's
   weight step (.wentry) takes the same note, keys and tiles, so its SET
   stays in the first view with the age row and the swatch above it. */
#sheet[data-wsheet] { padding: 14px 16px 12px; gap: 7px; }
#sheet[data-wsheet] .q { margin-bottom: 0; }
#sheet[data-wsheet] .wage-note, .wentry .wage-note { font-size: 0.6875rem; line-height: 1.35; }
#sheet[data-wsheet] .kicker.sub { padding-top: 2px; }
#sheet[data-wsheet] .band, .wentry .band { min-height: 48px; padding: 5px 6px 5px 9px; }
#sheet[data-wsheet] .log-guard { font-size: 0.6875rem; }
.wrow { display: flex; gap: 8px; }
.wrow > .proc-return { flex: none; min-height: 56px; }
.wrow > .action { flex: 1 1 auto; width: auto; min-height: 56px; }
/* a done procedure step is a control again: a tap takes its ✓ off */
.ck[data-untick], .ck[data-untick] .inert { cursor: pointer; }

/* ---- THE PEDIATRIC CICO, AS DRAWN — DRAFT (Lon's airway mockups,
   2026-09-28; s9/cico.js). body[data-cico] names the mode (assist = ALL STEPS, reader = READ ALOUD): ALL STEPS carries its
   own head, so the bar and the strip step aside; READ ALOUD keeps both, with
   BACK beside the strip; the debrief is its own page. THE RED IS AS DRAWN —
   the declare button, the undo, the eyebrows, the gap — and stands against
   rule 8 (red is the action, never decoration) as a question for Lon, not a
   ruling. Every colour here is a token; the plan's wash is a mix of two. */
body[data-cico="assist"] .bar, body[data-cico="assist"] #foot,
body[data-cico="debrief"] .bar, body[data-cico="debrief"] #foot { display: none; }
body[data-cico="reader"] #foot { display: flex; gap: var(--s1); align-items: stretch; }
body[data-cico="reader"] #foot .timeline-strip { flex: 1 1 auto; min-width: 0; }
.bar .back[data-hold] { font: 700 0.6875rem/1.15 var(--font-mono); letter-spacing: .06em; text-align: center; color: var(--ink); }
.bar .back[data-holding="true"], .cx-exit[data-holding="true"] { background: color-mix(in srgb, var(--ink) 16%, var(--card)); }
.cx-head { display: grid; grid-template-columns: auto auto minmax(0, 1fr); align-items: center; gap: var(--s2); }
/* the heads carry .moment so RESUME reads their name (S.hdr); they keep their drawn look, not the moment's rule */
.cx-head.moment, .cx-dhead.moment { border-bottom: none; padding-bottom: 0; align-items: center; }
.cx-head.moment { display: grid; justify-content: normal; }
.cx-dhead.moment { justify-content: flex-start; }
.cx-exit { min-width: 64px; min-height: 64px; border-radius: 16px; border: 1.5px solid var(--soft); background: var(--card); color: var(--ink);
  font: 700 0.75rem/1.2 var(--font-mono); letter-spacing: .06em; cursor: pointer; touch-action: none; user-select: none; -webkit-user-select: none; }
.cx-clock .clock-label { font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }
.cx-head .cx-clock .clock { font: 700 3.25rem/1 var(--font-mono); }
.cx-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; min-width: 0; text-align: right; }
.cx-head .cx-meta .nm { font: 700 1.25rem/1.15 var(--font-ui); color: var(--ink); }
.cx-meta .sub { font: var(--t-meta); color: var(--soft); }
.cx-meta .clockblock, .cx-meta .clockblock .clock-label, .cx-meta .clockblock .clock { display: inline; font: inherit; color: inherit; }
.cx-meta .clockblock .clock-label::after { content: ' '; }
.cx-undo { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); padding: 14px 16px; border-radius: 16px; background: var(--act); color: var(--act-ink); }
.cx-undo .m { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cx-undo .t { font: 700 1.25rem/1.2 var(--font-ui); }
.cx-undo .s { font: var(--t-meta); }
.cx-undo-btn { flex: none; min-width: 120px; min-height: 56px; border-radius: 12px; border: none; background: var(--card); color: var(--act);
  font: 700 1rem/1.2 var(--font-mono); letter-spacing: .08em; cursor: pointer; }
.cx-eyebrow { font: 700 0.8125rem/1.3 var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--act); }
.cx-q { font: 700 2.5rem/1.08 var(--font-ui); letter-spacing: -.02em; color: var(--ink); text-wrap: balance; }
.cx-sub { font: var(--t-body); color: var(--soft); }
.cx-note { text-align: center; font: var(--t-meta); color: var(--soft); }
.cx-appr { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 10px; width: 100%; min-height: 112px; padding: 16px 20px;
  text-align: left; border-radius: 20px; border: 2px solid var(--soft); background: var(--card); color: var(--ink); cursor: pointer; }
.cx-appr .t { font: 700 1.75rem/1.15 var(--font-ui); letter-spacing: -.01em; }
.cx-appr[data-plan="true"] { border: 3px solid var(--ink); background: color-mix(in srgb, var(--ink) 9%, var(--card)); }
body[data-cico="reader"] .cx-appr { flex-direction: row; align-items: center; justify-content: space-between; min-height: 96px; }
.cx-pill { padding: 4px 10px; border-radius: 8px; background: var(--ink); color: var(--paper); font: 700 0.75rem/1.2 var(--font-mono); letter-spacing: .12em; }
.cx-tag { flex: none; padding: 6px 10px; border-radius: 10px; border: 1.5px solid var(--ink); font: 700 0.6875rem/1.2 var(--font-mono); letter-spacing: .12em; }
.cx-list { display: flex; flex-direction: column; border-radius: 20px; border: 1.5px solid var(--line); background: var(--card); overflow: hidden; }
.cx-row { display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; align-items: center; gap: 12px; width: 100%; min-height: 64px; padding: 12px 18px;
  text-align: left; border: none; border-top: 1px solid var(--line); background: none; color: var(--ink); font: 700 1.1875rem/1.25 var(--font-ui); cursor: default; }
.cx-row:first-child { border-top: none; }
.cx-row .n { color: var(--soft); }
.cx-row .t .d { display: block; margin-top: 4px; font: var(--t-help); font-size: 0.9375rem; color: var(--soft); }
.cx-row[data-now="true"] .t .d { color: var(--paper); opacity: .85; }
.cx-said { font: var(--t-body); font-size: 1.1875rem; color: var(--ink); }
.cx-row .at { font: var(--t-meta); color: var(--soft); }
.cx-row[data-done="true"] { color: var(--soft); }
.cx-row[data-now="true"] { min-height: 88px; background: var(--ink); color: var(--paper); font-size: 1.4375rem; cursor: pointer; }
.cx-row[data-now="true"] .n { color: var(--paper); }
.cx-foot { position: sticky; bottom: 0; z-index: 1; display: flex; gap: var(--s1); align-items: stretch; padding: var(--s1) 0 10px; background: var(--paper); }
.cx-fail { flex: 1 1 auto; display: flex; align-items: center; flex-wrap: wrap; gap: .3em; min-height: 64px; padding: 0 18px; border-radius: 16px;
  border: 1.5px dashed var(--soft); background: none; color: var(--soft); font: var(--t-body); text-align: left; }
button.cx-fail { cursor: pointer; }
.cx-fail b { color: var(--ink); }
.cx-mode-btn { flex: none; min-width: 112px; min-height: 64px; border-radius: 16px; border: 1.5px solid var(--ink); background: var(--card); color: var(--ink);
  font: 700 0.875rem/1 var(--font-mono); letter-spacing: .12em; cursor: pointer; }
.cx-kick { justify-content: space-between; }
.cx-seg { display: flex; flex: none; border: 1.5px solid var(--ink); border-radius: 14px; overflow: hidden; }
.cx-seg button { min-height: 52px; padding: 0 16px; border: none; background: var(--card); color: var(--ink); font: 700 0.875rem/1 var(--font-mono); letter-spacing: .12em; cursor: pointer; }
.cx-seg button[data-on="true"] { background: var(--ink); color: var(--paper); }
.cx-clocks { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s2); }
.cx-clocks .cx-clock .clock { font: 700 4.5rem/1 var(--font-mono); }
.cx-rsi { align-items: flex-end; text-align: right; }
.cx-rsi .clock-label { font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }
.cx-rsi .clock { font: 700 1.75rem/1 var(--font-mono); color: var(--soft); }
.cx-card { display: flex; flex-direction: column; gap: var(--s2); padding: 22px 24px; border-radius: 20px; border: 1.5px solid var(--line); background: var(--card); }
.cx-say { font: 700 2.5rem/1.1 var(--font-ui); letter-spacing: -.02em; color: var(--ink); overflow-wrap: anywhere; text-wrap: pretty; }
.cx-item { display: flex; align-items: baseline; gap: 12px; padding: 14px 16px; border-radius: 14px; background: var(--paper); color: var(--ink); text-decoration: none; }
.cx-item .k { flex: none; font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }
.cx-item .v { font: 700 1.125rem/1.25 var(--font-ui); }
.cx-next { display: flex; gap: 12px; align-items: baseline; padding: 0 4px; }
.cx-next .k { flex: none; font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }
.cx-next .v { font: 700 1.0625rem/1.3 var(--font-ui); color: var(--soft); }
.cx-adv { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; width: 100%; min-height: 200px; border-radius: 24px;
  border: none; background: var(--ink); color: var(--paper); cursor: pointer; }
.cx-adv .t { font: 700 1.875rem/1.1 var(--font-mono); letter-spacing: .1em; }
.cx-adv .s { font: var(--t-body); opacity: .85; }
.cx-back { flex: none; min-width: 96px; min-height: var(--tap); border-radius: var(--r); border: 1.5px solid var(--soft); background: var(--card); color: var(--ink);
  font: 700 0.875rem/1 var(--font-mono); letter-spacing: .1em; cursor: pointer; }
.cx-big { position: sticky; bottom: 10px; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: var(--s2); width: 100%; min-height: 112px; margin-top: var(--s1); padding: 16px 24px;
  text-align: left; border-radius: 24px; border: 4px solid var(--act); background: var(--card); color: var(--act); cursor: pointer; }
.cx-big .m { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.cx-big .t { font: 700 2.5rem/1 var(--font-ui); letter-spacing: -.01em; }
.cx-big .s { font: 600 0.75rem/1.25 var(--font-mono); letter-spacing: .06em; }
.cx-big .go { flex: none; font: 700 2.5rem/1 var(--font-ui); }
.cx-dhead { display: flex; align-items: center; gap: var(--s2); }
.cx-dhead .m { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cx-dhead .m .t { font: 700 1.75rem/1.1 var(--font-ui); color: var(--ink); }
.cx-dhead .s { font: var(--t-meta); color: var(--soft); }
.cx-done { flex: none; min-width: 88px; min-height: 64px; border-radius: 16px; border: 1.5px solid var(--soft); background: var(--card); color: var(--ink);
  font: 700 0.875rem/1 var(--font-mono); letter-spacing: .08em; cursor: pointer; }
.cx-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s1); }
.cx-tile { display: flex; flex-direction: column; gap: 6px; padding: 14px 16px; border-radius: 16px; border: 1.5px solid var(--line); background: var(--card); }
.cx-tile .k { font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }
.cx-tile .v { font: 700 2.25rem/1 var(--font-mono); color: var(--ink); }
.cx-tl { display: flex; flex-direction: column; gap: 8px; padding: 18px 20px; border-radius: 20px; border: 1.5px solid var(--line); background: var(--card); }
.cx-tl .sec { margin-top: 6px; font: var(--t-label); letter-spacing: var(--ls-label); color: var(--soft); }
.cx-tl .sec[data-cico] { color: var(--act); }
.cx-tl .row { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 12px; font: var(--t-body); color: var(--ink); }
.cx-tl .row .at { font: var(--t-meta); line-height: inherit; color: var(--soft); }
.cx-tl .row[data-b="true"] { font-weight: 700; }
.cx-gap { padding: 10px 14px; border-radius: 12px; border: 1.5px dashed var(--act); color: var(--act); font: 700 0.875rem/1.2 var(--font-mono); letter-spacing: .08em; }
.cx-saved { display: flex; align-items: center; min-height: 64px; padding: 0 20px; border-radius: 16px; background: var(--ink); color: var(--paper); font: 600 0.9375rem/1.2 var(--font-mono); }
/* ONE SCREEN, HANDS FREE (Lon, 2026-09-28: "it needs to fit on a iphone 14
   and forward screen without scrolling (hands free)"): the phone lies on the
   table and the whole ALL STEPS list — the tracheotomy's eight steps, each with
   its line — stands in 390 × 844 with no scroll. The head, the rows and the
   foot are tightened here, for ALL STEPS only; nothing is cut from a step. */
body[data-cico="assist"] #app { padding-top: 8px; }
body[data-cico="assist"] #screen { gap: var(--s1); }
body[data-cico="assist"] .stack.cx { gap: 4px; }
body[data-cico="assist"] .cx-head { gap: 10px; }
body[data-cico="assist"] .cx-exit { min-width: 52px; min-height: 52px; border-radius: 14px; font-size: 0.6875rem; }
body[data-cico="assist"] .cx-head .cx-clock .clock { font-size: 2.5rem; }
body[data-cico="assist"] .cx-head .cx-meta .nm { font-size: 1.0625rem; }
body[data-cico="assist"] .cx-list { border-radius: 16px; }
body[data-cico="assist"] .cx-row { grid-template-columns: 18px minmax(0, 1fr) auto; column-gap: 10px; min-height: 0; padding: 6px 12px; font: 700 1rem/1.18 var(--font-ui); }
body[data-cico="assist"] .cx-row[data-now="true"] { min-height: 0; font-size: 1.0625rem; }
body[data-cico="assist"] .cx-row .t .d { margin-top: 2px; font: 500 0.84375rem/1.3 var(--font-ui); }
body[data-cico="assist"] .cx-foot { padding: 4px 0 6px; }
body[data-cico="assist"] .cx-fail, body[data-cico="assist"] .cx-mode-btn { min-height: 52px; }
body[data-cico="assist"] .cx-fail { font-size: 1rem; padding: 0 14px; }
/* READ ALOUD on one screen too (390 × 844): the clocks, the card and the tiles a
   step smaller; TAP TO ADVANCE takes whatever height is left, never less than
   a thumb's worth */
body[data-cico="reader"] #screen { gap: var(--s2); }
body[data-cico="reader"] .stack.cx { gap: 10px; }
body[data-cico="reader"] .cx-seg button { min-height: 44px; }
body[data-cico="reader"] .cx-clocks .cx-clock .clock { font-size: 3.5rem; }
body[data-cico="reader"] .cx-card { gap: 10px; padding: 16px 20px; }
body[data-cico="reader"] .cx-card .cx-q { font-size: 2.125rem; }
body[data-cico="reader"] .cx-say { font-size: 2.25rem; }
body[data-cico="reader"] .cx-appr { min-height: 72px; padding: 12px 18px; }
body[data-cico="reader"] .cx-appr .t { font-size: 1.5rem; }
body[data-cico="reader"] .cx-adv { flex: 1 1 auto; min-height: 132px; }
body[data-cico="reader"] .cx-fail { min-height: 52px; }
/* THE TIER RIBBON (design/tier.js; release process, spec §8): DEV · v… /
   STAGING · v… / PREVIEW over every non-production copy, never production */
#tier-ribbon { display: block; position: relative; z-index: 2147483000; height: 22px; padding: 0 12px; text-align: center;
  font: 600 12px/22px var(--font-ui); letter-spacing: .08em; background: var(--ink); color: var(--paper); }
