/* ============================================================================
   Yeeba mock — TOKENS. The single source of every colour, size, weight and
   spacing value. Nothing else in the mock may carry a literal.

   PROVENANCE: extracted verbatim from `chat files/yeeba-sheet-fullmock.html`
   (:root L9–67, .dark L74–90) — the approved sheet mock, post shell-lift.
   Values are NOT redesigned here. Where a token is new (because a literal was
   inlined in the old markup and had to be named to satisfy the no-literals
   rule) it carries the comment NEW-FROM-LITERAL plus the line it came from.

   STRUCTURE
     :root                  light theme + shared geometry
     body.theme-dark        dark overrides (was `.dark` on the window element;
                            rehomed to body so a whole built page is dark)
     body.view-sheet        geometry that legitimately differs per view
     body.view-dashboard      (label column width, row height) — the ONLY
                            per-view token divergence, everything else shared
   ========================================================================== */

:root{
  /* macOS traffic-light status palette (entry 63) */
  --overdue:#FF605C;   /* Red Shimmer */
  --due:#FFBD44;       /* Coronation Gold */
  --done:#00CA4E;      /* Malachite */
  --skip:#9aa1ab;      /* grey: skip `step_over` / miss `priority_high` / cancel `close` (registry ratified 2026-08-27, src/icon-registry.md) */
  --nowline:#E03131;   /* old red, repurposed — distinct from overdue */
  /* INK ON A STATUS FILL — one ink per fill, consumed via --on-fill by chips,
     dots, legend swatches and the Done tick alike (86i.23, David 2026-08-23).
     White failed AA on every fill: done 2.20:1, grey 2.61:1, overdue 2.97:1.
     Amber and overdue took a DARK tint of their own fill's hue (5.64-6.3:1),
     the pattern --ink-on-amber set. Done and grey were SUPERSEDED by the
     C-ink ruling directly below — see its comment for their current FAINT
     (not dark) inks. ONE mechanism either way, which is what "consistent"
     buys. */
  --on-fill:#ffffff;         /* remains the ink on non-status fills (avatar, buttons) */
  --ink-on-amber:#5a4300; --ink-on-overdue:#3D0300;
  /* C-ink ruling (David 2026-08-27): non-actionable chips recede — the done tick
     goes faint green, grey glyphs faint near-white; red/amber ink untouched so
     actionable chips stay dominant. One rule reaches chips, dots and legends
     via --on-fill (86i.23 mechanism unchanged). */
  --ink-on-done:#cef5dd;  --ink-on-grey:#eceef1;
  /* surface */
  --row-even:#ffffff; --zebra:#eef3fb; --seam:#e9ebef; --panel-top:#f7f8fa;
  --card-border:#e4e7eb; --page:#fbfcfd;
  --hair:rgba(52,64,88,0.11); --hair-label:rgba(52,64,88,0.18);
  --ink:#232830; --ink-muted:#6b7280; --note:#5c636d;
  /* 86i.24 (David, 2026-08-23 — option B ratified): faint text was #9aa1ab, ~2.61:1
     on white, and it carries hour labels, ward names, dimmed task names and "+N more".
     Lifted to the existing --ink-muted step (4.83:1) — no new colour minted. The name
     is kept: the ROLE is still "the quietest readable text", and it may diverge again. */
  --ink-faint:#6b7280;
  --addnote:#b0b6be;        /* "Add notes…" TEXT stays light — 86i.24: only its pencil lifts */
  /* A19 literal sweep — chrome surfaces/inks tokenised by role; values unchanged from the signed-off literals */
  --surface:#ffffff;        /* window, patient bar, view bar, the live line's field and the EDVUF table, grid card, Due-Today items, controls */
  --column-bg:#ffffff;      /* left column (palette.rs shell_column) */
  --column-border:#eceef1;  /* left column right edge */
  --row:#f3f4f6;            /* left-rail item fill (e38) + active-tab pill (D1-tab) */
  --badge-bg:#e5e7eb; --badge-ink:#586070;          /* rail count badge */
  --child-ink:#39404a;      /* rail child (patient) row text — palette.rs child_text */
  --heading:#161a1f;        /* section heading ("What's on Today?", "Alerts") */
  --section-suffix:#6b7280; /* "· ward-wide" suffix; the "(initials, HH:MM)" attributions — 86i.24 */
  --ink-strong:#1b1f26;     /* wordmark, patient name, segmented-on label, active tab */
  --ink-body:#2b2f36;       /* body default ink; date button */
  --ink-soft:#5a6270;       /* tabs, toggles labels, mode/seg off labels, the collapsed card's latest-note text */
  --ink-quiet:#aab0ba;      /* muted TABS + their "soon" markers ONLY. 86i.24 split
                               the pencils out to --pencil-ink: inert navigation may
                               stay subdued, a control you click may not. */
  --pencil-ink:#6b7280;     /* the `edit` pencils — active controls (86i.24) */
  --field-ink:#3a414a;      /* patient-bar field text, Due-Today item text, the value-badge letters */
  --ctrl-ink:#3a4048;       /* the entry scale cells */
  --stepper-ink:#4a5058;    /* stepper arrows */
  --placeholder-ink:#6b7280;/* search field — 86i.24: the mock uses value=, not
                               placeholder=, so this is literally normal text */
  --chrome-border:#d9dce2;  /* search field border */
  --ctrl-border:#d7dbe1;    /* stepper / date / seg / + Record borders; toggle track */
  --ctrl-divider:#e4e7ec;   /* stepper inner dividers */
  --ctrl-fill:#eef0f3;      /* patient-bar more_vert button */ --kebab-hover:#dfe3e8; /* row-kebab hover circle - one step darker than --zebra #eef3fb, which swallowed --ctrl-fill (freeze-eye 2026-08-28) */
  --vbar-border:#eef0f3;    /* view-bar bottom edge */
  --separator-ink:#c7ccd3;  /* patient-bar "·" */
  --toggle-knob:#ffffff;    /* Critical/DNR switch knob. Was var(--surface); named 2026-08-22 because on dark a knob inheriting --surface (#2b3038) is DARKER than its --ctrl-border track, inverting the physical metaphor of a knob floating above the track. */
  --seg-on-bg:#e9ebef;      /* Focus/24h segmented on-fill */
  --mode-bd:#cdd3f2; --mode-on-bg:#eaeeff; --mode-on-ink:#2b3aa8; --mode-rec-bg:#efe9fb; /* mode toggle */
  --rec-bg:#efeafb; --rec-bd:#ddd2f5; --rec-ink:#463a86; --rec-ink-strong:#382d75; --rec-who:#6a5fa0; /* record banner, REV + phase badges */
  --rec-halo:rgba(109,93,211,.18); --rec-tint:#efeafb;      /* banner dot halo; record-mode grid-surround tint = --rec-bg (David 2026-09-05 at the v7 freeze eye: "B (same colour as header)" — the former #f7f6fd was invisible) */
  --menu-bg:#ffffff; --menu-shadow:rgba(0,0,0,.18); --destructive:#e03131; /* A28 user menu; --destructive PICKED (= nowline red) — the build's Sign-out hex was not read */
  --window-shadow:rgba(0,0,0,.22);
  /* reference-page chrome (outside the window — not UI) */
  --ref-bg:#c9cdd3; --ref-head:#1b2028; --ref-label-ink:#1f2632; --ref-label-bg:#eef1f5; --ref-label-bd:#dfe3e8;
  /* accents */
  --btn:#3b82f6; /* PLACEHOLDER accent — "OK for now, NOT final" (e68); one token, swappable */ --record:#6d5dd3;
  /* de-ambered chrome — VIOLET PLACEHOLDER (task #25) */
  --vchip-bg:#efeafb; --vchip-bd:#d7ccf0; --vchip-ink:#5b4aa8; --vchip-ink2:#8a7cc0;
  --vpanel-bg:#f6f3fd; --vpanel-bd:#e2d9f5; --vpanel-h:#6a5aa8;
  /* badges */
  --dosebg:#e9ebf3; --dosetx:#2f3660; --routebg:#eef1ec; --routetx:#4d5744;
  --mono:"JetBrains Mono","DejaVu Sans Mono",ui-monospace,Menlo,Consolas,monospace;
  /* geometry */
  --chip-radius:4px;
  --header-h:28px; /* e86: grid header strip 28px BOTH pages, one token; now-line starts at its bottom edge (A14) */
  /* glyph faces — SINGLE SOURCE. weight + nudge shared by cell AND legend; never re-typed. */
  --glyph-weight:400; --g-icon:18px;  /* Material Symbols SHARP, Medium outlines (registry ratified 2026-08-27, src/icon-registry.md; face swapped from Outlined 400). Sizes (e86a/86a-ii): 18 24H chip · 15 Focus chip · 16 controls (stepper, date/avatar carets, more_vert) · 14 rail (schedule, show-all) · 13 legend/notes/pencils/starve */
  --g-family:16px;      /* rail family/kind heading glyphs (registry: 16px grey) */
  --g-chip-skip:20px;   /* step_over in chips — dot legible (registry) */
  --g-chip-minor:16px;  /* priority_high / close in chips (registry) */
  --g-disclose:20px;    /* M5: the "Add more details" form disclosure caret (icon-registry.md
                           Control marks). Theme-invariant, restated below for the coverage gate. */

  /* ---- NEW-FROM-LITERAL: values that were inline in the old markup or CSS and
     had to be named to satisfy the no-literals rule. Values UNCHANGED. ---- */
  --ui-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; /* fullmock L92 */
  --g-ctrl:16px;      /* stepper / date + avatar carets / more_vert — inline style, fullmock L281,L303 (86a-ii) */
  --g-rail:14px;      /* Due-Today item glyph, Filters button icon — inline style, fullmock L295,L304 */
  --g-small:13px;     /* pencils, starve chip, legend, note glyphs — inline style, fullmock L302 */
  --window-radius:8px;      /* fullmock L98 */
  --window-shadow-geom:0 16px 44px;  /* fullmock L98 */
  --ctrl-radius:8px;        /* search, buttons, tabs, stepper, date, seg */
  --rail-radius:7px;        /* left-rail item pills (e38 rounding rule) */
  --gridcard-radius:8px;    /* the hourly-grid card, BOTH pages. 8px is the value in
                               every approved render and is founder-ratified (David,
                               2026-08-22, closing the grey-area question). Supersedes
                               the orphaned `--card-radius:3px`, which was minted for an
                               unratified dashboard draft, never consumed by any rule,
                               and is deleted. NOTE: this sits against the app-wide
                               "structure square, content cards rounded" standard —
                               8px is what is approved, and changing it would be a
                               deliberate change to an approved artefact, not a tidy-up. */
  --topbar-h:56px;          /* fullmock L100 */
  --col-w:240px;            /* left column — e37 240px final */
  --win-w:1536px; --win-h:864px;  /* the shell viewport (86h) */
  /* reference-page chrome geometry (not app UI) — fullmock L92–97 */
  --ref-pad:22px 0 46px; --ref-label-radius:8px; --ref-label-pad:10px 14px;
  --ref-label-margin:24px 0 11px; --ref-label-size:13.5px; --ref-label-accent:4px;
  --ref-head-size:20px; --ref-sub-size:12.5px;
  /* type / spacing scale — theme-invariant, restated for the coverage gate */
  --fs-9-5:9.5px;   /* the reserved-tab "soon" marker (86i.15). Size PICKED — read off
                       the build screenshot 2026-08-20 090900; the register rules that a
                       marker exists, not its size. */
  --fs-10-5:10.5px; --fs-11:11px; --fs-11-5:11.5px; --fs-12:12px; --fs-12-5:12.5px;
  --fs-13:13px; --fs-13-5:13.5px; --fs-14:14px; --fs-15:15px; --fs-16:16px;
  --fw-500:500; --fw-600:600; --fw-700:700; --fw-800:800;
  --bw-1:1px; --bw-2:2px;
  --sp-1:1px; --sp-2:2px; --sp-3:3px; --sp-4:4px; --sp-5:5px; --sp-6:6px;
  --sp-7:7px; --sp-8:8px; --sp-9:9px; --sp-10:10px; --sp-11:11px; --sp-12:12px;
  --sp-13:13px; --sp-14:14px; --sp-15:15px; --sp-16:16px; --sp-20:20px; --sp-27:27px;
  --fs-10:10px;
  --r-3:3px; --r-5:5px; --r-6:6px; --r-9:9px; --r-10:10px; --r-14:14px;
  --w-search:230px; --sz-ava:30px; --w-menu:236px; --minw-badge:18px;
  --menu-top:54px; --menu-right:12px; --menu-shadow-geom:0 10px 28px;
  --sz-sw-w:30px; --sz-sw-h:17px; --sz-knob:13px; --sz-pmore-w:26px; --sz-pmore-h:24px;
  --h-pbar:42px; --h-vbar:48px; --sz-rdot:9px; --halo-w:3px;
  --w-chip:66%; --h-chip:56%; --w-bchip:88%; --h-bchip:64%;
  --sw2-w:22px; --sw2-h:15px; --ls-02:.02em; --ls-03:.03em; --ls-04:.04em;
  --lh-14:1.4; --caret-nudge:-8px; --va-2:-2px; --va-3:-3px;
  --dot-size:12px;      /* dashboard per-task dot — uniform, no size ladder (e62/e73/e82) */
  --dot-legend:11px;    /* the same dot in the 4-item legend strip */
  --lh-125:1.25;        /* dashboard task line */
  /* v2 dispatch (sonnet-dispatch.md, M1 Change 1): the d1o Focus "+N more"
     disclosure popover. PICKED, not derived — anchored just below Quasimodo's
     10:00 Focus cell in the d1/d1o fixture geometry (col-w 240 + gridwrap pad
     14 + label-w 150 + one 139.75px hour column = cell left ~544; header 28 +
     3 rows * rowh 47 = cell top ~285, cell bottom ~332). David's eye at freeze
     ratifies the exact geometry. */
  --discl-top:333px; --discl-left:501px; --discl-w:176px;
  /* M4 record panel (sonnet-dispatch.md, w5-w9): docked geometry PICKED off
     the pre-freeze reference mock's `.rpanel` (358px width, left-edge shadow);
     colour reuses the existing --menu-shadow token (no new colour minted). */
  --rp-w:358px; --rp-shadow-geom:-14px 0 40px;
  /* M4 REDRAW (v4 fix round, w5-w9): the primary-seat / active-deck-card
     violet wash — the sketch's own #f8f6fe (.pilot/ui-m4-panel-redesign-
     sketch.html v8) re-picked as its own token because it is visibly fainter
     than --rec-bg; the dark value is derived by the same faint-tint-toward-
     violet proportion --rec-tint used over --page until v7 (light and dark
     each interpolate their --surface toward --rec-bg by the same ~0.4
     fraction; --rec-tint itself became = --rec-bg on David's 2026-09-05 ruling,
     --seat-wash keeps the old proportion). The active-card's slight lift is new-from-literal geometry
     (the sketch's own box-shadow offset); its colour reuses the existing
     --rec-halo token (no new violet minted). The deck/receipts circle count
     badge diameter is also new-from-literal (sketch v8's own 19px). */
  --seat-wash:#f8f6fe; --seat-lift-shadow-geom:0 2px 10px; --sz-cbadge:19px;
  /* M5: the New Patient form modal (sonnet-dispatch.md; look reference
     .pilot/ui-m5-approved-sketch-2026-08-31.html). A blocking Overlay Focus
     surface — the first one this mock draws — so its scrim/shadow have no
     existing token to reuse; geometry and the scrim/shadow colour are
     new-from-literal off the approved sketch, theme-invariant (chrome, not
     content — same reasoning as --window-shadow/--menu-shadow existing as a
     dedicated pair, restated below with a deeper dark value). */
  --modal-scrim:rgba(18,22,28,.30); --modal-shadow-geom:0 24px 70px; --modal-shadow:rgba(0,0,0,.34);
  --modal-radius:12px; --modal-w:600px; --modal-top:96px; --modal-bottom-gap:128px;
  --sz-modal-close:24px;
  /* per-field natural widths — new-from-literal off the approved sketch's own
     .w-* classes (dispatch: "fields at natural content widths, sketch is the
     guide"); theme-invariant geometry. */
  --np-w-name:225px; --np-w-loc:150px; --np-w-species:130px;
  --np-w-age:165px; --np-w-weight:78px;
  /* One shared column width for the details panel's two-column grid — the
     per-field snug widths left the three rows "almost lined up" (David, freeze
     eye 2026-08-31: line them up); 200px also cures the Colour placeholder
     clip (Fable-1066 Low). */
  --np-w-half:200px;
  --np-w-sex:var(--np-w-half); --np-w-neuter:var(--np-w-half);
  --np-w-breed:var(--np-w-half); --np-w-colour:var(--np-w-half);
  --np-w-contact:var(--np-w-half); --np-w-pid:var(--np-w-half);
  /* DNR toggle — a NEW form control, deliberately not --sz-sw-w/--sz-knob (the
     patient-bar switch is a different size); off track reuses --ctrl-border,
     on fill reuses --done (the traffic-light green, "no point in having
     something similar" — David), knob reuses --toggle-knob. Geometry
     new-from-literal off the sketch's own .tog (40×22, 12px radius, 18px
     knob); the on-knob offset is exactly --sp-20 (2px inset + 18px knob), so
     no separate offset token is minted. */
  --np-tog-w:40px; --np-tog-h:22px; --np-tog-radius:12px; --np-tog-knob:18px;
  --np-tog-knob-shadow:0 1px 2px rgba(0,0,0,.2); /* the approved sketch's knob shadow, tokenised (Codex-1064 L1); theme-invariant, restated in dark per the coverage gate */
  --np-dnr-ml:18px;         /* the sketch's own inline margin-left, tokenised (dispatch) */
  --np-btn-pad-x:18px;      /* Admit patient's horizontal padding — the sketch's own value */
  /* M3 rail-spacing scale (David 2026-08-27/28, rail-spacing rider): rail-
     specific tokens, never a retune of --sp-3/--sp-8 (those inventory tokens
     also size search/tab/patient-bar — tokens.css :247-255's own rule).
     Three strictly-increasing tiers via shell.html's .navrow/.rsep and
     components.css's .ahead (the shared lever, so "What's on Today?"
     inherits the same scale by construction): rows within one family
     tightest; a family heading's own gap — both arriving and to its first
     row, one symmetric value — looser; the .rsep hairline section boundary
     loosest. See ui-m3-delivery-report.md for the geometric proof. */
  --rail-gap-row:-8px; --rail-gap-heading:10px; --rail-gap-section:18px; /* row token is a between-rows OVERLAP (freeze-eye 2026-08-28; option A ruled on Codex-1037 M1): boxes overlap 8px so text-to-text reads 8px < heading 18px < section; the LATER row owns the shared strip, so each row's exclusive click strip is the ~26px row pitch (ruled acceptable), not the full padded box */
  /* M6: the Add-to-sheet modal (sonnet-dispatch.md; look reference
     .pilot/ui-m6-approved-sketch-2026-09-01.html). Structural chrome (scrim,
     shadow, radius, top anchor, max-height/body-scroll pattern, close-button
     size) REUSES the M5 New Patient modal tokens verbatim — the dispatch's
     "np-modal precedent" — so only the width and a handful of genuinely new
     content-specific values are minted here; the sketch's own near-duplicate
     throwaway numbers (e.g. a 10px modal radius, a 26px close button) are NOT
     separately tokenised. --as-w is the dispatch-named exception: this modal
     is deliberately narrower than the 600px New Patient modal, off the
     sketch's own 380px column. */
  --as-w:380px;
  --as-top:42px; /* FIX ROUND 5 (job 1085; FIX ROUND 4's H1 cure FAILED — its
                    report claimed a working 729/715 scrollHeight/clientHeight
                    pair, but the manager's own firsthand live-DOM read of
                    that delivered state found 744/715 (29px still clipped)
                    with the foot flush at the window's own bottom edge, zero
                    air. ROOT CAUSE: reusing --modal-top (96px, the M5 New
                    Patient modal's own anchor, still live on d1n/d1no and
                    deliberately untouched here) caps w1af — the tallest M6
                    state — at 96px-from-top no matter how the bottom gap is
                    tuned, and w1af's natural total (header + free-text-panel
                    body content) needs far more headroom than 864-96=768px
                    can ever give it. FIX: a dedicated M6-only top anchor,
                    lower than --modal-top, freeing enough of the 864px
                    window for the whole natural content to render without
                    any internal scroll AND with visible air below the
                    modal's own bottom edge — see --as-bottom-gap below for
                    the paired value and the live-DOM proof numbers. */
  --as-bottom-gap:24px; /* FIX ROUND 5 pair to --as-top above. Live-DOM
                           measurement THIS round (this machine's headless
                           Chrome, both themes, w1af): natural total
                           (--as-top 42px anchor + as-h header 53px +
                           as-body natural content 729px scrollHeight) = a
                           natural bottom edge at window-relative y=824,
                           40px of air above the 864px window edge — the
                           cap (max-height = 864-24 = 840px) sits above that
                           824px natural height so it never binds; as-body
                           renders at its full natural 729px with ZERO
                           internal scroll (scrollHeight==clientHeight), the
                           free-text panel's border and the Cancel/Next row
                           both render intact well inside the window, and
                           the modal's own bottom-left/right rounded corners
                           draw in full (the modal's real box ends at y=824,
                           40px shy of the window's own overflow:hidden
                           edge, so nothing slices the curve). The other
                           seven new states (w1a/w1am/w1ax 583px, w1ah 603px,
                           w1at 479px, w1atm/w1atc 521px modal height) sit
                           even further from either the old or the new cap
                           and re-measure byte-for-byte unchanged aside from
                           the uniform 54px upward shift from the lower top
                           anchor (96px -> 42px) — see the FIX ROUND 5
                           delivery report for the full per-state table. */
  --as-res-top:79px;    /* the medication results popup's anchor off as-body's
                           padding box — measured off the rendered geometry
                           (as-body padding-top + the Medication heading +
                           the search field's own bottom edge sits at 77px in
                           every state that draws this popup, +2px breathing
                           gap); the --discl-top precedent */
  --g-kind:16px;        /* the picker kind-row glyph. FIX ROUND 6 (David's
                           freeze-eye): retuned from the sketch's own 17px to
                           16px, matching the existing --g-ctrl/--g-family
                           registry step, rather than sitting alone between
                           the 16px control and 18px chip sizes */
  --as-dim:.45;         /* opacity of the muted picker while the free-text
                           panel is active — new-from-literal, the sketch's
                           own .dim rule; theme-invariant, restated in dark */
  --as-notes-minh:64px; /* free-text Notes box RENDERED outer minimum height —
                           the sketch's own .notes rule is 44px content-box
                           (+9px vertical padding +1px borders = 64px outer);
                           the shell's global box-sizing:border-box means this
                           token must state the outer value directly */
  --fw-400:400;         /* NEW scale step: resets an inherited weight on the
                           timing option's sub-line (the sketch's own .sub
                           rule) — joins the existing --fw-500/600/700/800
                           inventory, not a one-off literal */
  --as-hover:var(--zebra); /* FIX ROUND 6 (David's freeze-eye, dark-mode
                           visibility): the picker rollover/selected washes
                           used var(--zebra) directly — invisible in dark,
                           where --zebra (#282d35) sits only ~3 units off the
                           modal's own --surface (#2b3038). Split into named
                           tokens so light can stay pinned to --zebra (byte-
                           identical rendering, carried-fingerprint safe)
                           while dark gets its own clearly-visible value
                           below. Light value is deliberately an alias, not a
                           copied literal, so it can never drift from zebra. */
  --as-sel:var(--zebra);   /* same rationale as --as-hover, for the persistent
                           .as-sel selected-row wash (as-ri/as-topt/as-ropt) */
  /* M7: the Daily observations surface (sonnet-dispatch.md; look reference
     .pilot/ui-m7-approved-sketch-2026-09-04.html, sketch v20, David-approved
     in-render 2026-09-05). The TEAL family — David 2026-09-05, over cream and
     violet — is the one hue on the sheet not already carrying a status or
     mode meaning. Values are RULED, both themes, verbatim (obs-panel-brief.md
     § 5); never derived. */
  --obs-bg:#e6f5f2; --obs-bd:#c3e4dc; --obs-ink:#14574c; --obs-wash:#f3faf8;
  /* the opened panel's static internal-scroll cap (obs-panel-brief.md § 3,
     "Long days"); theme-invariant geometry, restated in dark per the
     coverage gate. */
  --obs-body-max-h:240px;
}

/* ---------------------------------------------------------------------------
   DARK — was `.dark` on the window (fullmock L74–90); rehomed to the body so a
   built dark page is dark throughout. Token VALUES are unchanged.
   Values from the build's dark palette (code files/palette.rs L283–315),
   role-mapped. Tokens with NO build counterpart are NOT overridden (they keep
   their light value and render as such — an honest gap, listed here, not an
   invented palette): --chrome-border --ctrl-border --ctrl-divider --ctrl-fill
   --vbar-border --seg-on-bg --mode-* --rec-* --vchip-* --vpanel-*
   --dosebg/--dosetx --routebg/--routetx --ink-on-amber --menu-*.
   --hair-label and --addnote are PICKED (no build value): one step off
   cell_hairline / note_text.
   --nowline NOT overridden: e63 §B rules #E03131; the build's dark
   current_time_line (#FF6060, palette.rs L290) needs a ruling first.
   --------------------------------------------------------------------------- */
body.theme-dark{
  --surface:#2b3038; --row-even:#2b3038;            /* row_even */
  --column-bg:#23272e; --column-border:#333a44;      /* shell_column; seam */
  --panel-top:#20242b; --page:#1b1f25;               /* shell_top; shell_grid */
  --seam:#333a44; --card-border:#333a44;             /* seam; biscuit_border */
  --zebra:#282d35;                                   /* zebra */
  --hair:#303640; --hair-label:#3a414c;              /* cell_hairline; (picked) */
  --row:#2e333b; --badge-bg:#363d47; --badge-ink:#aeb6c2; /* card; badge_bg; badge_text */
  --ink:#ebeff4; --ink-strong:#ebeff4; --heading:#ebeff4; /* text; heading */
  --ink-body:#d5dbe3; --child-ink:#c2c9d2; --field-ink:#c2c9d2; /* group_title; child_text */
  --ink-muted:#8b93a0; --ink-soft:#8b93a0;           /* scalar */
  /* 86i.24 dark half. The lifted roles take the dark --ink-muted step (#8b93a0),
     mirroring light's move to its own --ink-muted. --ink-quiet and the purely
     decorative --separator-ink stay at #7a828e — the split is the point: inert
     navigation and rule-of-thirds chrome stay subdued, text-you-read and
     controls-you-click lift. */
  --ink-faint:#8b93a0; --placeholder-ink:#8b93a0; --section-suffix:#8b93a0; --pencil-ink:#8b93a0;
  --ink-quiet:#7a828e; --separator-ink:#7a828e;
  --note:#9aa2ac; --addnote:#5f6873;                 /* note_text; (picked) */
  --ctrl-ink:#ebeff4; --stepper-ink:#d5dbe3;         /* text; group_title */
  --menu-bg:#2b3038;                                 /* row_even */

  /* ---- INVARIANT BY RULING, restated DELIBERATELY ------------------------
     The status palette and the accents do NOT change with theme. Source: the
     approved fullmock's own dark block comment — "surface + ink tokens only;
     status colours, --btn, --record untouched" — and e63 §B, which rules the
     macOS traffic-light palette as one set for both themes. Restated here at
     identical values so the total-coverage gate records them as considered.
     NOT included here, because they are OPEN rather than invariant:
       --nowline     e63 §B rules #E03131; the build's dark current_time_line is
                     #FF6060 (palette.rs L290). Needs a ruling, not a restatement.
       --destructive PICKED (= nowline red); the build's Sign-out hex was never
                     read, so there is nothing to restate faithfully. */
  --overdue:#FF605C; --due:#FFBD44; --done:#00CA4E; --skip:#9aa1ab;
  --on-fill:#ffffff;
  /* status inks are theme-invariant, because the fills are (86i.23) */
  --ink-on-overdue:#3D0300; --ink-on-done:#cef5dd; --ink-on-grey:#eceef1;
  --btn:#3b82f6; --record:#6d5dd3;
  /* reference-page chrome — outside the window, not app UI. The approved dark
     state was rendered inside this same light reference page, so these stay. */
  --ref-bg:#c9cdd3; --ref-head:#1b2028; --ref-label-ink:#1f2632;
  --ref-label-bg:#eef1f5; --ref-label-bd:#dfe3e8;

  /* ---- THEME-INVARIANT, restated DELIBERATELY ----------------------------
     Geometry, type scale and font stacks do not change with theme. They are
     repeated here with values identical to light so the total-coverage gate in
     build.py can see they were considered rather than forgotten. Editing one
     of these means editing it in BOTH blocks — the gate will catch a mismatch
     in coverage but NOT a mismatch in value, so keep them in step by hand. */
  --ui-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:"JetBrains Mono","DejaVu Sans Mono",ui-monospace,Menlo,Consolas,monospace;
  --chip-radius:4px; --header-h:28px; --glyph-weight:400; --g-icon:18px;
  --g-family:16px; --g-chip-skip:20px; --g-chip-minor:16px;
  --g-ctrl:16px; --g-rail:14px; --g-small:13px; --g-disclose:20px;
  --window-radius:8px; --window-shadow-geom:0 16px 44px;
  --ctrl-radius:8px; --rail-radius:7px; --gridcard-radius:8px;
  --topbar-h:56px; --col-w:240px; --win-w:1536px; --win-h:864px;
  --ref-pad:22px 0 46px; --ref-label-radius:8px; --ref-label-pad:10px 14px;
  --ref-label-margin:24px 0 11px; --ref-label-size:13.5px; --ref-label-accent:4px;
  --ref-head-size:20px; --ref-sub-size:12.5px;

  /* ---- TYPE / SPACING SCALE (rule 2) -------------------------------------
     Extracted verbatim from the approved mock. Named BY VALUE on purpose: a
     role-named scale would require deciding which occurrences mean the same
     thing, which is a design decision and not mine to make. This is therefore
     bookkeeping — it makes the inventory visible and changeable in one place,
     it is not yet a design system. Every value is unchanged; the computed-style
     fingerprint gate proves it.

     ⛔ CONSEQUENCE, and it is NOT neutral (external review, 2026-08-22):
     replacing every identical literal with one variable COUPLES those
     occurrences. `--fs-13` is now the search field AND the tab AND the patient
     bar AND the rail item; `--sp-8` is a dozen unrelated paddings. They are one
     value today by coincidence, not by decision.
     So: a future role-specific change MUST mint a new semantic token
     (e.g. `--fs-rail-item`) and point that role at it. It must NEVER be made by
     editing `--fs-13` or `--sp-8`, which would silently move every other
     occurrence with it. This scale is an inventory, not a set of decisions. */
  --fs-9-5:9.5px;   /* the reserved-tab "soon" marker (86i.15). Size PICKED — read off
                       the build screenshot 2026-08-20 090900; the register rules that a
                       marker exists, not its size. */
  --fs-10-5:10.5px; --fs-11:11px; --fs-11-5:11.5px; --fs-12:12px; --fs-12-5:12.5px;
  --fs-13:13px; --fs-13-5:13.5px; --fs-14:14px; --fs-15:15px; --fs-16:16px;
  --fw-500:500; --fw-600:600; --fw-700:700; --fw-800:800;
  --bw-1:1px; --bw-2:2px;
  --sp-1:1px; --sp-2:2px; --sp-3:3px; --sp-4:4px; --sp-5:5px; --sp-6:6px;
  --sp-7:7px; --sp-8:8px; --sp-9:9px; --sp-10:10px; --sp-11:11px; --sp-12:12px;
  --sp-13:13px; --sp-14:14px; --sp-15:15px; --sp-16:16px; --sp-20:20px; --sp-27:27px;
  --fs-10:10px;
  --r-3:3px; --r-5:5px; --r-6:6px; --r-9:9px; --r-10:10px; --r-14:14px;
  --w-search:230px; --sz-ava:30px; --w-menu:236px; --minw-badge:18px;
  --menu-top:54px; --menu-right:12px; --menu-shadow-geom:0 10px 28px;
  --sz-sw-w:30px; --sz-sw-h:17px; --sz-knob:13px; --sz-pmore-w:26px; --sz-pmore-h:24px;
  --h-pbar:42px; --h-vbar:48px; --sz-rdot:9px; --halo-w:3px;
  --w-chip:66%; --h-chip:56%; --w-bchip:88%; --h-bchip:64%;
  --sw2-w:22px; --sw2-h:15px; --ls-02:.02em; --ls-03:.03em; --ls-04:.04em;
  --lh-14:1.4; --caret-nudge:-8px; --va-2:-2px; --va-3:-3px;
  --dot-size:12px;      /* dashboard per-task dot — uniform, no size ladder (e62/e73/e82) */
  --dot-legend:11px;    /* the same dot in the 4-item legend strip */
  --lh-125:1.25;        /* dashboard task line */
  /* v2 dispatch: d1o disclosure popover geometry, restated — see :root */
  --discl-top:333px; --discl-left:501px; --discl-w:176px;
  /* M4 record panel geometry, restated — see :root */
  --rp-w:358px; --rp-shadow-geom:-14px 0 40px;
  /* M4 REDRAW: seat/active-card wash — DARK VALUE, not a light restatement.
     --surface (#2b3038) interpolated ~0.4 toward --rec-bg dark (#2c2840), the
     same proportion light's #f8f6fe sits between --surface and --rec-bg
     light — a faint violet tint, barely off the surface, matching the
     sketch's light-only intent per the token-derivation rule. The lift
     geometry and badge diameter are theme-invariant, restated. */
  --seat-wash:#2b2d3b; --seat-lift-shadow-geom:0 2px 10px; --sz-cbadge:19px;
  /* M5 New Patient modal geometry, restated — see :root. The scrim is
     theme-invariant (a neutral dark wash reads the same over either page);
     the modal shadow deepens on dark, matching the --window-shadow/
     --menu-shadow light→dark ratio already used for this window's own
     chrome shadows. */
  --modal-scrim:rgba(18,22,28,.45); --modal-shadow-geom:0 24px 70px; --modal-shadow:rgba(0,0,0,.5); /* dark scrim dims harder than light's .30 — a 30% dark veil barely reads on a dark page (Fable-1066 eye item, David-agreed); ordinary per-theme token value, same class as the deepened modal shadow */
  --modal-radius:12px; --modal-w:600px; --modal-top:96px; --modal-bottom-gap:128px;
  --sz-modal-close:24px;
  --np-w-name:225px; --np-w-loc:150px; --np-w-species:130px;
  --np-w-age:165px; --np-w-weight:78px;
  /* One shared column width for the details panel's two-column grid — the
     per-field snug widths left the three rows "almost lined up" (David, freeze
     eye 2026-08-31: line them up); 200px also cures the Colour placeholder
     clip (Fable-1066 Low). */
  --np-w-half:200px;
  --np-w-sex:var(--np-w-half); --np-w-neuter:var(--np-w-half);
  --np-w-breed:var(--np-w-half); --np-w-colour:var(--np-w-half);
  --np-w-contact:var(--np-w-half); --np-w-pid:var(--np-w-half);
  --np-tog-w:40px; --np-tog-h:22px; --np-tog-radius:12px; --np-tog-knob:18px;
  --np-tog-knob-shadow:0 1px 2px rgba(0,0,0,.2); /* the approved sketch's knob shadow, tokenised (Codex-1064 L1); theme-invariant, restated in dark per the coverage gate */
  --np-dnr-ml:18px; --np-btn-pad-x:18px;
  /* M3 rail-spacing scale, restated — see :root */
  --rail-gap-row:-8px; --rail-gap-heading:10px; --rail-gap-section:18px; /* row token is a between-rows OVERLAP (freeze-eye 2026-08-28; option A ruled on Codex-1037 M1): boxes overlap 8px so text-to-text reads 8px < heading 18px < section; the LATER row owns the shared strip, so each row's exclusive click strip is the ~26px row pitch (ruled acceptable), not the full padded box */
  /* M6 Add-to-sheet modal geometry/weight, restated — see :root */
  --as-w:380px; --as-top:42px; --as-bottom-gap:24px; --as-res-top:79px; --g-kind:16px; --as-dim:.45; --as-notes-minh:64px; --fw-400:400; /* M6 Add-to-sheet geometry restated per FIX ROUND 5 — see :root; --g-kind 16px per FIX ROUND 6 (David: registry-consistent 16, not 17) */
  --as-hover:var(--kebab-hover); --as-sel:var(--kebab-hover); /* FIX ROUND 6: dark-only visibility fix — NOT restated equal to light (light stays var(--zebra) in :root, deliberately). --kebab-hover (#363d47) is an already David-passed dark step that visibly contrasts --surface (#2b3038)/--zebra (#282d35, only ~3 units off surface — the invisibility this round fixes); reused rather than a new literal, per the no-literals rule. */

  /* ---- FOUNDER-SUPPLIED DARK PALETTE (David, 2026-08-22) ------------------
     The 31 values below + the two rulings close the total-coverage gate's
     residual 33. Hue preserved, lightness inverted, saturation eased;
     tints rendered as violet-whisper dark greys. */

  /* Due-Today panel */
  --vpanel-bg:#262336; --vpanel-bd:#3a3354; --vpanel-h:#a99ede;
  /* STARVE chip */
  --vchip-bg:#2c2840; --vchip-bd:#453c68; --vchip-ink:#b7abe8; --vchip-ink2:#9186bd;
  /* record banner, REV + phase badges */
  --rec-bg:#2c2840; --rec-bd:#3e3760; --rec-ink:#b7abe8; --rec-ink-strong:#cdc3f2;
  --rec-who:#9488c8; --rec-halo:rgba(109,93,211,.30); --rec-tint:#2c2840; /* --rec-tint = --rec-bg dark, the same ruling as light (David 2026-09-05) */
  /* Edit plan | Record care toggle */
  --mode-bd:#3d4566; --mode-on-bg:#2e3650; --mode-on-ink:#aab8f0; --mode-rec-bg:#352f4a;
  /* control chrome (mapped onto the existing dark greys — no new colours) */
  --seg-on-bg:#3a4150; --chrome-border:#3a414c; --ctrl-border:#3a414c;
  --ctrl-divider:#333a44; --ctrl-fill:#363d47; --vbar-border:#333a44; --kebab-hover:#363d47; /* dark: --ctrl-fill already contrasts the dark zebra - David-passed */
  /* dose / route badges */
  --dosebg:#333a50; --dosetx:#b9c2e8; --routebg:#333d33; --routetx:#b3c2ab;
  /* same as light, deliberate — amber chips are theme-invariant, so their ink is too */
  --ink-on-amber:#5a4300;
  /* shadows need depth on dark */
  --menu-shadow:rgba(0,0,0,.45); --window-shadow:rgba(0,0,0,.5);

  /* ---- RULED (David, 2026-08-22), closing the two open conflicts ----------
     --nowline: e63 §B's #E03131 stands for LIGHT; dark uses the build's
     #FF6060 — the now-line is chrome, not a status colour, so the
     one-set-both-themes rule does not bind it. Resolves the e63§B-vs-
     palette.rs conflict recorded in the provenance comment.
     --destructive: reuses the overdue red — correct read on dark menus,
     no new colour minted. Supersedes PICKED. */
  --nowline:#FF6060;
  --destructive:#FF605C;
  /* Critical/DNR knob — the existing child-ink grey, so the knob floats ABOVE the
     #3a414c track instead of sinking into it. No new colour minted.
     PM-proposed 2026-08-22; pending David's look at the next render. */
  --toggle-knob:#c2c9d2;
  /* M7: the Daily observations teal family — DARK VALUES, ruled verbatim
     (obs-panel-brief.md § 5), not derived from light. */
  --obs-bg:#1d2f2b; --obs-bd:#2f4a44; --obs-ink:#9fd8c9; --obs-wash:#182622;
  /* theme-invariant geometry, restated — see :root */
  --obs-body-max-h:240px;
}

/* ---------------------------------------------------------------------------
   PER-VIEW GEOMETRY — the only tokens whose value legitimately differs between
   the two pages. Both are register-ruled floors (e84 L1753), not style choices.
   Everything else about the shell is shared BY CONSTRUCTION (one shell.html).
   --------------------------------------------------------------------------- */
body.view-sheet{
  --label-w:296px;  /* care-item column floor — e84 L1753; raised from 285px at M3
                       (David 2026-08-27/28, kebab-position rider): under the old
                       285px floor the Amoxicillin-clavulanate row's long name
                       overflowed the column and pushed its `.dots` right to
                       513.66px from the window's left edge (w1 light, headless
                       Chrome 1536x864) — not a defect but the look David wants
                       for every row's kebab by default. 296px puts every row's
                       `.dots` (Amoxicillin included) at 514px, ~0px off target,
                       and retires the tlabel(+3) overflow as a side effect (the
                       column is now wide enough to hold Amoxicillin's name
                       without overflowing). See ui-m3-delivery-report.md. */
  --rowh:40px;      /* sheet row height — fullmock L63 */
}
body.view-dashboard{
  --label-w:150px;  /* patient column floor — e84 L1753 */
  --rowh:47px;      /* dashboard row density — e82 */
}
