/* app.css — the Stockport app's own stylesheet, copied unchanged by calc_sync.mjs. DO NOT EDIT THIS FILE.
   From the app file with sha256 99903722d61478c2477c55062798815e5fefc5fad7091dac29c1083416c336a3 (2026-10-16). The stylesheet's text (everything after this comment) has sha256 5a57130965fe7f398bba1535926f272f13f9798f04ec058fa5c3b43cd965a8d5. */

/* ═══════════════════════════════════════════════════════════════════════════
   THE TOKEN LAYER — Phase 1 of the UI/UX phase (3 Sep 2026, session 58).
   Spec: design/stockport_tokens.md. Baseline it answers: design/design_baseline_20260903.md.
   ⚠ RULES THAT DO NOT RELAX (§2a of the spec supersedes Phase 1's first rule, 3 Sep s59):
   · GREEN FILLS THE ONE THING YOU SHOULD DO NEXT, AND TINTS THE THINGS THAT ARE SIMPLY
     TRUE; EVERYTHING ELSE IS NAVY. The CTA is --action = --green-deep (one filled green
     per decision surface); navy is the NEUTRAL — chrome, headings, links, row actions,
     the active tab, focus and selection — and is never a filled button. Amber / red mean
     STATE (strained / broken) and nothing else; green tints state too (live, intact).
     Selection is GEOMETRY — a navy ring and weight — never a hue. Both carry-overs are
     now SETTLED: the green // EYEBROW voice went neutral in session 62, and the duplicate
     --accent-on-dark was merged into --action-on-dark in session 63 (see :root below).
   · The button ladder (§2a.5, rebuilt on the v2 board §1–§3 in session 73): .btn-primary
     is the one green fill per decision surface; .btn-neutral is the grey BOX of a header,
     a card head or a strip; .btn-secondary is the hairline (Cancel, Close, Edit settings);
     the green hairline (.btn-secondary.paired, the board's button-outline-action) sits
     ONLY beside a primary; the red fill confirms inside a dialog and nowhere else. Text
     controls live inside rows — violet forward, grey back, red destroy. The gold button
     that sat OFF the ladder (UX-44) is RETIRED — his decision, 11 Sep 2026 (v2 DESIGN.md
     rule 10): gold is a border, a fill and a glyph, never a word and never a button.
   · A shadow means the thing floats (§2a.8). Cards in the page get a hairline only; the
     lint harness counts box-shadow on non-floating selectors and that count only falls.
   · At most two nested surfaces (§2a.7): ground → card → row/chip with no border of
     its own. Phase 2 stops adding boxes; Phase 3/5 remove them (UX-40).
   · --navy-dk is RETIRED (§9 #3). It was the website's page background borrowed as
     modal chrome. --navy is the one modal chrome.
   · No raw hex, no raw font-size, no raw z-index, no raw radius outside this block.
     The website's geometry (--radius / --radius-sm / --radius-xs / --shadow) is adopted
     as-is; the app adds --radius-2xs and --radius-pill.
   · Six z layers, in-band order by calc(var(--z-x) + n), n ≤ 5. The composer lives in
     the STICKY band — below the nav band — which is the UX-03 fix.
   ═══════════════════════════════════════════════════════════════════════════ */
@layer base{
:root{
  /* ── brand — navy, the one ramp ── */
  --navy:#0D1E3B;--navy-soft:#2C4F9A;--navy-high:#1a3a5c;--navy-deep:#0a1830;
  --navy-tint:rgba(44,79,154,0.08);--navy-tint-strong:rgba(44,79,154,0.16);
  --brand-mark:#2ac783;              /* the wordmark's "port" — the logo only, never UI */
  --on-brand:#fff;                   /* text on navy chrome */
  /* IA §2b.2 #3 — the SUB-LINE on navy chrome. 9.6:1 on --navy, and one value where the file
     currently carries seven (.45 .5 .55 .6 .65 .7 .72) doing the same job on the same ground.
     ⚠ Only the shell's tagline is repointed here; folding the other six is a real ceiling drop
     (L29) and belongs to the step that owns those surfaces, not to the shell. */
  --on-brand-soft:rgba(255,255,255,0.72);
  --on-brand-line:rgba(255,255,255,0.12);   /* a divider ON navy chrome (the chain island) */
  --on-brand-faint:rgba(255,255,255,0.35);  /* an UNTESTED step's dot on navy */
  --chrome:linear-gradient(135deg,var(--navy) 0%,var(--navy-high) 100%);  /* dark cards, modal heads */
  /* ── action — the one filled green (§2a.4). --green-deep is --green darkened on hue
     154.7° until white text clears 6.5:1 (6.66:1; L 0.108). Hover darkens, never re-hues. ── */
  --green-deep:#0B6A42;
  --action:var(--green-deep);--action-hover:#095538;--on-action:#fff;
  --action-on-dark:var(--green);     /* the CTA on navy chrome flips to the light green, --navy label */
  /* ── selection — geometry, not hue ── */
  --ring:0 0 0 3px rgba(44,79,154,0.18);   /* the focus ring, everywhere */
  --sel-ring:0 0 0 1px var(--navy-soft) inset;   /* the chosen card, everywhere */
  /* ── state — the website's semantic set, byte-identical ── */
  --green:#2ac783;--green-strong:#27500A;--green-soft:rgba(42,199,131,0.12);
  --amber:#d4a949;--amber-strong:#7a4e00;--amber-soft:rgba(212,169,73,0.12);
  --red:#d35b6a;--red-strong:#b03050;--red-soft:rgba(211,91,106,0.10);
  /* ── the two named carry-overs — BOTH SETTLED ── */
  /* UX-50/51 (session 62): the section eyebrow was --green at 2.19:1 on --surface, and a
     heading has no state to report — green means intact, amber means strained. It is a
     neutral now. The terminal "// " prefix went with it, at 80 rendered sites. */
  --eyebrow:var(--text-muted);
  /* ⚠ --accent-on-dark IS GONE (session 63). It was a SECOND name for var(--green) on navy,
     alongside --action-on-dark above — one hex, two tokens, two comments, no difference in
     value or surface. It had to go BEFORE --accent lands as VIOLET (§2b.2 #5): --accent
     violet sitting beside --accent-on-dark green would read as the on-dark form of the
     accent, which it never was — it is the on-dark form of --action. Its 6 usages (tickers
     and eyebrows on navy chrome) now say --action-on-dark, which is the name the IA spec's
     §5 token list uses. ⚠ Do not reintroduce an --accent-on-dark; when violet needs an
     on-dark form it gets its own derived token, not this one. */
  --gold-deep:#b8892f;               /* the Lynch lens / legend accent */
  /* ── THE ACCENT — VIOLET, and the marker ramp. Phase 3 step 5 (session 65). ──────────
     Specified in stockport_tokens.md §2a.12 and §2b.3; wired here for the first time.
     ⚠ THIS IS ONE OF EXACTLY TWO SANCTIONED CEILING RAISES IN THE WHOLE PHASE (§2b.6):
     :root hex 30 → 40, whole-file 44 → 54. Every other ceiling still only falls, and
     these two rise HERE, once, with this comment as the reason. A ceiling raised on
     purpose is fine; one raised quietly is how the discipline dies.
     ⚠ VIOLET IS THE ACTION COLOUR AND IS NOT ON THE MARKER RAMP — his ruling D8:
     "violets etc. not be used for markup because they are the buttons." On an M2 card
     the left rule, the C-id and the Edit link would otherwise all have been violet eight
     pixels apart: identity and clickability in one colour.
     ⚠ --accent MUST STAY LIGHTER THAN --navy-soft (5.21:1 vs 7.80:1 on white). Under
     protan/deutan vision violet resolves to blue and sits ~2° from navy; luminance is
     the only cue that survives, so do NOT "fix" a violet link by darkening it to
     --accent-strong. That token is for text on --accent-soft and nowhere else. */
  --accent:#893BF7;                  /* Navigate — links, row actions, tertiary buttons */
  --accent-hover:#6C0AF5;            /* darkened on the same hue, ×1.34 contrast */
  --accent-soft:rgba(137,59,247,0.12);
  --accent-strong:#6309E1;           /* the text ON --accent-soft, 6.63:1 against it */
  --gold-soft:rgba(184,137,47,0.14); /* the ★ primary badge's fill; gold is never a word.
                                        ⚠ .14, not .12 — measured off the rendered prototype;
                                        the app carried a two-point-lighter fill for a phase. */
  /* The five-marker ramp — claim identity. M1 is --navy-soft, freed by the move of
     tertiary actions to violet above; that reassignment MUST stay in this same change or
     M1 inherits exactly the collision M2 was dropped for. Text contrast on white,
     measured: 7.80 · 6.12 · 8.25 · 9.06 · 7.88 — all clear L28's 4.5:1. */
  --mk1:var(--navy-soft);            /* M1 by name (v2 handoff) — the same colour, so no new hex */
  --mk2:#1C7FA0;--mk2-t:#136A86;     /* cerulean — NOT --teal, the commitment hue below */
  --mk3:#B0287A;--mk3-t:#8F1F63;     /* magenta */
  --mk4:#4A47C9;--mk4-t:#3B38A8;     /* indigo */
  --mk5:#5B6B8A;
  /* ⚠ THE RAMP'S TINT STEP (board 6e). A marked sentence in the review note wears its claim's
     colour at 12% with the same colour underlining it. rgba, not hex, so neither hex ceiling
     moves — and in :root, so no rule outside it carries a raw colour. */
  --mk1-tint:rgba(44,79,154,0.12);--mk2-tint:rgba(28,127,160,0.12);--mk3-tint:rgba(176,40,122,0.12);
  --mk4-tint:rgba(74,71,201,0.12);--mk5-tint:rgba(91,107,138,0.12);--mk5-t:#44526B;     /* slate */
  /* ── commitment — management's word (v2 handoff, 11 Sep 2026; he approved the values) ──
     The callout-commitment ground and rule, and the COMMITMENT / GUIDED pill. Nothing else:
     not a state, not an action, not a claim marker. ⚠ THE THIRD SANCTIONED RAISE OF THE HEX
     CEILINGS (§2b.6), on his ruling: :root distinct hex 41 → 43, the whole file 55 → 57.
     --teal-soft is rgba and counts in neither. Measured on white: --teal 4.71:1 (a rule and a
     glyph), --teal-strong 7.42:1 (the words). It sits near M2 (CIELCh hue 217° against 239°),
     which the handoff accepts because a marker is a line and a tag while a commitment is a block. */
  --teal:#137F8F;--teal-strong:#0C5E6B;--teal-soft:rgba(19,127,143,0.12);
  --event:#B4561A;--event-strong:#8A3F10;--event-soft:rgba(180,86,26,0.10);   /* s130 · the EVENT passage's hue — the board had none (his item 7; provision rule §2j.2). Measured: the glyph 6.57:1 on its soft ground, the rule 4.9:1 on white */
  /* ── surface · text · line — the roles the site fills dark and the app fills light ── */
  /* UX-54 (Phase 3, session 62): --bg WAS a four-stop blue gradient, so a white card separated
     from the ground at 1.24:1 at the top of the page and 1.06:1 at the bottom — the separation
     changed as he scrolled, and the blue cast desaturated every warm hue on the page. The ground
     is white; the hairline separates. MongoDB Atlas and Doppler ship the same arrangement. */
  --bg:#fff;
  --shell:#F7F9FB;                   /* the page ground AND the sidebar (session 109, his decision of 3 Oct) — one step under white, so a white card comes out on its hairline */
  --surface:#fff;--surface-sunken:#E7ECF2;--surface-tint:rgba(13,24,41,0.04);
  --surface-raised:var(--surface);   /* was a blue-white gradient; a card is white (§2a.7 level 1) */
  --text:#0D1829;--text-soft:#2A3D55;--text-muted:#4B6180;--text-faint:#8a9bb0;
  --line:rgba(13,24,41,0.08);--line-strong:rgba(13,24,41,0.14);
  /* session 107 · two values that lived in rules, named once. The scrim is the one both boards draw under a modal
     and under the drawer; the confirm dialog carried a lighter one of its own. The untested chain ring's edge is
     darker than a hairline on purpose (a ring nobody can see is not a ring). */
  --scrim:rgba(13,30,59,0.7);--untested-edge:rgba(13,24,41,0.28);
  /* ── data-viz palette (charts only; never UI) ── */
  --viz-indigo:#6366f1;--viz-blue:#60a5fa;--viz-mint:#86efac;--viz-amber:#fbbf24;--viz-red:#ef4444;
  --viz-heat:linear-gradient(to right,var(--viz-red) 0%,#d97706 50%,#10b981 100%);  /* the FOMO / gap gauge track — data, was inline ×2 */
  --viz-violet:#9b59b6;--viz-violet-soft:#f3e5f5;   /* the DIVIDEND chip — a category colour, Phase 5's to keep or drop */
  /* ── geometry — the website's, adopted ── */
  --radius:28px;--radius-sm:16px;--radius-xs:10px;--radius-ring:6px;--radius-2xs:4px;--radius-3xs:2px;--radius-pill:999px;
  /* --shadow went here (session 77, Phase 8, his ruling): the in-page card shadow. Its only
     two readers were .card and .metric-card and neither is raised any more. The floating
     tier keeps its own four — a shadow now means the thing floats, and nothing else. */
  --shadow-sm:0 2px 8px rgba(8,17,32,0.08);
  --shadow-drop:0 8px 24px rgba(8,17,32,0.10);   /* a bar that DROPS a list over the page —
                                     SPEC §1.3's own value. Between --shadow-sm (the slim head,
                                     which only sits on the page) and --shadow-pop (a popover). */
  --shadow-pop:0 10px 28px rgba(8,17,32,0.18);   /* a popover floats above its trigger (§2a.8) */
  --shadow-composer:0 12px 36px rgba(8,17,32,0.24);   /* the composer floats over the page (v2 handoff) */
  --shadow-modal:0 20px 50px rgba(8,17,32,0.28);   /* a modal over its scrim (v2 handoff). The old large
                                     shadow carried this value with no consumer; renamed, one name per value. */
  /* ── spacing — seven steps ── */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:24px;--sp-6:32px;--sp-7:48px;
  /* ── the IA's chip / pill / popover geometry (SPEC-components §1–2), named once ── */
  --chip-pad:3px 10px 3px 8px;    /* the ★ badge and the ☆ chip, so the two swap without reflow */
  --chip-gap:6px;                 /* glyph-to-word inside a chip and inside a box button (v2 board §1); also the 6px design step */
  --card-x:18px;                  /* the claim card's side inset — row and body must agree */
  --pill-pad:2px 7px;             /* pill-state and the neutral kind variant — v2 board §4 */
  --pop-row-pad:8px 10px;         /* a popover row — a 44px-friendly target at 13px */
  /* ⚠ NOT NAMED *-gap: L14's regex reads a custom property called --…-gap as a gap
     declaration, so the name alone would have spent one of the file's spacing literals.
     It applies to every token named from here on; --chip-gap above predates the rule and is
     counted. The pill control's own step was the last token this caught, and it is gone —
     his ruling below put the control back on --pill-pad and --sp-1. */
  /* ── the buttons — v2 board §1–§3 (design system v2, Phase 2, session 73) ── */
  /* The board's literals, named by the job they do, so no component carries a raw padding. A
     fill and a 1.5px hairline differ by exactly that border, so both render 36px tall. */
  --btn-pad:10px 18px;            /* button-primary · button-danger · primary-on-dark — a fill */
  --btn-pad-line:9px 16px;        /* button-secondary · outline-action · danger-outline — a hairline */
  --btn-pad-neutral:9px 14px;     /* button-neutral — the box of a header, a card head or a strip */
  --neutral-fill:rgba(13,24,41,0.06);        /* button-neutral's grey (his ask, 11 Sep) */
  /* ── the Claims header's neutral GROUP (board §2). It is one button-neutral box holding
     three things, so everything but these two is the ladder's already: the fill, the radius,
     the 9px 14px and the 600/13 Inter. ⚠ NEITHER NAME MAY END IN THE WORD L14 READS AS A
     SPACING DECLARATION — that is why the step is not called what it is. */
  --passchip-step:10px;           /* word → count → divider → word, inside the group */
  --passchip-rule:14px;           /* the 1px divider's height */
  --neutral-fill-hover:rgba(13,24,41,0.10);  /* and its hover */
  --icon-hit:32px;                /* an icon button's square (board §3) */
  --icon-hit-touch:44px;          /* the same square at 768 and below — a touch target; the glyph stays */
  --icon-glyph:16px;              /* Lucide in an icon button */
  --icon-glyph-sm:14px;           /* Lucide inside a box button, before the word; the disclosure chevron */
  /* ── the shell — session 109, the sidebar of his 3 Oct comments (Pages board §S). Named by the job, so no rule
     carries a raw number. ⚠ None of these names ends in the word L14 reads as a spacing declaration. ── */
  --nav-h:36px;                   /* a nav row, a position row, a menu row */
  --nav-h-touch:44px;             /* the same rows in the phone's drawer */
  --nav-pad:0 10px;               /* a nav row's inset */
  --nav-m:1px 8px;                /* and the 8px it keeps from the sidebar's edges */
  --nav-step:10px;                /* glyph → word */
  --nav-indent:36px;              /* a position row starts under its group's word */
  --sb-list-max:408px;            /* eleven position rows (11 × 36 + the 1px between and at each end); then the list scrolls.
                                     The board writes 406 and forgets the two end margins — the rule is eleven rows, not the number */
  --sb-list-max-sm:271px;         /* six, in the drawer (6 × 44 + the same) */
  --sb-logo-pad:22px 20px 12px;   /* the wordmark block */
  --sb-acct-h:44px;               /* the account row */
  --avatar:28px;                  /* the account's initial */
  --plate:32px;                   /* the heading plate (board: section-heading) */
  --spark-h:120px;                /* a KPI card chart's drawn height (_sigSpark: viewBox 124 high, drawn at H−4) — 56 until session 117 */
  --spark-y-lh:12px;              /* its y-axis label's line */
  --spark-y-inset:1.75px;         /* so the first and last label sit ON the top and foot gridlines (8/124 and 116/124 of the height) */
  --pg-title:var(--fs-display);   /* s117 · a PAGE's heading — 28; the phone block below sets it to the section role's 24. Named like
                                     --sec-fs, and for its reason: a role in use, not an eleventh --fs-* */
  --pg-plate:34px;                /* its plate — the heading plate a step up; 34 because plate + the head's padding and hairline is then the 60px head (36 made it 61) */
  --pg-glyph:18px;                /* and the glyph in it */
  --sec-fs:var(--fs-title);       /* a page-level card's title — 20; the phone block below sets it to the title role's 18. ⚠ Not named
                                     --fs-*: it is the title ROLE, not an eleventh one, and the lint counts roles by that prefix */
  --rec-sub-ic:24px;              /* the section sub-line hangs under the name, past the glyph (16 + 8). ⚠ Its own token: --rec-sub-x
                                     (14, past the old dot) is also two callouts' side padding and must not move with it */
  --mt-glyph:22px;                /* the phone bar's menu glyph */
  /* ── THE LADDER AT <768. v2 shipped these scoped to a modal footer and left every other
     390 button at its 1440 size; the v3 §10 self-check found 16 strays and wrote the set
     down (system file §2 button-primary). ONE SET, the whole ladder, at every site.
     ⚠ ONE EXCEPTION, and it is the same one as at 1440: in a button row beside an
     icon-button the text button takes the ROW's height (32 at ≥768, 44 at <768) with 0
     vertical padding — 04's [Log reading][⚙][⤢]. That is --sig-btn-pad-sm, below. */
  --btn-pad-sm:12px 18px;         /* button-primary · button-danger · primary-on-dark */
  --btn-pad-line-sm:11px 16px;    /* button-secondary · outline-action · danger-outline */
  --btn-pad-neutral-sm:11px 14px; /* button-neutral */
  /* ── chips, fields, surfaces, callouts and states — v2 board §4, §5, §6 and §10
     (design system v2, Phase 3, session 74). The board's literals, named by the job they do,
     so no component carries a raw padding. Every one is rgba or px: no hex ceiling moves. ── */
  /* ⚠ THE PILL AS A CONTROL HAS NO BOX OF ITS OWN ANY MORE — HIS RULING, 12 SEP 2026:
     "for the 4 decisions we can lock the v2 board's decision." Board 5a gave the control a
     narrower left inset so its trailing chevron could take the pixel back; the v2 board draws
     one pill box whether the pill reports or picks, and that is the one that is right. So
     --pill-pad-ctl and --pill-chev are retired, .clm-statebtn takes --pill-pad and --sp-1, and
     5a's state-pill probe carries the ruling as its reason (spec P3-Q3). */
  --tag-pad:2px 8px;              /* tag-mono and tag-marker — an identifier runs wider than a state word */
  --chip-sel-pad:8px 12px;        /* chip-select and chip-select-state — a thing you pick */
  --fld-pad:10px 12px;            /* field · field-mono · select · textarea */
  --fld-pad-sm:8px 12px;          /* field-sm — a field inside a row grid (v3 components §5) */
  --fld-ta-min:96px;              /* a textarea's floor (the composer's editor sets its own) */
  --callout-pad:12px 14px 12px 16px;   /* the callout family's one anatomy */
  --rule-w:3px;                   /* a callout's left rule, and a claim card's marker edge */
  --card-pad:20px;                /* a level-1 card (board §6) */
  --row-pad:12px;                 /* a level-2 row — nothing nests below it */
  --state-pad:32px 24px;          /* an empty / couldn't-load / no-results panel */
  --disc:48px;                    /* the tinted disc that stands where an illustration would go */
  --disc-glyph:22px;              /* and the Lucide glyph inside it */
  --cbx:16px;                     /* the checkbox */
  --sw-w:32px;--sw-h:18px;--sw-knob:14px;   /* the switch's track and its knob */
  --star-sz:28px;                 /* one star of a rating */
  /* ── peek · THE ONE READING PANEL (UX-64, closed 14 Sep 2026). It replaces the navy
     tooltip, which was 12px on navy — glance type. A long claim statement is READ, not
     glanced at, so it gets reading type on white, and the panel carries the WHOLE text:
     nothing is ever clamped inside a peek, because a peek exists to undo a clamp. */
  --peek-w-chip:360px;            /* on a chip — a claim-link or a question-link */
  --peek-w-cell:420px;            /* on a cell — where the navy tooltip used to be */
  --peek-pad:12px 14px;
  --peek-gap:10px;                /* the text to its hairline foot, and the foot's own rule to it */
  --peek-drop:6px;                /* how far below the trigger it opens */
  --peek-delay:300ms;
  --peek-rule:rgba(13,24,41,0.35);/* the cell trigger's dotted rule — the hint that there is more */
  --row-hover:rgba(13,24,41,0.02);     /* a record row under the pointer */
  --clamp-rule:rgba(13,24,41,0.35);    /* the dotted rule that says a cell is holding more */
  --mk1-t:var(--navy-soft);       /* M1's text twin — a reference, so no second hex (Phase 1 deferred it here) */
  --tag-pad-tight:1px 6px;        /* a C-id compressed into a callout's eyebrow */
  --skel-lo:rgba(13,24,41,0.03);  /* the low end of a skeleton's 1.6s pulse; the high end is the neutral fill */
  /* ── the modal family — v2 board §7 (design system v2, Phase 4, session 75). One head, one
     close, one footer grammar, three widths, one behaviour at 390. Every value is the board's
     own literal and every one is px, so no hex ceiling moves. ── */
  --modal-w-sm:420px;             /* one question — update conviction, contact support */
  --modal-w-md:640px;             /* a form or a reading — the family's default */
  --modal-w-lg:680px;             /* carries a chart or a table — the signal detail */
  --modal-head-pad:20px 28px;     /* the flat navy head */
  --modal-body-pad:24px 28px;     /* the body, which is what scrolls */
  --modal-foot-pad:16px 28px;     /* and the footer, on its hairline */
  --modal-close-pull:-6px -8px 0 0;  /* ⚠ THE ✕ IS PULLED OUT OF THE HEAD'S OWN INSET so the
                                     32px hit square lands 20px from the card's right edge and
                                     centres on the title's first line. Written as a negative
                                     margin because the head is a flex row, not a positioned box:
                                     the old absolute placement could not know where the title is. */
  --modal-inset:12px;             /* at 390 the card is inset this far on every side */
  --modal-head-pad-sm:16px 20px;  /* and the three bands compress with it */
  --modal-body-pad-sm:20px;
  --modal-foot-pad-sm:12px 20px;
  --modal-close-pull-sm:-12px -16px 0 0;
  --opt-pad:14px 16px;            /* 15's option card — a pick control that is a whole sentence */
  --opt-pad-sm:12px 14px;
  --badge-pad-inline:2px 8px 2px 6px;  /* badge-mark INSIDE a sentence: tighter than its own box,
                                     because it sits between words rather than on a line of its own */
  --modal-stack:20px;             /* the space between a modal body's blocks — SIX of the ten screens
                                     draw exactly this, so it is the family's measure and not a
                                     one-off. It is not a step on the 4-48 scale and is not meant
                                     to be: a modal's body has its own rhythm, as its padding does. */
  --modal-stack-sm:16px;          /* and at 390, where the same six compress */
  --star-conv:32px;               /* 18's stars — the rating component in a modal, at the size the
                                     board draws it there; §5's own demo is --star-sz */
  --star-conv-sm:40px;            /* 40 at 390 puts a 44px hit under each one */
  /* s122 · THE LADDER — ORDER: how far a story has come, which plan. The brand's blue carried from a light cyan to a deep
     indigo, its lightness falling at every stop so it reads as an order (and survives red-green CVD). Five stops so Home's four
     bars are ONE gradient split four ways — his ask (12 Oct): "a gradient bar so all 4 bars have visible difference in colors".
     Never a state: green / amber / red stay the thesis's. --ladder-soft is a ground, --ladder-tint a chip's and a track's ground,
     --ladder-line a hairline. The board had no colour allowed to mean an order; his "make provision for it" (12 Oct) is this. */
  --ladder-0:#64CCE0;--ladder-1:#1DA9E0;--ladder-2:#1F7BDD;--ladder-3:#304DC9;--ladder-4:#3721A1;
  --ladder-soft:rgba(39,99,215,0.07);--ladder-tint:rgba(39,99,215,0.14);--ladder-line:rgba(39,99,215,0.35);
  /* s122 · Pro's chip: navy with gold — --gold-deep's hue lightened for a navy ground (gold is never a word on white, 3.15:1) */
  --gold-on-navy:#E6C068;
  /* s122 · a page body's side inset — the phone's is the head's 16 (the 768 block) */
  --pg-pad-x:var(--sp-6);
  --red-on-navy:rgba(211,91,106,0.22);    /* a red state pill ON the navy head — the soft tint is
                                     drawn for white and disappears there (Phase 1 deferred this
                                     to the phase that consumes it, and 07 is that phase) */
  --fs-title-sm:1.125rem;         /* 18px — the TITLE ROLE at 390, not an eleventh role: the
                                     board's own type table gives a role a second size at 390
                                     (section 24 → 20) and this is the modal title's. Phase 1
                                     deferred it to the phase that first consumes it. */
  /* ⚠ THE EXTRACTION REVIEW HAS NO SHADOW OF ITS OWN ANY MORE — HIS RULING, 13 SEP 2026.
     A shadow is optics, and optics are consistent. The token that held board 6e's own
     0 40px 80px for that one screen had no second reader, so it retires with the rule it fed,
     and the review takes --shadow-modal like the other ten.
     ⚠ ITS NAME IS DELIBERATELY NOT WRITTEN HERE. L47 forbids it BY STRING and the lint reads
     comments, so naming it to explain it is how a green build goes red for the right reason —
     which is exactly what happened on the first run of this edit.
     What the UX earned on that screen is the WIDTH, and --pr-w below keeps it untouched. */
  /* ── THE RECORD ROW (§2b.4). Board 5a's Docs, Buy/Sell journal and Organizer are one
     construct, not three lists: a key column, a body, and one violet action, on a 1px
     rule. These are its four measurements, and they are the same measurements in all
     four sub-sections — which is what makes them read as one Record. ── */
  --rec-row-y:14px;               /* a record row's vertical padding — 12px in the KPI table */
  --rec-k:110px;                  /* the date column: 11px mono has to hold "08 Aug 2026" */
  --rec-k-wide:120px;             /* the Organizer's key column — a word, not a date */
  --rec-sub-x:14px;               /* the section sub-line hangs under the name, past the dot */
  --wn-x:20px;                    /* What's next is inset less than a card — it is a band */
  --note-row-b:20px;              /* a note row's bottom — the board's, one notch under --sp-5 */
  --rec-tight:2px;                /* title→meta inside a record row: a hair, not a gap */
  /* ── BOARD 03: INSIDE THE RECORD EVERY SECTION IS A LEVEL-1 CARD (DESIGN rule 14, his
     review of 11 Sep: "Organizer looks bad; sections merge; use cards"). The three paddings
     are the board's own and they differ for a reason it draws: a card whose body is a list of
     rows is closed by the last row's own 14px, and one whose body is an empty state is not.
     ⚠ NOT ONE OF THESE NAMES MAY END IN THE WORD L14 READS AS A SPACING DECLARATION. */
  --rec-card-pad:16px 20px 4px;   /* a section card — Events, Questions */
  --rec-strip-pad:16px 20px;      /* the review strip: one line of content, no row list */
  --rec-card-pad-e:16px 20px 24px;/* a section whose body is an empty state, which closes nothing */
  --rec-empty-pad:20px 0 0;       /* and that empty state INSIDE a card: it draws no box of its own */
  --rec-empty-w:320px;            /* its one line — 60px wider than the standalone panel's 260 */
  --rec-strip-step:14px;          /* the strip's dot → its two lines */
  --rec-open-step:2px;            /* "Open ›" — the word to its chevron */
  --rec-res-pad:12px 0 14px;      /* the Resolved disclosure's own row, under the last question */
  --rec-head-pad:12px;            /* a section card's head to its first rule */
  --rec-act-step:20px;            /* a row's text actions at 390, where each is a 44px target */
  /* ── BOARD 22, the quarterly review panel. It is an INLINE level-1 card that takes the modal
     head — his call, 11 Sep: a section of The Record written against The Record fills the
     content column, so it reads as one bounded piece of work. Its head, close and 390
     behaviour are the modal family's tokens; only the body, its eyebrows and its own footer
     are measured here, because a modal's body padding is 24/28 and this one is 4/24/20. */
  --qtr-body-pad:4px 24px 20px;   /* the head supplies the top; the eyebrow supplies the rest */
  --qtr-body-pad-sm:0 16px 16px;
  --qtr-eb-m:24px 0 8px;          /* an eyebrow, and what it clears above and below itself */
  --qtr-eb-m-sm:20px 0 8px;
  --qtr-eb-top1:20px;             /* the FIRST one clears less: the head is already above it */
  --qtr-eb-top1-sm:16px;
  --qtr-kpi-pad:14px 16px;        /* a KPI's level-2 row */
  --qtr-kpi-pad-sm:12px 14px;
  --qtr-kpi-val-w:160px;          /* and the value column beside its name */
  /* ⚠ UX-65 · THE PERIOD PICKER (closed 13 Sep 2026, v3). His ruling: "Keep this consistent
     with the KPI Log reading modal fields. There we have a picker not a selection. Keep it
     exactly like that." So it is the board's `select` in mono at field-sm's size, in a column
     of its own BETWEEN the name and the value, and the row reads name → period → reading →
     verdict with the two fields lined up. It offers the list the Log reading modal offers and
     assumes nothing of its own. */
  --qtr-kpi-per-w:150px;
  --qtr-dec-gap:var(--sp-6);      /* DECISION and CONVICTION, side by side (board 22, 13 Sep) */
  --qtr-dec-mt:var(--sp-5);
  --qtr-stars-h:36px;             /* the stars' row, so the two eyebrow columns share a baseline */
  /* ── UX-56 · THE CLAIMS BLOCK, authorised by him 14 Sep 2026. It replaces the panel's two
     flag rows: a claim's "Breaks if" IS the red flag, written against the bet it belongs to
     rather than against the thesis in general, so asking both was asking twice. */
  --qtr-clm-pad:14px 16px 14px 0; /* the rail sits flush left, so the row pads three sides */
  --qtr-clm-pad-sm:12px 14px 12px 0;
  --qtr-clm-gap:var(--sp-4);      /* the rail to the body */
  --qtr-clm-cond-mt:10px;         /* the statement line to its two conditions */
  --qtr-clm-chips-mt:var(--sp-3); /* and the conditions to the verdict */
  /* ── BOARD 04, the KPI cards. Two columns at the desk, one on a phone, and inside each card
     the board's own steps. The chart, its series and the card's structure are KEPT. */
  --sig-step:14px;                /* the card's inner step: chart -> figures -> the button row */
  --sig-legend-step:14px;         /* and the space between two legend entries */
  --sig-dot:8px;                  /* a legend dot */
  --sig-btn-h:32px;               /* Log reading is the card's lead action, at the icon size */
  --sig-btn-h-sm:44px;
  --sig-btn-pad:7px 16px;         /* …and it pads to that height rather than assuming it */
  --sig-btn-pad-sm:0 16px;
  --sig-eb-top:20px;              /* the milestone card's one eyebrow, clearing its head */
  /* ── BOARD 05, the inline New-signal tile. It is a level-1 card like every other inline form
     (the inline-vs-modal rule: the new card appears where the tile is). */
  --sig-tile-pad:24px;            /* the tile's own padding */
  --sig-tile-pad-sm:16px;
  --sig-kind-pad:16px 18px;       /* a kind card — Metric or Milestone */
  --sig-kind-pad-sm:14px 16px;
  --qtr-kpi-step:10px;            /* at 390 the row stacks: its name -> its value field */
  --rec-evt-step:10px;            /* an event row: its dot -> its text -> its pill */
  --rec-kic-top:3px;              /* a key whose glyph is 16px sits 1px higher than one that is 11px text */
  --nvrev-k:96px;                 /* session 87 · the key column of a verdict note's review rows */
  /* ── BOARD 08, the Buy/Sell journal. Two stat strips that read as ONE hairline grid, an
     action strip on the shell ground, and a table on bare hairlines. */
  /* ⚠ minmax(0,1fr), NOT 1fr. A bare 1fr is minmax(AUTO,1fr), so any cell whose label or
     figure runs long would widen its own track, and the board draws five EQUAL ones. The
     floor of 0 is what makes them equal. */
  --jr-stat-cols:repeat(5,minmax(0,1fr));   /* the first strip: Holding … XIRR */
  --jr-stat-cols-b:repeat(4,minmax(0,1fr)); /* the second: Unrealised … CMP */
  --jr-stat-cols-sm:repeat(2,minmax(0,1fr));/* and both of them, folded, at 390 */
  --jr-cell-pad:16px 18px;        /* a stat cell */
  --jr-cell-pad-sm:14px 16px;
  /* ── figure-md · THE STAT CELL'S NUMBER, named 14 Sep 2026 (v3 §10 row 7). The drawings
     had it at 24 (22 at 390) all along and the prose said 28; the prose was wrong. It is a
     ROLE, not a one-off: 08's stat grid and the Organizer's health cells are its consumers.
     ⚠ --fs-figure-lg (28) is a DIFFERENT role and keeps its two: the KPI card's value and
     the milestone's quarter. Naming one did not move the other. */
  --fs-figure-md:var(--fs-section);   /* 24px */
  --fs-figure-md-sm:22px;
  --jr-fig:var(--fs-figure-md);   /* its figure — the role, not a literal */
  --jr-fig-sm:var(--fs-figure-md-sm);
  --jr-fig-mt:var(--sp-2);        /* …and the step down from its label */
  --jr-fig-mt-sm:var(--chip-gap);
  --jr-lbl-fs:var(--fs-caption);  /* the label itself */
  --jr-lbl-fs-sm:var(--fs-label);
  --jr-sub-mt:var(--chip-gap);    /* the cells that carry a sub-line */
  --jr-sub-mt-sm:var(--sp-1);
  --jr-eb-m:28px 0 12px;          /* "Transaction log", and what it clears above and below */
  --jr-eb-m-sm:24px 0 10px;
  --jr-strip-pad:16px 20px 18px;  /* the log-a-trade strip */
  --jr-strip-pad-sm:14px;
  --jr-strip-mb:20px;             /* …and its clear of the log underneath */
  --jr-cols:150px 110px 90px 110px 110px 1fr auto;  /* date type qty price amount notes add */
  --jr-cols-sm:1fr 1fr;
  --jr-fld-pad:var(--fld-pad-sm); /* its fields ARE field-sm (v3 components §5) — 8px 12px.
                                     v2 drew a compact field at three paddings across three
                                     screens and this was the 8px 10px one; there is one now. */
  --jr-add-pad:9px 16px;          /* and its one green fill */
  --jr-add-pad-sm:12px 18px;
  --jr-side-pad:2px var(--sp-2);  /* a trade's side, as a neutral mono tag */
  --jr-th-pad:10px 6px;           /* the log's header row: half the board's 12 gap each side */
  --jr-th-pad-sm:8px 5px;
  --jr-td-pad:12px 6px;           /* and a trade */
  --jr-td-pad-sm:12px 5px;
  --jr-row-x:16px;                /* …with the board's own inset at the two outer edges */
  --jr-row-x-sm:4px;
  --jr-del:32px;                  /* the row's delete target */
  --chain-max:320px;              /* the thought-chain island's list scrolls past this (his ask) */
  --rec-col-w:168px;              /* the sections column — the Record grid and the composer agree on it. 280 → 168, his call 22 Sep (finding 16): "it has lots of space and it's cramping the main page" */
  /* ── THE COMPOSER · ONE OBJECT IN THREE HEIGHTS (v3 boards 11 and 12, 13-14 Sep 2026).
     ⚠ THE WIDTH IS A RULE, NOT A LITERAL — his ruling, 14 Sep. The board draws 1044 and calls
     it 'the content column'; it gets 1044 by padding a 1220 content area 88 each side over a
     page that has no sections column. THIS page has one, so the content column here is 844,
     and the composer is the content column's width. The dock is what enforces it: it spans
     the content area and pads right by the sections column and its gap, so the card lands on
     the column it writes into at ANY viewport, never on a number that is true at 1440 only.
     16 above the card and 24 below it are the board's, and they are the dock's own padding. */
  --spc-dock-pad:var(--sp-4) calc(var(--rec-col-w) + var(--sp-6) + var(--sp-6)) var(--sp-5) var(--sp-6);
  --spc-dock-pad-sm:var(--modal-inset);      /* 390: inset 12, the modal family's own number */
  /* ⚠ THE DOCK IS TRANSPARENT — his comment, 14 Sep: the solid shell band was too heavy. What
     makes the bar readable over whatever scrolls beneath is a navy halo behind the card, not a
     fill and not a hairline. The page stays visible through it. */
  --spc-halo:radial-gradient(ellipse 60% 150% at 50% 100%,rgba(13,24,41,0.18) 0%,rgba(13,24,41,0.08) 55%,rgba(13,24,41,0) 100%);
  --spc-halo-sm:radial-gradient(ellipse 80% 150% at 50% 100%,rgba(13,24,41,0.18) 0%,rgba(13,24,41,0.08) 55%,rgba(13,24,41,0) 100%);
  --spc-rowa-h:44px;              /* Row A — the whole composer at rest, and its head when open */
  --spc-rowa-pad:0 12px 0 20px;
  --spc-rowa-pad-sm:0 0 0 16px;
  --spc-rowa-gap:10px;
  --spc-rowa-gap-sm:var(--sp-2);
  --spc-tb-pad:6px 12px;          /* Row B — the FULL toolbar in active as well as expanded */
  --spc-tb-pad-sm:4px 6px;
  --spc-tb-hit:28px;
  --spc-tb-hit-sm:36px;           /* …and the board states this one on its face */
  --spc-body-pad:16px 20px 0;
  --spc-body-pad-sm:16px 16px 0;
  --spc-body-gap:var(--sp-4);
  --spc-body-gap-sm:var(--sp-3);
  --spc-foot-pad:12px 20px 14px;
  --spc-foot-pad-sm:8px 12px 10px 16px;
  --spc-ed-min:96px;              /* active … */
  --spc-ed-min-x:280px;           /* … expanded, then it scrolls */
  --spc-ed-max:60vh;
  --spc-ed-min-sm:72px;
  --spc-ed-min-x-sm:150px;
  --cbx-tick:9px 5px;             /* the checkbox's tick, drawn from two borders so no hex lands */
  --composer-clear:88px;          /* the COLLAPSED footprint — 44 + 16 + 24. The Record's last
                                     row must clear it, every section, not only Notes. */
  --tx-min:560px;                 /* the trade log's narrowest honest width before it scrolls */
  /* ── the extraction review (SPEC §7 / §8, board 6e/6f). Its own measurements, named. ── */
  --pr-w:1100px;                  /* the modal — wide enough to read a note BESIDE the claims */
  --qr-w:860px;                   /* session 87 · the review as a modal: four KPI columns need the content column's width, not the family's 680 (written exception, design/v2_for_claude_design_next.md) */
  --tbi-ctl-w:200px;              /* session 90 · the import's broker and header-row selects, and the status line's floor */
  --tbi-col-w:172px;              /* …a mapping dropdown over a file column: wide enough for its longest label ("Trade or order ID", "Trade value (total)") — 140 clipped it (his Chrome test, 23 Sep; measured in Chromium, session 91) */
  --pr-cell-min:104px;            /* session 91 · a table cell in the claim review's 400px note pane: never narrower than this, so a word is never broken — the table scrolls instead (his delegated call) */
  --tbi-cell-max:200px;           /* …and a sample cell, clipped with an ellipsis past it */
  --nv-w:calc(100vw - 220px - 3 * var(--sp-6) - var(--rec-col-w));   /* session 89 · finding 1: the READ-NOTE modal is as wide as the composer it was written in — #sp-composer's left (220) plus its dock padding (sp-6 · rec-col-w + 2·sp-6). A written width exception, same reason as --qr-w: "so that the formatting stays consistent" */
  --pr-note-w:400px;              /* the note pane; the proposals take the rest */
  --pr-y:20px;                    /* the modal's own vertical inset */
  --pr-x:28px;                    /* and its horizontal one */
  --pr-note-x:24px;               /* the note pane is inset less — it is a reading column */
  --pr-card-x:16px;               /* a proposal card */
  --pr-tick:18px;                 /* the checkbox (22 at 390 — a 44px hit target's inner mark) */
  --pr-tick-390:22px;
  --pr-fade:44px;                 /* the "there is more note below" gradient */
  --pr-note-b:40px;               /* and the clearance the note keeps under it */
  /* ⚠ NEITHER OF THESE MAY BE NAMED *-gap. L14's regex reads a custom property whose name
     ends in that word as a spacing DECLARATION, so the name alone spends one of the file's
     spacing literals — the trap the token spec warns about beside --pill-chev, walked into
     anyway. ⚠ AND THE LINT READS COMMENTS: the first draft of THIS comment spelt the word
     out with its colon and tripped L14 by itself, across four lines of prose. */
  --pr-lane:14px;                 /* between cards, and between a card's tick and its body */
  --pr-cond-x:20px;               /* between Breaks if and Fulfilled if */
  --pr-note-390:130px;            /* at 390 the note is a box above the claims, not a column */
  /* ── the three sticky layers (§2b.3). Siblings, never nested: a sticky inside a
     sticky resolves against the wrong containing block, which is why .stock-sticky
     exists at all. Layer 1 is the slim head at top:0; these are layers 2 and 3. ── */
  --head-h:60px;                  /* the slim head: its height AND its overlay pull-back */
  --acc-h:40px;                   /* the claims strip's collapsed row AND its overlay pull-back */
  --head-bot:60px;                /* where the claims accordion sticks — the head's MEASURED bottom */
  --acc-k:96px;                   /* the strip's state column (SPEC §1.3's 96) */
  --acc-cid:28px;                 /* and its C-id column */
  --acc-rule:3px;                 /* the marker rule that opens each expanded row */
  --rec-top:60px;                 /* the slim head + the strip — MEASURED at runtime, never assumed */
  --rec-col-top:120px;            /* the head plus the Record title bar */
  /* ── type — two families, eight roles. The floor is 10px: nothing renders smaller. ── */
  --font-ui:'Inter',sans-serif;--font-mono:'JetBrains Mono',monospace;
  --fs-micro:0.625rem;--fs-label:0.6875rem;--fs-caption:0.75rem;--fs-small:0.8125rem;
  --fs-body:0.875rem;--fs-pane:0.9375rem;--fs-lead:1rem;--fs-title:1.25rem;--fs-section:1.5rem;--fs-display:1.75rem;
  /* ── z — six layers ── */
  --z-raised:10;--z-sticky:100;--z-nav:200;--z-popover:300;--z-modal:400;--z-top:500;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* The form reset the file never had (UX-23): a button inherits the page's type instead of
   the UA's Arial. Only what was hand-patched in seven places, applied once. */
button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
body{font-family:var(--font-ui);background:var(--bg);background-attachment:fixed;color:var(--text);line-height:1.6;font-size:var(--fs-body)}
.app{display:flex;min-height:100vh}

/* SIDEBAR */
/* UX-42 (Phase 3, session 62) — THE LIGHT SHELL. §2a.3: a colour that is a surface cannot also
   be an action, and a navy sidebar over a navy-topped header made the whole top of the page one
   dark mass. The sidebar is a near-white plane with a hairline; the active item is --action text
   at weight 600 with NO fill (§2a.3's end state, and Doppler's product ships exactly that).
   ⚠ SESSION 109 — HIS RULING OF 3 OCT REVERSES PLAN §0 #7: THE WORDMARK'S NAVY PLATE IS GONE ("it was stealing too
   much attention"). The mark sits on the shell — "stock" in navy, "port" in --brand-mark. --brand-mark is 2.19:1 on a
   light ground and that is accepted for the LOGO only; it is still never a UI colour and never text. */
.sidebar{width:220px;min-width:220px;background:var(--shell);border-right:1px solid var(--line);display:flex;flex-direction:column;position:fixed;top:0;left:0;bottom:0;z-index:var(--z-nav);overflow-y:auto}
/* UX-17 (session 58): at 1440×756 the flex column squeezed the footer — the name label to 5px. Nothing
   in the shell shrinks; the positions list is the one scrolling region, so the footer stays put. */
.sidebar>*{flex-shrink:0}
#sb-stocks{flex:0 1 auto;min-height:72px;max-height:var(--sb-list-max);overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
.sb-logo{padding:var(--sb-logo-pad);position:relative}
/* hidden at 1440 — there is no drawer to close there */
.sb-close{display:none;position:absolute;top:0;right:0;width:44px;height:44px;border:none;background:none;color:var(--text-muted);cursor:pointer;padding:0}
.sb-logo .brand{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);color:var(--navy)}
.sb-logo .brand span{color:var(--brand-mark)}
.sb-logo .tagline{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);text-transform:uppercase;letter-spacing:0.1em;margin-top:var(--sp-1)}
.nav-item{display:flex;align-items:center;gap:var(--nav-step);min-height:var(--nav-h);padding:var(--nav-pad);margin:var(--nav-m);border-radius:var(--radius-xs);font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--text-soft);cursor:pointer;border:none;background:none;width:calc(100% - 16px);text-align:left;transition:all 0.15s}
.nav-item:hover{background:var(--surface-tint);color:var(--text)}
/* the row's glyph — muted at rest, the row's green when it is the page you are on */
.nav-item > .ic{width:var(--icon-glyph);height:var(--icon-glyph);color:var(--text-muted)}
.nav-item.active > .ic{color:var(--action)}
/* ⚠ THE ACTIVE ITEM CARRIES A --green-soft FILL AGAIN — IA §2b.2 #1, HIS CALL (design turn 4,
   the MongoDB pattern). This REVERSES session 62's no-fill rule, which was §2a.3's end state and
   is amended by the IA. It is deliberate, not a regression: at 220px with eight items the text
   colour alone was not locating the page firmly enough once the ground went light. §2a.6 said
   selection is geometry not hue — that clause now reads "except the nav, where the fill IS the
   geometry". The Record's sections column uses the identical treatment. */
.nav-item.active{background:var(--green-soft);color:var(--action);font-weight:600}
.nav-dot{width:6px;height:6px;border-radius:50%;background:var(--line-strong);flex-shrink:0}
.nav-item.active .nav-dot{background:var(--action)}
/* STORY STATUS ON A POSITION ROW — IA SPEC-shell §5. The dot stops being decoration and starts
   carrying the holding's story status, so the sidebar answers "what needs me" before you click.
   ⚠ Read from getLatestVerdict(id).thesisIntact, which ALREADY normalises yes/intact → intact,
   watch → watch, no/broken → broken — the design's exact vocabulary, so nothing is re-derived.
   ⚠ These beat .nav-item.active .nav-dot on purpose: an active position still reports its status.
   Never colour alone — the row's own label and the legend below carry the words. */
.nav-item .nav-dot.st-intact{background:var(--green)}
.nav-item .nav-dot.st-watch{background:var(--amber)}
.nav-item .nav-dot.st-broken{background:var(--red)}
/* ⚠ THE LEGEND STRIP IS GONE — his comment, 3 Oct. The words that made the dots accessible now live on the dot itself:
   every status dot is role="img" with aria-label "Thesis state: …" (renderSidebar). Do not drop that label. */
/* ── POSITIONS — a group. The header folds the list; the rows sit in under its word. ── */
.sb-pos-hd{margin-top:var(--sp-3)}
.sb-pos-hd .tag-mono:empty{display:none}
/* ⚠ the chevron sits in a span, not bare: a button that opens AND closes on a glyph reads as icon-only to L52b's probe */
.sb-pos-chev{margin-left:auto;display:inline-flex;color:var(--text-muted);transition:transform .15s}
.sb-pos-chev > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.sb-pos-hd[aria-expanded="false"] .sb-pos-chev{transform:rotate(-90deg)}
#sb-stocks .nav-item{padding-left:var(--nav-indent);gap:var(--sp-2)}
.sb-empty{margin:var(--nav-m);padding:var(--sp-2) var(--sp-2) var(--sp-2) var(--nav-indent);font-size:var(--fs-caption);color:var(--text-muted)}
/* .nav-add is the sidebar's own decision surface, so it may carry the green fill without
   competing with the page's primary — §2a.1's ration is per surface (his ruling, plan §0 #2) */
.nav-add{margin:var(--sp-3) var(--sp-2) var(--sp-3);display:flex;align-items:center;justify-content:center;gap:var(--chip-gap);min-height:var(--nav-h);padding:0 var(--sp-3);border-radius:var(--radius-xs);border:1px solid var(--action);font-family:var(--font-ui);font-size:var(--fs-small);font-weight:600;color:var(--on-action);cursor:pointer;background:var(--action);width:calc(100% - 16px);transition:all 0.15s}
.nav-add:hover{border-color:var(--action-hover);background:var(--action-hover);color:var(--on-action)}
.nav-stock-warn{color:var(--amber-strong) !important}
.nav-stock-warn .nav-dot{background:var(--amber) !important}
/* the sidebar footer's two text buttons — was eight rgba(255,255,255,α) literals in four
   inline handlers; one class and a :hover instead */
.sb-nudge{min-height:var(--sp-6);margin:var(--sp-1) var(--sp-2) 0 var(--nav-indent);padding:0 var(--nav-step);gap:var(--sp-2);font-size:var(--fs-caption);font-weight:500;color:var(--amber-strong)}
.sb-nudge > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm);margin-left:auto}
.sb-nudge:hover{outline:1px solid var(--amber);outline-offset:-1px}
.nav-add > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
/* ── THE ACCOUNT ROW AND ITS MENU — the footer's three things (the name, the sync line, Sign out / Contact support) in
   one row and a menu that opens above it. The menu's rows ARE nav rows. ── */
.sb-acct-wrap{position:relative;border-top:1px solid var(--line);padding:var(--sp-2) 0}
.sb-acct{min-height:var(--sb-acct-h)}
.sb-acct > .ic{margin-left:auto}
.sb-acct-tx{display:flex;flex-direction:column;min-width:0;flex:1;line-height:1.3}
.sb-acct-nm{font-size:var(--fs-small);font-weight:600;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-menu{position:absolute;left:var(--sp-2);right:var(--sp-2);bottom:100%;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-xs);box-shadow:var(--shadow-pop);padding:var(--sp-1) 0;z-index:var(--z-popover)}
.sb-menu-id{display:flex;align-items:center;gap:var(--nav-step);padding:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-1);border-bottom:1px solid var(--line)}
.sb-menu-mail{font-size:var(--fs-caption);color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-menu .nav-item{margin:0 var(--sp-1);width:calc(100% - var(--sp-2))}
/* "synced HH:MM" — IA SPEC-shell §5. ⚠ NOTHING TRACKED A LAST-SYNC TIME before this: the only
   signal was #saveIndicator flashing "Saved" for 1.8s and vanishing, which tells you a write
   happened only if you were looking. The stamp is set where that flash already fires, so it
   reports the same event and cannot claim a sync that did not occur. Empty until the first
   write of the session — an unknown time renders as nothing, never as a guess. */
.sb-synced{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:400;color:var(--text-muted);letter-spacing:0.04em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-synced:empty{display:none}

/* MAIN */
/* ⚠ min-width:0 IS THE WIDTH BOUND FOR EVERY PAGE (session 68). .main is a flex item, and a
   flex item's min-width is `auto` = its min-content width — so ONE nowrap statement anywhere
   inside it sized the whole column: a collapsed claim card measured .main at 3227px and the
   page scrolled 2007px sideways at 1440. Every downstream min-width:0 (.clm-headmain, .rec-b,
   the 768px `.page *` rule) was a patch on a symptom; this is the class. Board 5a's <main> is
   1219px and nothing inside it can widen it. */
/* ⚠ SESSION 109 · THE GROUND IS THE SHELL, AND NOTHING CHANGES LEVEL. What draws a closed box is white inside (--surface);
   what is drawn on the ground stays on the ground and gets no box — the notes, the Ledger's rows, the journal's log.
   A band that must hide what scrolls under it paints --shell, never --surface. --bg is the window (sign-in, onboarding). */
.main{margin-left:220px;flex:1;min-width:0;min-height:100vh;background:var(--shell)}
/* THE PAGE HEAD — IA §2b.2 #6 (Phase 3, session 63). The navy top rule is GONE: with a light
   shell it was the last piece of navy furniture, and §2a.3 wants navy punctuating, not framing.
   60px, title and its count on ONE baseline row, a Help action at the right, no search and no
   breadcrumb. ⚠ min-height, not height: three pages still carry a prose subtitle rather than a
   count (Performance, Ledger, Import), and those wrap to a second line instead of being clipped.
   Their copy is a content question for the session that redesigns them. */
.page-header{background:var(--shell);border-bottom:1px solid transparent;min-height:60px;padding:var(--sp-3) var(--sp-6);display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);position:sticky;top:0;z-index:var(--z-sticky)}
/* the line arrives when the page has scrolled under the head (_pageHeadSync) — never before, and never on a phone, where the head is not sticky */
.main.scrolled .page-header{border-bottom-color:var(--line)}
.page-header>div:first-child{display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap;min-width:0}
.page-title{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);color:var(--navy)}
.page-subtitle{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted)}
/* session 107 · his ruling: the sub-line is mono for a count and Inter when it holds words (Performance, the Ledger, the Coach inbox) */
.page-subtitle-words{font-family:var(--font-ui);font-size:var(--fs-small)}
/* ── THE PAGE HEADING (.lg-head) — session 110 built it for the Ledger, session 117 gave it to every page of the sidebar
   (his finding, 7 Oct: the headings "much larger, accompanied with an icon … the text accompanying it is non-readable").
   The title row (plate · title · count) takes the whole line, so a sentence sits under it (the count drops under the title,
   flush left, where the row is too narrow for both); the page's actions line up with the title row (u-as-flex-start in the
   markup). The title is the display size — a page's name out-ranks the 24px section headings inside a story; a count is
   13px mono and a sentence 14px Inter, in the soft text colour (they were 11px in the muted grey).
   ⚠ Scoped to .lg-head ON PURPOSE: the stock page's slim head and the Flying Blind page's title are a STOCK's name, not a
   page heading (his words: "except the stock page heading"), and they keep .page-title's own size. */
.lg-head{row-gap:var(--sp-2)}
.lg-head > .sec-hd{flex:0 0 100%}
.lg-title{display:flex;align-items:baseline;flex-wrap:wrap;gap:var(--sp-1) var(--sp-3);min-width:0}
.lg-head .page-title{font-size:var(--pg-title);line-height:1.15}
.lg-head .sec-plate{width:var(--pg-plate);height:var(--pg-plate)}
.lg-head .sec-plate > .ic{width:var(--pg-glyph);height:var(--pg-glyph)}
.lg-head .page-subtitle{font-size:var(--fs-small);color:var(--text-soft)}
.lg-head .page-subtitle-words{font-size:var(--fs-body)}
/* ⚠ Tertiary tier, and it stays --navy-soft for now ON PURPOSE. §2b.2 #5 moves every tertiary
   action to --accent violet, but that migration is one sweep in the claim-card step — landing a
   single violet Help here would put one violet word among forty navy ones for two steps. */
.page-help{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--accent);background:none;border:none;cursor:pointer;padding:0;white-space:nowrap}
.page-help:hover{text-decoration:underline;color:var(--accent-hover)}
.page{display:none;padding:1.75rem 2rem}
.page.active{display:block;animation:fadeIn 0.2s ease}
@keyframes fadeIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}

/* ⚠ .verdict-banner AND EVERY .vb-* RULE ARE DELETED HERE (Phase 3, step 4, session 64).
   They had been dead since slice 6 — the verdict moved to the header strip — and the
   comment further down this stylesheet claimed they had to stay "because .vb-mono /
   .vb-sub are shared". THEY WERE NOT SHARED: a whole-file grep for vb-mono, vb-sub and
   vb-headline found the stylesheet and nothing else, zero markup consumers. That comment
   is the reason 15 dead rules survived three sessions, which is the lesson: a claim that
   something is load-bearing is worth exactly as much as the grep that backs it.
   The verdict's surface is now the hero island (_heroVerdictIslandHtml). */
.thesis-lock-pill{font-family:var(--font-mono);font-size:var(--fs-label);background:var(--navy);color:rgba(255,255,255,0.85);padding:6px 14px;border-radius:var(--radius-2xs);white-space:nowrap;align-self:flex-start}

/* DECISION TAX */
.decision-tax{display:flex;align-items:center;gap:10px;padding:0.9rem 1.2rem;background:var(--red-soft);border:1px solid var(--red-strong);border-left:4px solid var(--red-strong);border-radius:var(--radius-xs);margin-bottom:1.25rem}
.dt-count{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-display);color:var(--red-strong);line-height:1}
.dt-body{flex:1}
.dt-label{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;color:var(--red-strong);text-transform:uppercase;letter-spacing:0.06em}
.dt-sub{font-size:var(--fs-small);color:var(--red-strong);opacity:0.8;margin-top:2px}

/* LABEL */
.label,.lbl{font-family:var(--font-mono);font-size:var(--fs-caption);text-transform:uppercase;letter-spacing:2px;color:var(--eyebrow);font-weight:600;display:block;margin-bottom:0.75rem}

/* CARDS */
.card{background:var(--surface-raised);border:1px solid var(--line);border-radius:var(--radius-sm);padding:var(--sp-5);margin-bottom:1.25rem}
.card-title{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted);margin-bottom:1.1rem}
.card-title::before{content:"\258C ";color:var(--eyebrow)}

/* BUTTONS — the v2 ladder (board §1; rebuilt in session 73 from the board's own literals). ONE
   size: 600 13px Inter at line-height normal, radius 10, no shadow, one label line. A fill pads
   --btn-pad and a 1.5px hairline pads --btn-pad-line, so the border makes up the difference.
   ⚠ THE SMALL SIZE IS GONE — the board draws one size. Its class is still written on buttons
   across the app and is now inert; the Phase 2 sweep dropped it wherever it touched markup. */
.btn{font-family:var(--font-ui);font-weight:600;padding:var(--btn-pad);border-radius:var(--radius-xs);border:none;cursor:pointer;transition:all 0.2s;font-size:var(--fs-small);line-height:normal;white-space:nowrap;display:inline-block}
/* a box button carries its Lucide symbol at 14px BEFORE the word (board §3, "icons inside
   buttons"), laid out as the board lays it — inline-flex, centred, the chip's glyph-to-word step */
.btn:has(> .ic){display:inline-flex;align-items:center;justify-content:center;gap:var(--chip-gap)}
.btn > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
/* THE LADDER (spec §2a.5 → v2 board §1): fill vs outline is the hierarchy, not hue. Tier 1 is the
   one filled green per decision surface — no coloured shadow (§2a.8) and no lift: the board draws
   its hover as the darker fill and nothing else. The hairline is the workaday tier (Cancel,
   Close, Edit settings). The green hairline is the board's button-outline-action; the app has
   always called it .btn-secondary.paired, and the two names are one selector list so no reader
   moved. It sits ONLY beside a primary, or leads a card where a fill would shout. */
.btn-primary{background:var(--action);color:var(--on-action)}.btn-primary:hover{background:var(--action-hover)}
.btn-outline-action,.btn-secondary{background:transparent;color:var(--text-soft);border:1.5px solid var(--line-strong)}.btn-secondary:hover{border-color:var(--navy-soft);color:var(--navy)}
.btn-outline-action,.btn-secondary.paired{border-color:var(--green-deep);color:var(--green-deep)}.btn-outline-action:hover,.btn-secondary.paired:hover{border-color:var(--action-hover);color:var(--action-hover);background:var(--green-soft)}
.btn-secondary,.btn-outline-action,.btn-danger-outline{padding:var(--btn-pad-line)}
/* button-neutral — THE BOX: the action of a header, a card head or a strip (his ask, 11 Sep).
   Grey fill, navy word, its Lucide symbol when one exists. Never the surface's primary. */
.btn-neutral{background:var(--neutral-fill);color:var(--navy);padding:var(--btn-pad-neutral);display:inline-flex;align-items:center;justify-content:center;gap:var(--chip-gap)}
.btn-neutral:hover{background:var(--neutral-fill-hover)}
/* button-primary-on-dark — the fill flips to the light green with a navy word, ONLY on navy
   chrome. Built and not placed: which surface wears it is his question (Phase 2 run log). */
.btn-primary-on-dark{background:var(--action-on-dark);color:var(--navy)}
/* button-danger-outline — the in-place destructive when its neighbours are buttons (the note
   view's footer). Beside text controls the destructive stays red text; the red fill is the
   confirmation dialog's (see the destructive button, further down). */
.btn-danger-outline{background:transparent;color:var(--red-strong);border:1.5px solid var(--red-strong)}
.btn:disabled,.btn:disabled:hover{opacity:0.4;cursor:not-allowed;transform:none;box-shadow:none}
/* ⚠ THE GOLD BUTTON IS RETIRED — UX-44 closed on his decision, 11 Sep 2026 (v2 DESIGN.md rule 10).
   It sat off the ladder with zero markup sites while its meaning was his to decide; the answer
   is that there is no gold action. The lint (L25) pins the class name's absence from the WHOLE
   file, comments included, which is why this note describes the class without spelling it. */
/* .btn-done — demoted (§2a.6): it was a button in the state pill's clothes (--green-soft fill,
   --green border, --green-strong text). Zero markup sites; it now IS tier 2b so any future
   "done" button lands on the ladder. */
.btn-done{background:transparent;color:var(--text-soft);border:1.5px solid var(--line-strong)}.btn-done:hover{border-color:var(--navy-soft);color:var(--navy)}
.btn-snooze{background:var(--surface-tint);color:var(--text-muted);border:1px solid var(--line)}

/* TAGS */
.tag{display:inline-block;font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;padding:2px 8px;border-radius:var(--radius-2xs);letter-spacing:0.03em}
.tag.green{background:var(--green-soft);color:var(--green-strong)}
.tag.amber{background:var(--amber-soft);color:var(--amber-strong)}
.tag.red{background:var(--red-soft);color:var(--red-strong)}
.tag.navy{background:var(--navy-tint);color:var(--navy-soft)}
.tag.grey{background:var(--surface-tint);color:var(--text-soft)}
.tag.gold{background:var(--amber-soft);color:var(--amber-strong)}

/* METRICS */
.metric-row{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-4);margin-bottom:1.5rem}
.metric-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);padding:1.2rem 1.3rem;border-left:3px solid var(--line)}
.metric-card.pos{border-left-color:var(--green)}
.metric-card.neg{border-left-color:var(--red-strong)}
.metric-card.gold{border-left-color:var(--amber)}
.m-label{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:600;text-transform:uppercase;letter-spacing:0.07em;color:var(--text-muted);margin-bottom:6px}
.m-value{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-display);color:var(--navy);line-height:1}
.m-value.pos{color:var(--green-strong)}.m-value.neg{color:var(--red-strong)}
.m-sub{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:4px}

/* REGISTER TABLE */
.reg-wrap{overflow-x:auto}
.reg-table{width:100%;border-collapse:collapse;min-width:860px;font-size:var(--fs-small)}
.reg-table th{text-align:left;padding:var(--sp-2) var(--sp-3);font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;text-transform:uppercase;letter-spacing:0.07em;color:var(--text-muted);background:var(--surface-tint);border-bottom:2px solid var(--line)}
.reg-table td{padding:var(--sp-3) var(--sp-3);border-bottom:1px solid var(--surface-tint);vertical-align:middle}
.reg-table tr.sh td{background:var(--surface-tint);font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted);padding:6px 12px}
.reg-table tr.clickable:hover td{background:var(--navy-tint);cursor:pointer}
.s-name{font-weight:700;color:var(--navy)}
.s-meta{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:2px}
.mono{font-family:var(--font-mono);font-size:var(--fs-small)}
.pos-val{color:var(--green-strong);font-weight:600}
.neg-val{color:var(--red-strong);font-weight:600}

/* COMPLETION CHIPS */
.comp-set{display:flex;gap:var(--sp-1)}
.cc{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;padding:2px 6px;border-radius:var(--radius-2xs);text-transform:uppercase;letter-spacing:0.04em}
.cc.done{background:var(--green-soft);color:var(--green-strong)}
.cc.pend{background:var(--surface-tint);color:var(--line-strong)}
.cc.na{color:var(--line-strong);font-size:var(--fs-micro)}

/* COCKPIT */
/* ⚠ .cockpit-card DELETED (step 4, session 64) — provably dead: the string "cockpit-card"
   occurred exactly ONCE in the whole file, in its own rule, with no dynamic construction
   anywhere ("cockpit-" is never concatenated). Deleted to PAY for the two box rules the
   hero legitimately adds, because §2b.6 allows Phase 3 exactly two ceiling raises and both
   are hex. A ceiling is kept by removing boxes, not by asking for more.
   ⚠ Three more of the same kind are proven and NOT deleted here — .exp-card, .xirr-stat
   and .orig-box, each occurring once. They belong to UX-40's box cull, which is a register
   row with its own reasoning, not something to smuggle into a hero PR. */
.cockpit-header{background:var(--navy);color:var(--on-brand);padding:var(--sp-4) var(--sp-5);display:flex;justify-content:space-between;align-items:center}
.cockpit-header span{font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:1px}
/* ⚠ .stock-tabs / .stock-tab AND THE 390 OVERFLOW RULES WENT WITH THE TAB BAR (step 6).
   Greppped first: the bar was their only consumer file-wide, and the markup that held it
   is gone. A stylesheet that keeps rules for a retired control is how a comment claiming
   something is load-bearing survives three sessions past the truth. */
.tab-pane{display:none;padding:var(--sp-5)}.tab-pane.active{display:block}

/* POSITION STRIP */
/* ⚠ .pos-strip DELETED (step 4, session 64) — same evidence as .cockpit-card above: one
   occurrence in the whole file, its own rule, no dynamic construction. Its .ps-cell child
   is left alone; whether that is dead too is UX-40's question, not this step's. */
.ps-cell{flex:1;padding:var(--sp-2) var(--sp-3);border-right:1px solid var(--line);background:var(--surface-sunken)}
.ps-cell:last-child{border-right:none}
.ps-label{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);margin-bottom:3px}
.ps-val{font-family:var(--font-mono);font-size:var(--fs-body);font-weight:700;color:var(--navy)}
.ps-val.pos{color:var(--green-strong)}.ps-val.neg{color:var(--red-strong)}

/* THESIS GRID — .thesis-grid removed in session 44. The hero tab is one full-width column
   now: claims, then the notes timeline. Its mobile override went with it. */
.tf-label{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted);margin-bottom:3px}
.tf-value{font-size:var(--fs-small);color:var(--text);line-height:1.55}
.version-row{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:1rem;padding-bottom:0.75rem;border-bottom:1px solid var(--surface-tint)}
/* ⚠ .v-badge / .v-badge.cur DELETED (session 68) — zero consumers file-wide ("v-badge" occurred
   only in its own two rules; nothing constructs the name). The box pays for the slim head's
   verdict pill, which board 5a draws. */
.v-date{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted)}
.thesis-statement{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);color:var(--navy);line-height:1.55;margin:var(--sp-2) 0 var(--sp-4)}

/* THESIS FACTS GRID */
.tf-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);margin-bottom:1rem}
.tf-item{background:rgba(13,24,41,0.03);border-radius:var(--radius-xs);padding:var(--sp-3);border:1px solid var(--line)}
/* §6a — inline-editable thesis fields (single-field amendment, not a new version) */
.tf-legend{font-size:var(--fs-micro);font-weight:600;padding:1px 5px;border-radius:var(--radius-2xs);background:var(--surface-tint);color:var(--text-soft);letter-spacing:0.03em;vertical-align:middle;text-transform:none}
.tf-disp{cursor:pointer;border-radius:var(--radius-2xs)}
.tf-disp:hover .tf-editicon{opacity:1}
.tf-val-text{font-size:var(--fs-small);color:var(--text);line-height:1.55}
.tf-editicon{opacity:0;margin-left:6px;font-size:var(--fs-caption);color:var(--text-muted);transition:opacity 0.15s}
.tf-add{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-small);color:var(--action);font-weight:600;line-height:1.5}
.tf-item.tf-empty{border-style:dashed;border-color:var(--navy-soft);background:var(--navy-tint)}
.tf-add-legend{font-size:var(--fs-micro);font-weight:600;padding:1px 5px;border-radius:var(--radius-2xs);background:var(--neutral-fill);color:var(--text-soft)}
.tf-editrow{margin-top:6px}
.tf-input{width:100%;resize:vertical;padding:6px 8px;border:1.5px solid var(--navy);border-radius:var(--radius-2xs);font-family:var(--font-ui);font-size:var(--fs-small);background:var(--surface);color:var(--text)}
.tf-input:focus{outline:none;border-color:var(--navy-soft);box-shadow:var(--ring)}
.tf-editbtns{display:flex;gap:6px;margin-top:4px}

/* EXIT BLOCKS */
.exit-block{padding:0.9rem 1rem;border-radius:var(--radius-xs);display:flex;gap:var(--sp-2);align-items:flex-start;margin-bottom:0.6rem}
.exit-block.red{background:var(--red-soft);border-left:3px solid var(--red-strong)}
.exit-block.amber{background:var(--amber-soft);border-left:3px solid var(--amber)}
.eb-label{display:flex;align-items:center;gap:var(--chip-gap);font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;text-transform:uppercase;letter-spacing:0.06em;margin-bottom:3px}
.eb-label > .ic{font-size:var(--icon-glyph-sm);stroke-width:2}
.exit-block.red .eb-label{color:var(--red-strong)}
.exit-block.amber .eb-label{color:var(--amber-strong)}
.eb-text{font-size:var(--fs-small);color:var(--text-soft);line-height:1.55}

/* .hl-* (Research Highlights) removed in session 44 with the panel itself. */

/* KPI */
.kpi-item{display:grid;grid-template-columns:1fr 100px 80px 90px;gap:var(--sp-2);align-items:center;padding:0.85rem 0;border-bottom:1px solid var(--surface-tint)}
.kpi-item:last-child{border-bottom:none}
.kpi-name{font-size:var(--fs-body);font-weight:600;color:var(--text)}
.kpi-rule{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:2px}
.kpi-val{font-family:var(--font-mono);font-size:var(--fs-small);font-weight:600;text-align:center}
.pass{color:var(--green-strong)}.fired{color:var(--red-strong)}
.kpi-status-btns{display:flex;gap:var(--sp-1);justify-content:center}
.ksb.active-green{border-color:var(--green);background:var(--green-soft);opacity:1}
.ksb.active-amber{border-color:var(--amber);background:var(--amber-soft);opacity:1}
.ksb.active-red{border-color:var(--red-strong);background:var(--red-soft);opacity:1}

/* NOTE TIMELINE */
.note-tl{position:relative;padding-left:18px}
.note-tl::before{content:"";position:absolute;left:5px;top:7px;bottom:7px;width:1px;background:var(--line)}
.note-entry{position:relative;margin-bottom:1rem}
.note-entry::before{content:"";position:absolute;left:-15px;top:5px;width:7px;height:7px;border-radius:50%;background:var(--line-strong)}
.note-entry.key::before{background:var(--amber)}
.note-date{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-bottom:3px}
.note-text{font-size:var(--fs-small);color:var(--text);line-height:1.6}
.note-text-clamp{font-size:var(--fs-small);color:var(--text);line-height:1.6;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}
#ne-editor:empty:before{content:attr(data-placeholder);color:var(--text-muted);pointer-events:none;display:block}
/* ── Rich-text typography: ONE scale, applied to BOTH the note editor and the note viewer ──
   These used to be two different worlds: the editor styled h1 at 1.3rem against 0.85rem body
   (barely bigger than a paragraph), while the viewer had no heading rules at all and fell back to
   browser defaults where h1 is 2em — so the same note looked different depending on where it was
   read. That is the whole of the "H1 doesn't stand out" and "pasted headings are inconsistent"
   report. Every rule below MUST stay on the shared selector list; splitting them re-opens the bug.
   Scale is Notion-like: body 1×, h4 1.08×, h3 1.25×, h2 1.48×, h1 1.84×. */
#ne-editor,#nv-body{font-size:var(--fs-body);line-height:1.7;color:var(--text);word-break:break-word}
#ne-editor h1,#nv-body h1,#thv-body h1,.prose-rich h1,.pr-note-b h1,
#ne-editor h2,#nv-body h2,#thv-body h2,.prose-rich h2,.pr-note-b h2,
#ne-editor h3,#nv-body h3,#thv-body h3,.prose-rich h3,.pr-note-b h3,
#ne-editor h4,#nv-body h4,#thv-body h4,.prose-rich h4,.pr-note-b h4{line-height:1.28;color:var(--navy);font-weight:800;margin:1.15em 0 0.35em}
/* ⚠ UX-35 — THE VERSION LIST USED TO RUN ON. Thesis history rendered the same stored HTML as the
   note view and gave it none of the note view's scale, so six headed sections read as one block
   of prose. One selector list, two surfaces, and the ratio is the same one DESIGN names. */
#ne-editor h1,#nv-body h1,#thv-body h1,.prose-rich h1,.pr-note-b h1{font-size:calc(var(--fs-body) * 1.84);letter-spacing:-0.015em}
#ne-editor h2,#nv-body h2,#thv-body h2,.prose-rich h2,.pr-note-b h2{font-size:calc(var(--fs-body) * 1.48);letter-spacing:-0.01em}
#ne-editor h3,#nv-body h3,#thv-body h3,.prose-rich h3,.pr-note-b h3{font-size:calc(var(--fs-body) * 1.25);font-weight:700}
#ne-editor h4,#nv-body h4,#thv-body h4,.prose-rich h4,.pr-note-b h4{font-size:calc(var(--fs-body) * 1.08);font-weight:700;color:var(--text)}
/* 20's prose is a READING COLUMN — the board sets it 15/1.6 where the editor stays at body size.
   The heading ratio is unchanged: it multiplies the body ROLE, not this column's size. */
#nv-body{font-size:var(--fs-pane);line-height:1.6}
/* A heading pasted as the first line shouldn't push itself off the top of the box. */
#ne-editor>*:first-child,#nv-body>*:first-child,.prose-rich>*:first-child,.pr-note-b>*:first-child{margin-top:0}
#ne-editor p,#nv-body p,.prose-rich p,.pr-note-b p{margin:0.5em 0}
#ne-editor ul,#nv-body ul,#ne-editor ol,#nv-body ol,.prose-rich ul,.prose-rich ol,.pr-note-b ul,.pr-note-b ol{padding-left:1.5rem;margin:0.5em 0}
#ne-editor li,#nv-body li,.prose-rich li,.pr-note-b li{margin:0.2em 0}
/* s98 · R5-5: the rest of a list item a question box cut in two — it goes on under the box, without a second bullet */
#ne-editor li.ne-li-cont,#nv-body li.ne-li-cont,.prose-rich li.ne-li-cont,.pr-note-b li.ne-li-cont{list-style:none}
#ne-editor blockquote,#nv-body blockquote,.prose-rich blockquote,.pr-note-b blockquote{border-left:3px solid var(--navy-soft);margin:0.7em 0;padding:0.1em 0 0.1em 0.95rem;color:var(--text-soft);font-style:italic}
#ne-editor code,#nv-body code,.prose-rich code,.pr-note-b code{background:var(--surface-tint);border-radius:var(--radius-2xs);padding:1px 5px;font-family:var(--font-mono);font-size:0.86em;font-style:normal}
#ne-editor pre,#nv-body pre,.pr-note-b pre{background:var(--surface-tint);border-radius:var(--radius-2xs);padding:8px 10px;overflow-x:auto;font-family:var(--font-mono);font-size:0.82em;margin:0.6em 0}
#ne-editor a,#nv-body a,.prose-rich a,.pr-note-b a{color:var(--accent);text-decoration:underline}
#ne-editor strong,#nv-body strong,#ne-editor b,#nv-body b,.prose-rich strong,.prose-rich b,.pr-note-b strong,.pr-note-b b{font-weight:700;color:var(--navy)}
/* session 87 · a pasted table (finding 19b): hairline cells, the head in the label voice, scrolls sideways
   inside its surface rather than widening it */
#ne-editor table,#nv-body table,#thv-body table,.prose-rich table,.pr-note-b table{border-collapse:collapse;width:100%;margin:0.7em 0;font-size:var(--fs-small);display:block;overflow-x:auto}
#ne-editor td,#nv-body td,#thv-body td,.prose-rich td,#ne-editor th,#nv-body th,#thv-body th,.prose-rich th,.pr-note-b td,.pr-note-b th{border:1px solid var(--line);padding:var(--sp-1) var(--sp-2);vertical-align:top;text-align:left}
#ne-editor th,#nv-body th,#thv-body th,.prose-rich th,.pr-note-b th{font-weight:700;color:var(--navy);background:var(--surface-tint)}
#ne-editor hr,#nv-body hr,.pr-note-b hr{border:none;border-top:1px solid var(--line-strong);margin:1em 0}
/* Formatting toolbar */
.ne-tb{display:flex;gap:var(--sp-1);flex-wrap:wrap;align-items:center;padding:6px 8px;background:var(--surface-tint);border:1px solid var(--line);border-bottom:none;border-radius:var(--radius-2xs) var(--radius-2xs) 0 0}
.ne-tb-sep{width:1px;height:18px;background:var(--line-strong);margin:0 var(--sp-1);flex-shrink:0}
.ne-head-wrap{position:relative}
.ne-head-menu{position:absolute;top:100%;left:0;margin-top:5px;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-xs);box-shadow:0 10px 28px rgba(8,17,32,0.18);z-index:var(--z-popover);min-width:170px;padding:var(--sp-1)}
.ne-head-menu button{display:block;width:100%;text-align:left;background:none;border:none;padding:8px 10px;font-size:var(--fs-small);color:var(--text);cursor:pointer;border-radius:var(--radius-2xs)}
.ne-head-menu button:hover{background:var(--surface-tint)}
.ne-head-menu button.ne-head-sel{background:var(--navy);color:var(--on-brand)}
.ne-head-menu button.ne-head-sel:hover{background:var(--navy)}
/* ⚠ SESSION 89 · finding 7 (a regression he found): .spc-tb scrolls sideways at 390, and an
   overflow-x that is not visible turns overflow-y into auto — so an absolutely positioned menu inside
   the toolbar was CLIPPED to the toolbar's 41px. Open, a toolbar menu is moved to <body> and placed
   against its button (_nePopOpen), upward first. */
.ne-head-menu.ne-pop{position:fixed;top:auto;margin-top:0;z-index:calc(var(--z-top) + 1)}
/* session 89 · finding 8: a cell holding only a <br> collapses to a sliver — a table made with Insert
   table must be something you can click into */
#ne-editor td,#ne-editor th{min-width:calc(var(--sp-7) * 2)}
/* Formatting toolbar buttons + active (currently-applied) state */
.ne-fmt-btn{background:none;border:1px solid var(--line);border-radius:var(--radius-2xs);padding:var(--sp-1) var(--sp-2);font-size:var(--fs-small);cursor:pointer;color:var(--text);transition:background 0.12s,border-color 0.12s}
.ne-fmt-btn:hover{background:var(--surface-sunken)}
.ne-fmt-btn.active{background:var(--navy);border-color:var(--navy);color:var(--on-brand)}
/* The restored-edit-draft bar. Amber, because it is a warning about state, not an error. */
.ne-draft-bar{display:flex;gap:10px;align-items:center;justify-content:space-between;background:var(--amber-soft);border:1px solid var(--amber);border-radius:var(--radius-2xs);padding:var(--sp-2) var(--sp-3);margin-bottom:0.6rem;font-size:var(--fs-caption);color:var(--text-soft);line-height:1.4}
.ne-draft-discard{background:none;border:1px solid var(--line-strong);border-radius:var(--radius-2xs);padding:3px 10px;font-size:var(--fs-caption);cursor:pointer;color:var(--text);flex-shrink:0}
.ne-draft-discard:hover{background:var(--surface)}
/* ── Q2 · COMMAND MENU (slash-typed and selection-triggered) ──────────────────
   Appended to <body>, never to the editor: #ne-editor is overflow-y:auto, so a
   menu inside it would be clipped at the scroll edge. position:fixed + a body
   parent means the editor's scrollport cannot cut it off. Above .cfm-overlay so
   it is never buried the way the toast was. */
.ne-cmd-menu{position:fixed;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-xs);box-shadow:var(--shadow-pop);z-index:calc(var(--z-top) + 1);min-width:270px;max-width:330px;max-height:300px;overflow-y:auto;padding:6px 0;font-family:var(--font-ui);overscroll-behavior:contain}
.ne-cmd-grp{font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.1em;color:var(--text-muted);padding:7px 14px 5px;font-family:var(--font-mono)}
.ne-cmd-item{display:flex;gap:var(--sp-3);align-items:flex-start;width:100%;text-align:left;background:none;border:none;padding:8px 14px;cursor:pointer;color:var(--text)}
.ne-cmd-item:hover,.ne-cmd-item.on{background:var(--surface-tint)}
.ne-cmd-ico{width:27px;height:27px;flex-shrink:0;border:1px solid var(--line);border-radius:var(--radius-2xs);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--fs-body);color:var(--text-soft);background:var(--surface)}
.ne-cmd-lbl{display:block;font-size:var(--fs-small);font-weight:600;color:var(--navy);line-height:1.25}
.ne-cmd-hint{display:block;font-size:var(--fs-label);color:var(--text-muted);margin-top:1px;line-height:1.3}
.ne-cmd-foot{border-top:1px solid var(--surface-tint);margin-top:5px;padding:8px 14px 3px;display:flex;justify-content:space-between;gap:10px;font-size:var(--fs-caption);color:var(--text-muted)}
.ne-cmd-empty{padding:11px 14px;font-size:var(--fs-small);color:var(--text-muted)}
/* ── Q2 · the inline question block ──────────────────────────────────────────
   ONE FLAT ELEMENT. The "?" is a ::before marker, not a child node, so the caret
   can never land inside the decoration and el.textContent is exactly the question
   — which is what the save path stores. Rendered in the read-only note view too. */
/* ⚠ SESSION 89 · his Round 2 finding: "it's coming in a different background than purple that was
   decided for questions". A question is violet everywhere else (callout-question, v2 rule 12 and his
   comment of 13 Sep) — the block written in a note was the one amber-on-grey holdout. It now wears
   callout-question's ground, rule and -strong glyph. */
#ne-editor .ne-qb,#nv-body .ne-qb,#ne-editor .ne-rb,#nv-body .ne-rb{position:relative;border-left:var(--rule-w) solid var(--accent);background:var(--accent-soft);border-radius:0 var(--radius-2xs) var(--radius-2xs) 0;margin:0.7em 0;padding:0.45em 0.75em 0.45em 2.1rem;font-size:var(--fs-body);font-style:normal;color:var(--text)}
#ne-editor .ne-qb:before,#nv-body .ne-qb:before,#ne-editor .ne-rb:before,#nv-body .ne-rb:before{content:'?';position:absolute;left:0.78rem;top:0.45em;font-weight:700;color:var(--accent-strong)}
/* s130 · his item 7 — an event / milestone and a guidance passage: the question's box in their own hue, their own glyph */
#ne-editor .ne-rb-event,#nv-body .ne-rb-event{background:var(--event-soft);border-left-color:var(--event);--rb-ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E")}
#ne-editor .ne-rb-guidance,#nv-body .ne-rb-guidance{background:var(--teal-soft);border-left-color:var(--teal);--rb-ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Ccircle cx='12' cy='12' r='6'/%3E%3Ccircle cx='12' cy='12' r='2'/%3E%3C/svg%3E")}
#ne-editor .ne-rb:before,#nv-body .ne-rb:before{content:'';width:var(--icon-glyph-sm);height:var(--icon-glyph-sm);translate:0 var(--sp-1);background:currentColor;-webkit-mask:var(--rb-ic) center/contain no-repeat;mask:var(--rb-ic) center/contain no-repeat}
#ne-editor .ne-rb-event:before,#nv-body .ne-rb-event:before{color:var(--event-strong)}
#ne-editor .ne-rb-guidance:before,#nv-body .ne-rb-guidance:before{color:var(--teal-strong)}
/* s94 · R4-11 · a question edited since this note raised it: a mono meta line under his words, the question as it reads now */
#nv-body .ne-qb-ed{font-family:var(--font-mono);font-size:var(--fs-label);line-height:1.5;color:var(--text-muted);margin-top:var(--sp-1)}
#nv-body .ne-qb-ed-k{text-transform:uppercase;letter-spacing:0.04em}
#nv-body .ne-qb-ed-now{font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-soft)}
/* ⚠ BOTH HINTS ARE ABSOLUTELY POSITIONED, AND THAT IS THE FIX, NOT A STYLE CHOICE
   (Vikas, 21 Aug). As inline ::before/::after content they were real boxes in the line,
   so the caret was pushed to sit AFTER the hint text — "it wastes lots of space on the
   left in case I choose not to use command and plainly write" — and inside a question
   block the hint wrapped onto its own line below the caret. Out of flow, the caret sits
   at the start of the line and the grey text runs underneath it, which is the Notion
   behaviour he is comparing against. Offsets match each block's own padding. */
#ne-editor .ne-qb.ne-qb-empty:after{content:'Write your question';color:var(--text-muted);pointer-events:none;position:absolute;left:2.1rem;top:0.45em;white-space:nowrap}
#ne-editor .ne-ph-line{position:relative}
#ne-editor .ne-ph-line:before{content:"Type '/' for commands";color:var(--text-muted);pointer-events:none;position:absolute;left:0;top:0;white-space:nowrap}
.src-item{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-2) 0;border-bottom:1px solid var(--surface-tint)}
.src-item:last-child{border-bottom:none}
.src-name{font-size:var(--fs-small);color:var(--navy);font-weight:500}
.src-desc{font-size:var(--fs-caption);color:var(--text-muted);margin-top:1px}
.src-url{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-left:auto}

/* QUARTERLY REVIEW TABLE */
.qr-table{width:100%;border-collapse:collapse;font-size:var(--fs-small)}
.qr-table th{text-align:left;padding:var(--sp-2) var(--sp-3);font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);background:var(--surface-tint);border-bottom:2px solid var(--line)}
.qr-table td{padding:10px 12px;border-bottom:1px solid var(--surface-tint);vertical-align:top}
/* The thesis and conviction chips are chip-select (the box is in the component block); the
   three that pick a STATE take chip-select-state's chosen dress — the -soft fill, the base
   border and the -strong word. ⚠ Broken's border was the -strong twin, which is the WORD's
   colour; a border is a base-colour job. Their Lucide glyphs land with the modal (Phase 4). */
.qr-ta:focus{outline:none;border-color:var(--navy-soft);box-shadow:var(--ring)}
.kpi-dots{display:flex;gap:var(--sp-1)}
.kpi-dot{width:9px;height:9px;border-radius:50%}
.kpi-dot.g{background:var(--green)}.kpi-dot.a{background:var(--amber)}.kpi-dot.r{background:var(--red-strong)}.kpi-dot.x{background:var(--line-strong)}

/* AUDIT */
.audit-item{display:flex;gap:var(--sp-3);align-items:flex-start;padding:var(--sp-4) 0;border-bottom:1px solid var(--surface-tint)}
.audit-item:last-child{border-bottom:none}
.audit-badge.red{background:var(--red-soft);color:var(--red-strong)}
.audit-badge.amber{background:var(--amber-soft);color:var(--amber-strong)}
.audit-body{flex:1}
.audit-desc{font-size:var(--fs-body);color:var(--text);line-height:1.55}
.audit-date{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:3px}
.audit-acts{display:flex;gap:var(--sp-1);flex-shrink:0;align-items:flex-start}
.audit-grp-hdr{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;text-transform:uppercase;letter-spacing:0.1em;color:var(--text-muted);padding:var(--sp-4) 0 var(--sp-1);display:flex;align-items:center;gap:10px}
.audit-grp-hdr::after{content:"";flex:1;height:1px;background:var(--line)}

/* EXPERIMENT CARD */
.exp-title{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-display);margin-bottom:3px}
.exp-sub{font-family:var(--font-mono);font-size:var(--fs-micro);opacity:0.45;margin-bottom:1.25rem}
.exp-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.exp-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);opacity:0.5;text-transform:uppercase;letter-spacing:0.07em;margin-bottom:5px}
.exp-val{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-display)}
.exp-val.win{color:var(--green)}.exp-val.los{color:var(--red)}
.exp-verdict{font-family:var(--font-mono);font-size:var(--fs-label);margin-top:1rem;opacity:0.65;line-height:1.7}
.exp-verdict em{color:var(--action-on-dark);font-style:normal;font-weight:700}

/* DOCS */
.doc-sh{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;text-transform:uppercase;letter-spacing:0.1em;color:var(--text-muted);margin:1.25rem 0 0.75rem}
/* ⚠ RESTORED (DP-1, session 69). Docs is an [E] surface — audit §4.2 — and session 68 rebuilt
   its rows to the prototype's placeholder. The doc item is the existing surface's own row. */
.doc-item{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--rec-row-y);border-radius:var(--radius-2xs);border:1px solid var(--line);background:var(--surface);margin-bottom:var(--chip-gap)}
.doc-name{font-size:var(--fs-small);font-weight:600;color:var(--navy)}
.doc-meta{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:var(--rec-tight)}
/* a doc row's View · Delete are text controls now (board 09), so they sit the board's 16px apart */
.doc-acts{margin-left:auto;display:flex;gap:var(--sp-4)}

/* DROP ZONE */
.drop-zone{border:1.5px dashed var(--line-strong);border-radius:var(--radius-sm);padding:var(--state-pad);text-align:center;cursor:pointer;transition:border-color .15s,background .15s;background:var(--surface-tint);display:flex;flex-direction:column;align-items:center;gap:var(--sp-2)}
.drop-zone:hover,.drop-zone.dragover{border-color:var(--navy-soft);background:var(--navy-tint)}
.drop-zone:focus-visible{outline:none;box-shadow:var(--ring)}
.drop-zone .ic{width:var(--icon-glyph);height:var(--icon-glyph)}
/* ── THE TRADEBOOK IMPORT (session 90, Phase B · spec §3 steps 1–4) ──────────────────────────────────────
   One modal at the family's table width (680 — "carries a table"). Files are sections on hairlines, never
   cards; the mapping grid is the Ledger's own .tx-table and scrolls sideways INSIDE its wrapper, never the
   page. It draws no box of its own: the drop target is .drop-zone above, retokened from a dead rule. */
.tbi-file{display:flex;flex-direction:column;gap:var(--sp-3);padding-top:var(--sp-4);border-top:1px solid var(--line)}
.tbi-file:first-child{padding-top:0;border-top:0}
.tbi-fname{display:flex;align-items:center;gap:var(--sp-2);font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;color:var(--navy);overflow-wrap:anywhere}
.tbi-fname > .ic{width:var(--icon-glyph);height:var(--icon-glyph);color:var(--text-muted);flex-shrink:0}
.tbi-meta{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--sp-2) var(--sp-3)}
.tbi-meta .tbi-brk{width:auto;min-width:var(--tbi-ctl-w)}
.tbi-lbl{display:flex;flex-direction:column;min-width:var(--tbi-ctl-w);max-width:100%;align-self:flex-start}
.drop-zone.tbi-more{padding:var(--sp-4)}
.tbi-need,.tbi-res{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);flex:1 1 var(--tbi-ctl-w);min-width:0}
.tbi-map{display:flex;flex-direction:column;gap:var(--sp-3)}
.tbi-ess,.tbi-tags{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.tbi-scroll{max-width:100%}
.tbi-grid th{vertical-align:bottom;white-space:nowrap}
.tbi-grid .select{min-width:var(--tbi-col-w)}
.tbi-grid td{white-space:nowrap;max-width:var(--tbi-cell-max);overflow:hidden;text-overflow:ellipsis}
.tbi-skip{margin:0;padding-left:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-1)}
.tbi-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-3)}
/* s94 · D1 — the family's stat cell (the journal's .jr-lbl over .jr-fig): the label ABOVE, the figure 24 (22 at 390).
   A label that wraps at 390 ("Already in Stockport") keeps its figure on the row's line: the cell spreads, label top,
   figure bottom. No box — the review's parts sit on hairlines, never cards (#32). */
.tbi-stat{display:flex;flex-direction:column;justify-content:space-between}
.tbi-sect{display:flex;flex-direction:column;gap:var(--sp-2)}
/* ── session 91 · THE IMPORT REVIEW (spec §3 step 5) — at the claims review's width, --pr-w (his ruling, 23 Sep: "the
   review at the claims review's width"). A WIDTH EXCEPTION, written down: the review's tables carry a company, its
   shares, its cost and a choice on one line, and the mapping grid shows twice the columns. Everything else is the
   family's — the head, the close, the footer grammar, the 390 inset card. Sections sit on hairlines like the files
   step, never cards; the tables are the Ledger's own .tx-table and scroll sideways INSIDE their wrapper at 390. ── */
.modal-box.modal-tbi{max-width:var(--pr-w)}   /* two classes: .modal-box (later in the sheet) sets --modal-w-md */
#tbi-foot{flex-wrap:wrap}
.tbi-foot-opts{flex-basis:100%;display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-5)}
.tbi-foot-opts:empty{display:none}
.tbi-rsum{display:flex;flex-direction:column;gap:var(--sp-3)}
.tbi-rsec{display:flex;flex-direction:column;gap:var(--sp-3);padding-top:var(--sp-4);border-top:1px solid var(--line)}
.tbi-rh{display:flex;align-items:baseline;gap:var(--sp-2)}
.tbi-rt{margin:0;font-family:var(--font-ui);font-size:var(--fs-pane);font-weight:700;color:var(--navy)}
.tbi-rl{margin:0;font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.5;color:var(--text-soft)}
.tbi-co{display:flex;flex-direction:column;min-width:0}
.tbi-sym{font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:700;color:var(--navy)}
.tbi-nm{font-family:var(--font-ui);font-size:var(--fs-caption);color:var(--text-muted);overflow-wrap:anywhere}
.tbi-tbl td{vertical-align:top}
.tbi-tbl td.tbi-words{font-family:var(--font-ui);line-height:1.5}   /* s94 · D3 — words in Inter (the journal's notes column) */
.tbi-cbc{width:var(--cbx)}
.tbi-list{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:var(--sp-2)}
.tbi-list > li{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--sp-1) var(--sp-3)}
.tbi-cf{display:flex;flex-direction:column;gap:var(--sp-2)}
.tbi-cf + .tbi-cf{padding-top:var(--sp-3)}
.tbi-cf-h{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-3)}
.tbi-cf-ch{display:inline-flex;gap:var(--chip-gap);margin-left:auto}
.tbi-pick{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr) auto;gap:var(--sp-3);align-items:center}
/* the strip — "Import in review" on the Ledger and on a stock's Buy/Sell journal. ⚠ SESSION 110 · it is a NOTICE now (his
   comment of 3 Oct: it "needs highlighting like Home's red strip") — an amber-soft ground, a white disc with the upload glyph,
   the lead over its sentence, the two actions at the right. It was the family's description callout on the neutral ground
   (s94 · D7); a callout's ground is never a state colour (L46 c), so the strip stopped being one. .notice draws no box of its
   own: the corner is the u-r-2xs utility in the markup. */
.notice{background:var(--amber-soft);padding:var(--row-pad) var(--rec-sub-x)}
.notice > .state-disc{width:var(--plate);height:var(--plate);background:var(--surface);color:var(--amber-strong)}
.notice > .state-disc > .ic{font-size:var(--icon-glyph)}
.tbi-strip{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-4)}
.tbi-strip-t{display:flex;flex-direction:column;gap:var(--sp-1);min-width:0;flex:1 1 12rem}
.tbi-strip-b{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;color:var(--text)}
.tbi-strip-m{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted)}
.tbi-strip-a{display:flex;align-items:center;gap:var(--sp-4)}
/* ── session 92 · ONE STORY PER COMPANY (spec §6) — Add Stock says "You already have a story for X" and offers it. The
   family's description callout (s94 · D7 — its lead and its sentence are the family's .callout-b); this rule is the
   layout only — the strip's shape (.tbi-strip): the words, then one action. At 1440 the action stays at the right and the
   sentence takes two lines (the description body is 14, it was 12); at 390 the action goes under the words (#38) ── */
.as-dup:empty{display:none}                  /* no inline style: the box shows only when it has something to say */
.as-dup{display:flex;flex-wrap:nowrap;align-items:center;justify-content:space-between;gap:var(--sp-2) var(--sp-4);margin-top:var(--sp-3)}
.as-dup-t{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}
.drop-text{font-size:var(--fs-small);color:var(--text-soft);line-height:1.65}
.drop-text strong{color:var(--navy)}

/* SEP */
/* THE SECTION RULE — a hairline either side of one word (board Modals §13). The word is INTER:
   THE STOCK and THE THESIS are headings, and a heading is words, not an identifier. */
.sep{display:flex;align-items:center;gap:var(--sp-3);margin:1.25rem 0 0.9rem}
.sep-line{flex:1;height:1px;background:var(--line)}
.sep-text{font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;letter-spacing:0.06em;text-transform:uppercase;color:var(--text-muted);white-space:nowrap}

/* XIRR */
.xirr-banner{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:1.25rem}
.xirr-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);margin-bottom:4px}
.xirr-val{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);color:var(--navy)}
.xirr-val.pos{color:var(--green-strong)}.xirr-val.neg{color:var(--red-strong)}
.tx-table{width:100%;border-collapse:collapse;font-size:var(--fs-small)}
.tx-table th{text-align:left;padding:7px 10px;font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);border-bottom:1px solid var(--line);background:var(--surface-tint)}
.tx-table td{padding:8px 10px;border-bottom:1px solid var(--surface-tint);vertical-align:middle;font-family:var(--font-mono)}
/* the green and red trade-side rules went here. They had no consumer before this screen and
   board 08 retires the idea as well: green means state, and a trade's side is not one. */
/* Per-row classification slide toggle (HIST snapshot vs NEW trade) */
/* ⚠ THE SWITCH IS ONE COMPONENT — v2 board §5. A true pill track, a round knob with no drop
   shadow under it, and NAVY when it is on: a toggle picks a mode, and a mode is not a state,
   so it takes the selection colour rather than amber. Its word is Inter, like every label. */
.switch,.histsw{display:inline-flex;align-items:center;gap:var(--sp-2);cursor:pointer;margin-left:var(--sp-2);vertical-align:middle;user-select:none}
.switch-track,.histsw-track{position:relative;width:var(--sw-w);height:var(--sw-h);border-radius:var(--radius-pill);background:var(--line-strong);transition:background 0.18s;flex:none}
.switch.on .switch-track,.histsw.on .histsw-track{background:var(--navy-soft)}
.switch-knob,.histsw-knob{position:absolute;top:2px;left:2px;width:var(--sw-knob);height:var(--sw-knob);border-radius:var(--radius-pill);background:var(--surface);transition:left 0.18s}
.switch.on .switch-knob,.histsw.on .histsw-knob{left:16px}
.switch-label,.histsw-label{font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;letter-spacing:0.06em;text-transform:uppercase;color:var(--text-muted);white-space:nowrap}
.switch.on .switch-label,.switch-label.on,.histsw.on .histsw-label{color:var(--navy)}
/* Trade add/delete feedback */
@keyframes txFadeIn{from{background:var(--navy-tint-strong)}to{background:transparent}}
.tx-flash-add{animation:txFadeIn 1.3s ease}
.tx-fade-out{opacity:0 !important;transition:opacity 0.16s ease}
/* "syncing…" cloud-write indicator */
#sync-dot{position:fixed;bottom:16px;right:16px;z-index:calc(var(--z-top) + 2);display:none;align-items:center;gap:var(--sp-2);background:var(--navy);color:var(--on-brand);padding:6px 12px;border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:var(--fs-label);font-weight:600;letter-spacing:0.03em;box-shadow:var(--shadow-sm)}
#sync-dot.on{display:flex}
#sync-dot .sd{width:8px;height:8px;border-radius:50%;background:var(--amber);animation:sdPulse 0.9s ease-in-out infinite}
@keyframes sdPulse{0%,100%{opacity:0.35;transform:scale(0.8)}50%{opacity:1;transform:scale(1.1)}}

/* FINANCIALS */
.fin-table{width:100%;border-collapse:collapse;font-size:var(--fs-small)}
.fin-table th{text-align:right;padding:7px 10px;font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:0.06em;text-transform:uppercase;color:var(--text-muted);border-bottom:2px solid var(--line);background:var(--surface-sunken)}
.fin-table th:first-child{text-align:left}
.fin-table td{padding:7px 10px;border-bottom:1px solid var(--surface-tint);text-align:right;font-family:var(--font-mono)}
.fin-table td:first-child{text-align:left;font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-soft);font-weight:500}
.fin-table tr.hl td{background:var(--surface-sunken);font-weight:700;color:var(--navy)}
.trend-up{color:var(--green-strong)}.trend-dn{color:var(--red-strong)}

/* GRID HELPERS */
.g2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-5)}
/* UX-29 (Phase 2, session 60): a grid item's min-width is its content, so the financials table
   pushed the Docs page to 1553px at 1440 and starved the documents column (280px — the heading
   wrapped). Grid children may shrink; the table scrolls inside its card as it was meant to. */
.g2>*{min-width:0}
.g3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:var(--sp-4)}

/* FLYING BLIND */
.flying-blind-banner{background:var(--amber-soft);border:2px solid var(--amber);border-radius:var(--radius-sm);padding:var(--sp-6);margin-bottom:1.5rem;text-align:center}
.fb-headline{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-display);color:var(--amber-strong);margin-bottom:0.4rem}
.fb-sub{font-size:var(--fs-body);color:var(--amber-strong);opacity:0.85;max-width:420px;margin:0 auto 1.25rem}

/* FORM FIELDS */
.form-group{margin-bottom:1rem}
/* ⚠ A LABEL IS WORDS, SO IT IS INTER — not mono (§2a.9, v2 board §5). This one was the last
   mono eyebrow in the form layer. The field itself is in the component block above. */
.field-label,.form-label,.qtr-eyebrow,.sig-fld-lbl,.jr-lbl,.jr-fl,.jr-eb{font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);margin-bottom:var(--chip-gap);display:block}

/* QUARTERLY REVIEW HISTORY */
.qh-table{width:100%;border-collapse:collapse;font-size:var(--fs-small)}
.qh-table th{text-align:left;padding:6px 10px;font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);border-bottom:2px solid var(--line);background:var(--surface-sunken)}
.qh-table td{padding:9px 10px;border-bottom:1px solid var(--surface-tint);vertical-align:top}

/* ONBOARDING */
.ob-overlay{position:fixed;inset:0;background:var(--shell);background-attachment:fixed;z-index:calc(var(--z-modal) + 1);overflow-y:auto;padding:2.5rem 2.5rem 4rem;display:flex;align-items:flex-start;justify-content:center}
.ob-box{max-width:680px;width:100%;margin:0 auto}
.ob-progress{display:flex;gap:var(--sp-1);margin-bottom:2.5rem}
.ob-seg{height:3px;border-radius:var(--radius-2xs);background:var(--line);flex:1;transition:background 0.3s}
.ob-seg.done{background:var(--navy-soft)}.ob-seg.act{background:var(--navy)}
.ob-lbl{font-family:var(--font-ui);font-size:var(--fs-label);text-transform:uppercase;letter-spacing:0.06em;color:var(--eyebrow);font-weight:600;margin-bottom:0.75rem;display:block}
.ob-h{font-family:var(--font-ui);font-weight:800;font-size:clamp(1.6rem,3.5vw,2.4rem);color:var(--navy);margin-bottom:0.6rem;line-height:1.2}
.ob-sub{font-size:var(--fs-lead);color:var(--text-soft);line-height:1.7;margin-bottom:1.75rem;max-width:540px}
.ob-grid{display:grid;grid-template-columns:1fr 1fr;gap:0.9rem;margin-bottom:1.75rem}
.ob-card{border:1px solid var(--line);border-radius:var(--radius-sm);padding:1.35rem 1.5rem;cursor:pointer;background:var(--surface);transition:border-color 0.18s,box-shadow 0.18s}
.ob-card:hover{border-color:var(--line-strong)}
.ob-card.sel{border-color:var(--navy-soft);box-shadow:var(--sel-ring)}
.ob-card-num{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--eyebrow);font-weight:700;margin-bottom:5px;letter-spacing:0.08em}
.ob-card-title{font-family:var(--font-ui);font-weight:700;font-size:var(--fs-lead);color:var(--navy);margin-bottom:4px;line-height:1.2}
.ob-card-desc{font-size:var(--fs-small);color:var(--text-soft);line-height:1.55;margin-top:2px}
.ob-nav{display:flex;justify-content:space-between;align-items:center}
.ob-skip{font-size:var(--fs-small);color:var(--text-muted);cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.ob-step-content{display:none}.ob-step-content.active{display:block}
.ob-q-hint{font-weight:400;text-transform:none;letter-spacing:0;color:var(--text-muted);margin-left:var(--sp-1)}   /* s130 · step 2's "pick any that apply" */
.ob-year-row{display:flex;align-items:center;gap:var(--sp-4);margin-bottom:1.5rem}
.ob-year-input{width:110px;padding:var(--sp-2) var(--sp-3);border:1px solid var(--line-strong);border-radius:var(--radius-xs);font-family:var(--font-mono);font-size:var(--fs-lead);color:var(--navy);background:var(--surface);text-align:center}
/* a dark onboarding preview box went here; nothing in this file ever wore it (session 74). */
/* …and the six rules that dressed it went with it (session 77): a heading, a sub, a three-up
   grid and its three metric parts, none of which any element in this file has ever worn.
   Board 08 draws one new box — the log-a-trade strip — and this is what pays for it. */
.ob-checklist{margin-bottom:1.5rem}
.ob-ci{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--line)}
.ob-ci:last-child{border-bottom:none}
.ob-ci-check{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--fs-label);flex-shrink:0}
.ob-ci-check.done{background:var(--green-soft);color:var(--green-strong)}
.ob-ci-check.pend{background:var(--surface-tint);color:var(--line-strong);border:1px solid var(--line)}
.ob-ci-lbl{font-size:var(--fs-body);font-weight:500;color:var(--navy)}
.ob-ci-sub{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:1px}

/* COMPACT DROP ZONE (Step 3 + 4) */
.ob-upload-compact{margin-bottom:0.75rem}
/* a second, tighter upload target went here, with its drag state; neither had a consumer. */

/* STICKY ONBOARDING FOOTER */
.ob-footer-sticky{position:sticky;bottom:0;background:var(--shell);border-top:1px solid var(--line);padding:0.85rem 0;margin-top:1.25rem;display:flex;justify-content:space-between;align-items:center;z-index:var(--z-raised)}

/* SIZING LOCKED PLACEHOLDER */
.ob-sizing-locked{border:1.5px dashed var(--line-strong);border-radius:var(--radius-xs);padding:1.4rem 1.5rem;text-align:center;background:var(--surface-tint);margin-bottom:1rem;transition:border-color 0.18s,background 0.18s}
.ob-sizing-locked.dragover{border-color:var(--navy);background:var(--navy-tint);border-style:solid}

/* FORENSICS LOCKED CARD (Step 4) */
.ob-forensics-bg{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-2);padding:var(--sp-5);width:100%;filter:blur(5px);opacity:0.22;pointer-events:none}
/* an onboarding metric tile went here — one line in the file, and it was this rule. */
.ob-fml{font-family:var(--font-mono);font-size:var(--fs-micro);color:rgba(255,255,255,0.65);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:6px}
.ob-fmv{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-display);color:var(--on-brand)}
.ob-forensics-lock{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--sp-5);gap:0.4rem}
.ob-forensics-lock-icon{font-size:var(--fs-display);line-height:1;margin-bottom:0.1rem}
.ob-forensics-lock-label{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;text-transform:uppercase;letter-spacing:0.12em;color:rgba(255,255,255,0.45)}
.ob-forensics-lock-sub{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-lead);color:rgba(255,255,255,0.88);line-height:1.4;max-width:340px}

/* TICKER SUGGESTION DROPDOWN */
/* THE TICKER POPOVER — board Modals §13. It FLOATS, so it stops being welded to the bottom of
   the field: a 6px clear, its own hairline, the full radius and the drop shadow. Its rows are a
   three-column grid — ticker, exchange, name — and the row under the pointer is ring + navy
   tint, the same selection geometry as everything else you pick. */
.ticker-suggest{position:absolute;top:100%;left:0;right:0;margin-top:var(--chip-gap);background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-xs);z-index:var(--z-popover);max-height:190px;overflow-y:auto;box-shadow:var(--shadow-drop);padding:var(--sp-1)}
.ticker-suggest-item{display:grid;grid-template-columns:120px 44px 1fr;gap:10px;align-items:center;padding:var(--sp-2) 10px;border-radius:var(--radius-2xs);cursor:pointer}
.ticker-suggest-item:hover,.ticker-suggest-item.active{background:var(--navy-tint);box-shadow:var(--sel-ring)}
.ticker-suggest-sym{font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:700;color:var(--navy)}
.ticker-suggest-name{font-size:var(--fs-body);color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ticker-suggest-item > .tag-mono{text-align:center}
/* ── ONBOARDING REDESIGN (Steps 3–5 + completion) ── */
.ob-err{font-family:var(--font-ui);font-size:var(--fs-small);color:var(--red-strong);margin-top:6px;display:none}
.ob-err.ob-err-show{display:block}   /* s130 · the three errors steps 1 and 2 add (they wore an inline mono style) */
.ob-err.show{display:block}
.added-stocks{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:1rem}
.stock-pill{display:inline-flex;align-items:center;gap:6px;background:var(--neutral-fill);color:var(--text-soft);border-radius:var(--radius-2xs);padding:4px 10px;font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;letter-spacing:0.04em;animation:pillIn 0.18s ease}
@keyframes pillIn{from{opacity:0;transform:scale(0.9)}to{opacity:1;transform:scale(1)}}
.pill-remove{cursor:pointer;opacity:0.45;font-size:var(--fs-body);line-height:1;transition:opacity 0.1s;border:none;background:none;color:var(--text-muted);padding:0 0 0 2px}
.pill-remove:hover{opacity:1}
.stocks-added-count{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-bottom:0.75rem}
.stocks-added-count .sac-n{color:var(--navy);font-weight:700}
.conviction-grid{display:grid;grid-template-columns:1fr 1fr;gap:0.9rem;margin-bottom:1.75rem}
@media (max-width:520px){.conviction-grid{grid-template-columns:1fr}}
.conviction-card{border:1px solid var(--line);border-radius:var(--radius-sm);padding:1.25rem 1.35rem;cursor:pointer;background:var(--surface);transition:border-color 0.18s,box-shadow 0.18s}
.conviction-card:hover{border-color:var(--line-strong)}
.conviction-card.sel{border-color:var(--navy-soft);box-shadow:var(--sel-ring)}
.cc-ticker{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;color:var(--eyebrow);letter-spacing:0.08em;margin-bottom:5px;display:block}
.conviction-card.sel .cc-ticker{color:var(--navy)}   /* was --green-strong: text turning green to mean "selected" — demoted §2a.6; selection is the ring + weight */
.cc-name{font-weight:700;font-size:var(--fs-lead);color:var(--navy);line-height:1.25}
.cc-radio{width:20px;height:20px;border-radius:50%;border:2px solid var(--line-strong);position:relative;margin-top:10px;flex:0 0 auto;transition:all 0.18s}
.conviction-card.sel .cc-radio{border-color:var(--navy)}
.conviction-card.sel .cc-radio::after{content:'';position:absolute;inset:4px;border-radius:50%;background:var(--navy)}
/* stock-in-focus header (Step 5) + shared identity chip */
.ob-s1focus{margin-bottom:20px}
.ob-s1focus .eb{font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;letter-spacing:0.06em;text-transform:uppercase;color:var(--eyebrow);margin-bottom:5px}
.ob-idnm{font-size:var(--fs-display);font-weight:800;color:var(--navy);letter-spacing:-0.01em;line-height:1.15;display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap}
.rv-nm{font-weight:800;color:var(--navy)}
.rv-tk{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:0.04em;color:var(--text-soft);background:var(--surface-tint);border:1px solid var(--line);border-radius:var(--radius-2xs);padding:var(--sp-1) var(--sp-2);position:relative;top:-2px}
.prose-head{font-size:var(--fs-lead);font-weight:700;color:var(--navy);margin-bottom:3px}
.prose-sub{font-size:var(--fs-small);color:var(--text-soft);margin-bottom:9px}
.ob-s1-input{opacity:0;transform:translateY(10px);transition:opacity .55s cubic-bezier(.2,.7,.2,1),transform .55s cubic-bezier(.2,.7,.2,1)}
.ob-s1-input.ob-in{opacity:1;transform:none}
.prose-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.1em;color:var(--text-muted);margin-bottom:8px}
.prose-box{width:100%;min-height:112px;line-height:1.65;font-size:var(--fs-body);overflow:hidden;resize:vertical;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-xs);padding:14px 15px}
.prose-box::placeholder{color:var(--text-muted);font-style:italic}
/* session 87 · finding 19: the rich thesis box — grows with its content, scrolls past 60vh. Its
   typography is the note editor's: .prose-rich rides the #ne-editor selector lists above. */
.prose-rich{overflow-y:auto;max-height:60vh;resize:none;white-space:normal;outline:none}
.prose-rich:focus{border-color:var(--navy-soft)}
.prose-rich:empty:before{content:attr(data-placeholder);color:var(--text-muted);font-style:italic;pointer-events:none}
.tp-eyebrow{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.1em;color:var(--on-brand-faint);margin-bottom:3px}
.tp-stock{font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:700;color:var(--action-on-dark);margin-bottom:12px;letter-spacing:0.05em}
.tp-headline{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);color:var(--on-brand);line-height:1.25;margin-bottom:10px}
.tp-rule{font-size:var(--fs-small);color:rgba(255,255,255,0.55);line-height:1.6;border-top:1px solid rgba(255,255,255,0.08);padding-top:10px;margin-top:4px}
.tp-rule strong{color:rgba(255,255,255,0.82)}
.btn-lock{padding:0.75rem 1.75rem;font-size:var(--fs-body)}

/* TRADEBOOK FILE CHIPS */
.ob-file-chip{display:inline-flex;align-items:center;gap:6px;background:var(--surface-tint);border:1px solid var(--line);border-radius:var(--radius-2xs);padding:var(--sp-1) var(--sp-2);font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-soft);margin:var(--sp-1) var(--sp-1) 0 0}
.ob-file-chip button{border:none;background:none;cursor:pointer;color:var(--text-muted);font-size:var(--fs-body);line-height:1;padding:0 0 0 2px}
.ob-file-chip button:hover{color:var(--red-strong)}

/* AUTH SCREEN */
.auth-screen{position:fixed;inset:0;background:var(--bg);background-attachment:fixed;z-index:calc(var(--z-modal) + 5);display:flex;align-items:center;justify-content:center}
.auth-box{max-width:420px;width:100%;text-align:center;padding:var(--sp-7) var(--sp-6)}
.auth-logo{font-family:var(--font-ui);font-weight:800;font-size:calc(var(--fs-display) * 1.43);color:var(--navy);margin-bottom:0.25rem}
.auth-logo span{color:var(--brand-mark)}
.auth-tagline{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);text-transform:uppercase;letter-spacing:0.1em;margin-bottom:2.5rem}
.auth-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);padding:var(--sp-6)}
.auth-headline{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);color:var(--navy);margin-bottom:0.5rem}
.auth-sub{font-size:var(--fs-body);color:var(--text-soft);margin-bottom:1.75rem;line-height:1.6}
.btn-google{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:var(--sp-3) var(--sp-5);background:var(--surface);border:1.5px solid var(--line-strong);border-radius:var(--radius-xs);font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;color:var(--text);cursor:pointer;transition:all 0.2s}
.btn-google:hover{border-color:var(--navy-soft);box-shadow:var(--shadow-sm)}
.auth-note{font-size:var(--fs-caption);color:var(--text-muted);margin-top:1rem;line-height:1.5}

/* ══ THE MODAL FAMILY — v2 board §7 (design system v2, Phase 4, session 75) ═══════════════════
   One head, one close, one footer grammar, three widths, one behaviour at 390. Screens 15, 16
   and 17 are the reference shape and every other modal is made to look like them.
   ⚠ .tm-* WAS A SECOND SHELL AND IS NOW THIS ONE. Add stock and the thesis form wore their own
   chrome — a gradient head with a rule band under it, a 760 box, an absolutely placed ✕ — and
   they join these selector lists instead. An old class keeps a rule of its own only where it
   still does something this one does not.
   ⚠⚠ THE ELEVENTH MODAL IS THE EXTRACTION REVIEW AND IT IS ON THIS SHELL FOR EVERYTHING BUT
   ITS WIDTH — his ruling, 13 Sep 2026, which answers the question session 75 left open here.
   A screen may differ from the family in its STRUCTURE, its WIDTH or its BEHAVIOUR where the
   UX earns it, and in nothing else. That one puts the note BESIDE the claims so the two can be
   compared, so --pr-w stays; its corners, its shadow, its inner cards and its 390 behaviour are
   optics and are this family's. Board 6e is superseded on exactly those, each change carrying
   the ruling as its reason in conform_review.py — the mechanism 5a already had. */
.modal-overlay{position:fixed;inset:0;background:var(--scrim);z-index:var(--z-modal);display:none;align-items:center;justify-content:center;padding:var(--sp-6);overscroll-behavior:contain}
.modal-overlay.open{display:flex}
.modal-box,.tm-box{background:var(--surface);border-radius:var(--radius-sm);width:100%;max-width:var(--modal-w-md);max-height:88vh;overflow:hidden;display:flex;flex-direction:column;box-shadow:var(--shadow-modal)}
/* three widths and no fourth: one question · a form or a reading · a chart or a table */
.modal-420{max-width:var(--modal-w-sm)}
.modal-680{max-width:var(--modal-w-lg)}
.modal-header,.tm-head{background:var(--navy);padding:var(--modal-head-pad);border-radius:var(--radius-sm) var(--radius-sm) 0 0;display:flex;justify-content:space-between;align-items:flex-start;gap:var(--sp-4);flex-shrink:0}
.modal-title,.tm-headline{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);line-height:1.2;color:var(--on-brand)}
.modal-sub{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--on-brand-soft);margin-top:var(--sp-1)}
/* an eyebrow is not state, so it is never green — it is the sub-line's white at 72% (v2 §7) */
.modal-eyebrow,.tm-eyebrow{font-family:var(--font-ui);font-size:var(--fs-label);font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:var(--on-brand-soft);margin-bottom:var(--chip-gap)}
/* .modal-close and .tm-close are the board's icon-button-on-dark — their LOOK is in ICON
   BUTTONS and only their placement is here (v2 board §3 + §7). */
.modal-close,.tm-close{margin:var(--modal-close-pull)}
.modal-body,.tm-body{padding:var(--modal-body-pad);overflow-y:auto;flex:1;min-height:0;overscroll-behavior:contain}
/* The signal modal writes its whole header+body into this wrapper, which sits BETWEEN
   .modal-box and .modal-body. Without these three properties the wrapper is a plain
   block that grows to its content height, so .modal-body's `overflow-y:auto; flex:1`
   never applies to anything — .modal-box's `overflow:hidden` then CLIPS the overflow,
   which is why the Save button was unreachable, and the wheel fell through to the page
   behind. `min-height:0` is the load-bearing one: a flex item defaults to
   min-height:auto and refuses to shrink below its content, defeating the inner scroll. */
#sig-detail-content{display:flex;flex-direction:column;flex:1;min-height:0}
/* session 87 · finding 7: the pop-out forms' wrapper, the same three properties for the same reason */
#rec-form-content{display:flex;flex-direction:column;flex:1;min-height:0}
.modal-qr{max-width:var(--qr-w)}
/* session 89 · finding 1: never narrower than the family's reading width; as wide as the composer when
   the composer is wider. At ≤900 the composer is the inset card, and so is this (--nv-w is re-set in
   the composer's own 900px block). */
.modal-nv{max-width:max(var(--modal-w-md), var(--nv-w))}
/* inside the modal the form tile is the BODY, not a box in a box: its chrome and its own title go
   (the head names the form) and its foot is moved into the modal's pinned footer by the opener */
#rec-form-content .sig-add-tile{border:none;background:none;box-shadow:none;padding:0}
#rec-form-content .sig-add-tile{border-radius:0}   /* its own rule, so un-drawing the box does not read as drawing one (L18) */
#rec-form-content .sig-add-tile > .sig-tile-t{display:none}
.modal-footer,.tm-foot{padding:var(--modal-foot-pad);border-top:1px solid var(--line);background:var(--surface);flex-shrink:0;display:flex;gap:var(--sp-2);align-items:center;justify-content:flex-end}
/* THE FOOTER'S GRAMMAR. The primary is always right-most; a second important action is the
   green OUTLINE to its left, never a second fill. Anything at the left edge — the draft status
   on a writable modal, a destructive action, a read-only modal's one plain line — is pushed
   there by the same rule, so a footer never needs a spacer element. */
.modal-draft{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-right:auto}
/* ══ 22 · THE QUARTERLY REVIEW PANEL — inline, and it takes the modal head (board 22) ══════
   His call, 11 Sep, and the inline-vs-modal rule is amended by it: an inline form that fills
   the content column may take the navy head so it reads as one bounded piece of work. The head,
   the title, the sub-line, the close and every one of their 390 values are the family's, which
   is why none of them is re-measured here — the panel wears .modal-header / .modal-title /
   .modal-sub / .modal-close and inherits the 390 compression with them.
   ⚠ WHAT IS NOT THE FAMILY'S: the box. A modal floats and carries --shadow-modal; this one
   sits in the page, so it is the Record's level-1 card and its two green rails are gone —
   green means state, and a panel is not a state. */
.qtr-body{padding:var(--qtr-body-pad)}
.qtr-eyebrow{margin:var(--qtr-eb-m)}
.qtr-body > .qtr-eyebrow:first-child{margin-top:var(--qtr-eb-top1)}
.qtr-chips{display:flex;gap:var(--chip-gap);flex-wrap:wrap}
.qtr-kpis{display:flex;flex-direction:column;gap:var(--sp-2)}
/* the KPI row is a .row — level 2, so its ground and its corner come from there and this rule
   draws no box of its own. Name · value · verdict, on one line at the desk.
   ⚠ .row.qtr-kpi, NOT .qtr-kpi — .row is declared further down the file and would win on
   source order at equal specificity, which is how its 12px beat this row's 14px 16px. */
/* ⚠ FOUR COLUMNS, NOT THREE. The period picker sits between the name and the value — board 22
   at 1440 — so a reading is entered against the period it belongs to rather than against
   whichever period the app last guessed. */
.row.qtr-kpi{padding:var(--qtr-kpi-pad);display:grid;grid-template-columns:minmax(0,1fr) var(--qtr-kpi-per-w) var(--qtr-kpi-val-w) auto;gap:var(--sp-4);align-items:center}
/* ⚠ A MILESTONE CARRIES NO READING AND NO PERIOD — his comment, 13 Sep: "Give the original
   options here that are there for milestones like delayed, on track, delivered etc." Its pick
   IS its state, so it wears chip-select-state like every other pick that is a state, and the
   two field columns simply are not there. */
.row.qtr-kpi.qtr-ms{grid-template-columns:minmax(0,1fr) auto}
/* the picker is the select the system already has, at the value field's size beside it */
.qtr-kpi .sig-select{font-family:var(--font-mono)}
.qtr-kpi-fields{display:contents}
.qtr-kpi-n{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:600;color:var(--text)}
.qtr-kpi-m{font-family:var(--font-ui);font-size:var(--fs-caption);color:var(--text-muted);margin-top:var(--rec-tight)}
/* ── THE DECISION BLOCK (board 22, his ask of 13 Sep) ──────────────────────────────────────
   DECISION and CONVICTION are two eyebrow columns side by side, and one WHAT THIS QUARTER
   SHOWED? textarea sits under both — a quarter has one story, not one per claim, which is why
   the per-claim field is gone. */
.qtr-dec{display:grid;grid-template-columns:auto 1fr;gap:var(--qtr-dec-gap);align-items:start;margin-top:var(--qtr-dec-mt)}
.qtr-dec > div > .qtr-eyebrow{margin:0 0 var(--chip-gap)}
/* ⚠ THE SAME LITERALS 18 SHIPS (§10 row 8, closed 14 Sep: 32 at 1440, 40 at 390). The review
   performs the same write 18 performs, so it had better not look like a different control. */
.qtr-stars{display:flex;align-items:center;gap:var(--sp-3);height:var(--qtr-stars-h)}
.qtr-stars .star-rating > button > .ic{font-size:var(--star-conv)}
.qtr-stars .star-rating > button{background:none;border:none;padding:0;cursor:pointer;display:inline-flex;line-height:1}
.qtr-starw{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--text-soft)}
/* where it came from, in the floor voice — "from High" when it moved, "unchanged" when it did not */
.qtr-starwas{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted)}
/* ── the claim row · board 22, a level-2 tinted row wearing its own marker line ──────────
   ⚠ IT IS A ROW, NOT A CARD. Page → card → row, and it stops there (rule 6): the claim card's
   own 16px corner and hairline would be a third box inside the panel's card. What it keeps
   from the card is the one thing that identifies it — the 3px marker line and the C-id in the
   same tint, so the row and the card are visibly the same bet. */
.qtr-claim{display:flex;gap:var(--qtr-clm-gap);padding:var(--qtr-clm-pad)}
.qtr-clm-rail{width:var(--rule-w);border-radius:0 2px 2px 0;flex-shrink:0}
.qtr-clm-rail.mk1{background:var(--mk1)}.qtr-clm-rail.mk2{background:var(--mk2)}
.qtr-clm-rail.mk3{background:var(--mk3)}.qtr-clm-rail.mk4{background:var(--mk4)}
.qtr-clm-rail.mk5{background:var(--mk5)}
.qtr-clm-stmt{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;line-height:1.5;color:var(--text)}
.qtr-clm-conds{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);margin-top:var(--qtr-clm-cond-mt)}
.qtr-clm-cl{font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted)}
.qtr-clm-ct{font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.5;color:var(--text-soft);margin-top:var(--rec-tight)}
/* ⚠ ONE PAIR OF CONDITION GLYPHS EVERYWHERE (his note on consistency): fulfil is check in the
   state green, break is x in the state red — the same two the Intact / Broken chips use. The
   octagon is reserved for Alert and for errors. */
/* a 16px glyph beside 11px caps sits a hair high without this — the same nudge, and the same
   token, the Record's key column uses where a glyph meets text */
.qtr-clm-cond > .ic{flex-shrink:0;margin-top:var(--rec-tight)}
.qtr-clm-cond.ful > .ic{color:var(--green)}
.qtr-clm-cond.brk > .ic{color:var(--red)}
.qtr-claim .qtr-chips{margin-top:var(--qtr-clm-chips-mt)}
.qtr-note{margin-top:var(--chip-gap)}
/* the footer sits INSIDE the body and shares its gutter, which is what board 22 draws — the
   grammar is the modal footer's: draft status far left, Cancel, then the one fill. */
.qtr-foot{display:flex;justify-content:flex-end;gap:var(--sp-2);align-items:center;margin-top:var(--sp-5);padding-top:var(--sp-4);border-top:1px solid var(--line)}
/* A BODY THAT STACKS. Six of the ten screens lay their blocks out in one column at one
   distance; the form groups inside stop carrying their own bottom margin so the two do not add up. */
.modal-body.modal-stack{display:flex;flex-direction:column;gap:var(--modal-stack)}
.modal-body.modal-stack > .form-group{margin-bottom:0}
/* 21's mail button is a link that acts as a button; its glyph is 16 because it is the surface's
   one action rather than a symbol before a word (board §21 draws it at 16, not 14). */
/* the prose is a READING COLUMN, not body copy — Inter 15/1.6, the pane role (board §21) */
/* 19's version cards — a card inside a modal, so radius 10 and the modal's own inset rather than
   a page card's 16 and 20. The current one is card-selected; the rest are hairlines. */
.thv-ver{border:1px solid var(--line);border-radius:var(--radius-xs);padding:var(--sp-4) 18px;margin-bottom:var(--sp-3)}
.thv-ver.thv-cur{background:var(--navy-tint);border-color:var(--navy-soft);box-shadow:var(--sel-ring)}
.thv-ver-hd{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-3)}
.thv-date{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted)}
/* the way back is wayfinding, and it carries the one icon a text control may: its direction */
/* a raised question sits in the reading column, so it takes the same clear a paragraph does */
#nv-answers .callout{margin-bottom:var(--sp-4)}
#nv-answers .callout-m{margin-top:0}
/* 07's chart panel — level 2: a tint, radius 10, no border (a bordered box inside a modal would
   be the third nested surface). The chart itself is kept exactly as built. */
.chart-panel{background:var(--surface-tint);border-radius:var(--radius-xs);padding:var(--sp-4);margin-bottom:var(--sp-4)}
/* a state pill ON THE NAVY HEAD. The soft tints are drawn for white; on navy they vanish, so the
   ground goes to 22% and the word to white — 4.5:1 there, which the -strong twin is not. */
/* ⚠ s94 · TWO CLASSES, BECAUSE ONE LOST. .pill-state is declared ~600 lines later at the same weight, so its --text-soft
   word and neutral ground won the cascade — WEAKENING on his SSSG head read dark slate on red over navy (his screenshot). */
.pill-ondark,.pill-state.pill-ondark{color:var(--on-brand);background:var(--on-brand-line)}
.pill-ondark.ondark-red,.pill-state.pill-ondark.ondark-red{background:var(--red-on-navy)}
.sub-withpill{display:flex;align-items:center;gap:var(--chip-gap);flex-wrap:wrap}
.nv-back{display:inline-flex;align-items:center;gap:var(--sp-1)}
.nv-back > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.sup-prose{font-family:var(--font-ui);font-size:var(--fs-pane);line-height:1.6;color:var(--text-soft);margin:0}
/* 13's POSITION STATE pair — a chip-select row. The chosen chip is ring + navy tint like every
   other pick; its check is green because the GLYPH reports what holding means, and the board
   draws it that way. A row of chips is a row of chips: one rule, wherever they sit. */
.chip-row{display:flex;gap:var(--chip-gap);flex-wrap:wrap}
.pos-tick{color:var(--green)}
.sup-mail{text-decoration:none}
.sup-mail > .ic{width:var(--icon-glyph);height:var(--icon-glyph)}
.modal-foot-lead{display:inline-flex;align-items:center;gap:var(--sp-2);margin-right:auto}

/* ⚠ THE SECOND SHELL IS GONE. .tm-box, .tm-head, .tm-eyebrow, .tm-headline, .tm-close, .tm-body
   and .tm-foot are in the family's selector lists above; their own rules restated a look the
   family now carries, so they are deleted rather than kept as a copy that can drift. What went
   with them and is NOT coming back: the --chrome gradient head (v2: one flat navy head for
   every modal), the 760 box (there are three widths and 760 is not one), the GREEN eyebrow (an
   eyebrow is not state), .tm-stock (a sub-line is mono at 72% white, not a green ticker),
   .tm-rule's band (the head carries eyebrow + title + one sub-line AT MOST — the prose it held
   is the body's first paragraph now, which is what fixes UX-12) and the 640 bottom sheet (v2
   §7 decides 390 once: an inset card, never a sheet and never full-screen).
   .tm-hint stays — it is the ticker field's own helper line, not part of any shell. */
.tm-hint{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:6px;min-height:1rem}
@media (max-width:640px){
  .tm-box .g2{grid-template-columns:1fr;gap:0}
}

/* SAVE INDICATOR */
#saveIndicator{position:fixed;bottom:18px;right:18px;background:var(--navy);color:var(--on-brand);font-family:var(--font-mono);font-size:var(--fs-label);padding:6px 14px;border-radius:var(--radius-2xs);z-index:calc(var(--z-sticky) + 2);opacity:0;transition:opacity 0.3s;pointer-events:none}
#saveIndicator.show{opacity:1}

/* TOAST */
/* ⚠ THE TOAST MUST OUTRANK EVERY OVERLAY IN THE FILE (Vikas, 21 Aug). At z-index 99998 it
   sat UNDERNEATH .cfm-overlay (100000), so "Pick a note first" in the note picker was
   painted behind the dialog that raised it — a refusal the user could not read, which
   reads as a dead click. Anything added above 100050 must justify itself: a message the
   user cannot see is worse than no message. #sync-dot had the same latent bug at 9999. */
.toast{position:fixed;bottom:56px;right:18px;background:var(--navy);color:var(--on-brand);font-family:var(--font-mono);font-size:var(--fs-label);padding:var(--sp-2) var(--sp-4);border-radius:var(--radius-2xs);z-index:calc(var(--z-top) + 3);opacity:0;transition:opacity 0.3s;pointer-events:none;max-width:340px;line-height:1.35}
.toast.show{opacity:1}
.toast.err{background:var(--red-strong)}

/* IMPORT LOG */
.import-log-table{width:100%;border-collapse:collapse;font-size:var(--fs-small)}
.import-log-table th{text-align:left;padding:var(--sp-2) var(--sp-3);font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);border-bottom:2px solid var(--line);background:var(--surface-tint)}
.import-log-table td{padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--surface-tint);vertical-align:middle}

/* ── STEP 4: FULL FORENSICS REPORT ─────────────────────────────────────── */
.ob-spinner{width:34px;height:34px;border:3px solid var(--line);border-top-color:var(--navy);border-radius:50%;animation:ob-spin 0.8s linear infinite;margin:0 auto}
@keyframes ob-spin{to{transform:rotate(360deg)}}
.ob-rsl{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:1.5px;text-transform:uppercase;color:var(--navy);margin-bottom:0.55rem;padding-top:0.2rem}
.ob-metrics-row{display:grid;grid-template-columns:1fr 1fr 1fr;gap:var(--sp-2);margin-bottom:8px}
.ob-mc-label{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:0.7px;text-transform:uppercase;margin-bottom:1px}
.ob-mc-sub{font-size:var(--fs-label);color:var(--text-muted);margin-bottom:5px}
.ob-mc-number{font-family:var(--font-mono);font-size:var(--fs-display);font-weight:600;line-height:1;margin-bottom:5px}
.ob-mc-vs{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:600;padding:2px 7px;border-radius:var(--radius);display:inline-block}
.ob-mc-vs.pos{background:var(--green-soft);color:var(--green-strong)}
.ob-mc-vs.neg{background:var(--red-soft);color:var(--red-strong)}
.ob-mc-vs.na{background:var(--surface-tint);color:var(--text-muted)}
.ob-metric-card.ob-green .ob-mc-label{color:var(--green-strong)}
.ob-metric-card.ob-green .ob-mc-number{color:var(--green-strong)}
.ob-metric-card.ob-red .ob-mc-label{color:var(--red-strong)}
.ob-metric-card.ob-red .ob-mc-number{color:var(--red-strong)}
.ob-mc-bench{border-style:dashed}
.ob-mc-bench .ob-mc-label,.ob-mc-stub .ob-mc-label{color:var(--text-muted)}
.ob-mc-bench .ob-mc-number{color:var(--text);font-size:var(--fs-title)}
.ob-mc-stub{opacity:0.5}
.ob-compare-chart{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-xs);padding:12px 18px;margin-bottom:8px;display:flex;flex-direction:column;gap:10px}
.ob-compare-row{display:grid;grid-template-columns:68px 1fr 52px;align-items:center;gap:var(--sp-2)}
.ob-compare-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:0.5px;color:var(--text-muted);text-transform:uppercase}
.ob-compare-bar-wrap{height:22px;background:var(--surface-tint);border-radius:var(--radius-2xs);overflow:hidden}
.ob-compare-bar{height:100%;border-radius:var(--radius-2xs);transition:width 0.6s ease;min-width:3px;display:flex;align-items:center;padding-left:6px}
.ob-compare-bar .ob-cb-lbl{font-size:var(--fs-micro);font-weight:600;color:var(--on-brand);white-space:nowrap;opacity:0;transition:opacity 0.3s}
.ob-compare-bar.ob-wide .ob-cb-lbl{opacity:1}
.ob-cbar-g{background:var(--green)}.ob-cbar-b{background:var(--navy-soft)}.ob-cbar-m{background:var(--text-muted)}.ob-cbar-r{background:var(--red-strong)}
.ob-compare-val{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;text-align:right}
.ob-sanity-strip{display:flex;flex-wrap:wrap;gap:5px 18px;background:var(--surface-tint);border-radius:var(--radius-2xs);padding:var(--sp-2) var(--sp-3);margin-bottom:8px;border:1px solid rgba(0,0,0,0.05)}
.ob-sanity-item{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted)}
.ob-sanity-item strong{color:var(--text);font-weight:700}
.ob-sanity-item.ob-si-hi strong{color:var(--green-strong)}
.ob-sanity-item.ob-si-hi.ob-si-neg strong{color:var(--red-strong)}
.ob-gap-card{border-radius:var(--radius-xs);padding:14px 18px;display:flex;gap:var(--sp-4);align-items:flex-start;margin-bottom:0.8rem;border:1px solid transparent}
.ob-gap-number{font-family:var(--font-mono);font-size:var(--fs-display);font-weight:600;white-space:nowrap;flex-shrink:0}
.ob-gap-text h3{font-size:var(--fs-body);font-weight:700;margin-bottom:3px}
.ob-gap-text p{font-size:var(--fs-caption);color:var(--text-soft);line-height:1.55}
.ob-gap-stub{opacity:0.45;background:var(--amber-soft);border-color:rgba(133,79,11,0.2)}
.ob-driver-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:0.8rem}
.ob-driver-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-xs);padding:16px 14px 12px;display:flex;flex-direction:column}
.ob-dc-eyebrow{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:1.4px;text-transform:uppercase;color:var(--text-muted);margin-bottom:3px}
.ob-dc-headline{font-size:var(--fs-body);font-weight:800;line-height:1.25;color:var(--text);margin-bottom:8px}
.ob-dc-badge{display:inline-flex;align-items:center;gap:var(--sp-1);font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:0.3px;text-transform:uppercase;padding:var(--sp-1) var(--sp-2);border-radius:var(--radius);width:fit-content;margin-bottom:10px}
.ob-dc-badge::before{content:"";display:inline-block;width:5px;height:5px;border-radius:50%}
.ob-dc-badge.good{background:var(--green-soft);color:var(--green-strong)}.ob-dc-badge.good::before{background:var(--green-strong)}
.ob-dc-badge.poor{background:var(--red-soft);color:var(--red-strong)}.ob-dc-badge.poor::before{background:var(--red-strong)}
.ob-dc-badge.neutral{background:var(--amber-soft);color:var(--amber-strong)}.ob-dc-badge.neutral::before{background:var(--amber-strong)}
.ob-dc-badge.na{background:var(--surface-tint);color:var(--text-muted)}.ob-dc-badge.na::before{background:var(--text-muted);opacity:0.5}
.ob-cm-track{position:relative;height:6px;border-radius:var(--radius);background:linear-gradient(to right,var(--red-soft) 0%,var(--amber-soft) 40%,var(--green-soft) 80%);margin-bottom:4px}
.ob-cm-needle{position:absolute;top:50%;transform:translate(-50%,-50%);width:11px;height:11px;background:var(--text);border-radius:50%;border:2px solid var(--surface);box-shadow:0 1px 3px rgba(0,0,0,0.2);transition:left 0.6s ease}
.ob-cm-labels,.ob-hb-labels{display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-bottom:8px}
.ob-hb-track{position:relative;height:6px;border-radius:var(--radius);background:linear-gradient(to right,var(--viz-blue) 0%,var(--viz-mint) 40%,var(--viz-amber) 70%,var(--viz-red) 100%);margin-bottom:4px}
.ob-hb-needle{position:absolute;top:50%;transform:translate(-50%,-50%);width:11px;height:11px;background:var(--text);border-radius:50%;border:2px solid var(--surface);box-shadow:0 1px 3px rgba(0,0,0,0.2);transition:left 0.6s ease}
.ob-hold-compare{margin-bottom:10px;display:flex;flex-direction:column;gap:var(--sp-1)}
.ob-hc-row{display:flex;align-items:center;gap:var(--sp-1)}
.ob-hc-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);width:56px;flex-shrink:0}
.ob-hc-bar-wrap{flex:1;height:16px;background:var(--surface-tint);border-radius:var(--radius-2xs);overflow:hidden}
.ob-hc-bar{height:100%;border-radius:var(--radius-2xs);display:flex;align-items:center;padding-left:5px;font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;white-space:nowrap;transition:width 0.6s ease;min-width:2px}
.ob-hc-bar.winners{background:var(--green-soft);color:var(--green-strong)}.ob-hc-bar.losers{background:var(--red-soft);color:var(--red-strong)}
.ob-dc-human{font-size:var(--fs-caption);color:var(--text);line-height:1.6;font-weight:500;margin-bottom:8px;flex:1}
.ob-dc-human .hi-good{font-weight:700;color:var(--green-strong)}.ob-dc-human .hi-bad{font-weight:700;color:var(--red-strong)}.ob-dc-human .hi{font-weight:700}
.ob-dc-human .hi-sym{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:600;background:var(--surface-tint);padding:1px 4px;border-radius:var(--radius-2xs)}
.ob-dc-details{border-top:1px solid var(--line);padding-top:7px;margin-top:auto}
.ob-dc-details summary{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--text-soft);cursor:pointer;user-select:none;list-style:none;display:flex;align-items:center;gap:var(--sp-1)}
.ob-dc-details summary::before{content:"›";font-size:var(--fs-label);transition:transform 0.2s}
.ob-dc-details[open] summary::before{transform:rotate(90deg)}
.ob-dc-details .ob-tech-body{margin-top:5px;font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);line-height:1.65}
.ob-fy-legend{display:flex;gap:var(--sp-3);margin-bottom:4px;flex-wrap:wrap}
.ob-fy-legend-item{display:flex;align-items:center;gap:var(--sp-1);font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted)}
.ob-fy-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.ob-fy-dot.xirr{background:var(--viz-indigo)}.ob-fy-dot.twrr{background:var(--green)}.ob-fy-dot.nifty{background:var(--text-muted);opacity:0.6}
.ob-fy-chart-wrap{display:flex;flex-direction:column;gap:10px;margin-top:4px}
.ob-fy-chart-row{display:grid;grid-template-columns:44px 1fr;gap:var(--sp-2);align-items:center}
.ob-fy-chart-label{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;color:var(--text-muted);text-align:right}
.ob-fy-bars-group{display:flex;flex-direction:column;gap:var(--sp-1)}
.ob-fy-bar-line{display:flex;align-items:center;gap:var(--sp-1);height:17px}
.ob-fy-bar-track{flex:1;height:17px;display:flex;align-items:center}
.ob-fy-neg-zone{flex:1;height:100%;display:flex;align-items:center;justify-content:flex-end}
.ob-fy-pos-zone{flex:1;height:100%;display:flex;align-items:center;justify-content:flex-start}
.ob-fy-axis{width:2px;height:100%;background:var(--line);flex-shrink:0}
.ob-fy-bar-fill{height:9px;border-radius:var(--radius-2xs);transition:width 0.45s ease;flex-shrink:0}
.ob-fy-bar-fill.pos.xirr{background:rgba(99,102,241,0.28)}.ob-fy-bar-fill.pos.twrr{background:var(--green-soft)}.ob-fy-bar-fill.pos.nifty{background:rgba(136,136,136,0.18)}
.ob-fy-bar-fill.neg.xirr,.ob-fy-bar-fill.neg.twrr,.ob-fy-bar-fill.neg.nifty{background:rgba(121,31,31,0.18)}
.ob-fy-bar-val{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;white-space:nowrap;min-width:46px;padding-left:5px}
.ob-fy-bar-val.xirr{color:var(--viz-indigo)}.ob-fy-bar-val.twrr{color:var(--green-strong)}.ob-fy-bar-val.nifty{color:var(--text-muted)}.ob-fy-bar-val.neg{color:var(--red-strong)}
.ob-losers-table{width:100%;border-collapse:collapse;font-size:var(--fs-small)}
.ob-losers-table th{text-align:left;font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:0.5px;text-transform:uppercase;color:var(--text-muted);padding:0 var(--sp-2) var(--sp-2) 0;border-bottom:1px solid var(--line)}
.ob-losers-table td{padding:var(--sp-2) var(--sp-2) var(--sp-2) 0;border-bottom:1px solid var(--surface-tint);vertical-align:middle}
.ob-losers-table tr:last-child td{border-bottom:none}
.ob-sym-badge{font-family:var(--font-mono);font-weight:600;font-size:var(--fs-label);background:var(--surface-tint);padding:2px 5px;border-radius:var(--radius-2xs)}
.ob-pnl-cell{font-family:var(--font-mono);font-weight:600;color:var(--red-strong)}
.ob-pct-badge{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;padding:2px 5px;border-radius:var(--radius)}
.ob-pct-badge.neg{background:var(--red-soft);color:var(--red-strong)}.ob-pct-badge.pos{background:var(--green-soft);color:var(--green-strong)}

/* ════════ MOBILE / RESPONSIVE (added Jun 2026) ════════ */
.mobile-topbar{display:none}
.sb-scrim{display:none}
/* discipline holding cards (mobile register) */
.mobile-reg{display:none}
.mreg-sec{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted);margin:0.4rem 0 0.6rem}
.mreg-card{background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--green);border-radius:var(--radius-sm);padding:var(--sp-4) var(--sp-4);margin-bottom:0.7rem}
.mreg-card.watch{border-left-color:var(--amber)}
.mreg-card.exit{border-left-color:var(--red-strong)}
.mreg-card.blind{border-left-color:var(--text-muted);background:var(--surface)}
.mrc-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:0.7rem}
.mrc-name{font-weight:700;color:var(--navy);font-size:var(--fs-lead)}
.mrc-meta{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:1px}
.mrc-line{margin-bottom:0.6rem}
.mrc-k{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:var(--eyebrow);margin-bottom:2px}
.mrc-k.red{color:var(--red-strong)}
.mrc-v{font-size:var(--fs-small);color:var(--text-soft);line-height:1.42;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.mrc-foot{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:0.75rem;padding-top:0.65rem;border-top:1px solid var(--surface-tint)}
.mrc-conv{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;color:var(--text-soft)}
.mrc-pill{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;padding:var(--sp-1) var(--sp-2);border-radius:var(--radius-sm);letter-spacing:0.03em;margin-left:auto}
.mrc-pill.intact{background:var(--green-soft);color:var(--green-strong)}
.mrc-pill.review{background:var(--amber-soft);color:var(--amber-strong)}
.mrc-pill.decide{background:var(--red-soft);color:var(--red-strong)}
.mrc-pill.locked{background:var(--surface-tint);color:var(--text-muted)}
.mrc-blind{font-size:var(--fs-small);color:var(--text-soft);line-height:1.45;margin-bottom:0.7rem}
.mrc-cta{font-family:var(--font-ui);font-weight:600;font-size:var(--fs-small);padding:var(--sp-2) var(--sp-4);border-radius:var(--radius-xs);border:1px solid var(--navy-tint-strong);background:var(--navy-tint);color:var(--navy);cursor:pointer;width:100%}
.mreg-mini{display:flex;align-items:center;justify-content:space-between;gap:10px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-xs);padding:0.7rem 0.9rem;margin-bottom:0.55rem}
@media (max-width:768px){
  /* ⚠ THE 390 STRIP IS LIGHT — session 109, his pick of 3 Oct (Pages board 6d), with the 1440 wordmark: the shell's
     ground, a hairline under it, the menu glyph and the mark in navy. It WAS navy end to end (IA SPEC-shell §6, UX-55,
     to give --brand-mark a ground it could be read on); the mark is accepted on light as a logo. 52px. */
  :root{--sec-fs:var(--fs-title-sm);--pg-title:var(--fs-section)}
  :root{--pg-pad-x:var(--sp-4)}   /* s122 · a page's body on the head's 16px line (mockup v1's question 5) */   /* session 109 · a page-level card's title at the phone's title size · s117 · a page's heading at 24 */
  .mobile-topbar{display:flex;position:fixed;top:0;left:0;right:0;z-index:calc(var(--z-nav) + 1);align-items:center;gap:var(--sp-3);min-height:52px;background:var(--shell);border-bottom:1px solid var(--line);padding:0 var(--sp-4)}
  .mt-burger{width:44px;height:44px;border:none;border-radius:var(--radius-2xs);background:none;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;padding:0;margin-left:calc(var(--sp-3) * -1);color:var(--navy)}
  .mt-burger .ic{width:var(--mt-glyph);height:var(--mt-glyph)}
  .mt-brand{font-weight:800;font-size:var(--fs-title-sm);color:var(--navy)}
  .mt-brand span{color:var(--brand-mark)}

  /* the drawer — 280 (was 248), and the scrim is the modal navy at .7 rather than a near-black,
     so the app behind it reads as dimmed rather than switched off (IA SPEC-shell §6) */
  .sidebar{width:280px;min-width:280px;z-index:calc(var(--z-nav) + 3);transform:translateX(calc(-100% - var(--sp-7)));transition:transform 0.2s cubic-bezier(.4,0,.2,1);box-shadow:var(--shadow-modal)}
  .sidebar.open{transform:none}
  .sb-scrim.show{display:block;position:fixed;inset:0;background:var(--scrim);z-index:calc(var(--z-nav) + 2)}
  /* 44px rows in the drawer — the IA's hit-target floor at 390 */
  /* only the VERTICAL padding grows — the 14px gutter is the sidebar's own and is inherited,
     so the drawer's rows stay aligned with the group labels above them */
  .sidebar .nav-item{font-size:var(--fs-body);min-height:var(--nav-h-touch)}
  .sidebar .nav-add{min-height:var(--nav-h-touch)}
  #sb-stocks{max-height:var(--sb-list-max-sm)}
  .sb-close{display:flex;align-items:center;justify-content:center}

  .main{margin-left:0;padding-top:52px}
  .page{padding:0}
  .page-header{position:static;flex-wrap:wrap;gap:10px;padding:var(--sp-4)}
  .main.scrolled .page-header{border-bottom-color:transparent}
  .page-title{font-size:var(--fs-title)}
  .page > div[style*="padding"]{padding-left:1rem!important;padding-right:1rem!important}

  /* iOS Safari auto-zooms on focus when an input's font-size < 16px and never
     zooms back. Force 16px on all text controls (incl. inline-styled + the
     contenteditable note editor) to stop the zoom entirely. */
  input, textarea, select, .form-input, [contenteditable]{font-size:16px!important}

  /* Stop horizontal overflow — a single element wider than the viewport makes
     iOS render the whole page zoomed-out and the zoom sticks across navigation.
     (1) hard cap width + hide any stray horizontal scroll;
     (2) let long words break;
     (3) make inline `space-between` header rows (e.g. the thesis header with its
         Revisions / + Add Revision buttons) wrap instead of pushing past the edge. */
  /* ⚠ AND `overflow-x:hidden` GOES ON html ONLY — NOT ON body. Measured in a browser at 390
     on 9 Sep: with it on BOTH, every `position:sticky` inside body is INERT. Setting one axis
     to hidden computes the other from `visible` to `auto`, so body becomes a scroll container
     that never scrolls (its scrollHeight equals its clientHeight — html is what scrolls), and
     a sticky element's nearest scrolling ancestor is that dead container. The stock page's
     header measured top:-1124 at scrollY 1176 — it had not stuck on a phone since slice 6,
     and nobody could see it because R2 has never been tested on a device.
     ⚠ THIS IS WHY THE THREE-STICKY CHECK IS MANDATORY. Step 6 stacks three sticky layers on
     this page; all three were dead at 390 and the harnesses cannot see it, because a
     stylesheet that parses is not a layout that works. The clip still happens — html's own
     overflow applies to the viewport once it is non-visible, so the iOS zoom defect this
     rule exists for stays fixed. */
  html{overflow-x:hidden}
  .main,.page,.card,.tab-pane{max-width:100%}
  .card,.tab-pane{overflow-wrap:break-word}
  #page-stock [style*="justify-content:space-between"],
  #page-stock-empty [style*="justify-content:space-between"]{flex-wrap:wrap;gap:var(--sp-2)}

  .metric-row{grid-template-columns:1fr 1fr;gap:var(--sp-3)}
  .exp-grid{grid-template-columns:1fr 1fr}
  .xirr-banner{grid-template-columns:1fr 1fr}
  .g2,.g3{grid-template-columns:1fr}
  .tf-grid{grid-template-columns:1fr}
  .kpi-item{grid-template-columns:1fr 1fr;row-gap:var(--sp-1)}
  .kpi-item>*:first-child{grid-column:1/-1}

  /* ⚠ THE 390 HERO RULES MOVED TO THE 640px BLOCK (session 68). They sat HERE, 480 lines
     ABOVE the base rules they override, at equal specificity — so .hero-figs{display:flex}
     and .hero-factline{display:none} won on source order and the phone showed the four
     figures the IA replaces with one fact line. Measured, not reasoned: stmt from the shot. */

  .reg-desktop{display:none}
  .mobile-reg{display:block}

  /* Flex/grid children default to min-width:auto and refuse to shrink below their
     content width. So a wide element (e.g. the financials/journal table inside its
     overflow-x:auto wrapper) stretches its ancestors past the viewport instead of
     letting the wrapper scroll. On desktop body{overflow-x:hidden} hides this; iOS
     Safari ignores that and renders the whole page wide + zoomed. min-width:0 lets
     these containers shrink so the scroll wrappers actually scroll. Inline
     min-widths (e.g. the table's own min-width:500px) win on specificity and survive. */
  .page *{min-width:0}

  /* Ledger "New Transaction" form: the desktop rows (1fr×5 and 1fr 1fr auto) cram
     fields to unusable widths on mobile (the date input hogs the row), clipping the
     Price field. Collapse both rows to 2 equal columns. */
  .lg-form-row{grid-template-columns:1fr 1fr!important}

  /* KPI Monitor table (Evidence tab): desktop grid is 1fr 90px 90px 80px = 260px of
     fixed columns, which overflows narrow phones (≤360px). Drop the redundant Rule
     column (the rule already shows under the KPI name) and tighten Value/Status so the
     table fits. Status keeps 80px for its three 24px buttons. */
  .kpi-mon-row{grid-template-columns:1fr 56px 80px!important;gap:6px!important}
  .kpi-mon-row>*:nth-child(2){display:none}

  /* QR (Quarterly Review) accordion header on the Evidence tab is a flex row
     (label · quarter · status · chevron) with nowrap children. On narrow phones
     (≤~360px) the children don't fit on one line, so the chevron overflows and the
     min-width:0 shrink makes the nowrap label overlap its neighbours. Let the strip
     wrap — the label then sits on a line with room and keeps its full width. */
  .qr-strip{flex-wrap:wrap;row-gap:var(--sp-1)}
  /* Signals grid collapses to a single column on narrow phones */
  .sig-grid{grid-template-columns:1fr!important}
}

/* ─────────────────────────────────────────────────────────────────────────
   SIGNALS (Evidence tab redesign — Phase 1). Trend-based KPI cards.
   ───────────────────────────────────────────────────────────────────────── */
/* ⚠ THE SIGNALS LIST IS A GRID OF CARDS AGAIN (DP-1, session 69). Session 67 read the
   prototype's KPI pane as a five-column table and rebuilt this to it; nobody designed that
   table — the brief withheld every picture of the app and asked for four screens, none of
   them this one (audit §1.1). KPIs is an [E] surface: the existing signal card IS its spec,
   chart inside, and only the engulfing wrapper goes (.rec-sec .card, kept from session 68). */
/* ⚠ THE FLOOR IS RE-PINNED, AND MEASURED (DP-1). Session 66 drew a 2-column grid of 358px
   cards — but it got 2 columns from a 238px floor only because the engulfing card's 48px of
   padding narrowed the pane. Drop the wrapper, as he asked, and the same floor tips to 3
   columns of 273px, which squeezes the chart the restore exists to protect. 320px holds two
   at the pane's measured 844px and falls to one below 652px. */
/* board 04: two columns at 1440, one under 768, gap 16. It was auto-fill at a 320px minimum,
   which gives THREE in the Record's content column — a KPI card is a reading surface, and the
   board sizes it so a chart in it is still worth looking at. */
.sig-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}
.sig-card{border:1px solid var(--line);border-radius:var(--radius-sm);padding:var(--card-pad);background:var(--surface);display:flex;flex-direction:column}
/* the milestone card's one eyebrow — the field-label voice, clearing the head by the board's 20 */
.sig-card .field-label{margin-top:var(--sig-eb-top)}
.sig-name{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:700;color:var(--navy);line-height:1.25}
/* .sig-cad — QUARTERLY / MILESTONE — is the neutral pill-state (board 04: "words are not
   identifiers"). Its own rule is gone; it joins the component's selector list below. */
.sig-x{display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);margin-top:var(--chip-gap)}
/* s110 · the card chart's y-axis: the labels are a column beside the chart (the chart is stretched to the card's width, so
   nothing with letters in it may live inside the drawing). --spark-h is the chart's drawn height; the column's inset puts
   the first and last label on the top and foot gridlines, which sit the same distance in from each end. */
.sig-plot{display:flex;align-items:flex-start;gap:var(--sp-2)}
.sig-plot-c{flex:1 1 auto;min-width:0}
.sig-y{display:flex;flex-direction:column;justify-content:space-between;align-items:flex-end;flex:0 0 auto;height:var(--spark-h);padding:var(--spark-y-inset) 0;font-family:var(--font-mono);font-size:var(--fs-label);line-height:var(--spark-y-lh);color:var(--text-muted);white-space:nowrap}
/* S1 — composite signal legend, component editor, per-part log form */
/* the legend names the series, so it is words: Inter 12 in --text-soft, with a round dot.
   Board 04: "— watch only and legend → Inter; axis labels and figures stay mono." */
.sig-legend{display:flex;flex-wrap:wrap;gap:var(--sig-legend-step);margin-top:10px}
.sig-leg{display:inline-flex;align-items:center;gap:var(--chip-gap);font-family:var(--font-ui);font-size:var(--fs-caption);color:var(--text-soft);line-height:1.3}
.sig-leg i{width:var(--sig-dot);height:var(--sig-dot);border-radius:50%;flex-shrink:0;display:inline-block}
/* .compact is inert: board 04 draws ONE legend, and the card and the detail modal wear it. */
.sig-partial{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--amber-strong);background:var(--amber-soft);border-radius:var(--radius-2xs);padding:1px 5px;white-space:nowrap;margin-left:6px}
.sig-comp-row{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:6px}
.sig-comp-row i{width:11px;height:11px;border-radius:var(--radius-2xs);flex-shrink:0;display:inline-block}
/* board 06: a field inside a row grid is field-sm — 13px on 8px 12px — at >=768 only. The 390
   rule in the responsive block puts every field back to 16px, which is the iOS rule. */
.sig-comp-row input{flex:1;min-width:0;font-size:var(--fs-small);padding:var(--fld-pad-sm)}
.sig-part-lbl{display:flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-soft);min-width:0}
.sig-part-lbl i{width:9px;height:9px;border-radius:var(--radius-2xs);flex-shrink:0;display:inline-block}
.sig-total-pv{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-soft);margin-top:2px}
.sig-total-pv b{color:var(--navy);font-size:var(--fs-caption)}
/* the reading itself is a FIGURE, so it is mono — board 04 draws 700 28px/1, with the unit at 16 */
.sig-val{font-family:var(--font-mono);font-weight:700;font-size:var(--fs-display);color:var(--navy);line-height:1}
.sig-val small{font-size:var(--fs-lead);font-weight:700}
.sig-delta{font-family:var(--font-mono);font-size:var(--fs-caption);margin-top:var(--chip-gap)}
.sig-delta.flat{font-family:var(--font-ui);font-size:var(--fs-small)}
.sig-delta.up{color:var(--green-strong)}
.sig-delta.down{color:var(--red-strong)}
.sig-delta.flat{color:var(--text-muted)}
/* Improving / Weakening / Watch report a state, so they are pill-state — and the two that have
   a direction carry the Lucide arrow board 04 draws instead of a ▲▼ character. */
.sig-verdict.up{background:var(--green-soft);color:var(--green-strong)}
.sig-verdict.down{background:var(--red-soft);color:var(--red-strong)}
/* board 04: a solid hairline, 14 above and 14 below — a dashed rule inside a card is a second
   kind of line for no second reason. */
.sig-foot{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sig-step);padding-top:var(--sig-step);border-top:1px solid var(--line)}
/* Log reading is the card's LEAD action in the green outline — his call, 11 Sep: it must read as
   one, and with four cards in sight a fill would shout. It was a navy-tinted mono box, which is
   a tier the ladder does not have. ⚠ The MILESTONE card's Update status is the grey secondary:
   board 04's notes say outline-action and its HTML draws the hairline, and the HTML wins. */
.sig-logbtn{flex:1;height:var(--sig-btn-h);padding:var(--sig-btn-pad)}
/* .sig-expand — the KPI card's settings and expand, beside Log reading — is the board's
   icon-button-framed; its look is in ICON BUTTONS. */
.sig-seg{display:flex;gap:6px;flex-wrap:wrap}
/* the KPI editor's segmented picks are chip-select — one component, one hairline. */
/* board 05: "Field labels → Inter 12/600 caps (were mono). '(optional)' at weight 400." It is
   the field-label component with the board's own top step; the component's 6px is what sits
   under it, which board 05 draws under every field and widens to 8 under a chip group — one
   value ships, the way every other doubled value in this phase has. */
.sig-fld-lbl{margin-top:var(--sig-eb-top)}
/* board 05: the tile is a level-1 card — hairline, radius 16, no shadow, padding 24. It was a
   1.5px DASHED box on a 1.5%-tinted ground, which is a fourth kind of surface the system does
   not have; an inline form is a card (the inline-vs-modal rule says so in as many words).
   ⚠ ITS CORNER STAYS ON THE MARKUP, where this file already kept it. Folding a radius in
   here would make the box probe count a box that has been drawn since the add-form
   shipped — a more accurate probe, and a number that RISES, which is his call and not a
   phase's. The utility moves from the 10 to the 16 a card wears; nothing else changes. */
.sig-add-tile{border:1px solid var(--line);background:var(--surface);padding:var(--sig-tile-pad)}
/* its heading — a label, not a field, and the board draws it at the card-heading weight */
.sig-tile-t{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:800;color:var(--navy)}
/* and its footer is the family's grammar on the family's hairline */
.sig-tile-foot{display:flex;justify-content:flex-end;gap:var(--sp-2);align-items:center;margin-top:var(--sp-5);padding-top:var(--sp-4);border-top:1px solid var(--line)}
/* Kind chooser — card-style like the thesis-modal path picker, for a crisp primary choice */
.sig-kindgrp{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3)}
/* the chosen one is ring + navy tint already — board 05: "kind cards already right. Kept."
   What moves is the geometry: the board pads them 16/18 and hairlines them at --line. */
.sig-kind{text-align:left;background:var(--surface);border:1.5px solid var(--line);border-radius:var(--radius-xs);padding:var(--sig-kind-pad);cursor:pointer;transition:border-color .15s,background .15s,box-shadow .15s;font-family:inherit}
.sig-kind:hover{border-color:var(--navy-soft)}
.sig-kind.on{border-color:var(--navy-soft);background:var(--navy-tint);box-shadow:var(--sel-ring)}
.sig-kind-t{display:block;font-weight:700;font-size:var(--fs-pane);color:var(--navy)}
.sig-kind-d{display:block;font-size:var(--fs-small);color:var(--text-soft);line-height:1.5;margin-top:var(--sp-1)}
@media(max-width:640px){.sig-kindgrp{grid-template-columns:1fr}}
/* ⚠ NOT A BOX (DP-1, §2a.7): a bordered tinted panel inside the signal card put the log
   form's own fields three boxes deep. The card is the ground; a hairline is the opening. */
.sig-logform{margin-top:var(--sp-3);padding-top:var(--sp-3);border-top:1px solid var(--line)}
.sig-th{text-align:left;font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);padding:var(--sp-2) var(--sp-2);border-bottom:2px solid var(--line)}
.sig-td{padding:var(--sp-2);border-bottom:1px solid var(--surface-tint);font-size:var(--fs-small);color:var(--text)}
.sig-rd-act{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--accent);cursor:pointer;margin-left:var(--sp-4);background:none;border:none;padding:0}
.sig-rd-act:hover{text-decoration:underline;color:var(--accent-hover)}
.sig-rd-act.del,.sig-rd-act.del:hover{color:var(--red-strong)}
.sig-select{min-width:0}
.sig-select:disabled{background:var(--surface-tint);color:var(--text-muted)}
.ms-chip.pending{background:var(--neutral-fill);color:var(--text-soft)}
.ms-chip.ontrack{background:var(--green-soft);color:var(--green-strong)}
.ms-chip.delayed{background:var(--amber-soft);color:var(--amber-strong)}
.ms-chip.delivered{background:var(--green-soft);color:var(--green-strong);font-weight:700}   /* was a saturated --green fill carrying a STATE — demoted §2a.6 to the tint every other state pill wears; weight marks "done" */
.ms-chip.missed{background:var(--red-soft);color:var(--red-strong)}
.sig-empty{display:grid;grid-template-columns:1.15fr 0.85fr;gap:1.4rem;align-items:center;padding:0.6rem 0.4rem}
.sig-empty-q{font-size:var(--fs-lead);font-weight:800;color:var(--navy);line-height:1.25}
.sig-empty-p{font-size:var(--fs-small);color:var(--text-soft);margin-top:8px;line-height:1.5}
.sig-empty-sug{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);margin:var(--sp-4) 0 var(--sp-2)}
.sig-echips{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.sig-echip{font-family:var(--font-mono);font-size:var(--fs-label);background:var(--surface-tint);border:1px solid var(--line-strong);color:var(--text-soft);border-radius:var(--radius-sm);padding:var(--sp-1) var(--sp-3);cursor:pointer;transition:all .15s}
.sig-echip:hover{background:var(--line);color:var(--text)}
.sig-ghost{border:1.5px dashed var(--line-strong);border-radius:var(--radius-xs);padding:var(--sp-4);background:rgba(13,24,41,0.015)}
@media(max-width:768px){.sig-empty{grid-template-columns:1fr}}
/* ── Evidence tab · Phase 2 ─────────────────────────────────────────────────── */
/* Thesis Health */
/* ⚠ RESTORED (DP-1, session 69) — his instruction, 9 Sep: "use the existing KPI card, just
   drop the engulfing card… same feedback for other pages". The Organizer is an [E] surface
   (audit §4.2): the ring, the counts, the calendar tile and the review rail are the existing
   surface, and the only thing that goes is the wrapper (.rec-sec .card, session 68's rule). */
.ev2-row2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-5);margin-bottom:var(--sp-5);align-items:stretch}
.ev2-row2 .card{margin-bottom:0;height:100%}
.th-card{display:flex;align-items:center;gap:var(--sp-4)}
.th-ring{width:60px;height:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.th-ring.good{background:var(--green-soft)} .th-ring.mixed{background:var(--amber-soft)} .th-ring.risk{background:var(--red-soft)} .th-ring.none{background:var(--surface-tint)}
.th-ring svg{width:28px;height:28px}
.th-status{font-weight:800;font-size:var(--fs-title);line-height:1}
.th-status.good{color:var(--green-strong)} .th-status.mixed{color:var(--amber-strong)} .th-status.risk{color:var(--red-strong)} .th-status.none{color:var(--text-muted)}
.th-sub{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:var(--sp-1)}
.th-counts{margin-left:auto;display:flex;flex-direction:column;gap:var(--sp-1);min-width:var(--rec-k-wide)}
.th-cnt{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-caption);color:var(--text-soft)}
.th-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.th-num{margin-left:auto;font-weight:700;font-family:var(--font-mono);color:var(--navy)}
.th-empty{display:flex;align-items:center;gap:var(--sp-4)}
/* Next Review */
.nr-card{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4)}
.nr-lead{display:flex;align-items:center;gap:var(--rec-strip-step);min-width:0}
/* s117 · the strip leads with the section plate (.sec-plate) and Quarterly Review's glyph; its 10px state dot is gone. */
.nr-title{font-weight:700;font-size:var(--fs-lead);color:var(--navy)}
.nr-due{font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-muted);margin-top:var(--rec-tight)}
.nr-btn{margin-left:auto;flex-shrink:0}
.nr-btns{margin-left:auto;display:flex;gap:var(--sp-2);flex-shrink:0;align-items:center}
.nr-btns .nr-btn{margin-left:0;white-space:nowrap}
/* Review history — the rail of quarter cards */
.rh-track{display:flex;align-items:stretch;gap:var(--sp-4);overflow-x:auto;padding:var(--sp-2) var(--rec-tight) var(--chip-gap)}
.rh{min-width:232px;max-width:270px;flex:0 0 auto;display:flex;flex-direction:column;background:var(--surface-tint);border:1px solid var(--line-strong);border-radius:var(--radius-xs);padding:var(--sp-4) var(--sp-4) var(--rec-row-y)}
.rh-q{font-family:var(--font-mono);font-size:var(--fs-small);font-weight:700;color:var(--navy);letter-spacing:0.02em}
.rh-date{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:var(--rec-tight)}
.rh-dec-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted);margin-top:var(--rec-row-y)}
.rh-action{font-size:var(--fs-body);font-weight:700;color:var(--text);margin-top:var(--rec-tight)}
.rh-link:hover{text-decoration:underline;color:var(--accent-hover)}
.rh-link{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--accent);margin-top:auto;padding-top:var(--sp-3);display:inline-block;cursor:pointer;background:none;border:none;align-self:flex-start}
/* Exit commitment framing */
.ev2-commit{border-left:3px solid var(--navy-soft)}
.ev2-commit-sub{font-size:var(--fs-caption);color:var(--text-soft);margin:2px 0 0.9rem;line-height:1.5}
/* Events & Milestones timeline */
.ev2-ev{display:flex;gap:var(--sp-3);padding:var(--sp-2) 0;border-bottom:1px solid var(--surface-tint)}
.ev2-ev:last-child{border-bottom:none}
.ev2-date{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);white-space:nowrap;width:74px;flex-shrink:0;padding-top:3px}
.ev2-dot{width:8px;height:8px;border-radius:50%;background:var(--green);margin-top:7px;flex-shrink:0}
.ev2-dot.grey{background:var(--text-muted)} .ev2-dot.red{background:var(--red-strong)} .ev2-dot.amber{background:var(--amber)}
.ev2-body{font-size:var(--fs-small);color:var(--text-soft);flex:1;line-height:1.4}
.ev2-ev .ev2-act{margin-left:auto;display:flex;gap:var(--sp-2);flex-shrink:0;align-self:flex-start;padding-top:1px}
/* Row actions. These used to be padding:0 at 0.58rem sitting 6px from a 1rem kebab — two
   different sizes with no hit area, visually merging into each other. Both now share one height
   and a real target. */
/* ⚠ THE TERTIARY TIER IS VIOLET FROM HERE (§2b.2 #5, step 5). One rule, 37 call sites —
   the sweep is a colour change, not a markup change, which is the whole point of having
   had a tier. It lands in the SAME change as the marker ramp because M1 is --navy-soft:
   until these row actions stop being navy-soft, an M1 claim's identity rule and its Edit
   link are the same colour. */
/* ⚠ ONE VIOLET SPEC, TAKEN FROM THE PROTOTYPE RATHER THAN INFERRED. Every tertiary action
   the design draws is Inter 13/500 --accent with no padding, no border and no box — the
   hover is an underline. A second violet style (mono, boxed, lowercase) beside the first
   is the inconsistency he named: "some violet buttons are different".
   ⚠ .del STAYS RED. Destructive actions are red in this app with no exceptions, and the
   tier is about geometry and weight, never about overriding a meaning.
   ⚠ THE v2 NAMES (board §2, session 73): this group IS text-action and its red variant IS
   text-destructive. The board's names head the selector lists so new markup can use them; the
   old names stay in the lists so no reader moved. Text controls live INSIDE ROWS — a header, a
   card head or a strip gets a box (button-neutral) — and a destructive one is always gated. */
/* ⚠ .clm-sect-act HAS LEFT THIS TIER AND KEPT ITS NAME. His ruling, 12 Sep: Add a claim is the
   Claims surface's one green fill, so it wears the ladder's button-primary — but the class
   stays on the element because board 5a's claims-add probe aims at it BY NAME, and a probe
   that stops finding its element reports nothing rather than a difference. It draws nothing
   now; it is a hook. ⚠ .clm-editlink STAYS: only the claim head's instance became a box, and
   the note row's Open note and the hero's two inline links are text-action inside a row,
   which is exactly where violet belongs. */
.text-action,.text-destructive,.ev2-mini,.clm-editlink,.clm-addbtn{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--accent);cursor:pointer;background:none;border:none;padding:0;white-space:nowrap;text-align:left;line-height:normal;text-decoration:none}
.text-action:hover,.text-destructive:hover,.ev2-mini:hover,.clm-editlink:hover,.clm-addbtn:hover{text-decoration:underline;color:var(--accent-hover);background:none}
.text-destructive,.ev2-mini.del{color:var(--red-strong)}
.text-destructive:hover,.ev2-mini.del:hover{color:var(--red-strong)}
/* ⚠ WAYFINDING IS NOT AN ACTION — §2b.2 #4, and it answers his question directly. Violet
   means "the thing to do next", so a card cannot carry two violet controls; View source
   note does not ask you to do anything, it takes you to where the claim came from. The
   system already had the treatment: --text-soft 500, same size, no colour.
   v2 (board §2) names it text-wayfinding — back, where-from, or what is already on the page.
   Alone in its row; beside another control it becomes a button-neutral. Its one icon is the
   disclosure chevron, 14px, before the word, the sp-1 step from it. */
.text-wayfinding,.clm-srclink{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--text-soft);background:none;border:none;padding:0;cursor:pointer;white-space:nowrap;line-height:normal;text-decoration:none}
.text-wayfinding:hover,.clm-srclink:hover{text-decoration:underline;color:var(--navy)}
.text-wayfinding:has(> .ic){display:inline-flex;align-items:center;gap:var(--sp-1)}
/* text-dismiss (board §2) — Cancel or Close standing bare, out of a footer: grey 600, never violet
   and never green. In a footer the dismiss is the hairline button. The board draws no hover. */
.text-dismiss{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:600;color:var(--text-soft);background:none;border:none;padding:0;cursor:pointer;white-space:nowrap;line-height:normal}
/* Notes / Sources item rows */
.ev2-item{display:flex;align-items:center;gap:10px;padding:var(--sp-2) 0;border-bottom:1px solid var(--surface-tint)}
.ev2-item:last-child{border-bottom:none}
.ev2-ico{font-size:var(--fs-body);color:var(--text-muted);flex-shrink:0}
.ev2-name{font-size:var(--fs-small);font-weight:600;color:var(--text)}
/* s94 · R4-5 · a source's description — his words about it, whole, under its name */
.src-desc{font-size:var(--fs-small);line-height:1.45;color:var(--text-soft);margin-top:var(--rec-tight)}
/* s117 · a saved source's link (its name, and the domain under it): drawn as it was at rest; on hover and on keyboard focus
   it underlines and takes the link colour — the hover every text action has (.text-action:hover). His line of 7 Oct. */
.src-link{color:inherit;text-decoration:none}
.src-open{display:block;width:fit-content;max-width:100%;color:var(--text)}
.src-link:hover,.src-link:focus-visible{text-decoration:underline;color:var(--accent-hover)}
/* Q1 · A note's SOURCE is its title line in the notes card, and the resolve flow pre-fills
   it with the whole question — which can be long. Clamp to two lines so a long title can
   never blow the row height out. Applies to notes and questions only, not every ev2-name. */
.ev2-name.clamp2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* PB slices 1–3 · claim cards.
   Slice 1 was a read-only preview. Slice 3 makes every card actionable (D5: all the verbs),
   so the hover affordances that were deliberately absent are now deliberately present —
   an interactive card must look interactive, and a static one must not. */
.clm-card{border:1px solid var(--line);border-radius:var(--radius-xs);padding:0.8rem 0.85rem;margin-bottom:0.7rem;background:var(--surface);transition:border-color .12s,box-shadow .12s}
/* ⚠ ON THE STOCK PAGE THE PADDING IS THE ROW'S, NOT THE CARD'S (SPEC-components §1). The
   card sits at 0 so the collapsed row and the expanded body each own their inset and the
   two cannot compound. Scoped: .clm-card also dresses the proposal card and the thesis
   history modal, which are not redesigned. */
/* ⚠ A CARD IS 16, AND THE SCALE SAYS SO WITHOUT ANYONE RULING ON IT — --radius-sm is cards and
   modals, --radius-xs is buttons, fields, select chips and popovers, --radius-2xs is pills, tags
   and rows. THERE IS NO 10px CARD IN THE SCALE. His ruling of 12 Sep put the on-page claim card
   there (spec P3-Q1, board 5a superseded on that element); the scale is why it stays there.
   ⚠ SO THE DISCARD SHELF TAKES IT TOO — his call, 13 Sep, delegated to the hierarchy. A
   discarded claim is a claim card: same content, same renderer, read-only and dimmed. It was
   sitting at 10 directly beneath its live siblings at 16, on one section.
   ⚠ AND THE SCOPE STILL DOES NOT COLLAPSE ONTO THE BARE CLASS — but the REASON changed under it.
   Session 75's note said the bare .clm-card dresses the proposal card and the thesis history
   modal. The proposal card has not worn it since DP-5; it is .pr-card, which is what board 6e
   actually measures. The one consumer left is the LEGACY thesis-form card inside 19, whose
   siblings that board draws at 10 — where the scale says 16. A board disagreeing with the scale
   is the next design round's to settle, not this phase's to assume, so that one is left alone
   and the question is written down. */
.clm-card.clm-onpage,.clm-card.discarded{border-radius:var(--radius-sm)}
.clm-card.clm-onpage{padding:0}
.clm-card.clm-onpage .clm-head{padding:var(--sp-4) var(--card-x)}
.clm-card.clm-onpage .clm-body{padding:var(--sp-1) var(--card-x) var(--card-x);margin-top:0;border-top:none}
/* An open card takes the selection ring — the same one every chosen thing in this app
   takes. It is how the card you are reading is told from the two you are not. */
.clm-card.clm-onpage.open{box-shadow:var(--sel-ring)}
.clm-card:last-child{margin-bottom:0}
.clm-card:hover{border-color:var(--line-strong)}
/* ⚠ THE PRIMARY CARD IS THE ONLY ONE THAT LOOKS CHOSEN. Nothing is pre-selected — is_primary
   is false on every extracted claim precisely because which bet is primary is a judgement
   made HERE. This style must never be applied by a default. */
.clm-card.primary{border-color:var(--navy-soft);box-shadow:0 0 0 1px var(--navy-soft) inset}
/* Session 55 · the REVIEW card is a claim card. His review, 2 Sep: "the buttons, the
   selections, the chips etc., the chip colors, everything is violating what has been
   already there." The review modal had grown its own vocabulary — raw checkboxes, raw
   radios, inline-styled boxes. It now uses .clm-card / .clm-stmt / .clm-cond /
   .clm-primary-badge / .ev2-mini / .cs-mode exactly as the stock page does. A KEPT card is
   outlined (this rule); the BET card is .primary, the same ring as on the stock page. */
.clm-card.kept{border-color:var(--navy-soft)}
.clm-card.discarded{opacity:0.62;background:var(--surface-sunken)}
.clm-stmt{font-size:var(--fs-body);line-height:1.5;font-weight:600;color:var(--text)}
.clm-stmt-row{display:flex;align-items:flex-start;gap:var(--sp-2)}
.clm-condgrp{margin-top:0.7rem}
.clm-condlbl{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;color:var(--text-muted)}
/* ⚠ THE CONDITION PAIR IS ONE PAIR EVERYWHERE — board 22 draws check for fulfil and x for
   break at 14px stroke 2.25, the SAME pair as the Intact/Broken chips and the review panel,
   and DESIGN says so as a rule rather than as a drawing. It replaces the 6px dot on this row
   only: .clm-dot is still the chain island's, the state picker's and the hero strip's, and a
   rule written for the shape would have reached all of them. */
.clm-condic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.clm-condic.brk{color:var(--red)}
.clm-condic.flf{color:var(--green)}
/* Conditions are the user's verbatim words. Left rule, not a bullet — a bullet list implies
   an ordered severity ranking, and breaks_if is explicitly NOT ranked (engine notes §12.1:
   the yellow flag and the red flag are two entries in one list, not two kinds of thing). */
.clm-cond{font-size:var(--fs-small);line-height:1.45;color:var(--text-soft);padding:2px 0 2px 9px;border-left:2px solid var(--line-strong);margin-bottom:3px;display:flex;align-items:flex-start;gap:6px}
.clm-cond-txt{flex:1;min-width:0}
/* ⚠ AN AUTHORED CONDITION IS MARKED — by the SELF-AUTHORED pill, and by that alone (session 87,
   finding 17). The dashed rail carried the same fact a second way and he read it as a rendering
   defect after editing a condition. A hand-typed line still has no offsets into any source; the
   pill keeps the distinction the PB-e migration exists to keep. */
.clm-cond.authored{border-left-style:solid}
/* ⚠ ROLE-COLOURED, AND THE ROLE IS PASSED IN RATHER THAN READ OFF THE SPAN. A span row
   knows its role only because _claimCondSpans filtered for it; asking the row to
   re-derive it is how the two disagree later. */
.clm-cond.brk{border-left-color:var(--red)}
.clm-cond.flf{border-left-color:var(--green)}
/* ── Self-authored chip. His review, 30 Aug: "Self-authored claims and conditions
   look wierd with 'yours' tag. Why the complete abolishment of the design system."
   So it is a PILL now, in the .clm-state / .ev2-pill family — mono, uppercase,
   padded, tinted — not a bare lowercase word floating in the row. */
.clm-yours-chip{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;padding:2px 7px;border-radius:var(--radius-2xs);background:rgba(44,79,154,0.08);color:var(--navy-soft);white-space:nowrap;flex-shrink:0}
.clm-condacts{display:flex;gap:var(--sp-3);flex-shrink:0;margin-left:auto;opacity:0;transition:opacity .12s}
.clm-cond:hover .clm-condacts,.clm-cond:focus-within .clm-condacts{opacity:1}
/* ⚠ A PHONE HAS NO HOVER. Reveal-on-hover would make editing and removing a condition
   completely unreachable on touch — the actions would render, be invisible, and still take
   the tap. Any coarse pointer gets them shown outright. R2 is still untested on a device,
   but this particular defect is closed rather than carried. */
@media (hover:none),(pointer:coarse){ .clm-condacts{opacity:1} .clm-card.clm-onpage .clm-stmt-d{white-space:normal;overflow:visible} }
.clm-nocond{font-size:var(--fs-caption);color:var(--text-muted);margin-top:0.6rem;font-style:italic}
.clm-foot{display:flex;align-items:center;gap:var(--sp-2);margin-top:0.75rem;flex-wrap:wrap}
/* ⚠ STATE WORDS ARE INTER 600 12px UPPERCASE NOW, NOT 10px MONO (§2b.2 #2, and the
   unresolved half of UX-19). §2a.9's converged rule: mono is for IDENTIFIERS and FIGURES.
   "STRAINED" is a word, not an identifier — it was the weakest use of mono in the app.
   The C-id beside it stays mono, because that genuinely is an identifier. */
/* ══ pill-state — v2 board §4 (Phase 3, session 74) ═══════════════════════════════════════
   What state is this in — and what KIND of thing is this. One box, one type, a tint and its
   text twin; the chevron is what makes it a control. It is exempt from the green ration
   because it reports rather than asks. A pill borrows its hue from the callout family:
   violet is a question, teal is their word, navy is settled, gold is the one. Green, amber
   and red stay for state, and no other hue makes a pill.
   ⚠ THE NEUTRAL GROUND IS THE BOX BUTTON'S FILL, NOT THE ROW TINT. Both boards draw .06 and
   this file carried .04 for two phases — a ruled deviation on 6e purely because no token held
   the value. Phase 2's named it, so it closes here rather than being carried again. */
/* ⚠ white-space:nowrap — board 04's own 390 drawing declares it and this rule did not, so the
   MILESTONE pill rendered 86×38 as "MILESTON / E" on a phone (session 78's audit). tag-mono,
   tag-marker and clm-cid have carried it all along; the pill family was the one that did not. */
.pill-state,.clm-state,.ev2-pill,.ms-chip,.sig-cad,.sig-verdict{font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;line-height:1.4;text-transform:uppercase;letter-spacing:0.04em;padding:var(--pill-pad);border-radius:var(--radius-2xs);background:var(--neutral-fill);color:var(--text-soft);white-space:nowrap}
/* a pill carrying a glyph lays out like the board's: the glyph is 12px and 4px from the word */
.pill-state:has(> .ic),.clm-state:has(> .ic),.ms-chip,.sig-verdict:has(> .ic){display:inline-flex;align-items:center;gap:var(--sp-1)}
.pill-state > .ic,.clm-state > .ic,.ms-chip > .ic{font-size:var(--fs-caption)}
.pill-state.strained,.clm-state.strained{background:var(--amber-soft);color:var(--amber-strong)}
.pill-state.broken,.clm-state.broken{background:var(--red-soft);color:var(--red-strong)}
/* ⚠ `live` IS THE DATABASE VALUE AND `supported` IS THE LABEL — his ruling D1: "rename
   intact to supported. Live was not a good word and intact clashes with the overall
   thesis status." Nothing writes `supported` to Postgres; only the word on screen
   changes. `intact` belongs to STORY status, fourteen vertical pixels away at 390. */
.pill-state.supported,.pill-state.live,.clm-state.live{background:var(--green-soft);color:var(--green-strong)}
.pill-state.fulfilled,.pill-state.reviewed,.clm-state.fulfilled{background:var(--navy-tint);color:var(--navy-soft)}
/* superseded is SYSTEM-SET, never user-set, and it is shown rather than hidden (his D2).
   Neutral by design: it is not a state the bet is in, it is a note that it was rewritten. */
.pill-state.superseded,.clm-state.superseded{background:var(--surface-sunken);color:var(--text-muted)}
/* Session 48 · the route-link effect chips share the state-pill family. ⚠ All three carried a
   raw rgba of their own — two of them a DIFFERENT alpha and a different hue from the state
   token that means the same thing. The board draws the state's own -soft; so do they now. */
.pill-state.supports,.clm-state.supports{background:var(--green-soft);color:var(--green-strong)}
.pill-state.strains,.clm-state.strains{background:var(--amber-soft);color:var(--amber-strong)}
.pill-state.breaks,.pill-state.weakening,.clm-state.breaks{background:var(--red-soft);color:var(--red-strong)}
/* the coloured KINDS — what sort of thing this is, never what state it is in */
.pill-state.question{background:var(--accent-soft);color:var(--accent-strong)}
.pill-state.commitment{background:var(--teal-soft);color:var(--teal-strong)}
.pill-state.key{background:var(--gold-soft);color:var(--navy)}
/* ⚠ GOLD IS A BORDER, A FILL AND A GLYPH — NEVER A WORD. --gold-deep measures 3.15:1,
   which clears the 3:1 minimum for a non-text mark and FAILS as text. So the ★ is gold
   and "PRIMARY CLAIM" is navy. This is the one part of the design that was already
   self-aware about its own contrast, and it must not be "tidied" into all-gold. */
.badge-mark,.badge-mark-off,.clm-primary-badge,.clm-mkprim{font-family:var(--font-ui);font-size:var(--fs-label);font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:0.06em;padding:var(--chip-pad);border-radius:var(--radius-2xs);background:var(--gold-soft);border:1.5px solid var(--gold-deep);color:var(--navy);display:inline-flex;align-items:center;gap:var(--chip-gap)}
.badge-mark > .ic,.clm-primary-badge .pb-star{color:var(--gold-deep);font-size:var(--fs-caption)}

/* ── THE FIVE-MARKER RAMP — claim identity (§2b.3). ────────────────────────────────
   A 3px left rule plus a bold mono C-id on every claim card. The ramp cycles after five
   and the C-id carries the rest, which is why the C-id is not decoration: it is the
   non-chromatic half of the identity, and under protan/deutan vision navy-soft and
   indigo converge, so colour alone was never going to be enough. */
.clm-card.clm-onpage{border-left-width:3px;border-left-style:solid;border-left-color:var(--line)}
.clm-card.mk1,.pr-card.mk1{border-left-color:var(--navy-soft)} .pr-c-n.mk1,.prhl-n.mk1{color:var(--navy-soft)}
.clm-card.mk2,.pr-card.mk2{border-left-color:var(--mk2)}       .pr-c-n.mk2,.prhl-n.mk2{color:var(--mk2-t)}
.clm-card.mk3,.pr-card.mk3{border-left-color:var(--mk3)}       .pr-c-n.mk3,.prhl-n.mk3{color:var(--mk3-t)}
.clm-card.mk4,.pr-card.mk4{border-left-color:var(--mk4)}       .pr-c-n.mk4,.prhl-n.mk4{color:var(--mk4-t)}
.clm-card.mk5,.pr-card.mk5{border-left-color:var(--mk5)}       .pr-c-n.mk5,.prhl-n.mk5{color:var(--mk5-t)}
.clm-idrow{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-1);flex-wrap:wrap}
.clm-spacer{margin-left:auto}
.clm-editrow{margin-top:6px}
/* ⚠ ONE RULE FOR EVERY CLAIM-SURFACE TEXTAREA. His review, 30 Aug: "the edit box is
   very narrow. Why a different box? It should be same as how it was while adding."
   The edit box was never styled differently on purpose — it sat OUTSIDE .clm-editrow
   /.clm-addrow, so it fell through to the browser default (narrow, monospace). The
   fix is the markup wrapping it in .clm-editrow; this selector list is kept tight so
   the same fall-through cannot happen silently again. */
.clm-editrow textarea,.clm-addrow textarea{width:100%;resize:vertical;padding:var(--sp-2) var(--sp-2);border:1.5px solid var(--line-strong);border-radius:var(--radius-2xs);font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.45;background:var(--surface);box-sizing:border-box}
.clm-editbtns{display:flex;gap:6px;justify-content:flex-end;margin-top:6px}
/* ── Claim state-change modal (session 46) ── */
/* the quoted claim is callout-quote (the anatomy is in the component block): a navy-tint
   ground and a 3px rule — a quotation mark, not a box. Only its own margin is left here. */
.cs-quote{border-radius:var(--radius-2xs);padding:var(--callout-pad);margin-bottom:var(--sp-4);font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;line-height:1.5;color:var(--text)}
/* Helper line under a form field. ⚠ NOT .ev2-isub — that class is a one-line truncating
   sublabel (max-width:180px, nowrap) and using it under form fields is what clipped the
   claim-author modal's helper copy mid-sentence. */
.form-help{font-size:var(--fs-caption);color:var(--text-soft);margin-top:5px;line-height:1.45}
/* Freed from --navy-soft in the same change, so navy-soft can carry M1's identity. */
/* The heading row itself: dot + label left, Add right. baseline, so the 13px action sits
   on the same line as the 10px mono label rather than centring against it. */
.clm-condhd{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:var(--chip-gap)}
.clm-condlbl-w{display:flex;align-items:center;gap:var(--chip-gap);min-width:0}
/* ONE dot primitive for the condition headings and the Set-state rows. It carries no fill
   of its own, so the rule draws no box (§2a.7 / L18) and every colour is a modifier. */
.clm-dot{width:var(--chip-gap);height:var(--chip-gap);border-radius:50%;flex-shrink:0;display:inline-block}
.clm-dot.lg{width:var(--sp-2);height:var(--sp-2)}
.clm-dot.brk,.clm-dot.broken{background:var(--red)}
.clm-dot.flf,.clm-dot.live{background:var(--green)}
.clm-dot.strained{background:var(--amber)}
.clm-dot.fulfilled{background:var(--navy-soft)}
.clm-dot.untested{background:var(--line-strong)}
/* The per-group empty state. The prototype prints it; step 5 printed nothing, so an open
   card with one list filled read as if the other list did not exist. */
.clm-condnone{font-size:var(--fs-small);color:var(--text-faint);margin-top:var(--sp-1)}
/* D6 · the 5-cap is a DISCLOSURE, never silence. "In case our 5 suggestions are discarded
   then user have other claims to select from." The five are SUGGESTIONS, not a shortlist
   the product has decided on. */
/* ⚠ THE THREE DISCLOSURE TOGGLES ARE ONE TIER (his finding on "show 2 discarded", session 68).
   .clm-more, .q-resolved-toggle and .ev2-viewall were three copies of an 11px mono grey/navy
   button — none of them on the design system — and session 68 put all three on the violet tier.
   ⚠ v2 MOVES THE TIER, ALL THREE TOGETHER (board §2, session 73): "disclosure lives here" — in
   text-wayfinding, grey 500, an underline and --navy on hover — because showing what is already
   on the page is not an action. The chevron sits before the word at 14px, the sp-1 step from
   it, exactly as the board draws Resolved (1). The words are unchanged; only the tier is. */
.clm-more,.q-resolved-toggle,.ev2-viewall{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--text-soft);margin-top:var(--sp-3);display:inline-flex;align-items:center;gap:var(--sp-1);cursor:pointer;background:none;border:none;padding:0}
.clm-more:hover,.q-resolved-toggle:hover,.ev2-viewall:hover{color:var(--navy);text-decoration:underline}
.text-wayfinding > .ic,.clm-more > .ic,.q-resolved-toggle > .ic,.ev2-viewall > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
/* D9 · the Coach's first speech on this surface. It must be visually distinct from the
   user's own words — machine prose never shares a lane with his writing. */
.clm-coach{border:1px solid var(--navy-tint-strong);background:var(--navy-tint);border-radius:var(--radius-xs);padding:0.75rem 0.85rem;margin-bottom:0.8rem}
.clm-coach-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;color:var(--navy-soft);margin-bottom:5px}
.clm-coach-q{font-size:var(--fs-small);line-height:1.5;color:var(--text)}
/* ⚠ THE QUESTION AND THE EXPLANATION ARE DIFFERENT CLASSES ON PURPOSE. coach_principles:
   "Ask EXACTLY ONE impactful question per email — never a list." The harness counts
   .clm-coach-q to hold that rule, so the explanatory paragraph must not borrow it. */
.clm-coach-body{font-size:var(--fs-small);line-height:1.5;color:var(--text-soft)}
.clm-coach-quote{font-size:var(--fs-small);line-height:1.45;color:var(--text-soft);border-left:2px solid var(--navy-soft);padding:2px 0 2px 9px;margin:var(--sp-2) 0}
.clm-coach-btns{display:flex;gap:6px;margin-top:9px;flex-wrap:wrap}
/* PB slice 5 · the hero notes timeline. FULL WIDTH, never a side column — his ruling,
   30 Aug: a timeline keeps growing and a narrow column strangles it after two notes. */
/* The origin note (F13) is a ROW with a rule, not a filled box (session 68): nothing on board 5a
   is a card, and the board marks a distinguished row — the open question — with a 2px left rule.
   The navy-soft rule keeps it distinct; the label above it says what it is. */
.hnt-origin{border-left:2px solid var(--navy-soft);padding:var(--sp-1) 0 var(--sp-1) var(--sp-3);margin-bottom:var(--sp-4)}
.hnt-origin-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;color:var(--navy-soft);margin-bottom:5px}
/* the foot of the timeline: what is still below, in the muted mono the app uses for a fact
   about the page rather than an action on it. It loads itself; clicking is the fallback. */
.hnt-more{display:block;width:100%;text-align:center;padding:var(--sp-4) 0;font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);background:none;border:none;cursor:pointer}
.hnt-more:hover{color:var(--text-soft)}
/* ══ ICONS (DP-4) ═══════════════════════════════════════════════════════════════════════
   .ic is the whole icon system: 1em square so it scales with the type it sits in, stroked in
   currentColor so it is the colour of its label, and baseline-nudged so it centres on the
   text rather than sitting on it. A rotation (an open chevron) is a transform on the element,
   exactly as it was when these were characters. */
.ic-sprite{position:absolute;width:0;height:0;overflow:hidden}
.ic{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;display:inline-block;vertical-align:-0.125em}
/* ⚠ STROKE 1.75 IS THE SYSTEM (v2 board §3: "Lucide, 16px, stroke 1.75"). The board draws four
   heavier: plus inside a box (Add event, Add a claim — the icon helper passes ic-sw2), the state
   pill's chevron, the fulfil check at 2.25, and a checkbox's tick at 3.
   ⚠ THE REVIEW'S TICK NO LONGER RIDES THE SAME LIST. Phase 3 builds the checkbox, and the two
   are different components at different sizes: board 6e signed this one off at 18px and stroke
   2, the v2 board §5 draws an 11px mark at 3 inside a 16px navy square. A shared selector would
   have moved a signed-off surface the next time the other one changed. */
.ic-sw2,.sb-chev .ic{stroke-width:2}
.pr-tick .ic{stroke-width:2}
.ic-sw225{stroke-width:2.25}          /* the fulfil check — board §4's chip and the condition line */
.ic-fill{fill:currentColor}           /* a mark, not an outline: badge-mark's star, a chosen rating star */
.ic-ask{color:var(--accent-strong)}   /* a question's glyph — board 03 draws circle-help in the
                                         violet the token already carries; naming the value here is
                                         what L6 reads as a raw hex in a rule, so it is not named */
/* ══ ICON BUTTONS — board §3 (Phase 2, session 73 · the fill retired in v3, session 79) ══════
   One component, THREE dress states: bare · framed · on dark. Lucide 16px in a 32px square,
   radius 4 — and a 44px square at 768 and below, the glyph staying 16 inside it.
   ⚠ THE OLD PER-SURFACE CLASSES JOIN THE BOARD'S NAMES IN THESE SELECTOR LISTS, so no reader of
   them moved: .spc-expand and .ev2-kebab are bare, .sig-expand is framed, .modal-close and
   .tm-close are on dark. An old class keeps a rule of its own only for a PLACEMENT — never for
   a look.
     bare     kebab, composer expand and collapse, a row's remove, disclosure chevrons
     remove   a row's ✕ — muted at rest, red on hover, and confirmation-gated behind the click
     framed   ONLY in a button row beside a text button, to share its height (the KPI card)
     on dark  the modal ✕ on navy chrome
   ⚠ THE FOURTH STATE IS GONE AND IT IS NOT COMING BACK BY ACCIDENT. The fill dressed exactly
   one control — the composer's send ↑ — and the v3 redraw replaced that with the real
   [Cancel][Save Note] footer, so his call on 14 Sep was to retire the state rather than keep a
   dress with nothing wearing it. A future filled icon-only action is a new decision. */
.icon-btn,.spc-expand,.ev2-kebab,.sig-expand,.modal-close,.tm-close{display:inline-flex;align-items:center;justify-content:center;width:var(--icon-hit);height:var(--icon-hit);flex-shrink:0;padding:0;border:none;border-radius:var(--radius-2xs);background:none;color:var(--text-muted);cursor:pointer;line-height:1;transition:background .12s,color .12s,border-color .12s}
.icon-btn .ic,.spc-expand .ic,.ev2-kebab .ic,.sig-expand .ic,.modal-close .ic,.tm-close .ic,.sb-close .ic{width:var(--icon-glyph);height:var(--icon-glyph)}
.icon-btn:hover,.spc-expand:hover,.ev2-kebab:hover{background:var(--surface-tint);color:var(--navy)}
.icon-btn-remove:hover{background:var(--red-soft);color:var(--red-strong)}
.icon-btn-framed,.sig-expand{border:1px solid var(--line-strong);background:var(--surface)}
.icon-btn-framed:hover,.sig-expand:hover{border-color:var(--navy-soft);background:var(--surface);color:var(--navy)}
.icon-btn-on-dark,.modal-close,.tm-close{color:var(--on-brand-soft)}
.icon-btn-on-dark:hover,.modal-close:hover,.tm-close:hover{background:var(--on-brand-line);color:var(--on-brand)}
/* ⚠ icon-button-fill IS RETIRED — his call, 14 Sep 2026. Its ONE consumer was the composer's
   send circle, and the v3 redraw replaced that with the real [Cancel][Save Note] footer, so
   the dress state was left without a job. The family is bare · framed · on-dark. A future
   filled icon-only action is a new decision, not a revival of this one. */
/* ══ THE CHIP FAMILY, FIELDS, SURFACES, CALLOUTS AND STATES — v2 board §4, §5, §6, §10 ═══════
   (design system v2, Phase 3, session 74. Extraction: design/v2_spec/phase3_spec.md.)
   Radius 4 on everything that REPORTS — a pill, a tag, a badge, a row, a callout. Radius 10 on
   everything you PICK — a chip-select, a field. Inter for words, mono for identifiers. A value
   here is the board's own literal, carried by a token; nothing is snapped to a near neighbour.
   ⚠ FOUR OF THESE COMPONENTS HAD A SECOND DRAWING AND HE HAS RULED, 12 SEP 2026: "for the 4
   decisions we can lock the v2 board's decision." The signed-off IA (board 5a) drew the claim
   card's radius, its ☆ offer, its state pill as a control and its C-id differently; the v2 board
   wins all four, 5a is deliberately superseded on those elements ALONE, and its probes for them
   carry the ruling as their reason. So .clm-cid now joins .tag-marker and .clm-mkprim joins the
   unfilled twin (spec P3-Q1..Q4 · design/v2_spec/job1_rulings_spec.md).
   ⚠ ONE ELEMENT OF THE SAME FAMILY IS STILL WAITING AND IT IS NOT AN OVERSIGHT: the Claims
   header's Add a claim. His ruling covers it, but it shares its line with a hairline group
   Prompt 7 rebuilds, and a fill beside half a hairline breaks rule 13 — the two move together. */

/* tag-mono — which one is this. Always neutral: an identifier is not a state, so BSE is no
   longer amber and BUY is no longer green. */
.tag-mono,.tag-marker,.clm-cid{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;line-height:1.4;letter-spacing:0.03em;padding:var(--tag-pad);border-radius:var(--radius-2xs);background:var(--neutral-fill);color:var(--text-soft);white-space:nowrap}
/* tag-marker — WHICH CLAIM. The one coloured identifier, because it points at the card wearing
   the same 3px line. Its ground is the marker at 12% and its word is the marker's text twin. */
.tag-marker.mk1,.clm-cid.mk1{background:var(--mk1-tint);color:var(--mk1-t)}
.tag-marker.mk2,.clm-cid.mk2{background:var(--mk2-tint);color:var(--mk2-t)}
.tag-marker.mk3,.clm-cid.mk3{background:var(--mk3-tint);color:var(--mk3-t)}
.tag-marker.mk4,.clm-cid.mk4{background:var(--mk4-tint);color:var(--mk4-t)}
.tag-marker.mk5,.clm-cid.mk5{background:var(--mk5-tint);color:var(--mk5-t)}
/* the note-to-claim chip (F11): the tag says WHICH, the pill says what it DID */
.chip-link{display:inline-flex;align-items:center;gap:var(--sp-1)}

/* badge-mark's unfilled twin — the OFFER to make something the one. Gold is a border, a fill and
   a glyph; the word stays navy-neutral, because gold measures 3.15:1 and fails as text. */
.badge-mark-off,.clm-mkprim{font-weight:500;border-color:var(--line-strong);background:var(--surface);color:var(--text-muted);cursor:pointer;white-space:nowrap}
.badge-mark-off > .ic,.clm-mkprim > .ic{font-size:var(--fs-caption)}

/* chip-select — pick one. Selection is GEOMETRY: a 1px inset navy ring and a navy tint, never a
   coloured fill. A trailing chevron makes it a picker that opens a popover. */
.chip-select,.chip-picker,.chip-select-state,.cs-mode,.sig-seg button{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;line-height:normal;color:var(--text-soft);background:var(--surface);border:1.5px solid var(--line);border-radius:var(--radius-xs);padding:var(--chip-sel-pad);cursor:pointer;white-space:nowrap;transition:border-color .15s,background .15s,color .15s}
.chip-select:hover,.chip-picker:hover,.cs-mode:hover,.sig-seg button:hover{border-color:var(--navy-soft);color:var(--navy)}
.chip-select.on,.cs-mode.on,.sig-seg button.on{font-weight:600;color:var(--navy);background:var(--navy-tint);border-color:var(--navy-soft);box-shadow:var(--sel-ring)}
.chip-select:has(> .ic),.chip-picker{display:inline-flex;align-items:center;gap:var(--chip-gap)}
.chip-select > .ic{font-size:var(--fs-body);color:var(--text-muted)}
/* the picker — a role or a conviction, opening a popover. Its hairline is the stronger one. */
.chip-picker{font-weight:600;color:var(--navy);border-color:var(--line-strong)}
.chip-picker > .ic{font-size:var(--fs-body);color:var(--text-muted)}
.chip-stars{color:var(--gold-deep);letter-spacing:1px}

/* chip-select-state — his rule, 11 Sep: when the pick IS a state, the chip wears it. The glyph
   carries the state's base colour at rest; the chosen chip takes the -soft fill, the base border
   and the -strong word AND glyph. Nowhere else — every other pick stays ring and navy tint. */
.chip-select-state{display:inline-flex;align-items:center;gap:var(--chip-gap)}
.chip-select-state > .ic{font-size:var(--fs-body)}
.chip-select-state.intact > .ic,.chip-select-state.ok > .ic,.chip-select-state.supports > .ic{color:var(--green)}
.chip-select-state.watch > .ic,.chip-select-state.strains > .ic{color:var(--amber)}
.chip-select-state.broken > .ic,.chip-select-state.alert > .ic,.chip-select-state.breaks > .ic{color:var(--red)}
.chip-select-state.intact.on,.chip-select-state.ok.on,.chip-select-state.supports.on{font-weight:600;background:var(--green-soft);border-color:var(--green);color:var(--green-strong)}
.chip-select-state.watch.on,.chip-select-state.strains.on{font-weight:600;background:var(--amber-soft);border-color:var(--amber);color:var(--amber-strong)}
.chip-select-state.broken.on,.chip-select-state.alert.on,.chip-select-state.breaks.on{font-weight:600;background:var(--red-soft);border-color:var(--red);color:var(--red-strong)}
.chip-select-state.on > .ic{color:inherit}

/* the field family — one size. Inter for prose, mono only where the value IS a figure or an
   identifier. The focus ring is navy, never green: a field is not an action. */
.field,.field-mono,.textarea,.select,.form-input,.sig-select,.sig-comp-row input,.fld-lg,.fld-ta{width:100%;box-sizing:border-box;font-family:var(--font-ui);font-size:var(--fs-body);line-height:normal;color:var(--text);background:var(--surface);border:1.5px solid var(--line-strong);border-radius:var(--radius-xs);padding:var(--fld-pad);resize:none}
.field-mono{font-family:var(--font-mono)}
.textarea,.fld-ta{min-height:var(--fld-ta-min);line-height:1.5;resize:vertical}
.select{display:flex;align-items:center;justify-content:space-between}
.select > .ic{font-size:var(--icon-glyph);color:var(--text-muted);flex-shrink:0}
.field:focus,.field-mono:focus,.textarea:focus,.select:focus,.form-input:focus,.sig-select:focus,.sig-comp-row input:focus,.fld-lg:focus,.fld-ta:focus{outline:none;border-color:var(--navy-soft);box-shadow:var(--ring)}
.field::placeholder,.field-mono::placeholder,.textarea::placeholder,.form-input::placeholder,.fld-lg::placeholder,.fld-ta::placeholder{color:var(--text-faint)}
.field-opt{font-weight:400}
/* ── field-sm · A FIELD INSIDE A ROW GRID (components board §5, named 14 Sep 2026).
   The SAME component — border, radius, focus, colours — at 13px on 8px 12px. v2 drew a
   compact field at three different paddings on three screens (8px 10px · 8px 12px · 14px
   at 8px 12px); this is the one size, and it is the period picker's.
   ⚠ ≥768 ONLY. At 390 every field is the full field (16px, 10px 12px) — the iOS rule
   outranks the grid, and the 390 drawings stack the row rather than compress it. */
.field-sm{font-size:var(--fs-small);padding:var(--fld-pad-sm)}
.field-sm.field-mono,.field-mono.field-sm{font-family:var(--font-mono)}

/* checkbox · switch · star-rating */
.cbx-row{display:inline-flex;align-items:center;gap:var(--sp-2);font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-soft);cursor:pointer}
.cbx-row.on{color:var(--text)}
.checkbox{width:var(--cbx);height:var(--cbx);border:1.5px solid var(--line-strong);border-radius:var(--radius-2xs);display:inline-block;flex-shrink:0}
.checkbox.on{background:var(--navy);border:none;display:inline-flex;align-items:center;justify-content:center}
.checkbox > .ic{display:none}
.checkbox.on > .ic{display:inline-block;font-size:var(--fs-label);color:var(--on-brand);stroke-width:3}
.star-rating{display:inline-flex;align-items:center;gap:var(--chip-gap);color:var(--gold-deep)}
.star-rating > .ic,.star-rating > span > .ic{font-size:var(--star-sz);color:var(--line-strong);stroke-width:1.5}
.star-rating > .ic.ic-fill,.star-rating > span > .ic.ic-fill{color:var(--gold-deep)}
/* 18's rating is the component in a modal: the board draws it centred and larger there, and
   larger again at 390, where each star has to carry a 44px touch target of its own. */
#conv-modal-stars{justify-content:center;gap:var(--sp-3)}
#conv-modal-stars > span > .ic{font-size:var(--star-conv)}

/* surfaces — at most two nested. Level 1 is a hairline card with no shadow; level 2 is a tinted
   row with no border of its own; nothing nests below that. A shadow means the thing floats. */
.row{background:var(--surface-tint);border-radius:var(--radius-2xs);padding:var(--row-pad)}
.card-selected{background:var(--navy-tint);border:1px solid var(--navy-soft);box-shadow:var(--sel-ring);border-radius:var(--radius-sm);padding:var(--card-pad)}

/* the callout family — ONE anatomy, one hue per purpose: a -soft ground, a 3px left rule in the
   base colour, an Inter 11 caps eyebrow in the -strong with one Lucide glyph, an Inter 14 body
   and mono meta. A new purpose gets a new hue and a new glyph; the anatomy does not change.
   ⚠ A STATE COLOUR IS NEVER A CALLOUT'S GROUND. The callout says what kind of thing this is; a
   pill inside it says what state it is in. */
.callout,.cs-quote{border-radius:var(--radius-2xs);padding:var(--callout-pad);border-left:var(--rule-w) solid var(--line-strong);background:var(--surface-tint)}
.callout-eb{display:flex;align-items:center;gap:var(--chip-gap);font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;text-transform:uppercase;letter-spacing:0.06em}
.callout-eb > .ic{font-size:var(--icon-glyph-sm);stroke-width:2}
.callout-eb .tag-marker{padding:var(--tag-pad-tight);color:inherit}
.callout-b{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;line-height:1.5;color:var(--text);margin-top:var(--sp-2)}
.callout-m{font-family:var(--font-mono);font-size:var(--fs-label);line-height:1.5;color:var(--text-muted);margin-top:var(--sp-2)}
.callout-quote,.cs-quote{background:var(--navy-tint);border-left-color:var(--navy-soft)}
.callout-quote .callout-eb{color:var(--navy-soft)}
.callout-question{background:var(--accent-soft);border-left-color:var(--accent)}
.callout-question .callout-eb{color:var(--accent-strong)}
.callout-commitment{background:var(--teal-soft);border-left-color:var(--teal)}
.callout-commitment .callout-eb{color:var(--teal-strong)}
.callout-hd{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2)}
.callout-lens{background:var(--gold-soft);border-left:none;padding:var(--row-pad) var(--rec-sub-x);display:flex;align-items:flex-start;gap:var(--sp-3)}
.callout-lens .callout-b{font-weight:400;font-style:italic;margin-top:0}
.callout-lens .callout-eb{color:var(--text-muted);margin-top:var(--chip-gap)}
.state-disc,.callout-coin,.sb-avatar,.sec-plate{width:var(--disc);height:var(--disc);border-radius:var(--radius-pill);background:var(--surface-tint);color:var(--text-muted);display:flex;align-items:center;justify-content:center;flex-shrink:0}
/* ── THE SECTION HEADING — session 109, the board's `section-heading` (Pages H1, Q1; system file §4). A plate — the tinted
   disc at 32 with the card's 10px corner and a navy glyph — then the title. ⚠ The plate is a SIBLING of the title inside a
   .sec-hd row, never a child of it: two harnesses read a title's own markup. A page-level card's title also wears
   .sec-hd-main (20 / 800, declared with .sec-h below so it out-ranks the title's own class); a sub-heading keeps its size. */
.sec-plate{width:var(--plate);height:var(--plate);border-radius:var(--radius-xs);color:var(--navy)}
.sec-plate > .ic{width:var(--icon-glyph);height:var(--icon-glyph)}
.sec-hd{display:flex;align-items:center;gap:var(--sp-3);min-width:0}
/* the account's initial is the disc at its own size and in the navy tint. ⚠ It sits HERE, after the disc's rule: both are in
   the base layer at equal weight, so the later one wins — up in the sidebar's block it lost and measured 48px. */
.sb-avatar{width:var(--avatar);height:var(--avatar);background:var(--navy-tint);color:var(--navy);font-size:var(--fs-caption);font-weight:700}
.callout-coin{width:36px;height:36px;background:var(--navy);border:2px solid var(--gold-deep);font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;color:var(--gold-deep)}
.callout-description{background:var(--surface-tint);border-left:none;padding:var(--row-pad) var(--rec-sub-x)}
.callout-description .callout-b{font-weight:400;color:var(--text-soft);margin-top:0}
/* s94 · D5 — a description that says two things: the lead is the family's own body line (600, the text colour), the
   sentence under it the description's body. Meta (label-mono) stays for counts, names and dates, never a sentence. */
.callout-description .callout-b.callout-lead{font-weight:600;color:var(--text)}
.callout-description .callout-b + .callout-b{margin-top:var(--sp-1)}
/* s94 · R4-7 · callout-thought — HIS reasoning on a link: the family's anatomy, the neutral hue (not a state, a question or
   management's word), the Lucide lightbulb, his words at body weight. The island re-dresses it below. */
.callout-thought .callout-eb{color:var(--text-muted)}
.callout-thought .callout-b{font-weight:400;margin-top:var(--sp-1)}

/* the states — quiet. A Lucide glyph in a tinted disc stands where an illustration would go;
   one heading, one line, one action. No spinner in the page: a spinner lives only inside the
   button that was pressed. */
.state-panel,.skeleton{border:1px solid var(--line);border-radius:var(--radius-sm)}
/* session 109 · on the shell ground a closed box is white. ⚠ Its own rule: the lint's L46 pins the line above to the v2 board's exact text. */
.state-panel,.skeleton{background:var(--surface)}
.state-panel{padding:var(--state-pad);display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px}
.state-disc > .ic{font-size:var(--disc-glyph)}
.error-state .state-disc{background:var(--red-soft);color:var(--red-strong)}
.state-t{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:800;color:var(--navy)}
.state-d{font-family:var(--font-ui);font-size:var(--fs-body);line-height:1.5;color:var(--text-soft);max-width:260px}
.state-code{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted)}
.state-panel .btn,.state-panel .text-action{margin-top:var(--sp-1)}
.skeleton{padding:var(--card-pad)}
.skel-bar{display:block;border-radius:var(--radius-2xs);background:var(--neutral-fill);animation:skel-pulse 1.6s ease-in-out infinite}
.skel-bar.block{background:var(--surface-tint);animation:none}
.skel-bar.act{border-radius:var(--radius-xs)}   /* a bar standing in for the button in an action row */
@keyframes skel-pulse{0%,100%{background:var(--neutral-fill)}50%{background:var(--skel-lo)}}
.btn-spin{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm);border:2px solid currentColor;border-top-color:transparent;border-radius:var(--radius-pill);animation:spin-btn .7s linear infinite;flex-shrink:0}
@keyframes spin-btn{to{transform:rotate(360deg)}}

/* a clamped CELL says there is more with an ellipsis and a dotted rule, and shows the rest in a
   tooltip after 300ms. A clamped CARD discloses in place with Show more — a tooltip is for a
   cell, disclosure is for a card, and at 390 (no hover) everything is the second one. */
/* ⚠ .clamp-cell IS RETIRED WITH THE TOOLTIP IT EXISTED TO POSITION. It was position:relative
   so a navy tooltip could hang off it; peek is fixed and measures the trigger's own rect,
   so a wrapper buys nothing. The cell trigger is .peek-cell — one line, an ellipsis and a
   dotted rule — which is the same shape v2 drew, without the anchor. */
.clamp-t{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-bottom:1px dotted var(--clamp-rule);padding-bottom:1px}
/* ── peek · THE READING PANEL (UX-64, components board §10) ────────────────────────────
   ⚠ THE NAVY TOOLTIP IS RETIRED AND THIS IS WHAT REPLACED IT. His ask was a component that
   shows the full text where a card truncates it; the v2 board ruled the opposite ("tooltips
   are for cells; disclosure is for cards") and left 83 native title= attributes behind. The
   v3 answer is ONE panel for every truncation that is not a card body — a cell, a chain row,
   a claim-link or question-link chip — in reading type, with the whole text, a key and one
   way to the thing itself. Cards still clamp and disclose in place. title= is forbidden. */
.peek{position:fixed;z-index:calc(var(--z-top) + 1);width:var(--peek-w-cell);max-width:calc(100vw - var(--sp-6));background:var(--surface);border:1.5px solid var(--line-strong);border-radius:var(--radius-xs);box-shadow:var(--shadow-pop);padding:var(--peek-pad);display:none;flex-direction:column;gap:var(--peek-gap)}
.peek.on{display:flex}
.peek.chip{width:var(--peek-w-chip)}
/* ⚠ THE TEXT IS WHOLE. No clamp, no ellipsis, no max-height — a panel that cut its own text
   would be the defect it exists to fix. */
.peek-t{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:400;line-height:1.5;color:var(--text)}
.peek-f{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);border-top:1px solid var(--line);padding-top:var(--peek-gap)}
.peek-k{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:400;color:var(--text-muted)}
/* a C-id in the foot is the tag-marker, because it points at the card wearing the same line */
.peek-k.tag-marker{font-weight:700;letter-spacing:0.03em;padding:var(--tag-pad);border-radius:var(--radius-2xs)}
/* the trigger: a cell keeps its one line, its ellipsis and its dotted rule — unchanged from v2 */
.peek-cell{display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-bottom:1px dotted var(--peek-rule)}
[data-peek]:not([data-peek-clip]),[data-peek-clip].peek-cut{cursor:help}   /* s94 · R4-10: only cut text says there is more */
[data-peek]:focus-visible{outline:none;border-radius:var(--radius-2xs);box-shadow:var(--ring)}
.clamp2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ══ THE EXTRACTION REVIEW · board 6e (1440) and 6f (390) — SPEC §7/§8, DP-5 ═══════════
   The box is .modal-box and since his 13 Sep ruling it wears the family whole: the corners,
   the shadow and the 88vh ceiling are the other ten modals'.
   ⚠ THE WIDTH IS THE EXCEPTION AND IT IS THE ONLY ONE — "it has many things on it and the
   user needs to do comparison, so we needed a bigger area." A width may differ where the UX
   earns it; optics may not. So this rule is the width, the fixed height that width implies,
   and the two panes — and nothing else is said here that the family already says. */
.pr-modal{max-width:var(--pr-w);height:88vh;max-height:88vh}
.pr-head{background:var(--navy);padding:var(--pr-y) var(--pr-x);display:flex;justify-content:space-between;align-items:flex-start;flex-shrink:0}
.pr-h-t{font-size:var(--fs-title);font-weight:800;color:var(--on-brand);line-height:1.25}
.pr-h-s{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--on-brand-soft);margin-top:var(--rec-tight)}
.pr-x{margin:var(--modal-close-pull)}   /* placement only: pulled into the head's corner as the modal close is; its look is the icon button's */
.pr-body{flex:1;min-height:0;display:grid;grid-template-columns:var(--pr-note-w) minmax(0,1fr)}
/* ── the note pane ─────────────────────────────────────────────────────────────────── */
.pr-note{background:var(--surface-sunken);border-right:1px solid var(--line);display:flex;flex-direction:column;min-height:0;position:relative}
.pr-note-hd{padding:var(--pr-y) var(--pr-note-x) var(--sp-2);display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3)}
.pr-note-t{font-size:var(--fs-pane);font-weight:700;color:var(--navy)}
.pr-note-n{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);white-space:nowrap}
.pr-note-b{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;padding:0 var(--pr-note-x) var(--pr-note-b);font-size:var(--fs-body);line-height:1.75;color:var(--text-soft)}
/* ⚠ SESSION 89 · finding 4 (Viyash): the pane took the story note's HTML with NO note typography and no
   containment — his note carries fifteen five-column tables, drawn at browser defaults wider than the
   400px pane, so the pane scrolled sideways. It joins the reading view's typography lists (the note
   rules at the top of the sheet), and here everything is held to the pane's width: a table is a real
   table at the pane's width (the shared rule makes it a block that scrolls itself), its cells wrap,
   code wraps, long words break. */
.pr-note-b{overflow-x:hidden;overflow-wrap:anywhere}
/* ⚠ SESSION 91 (his delegated call, 23 Sep): a table here SCROLLS SIDEWAYS inside itself — the shared rule above already
   makes it a block that scrolls — and its words are never broken mid-word; a cell keeps --pr-cell-min, so a five-column
   table is wider than the pane and moves under the finger rather than stacking one letter per line. */
.pr-note-b td,.pr-note-b th{overflow-wrap:normal;word-break:normal;min-width:var(--pr-cell-min)}
.pr-note-b pre{white-space:pre-wrap;overflow-wrap:anywhere}
.pr-note-b img{max-width:100%;height:auto}
/* a reading column beside the claims, not the reading view: its headings step down a size */
.pr-note-b h1{font-size:calc(var(--fs-body) * 1.3)}
.pr-note-b h2{font-size:calc(var(--fs-body) * 1.15)}
.pr-note-b h3,.pr-note-b h4{font-size:var(--fs-body)}
/* the fade says "there is more note" and is suppressed when there is not (_prNoteFadeSync) */
.pr-note-fade{position:absolute;left:0;right:0;bottom:0;height:var(--pr-fade);pointer-events:none;
  background:linear-gradient(transparent,var(--surface-sunken) 70%);display:flex;align-items:flex-end;justify-content:center;
  font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.1em;color:var(--text-muted);padding-bottom:var(--sp-1)}
/* ⚠ ONE COLOUR PER CLAIM, AND IT IS THE CLAIM'S OWN. The marker a claim wears on the stock
   page is the marker its sentences wear in the note — that is the whole argument of this
   screen: these claims came from THESE words. The tint, the underline and the superscript
   all come off .mk1–.mk5, so a claim cannot be one colour here and another there. */
.prhl{color:var(--text);box-decoration-break:clone;-webkit-box-decoration-break:clone}
.prhl.mk1{background:var(--mk1-tint);box-shadow:inset 0 -2px var(--navy-soft)}
.prhl.mk2{background:var(--mk2-tint);box-shadow:inset 0 -2px var(--mk2)}
.prhl.mk3{background:var(--mk3-tint);box-shadow:inset 0 -2px var(--mk3)}
.prhl.mk4{background:var(--mk4-tint);box-shadow:inset 0 -2px var(--mk4)}
.prhl.mk5{background:var(--mk5-tint);box-shadow:inset 0 -2px var(--mk5)}
.prhl-n{font-family:var(--font-mono);font-size:var(--fs-micro);margin-left:var(--rec-tight)}
/* ── the proposals ────────────────────────────────────────────────────────────────── */
.pr-props{padding:var(--pr-y) var(--pr-x) var(--sp-5);overflow:auto;overscroll-behavior:contain;min-height:0;display:flex;flex-direction:column;gap:var(--pr-lane)}
.pr-t-row{margin-bottom:0}
.pr-t{font-size:var(--fs-pane);font-weight:700;color:var(--navy)}
.pr-t-sub{font-size:var(--fs-small);color:var(--text-soft);margin-top:var(--sp-1);line-height:1.5}
/* ⚠ THE PROPOSAL CARD TAKES THE ON-PAGE CLAIM CARD'S 16 — his ruling, 13 Sep 2026. Board 6e
   draws it at 10, which was right while the claim card it BECOMES was also 10; his 12 Sep
   ruling moved that card to 16, so a proposal and the claim it turns into would otherwise
   wear two different corners on the way through one flow. 6e's card probe carries the reason.
   ⚠ This is .pr-card, NOT .clm-card — the two parted company in DP-5 and the scope note on
   .clm-card still said otherwise; see the spec's reader list. */
.pr-card{display:grid;grid-template-columns:var(--pr-tick) minmax(0,1fr);gap:0 var(--pr-lane);
  padding:var(--rec-row-y) var(--pr-card-x);border:1px solid var(--line);border-left-width:3px;border-radius:var(--radius-sm);
  opacity:0.55}
.pr-card.on{opacity:1}
.pr-tick{width:var(--pr-tick);height:var(--pr-tick);border-radius:var(--radius-2xs);border:1.5px solid var(--line-strong);
  background:var(--surface);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;
  color:var(--navy-soft);font-size:var(--fs-caption);margin-top:var(--rec-tight)}
.pr-tick.on{border-color:var(--navy-soft);background:var(--navy-tint)}
.pr-c-hd{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;min-height:var(--sp-5);margin-bottom:var(--sp-1)}
.pr-c-n{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700}
/* board 6e's Untested pill is muted text on the quiet chip ground. .clm-state's own ground is
   --surface-tint (rgba 0.04) and the board draws 0.06 — a 2% alpha nobody can see, and §5 does
   not let a rule carry a raw colour to close it. The GROUND STAYS THE APP'S; only the text
   colour moves, and it moves to the muted role the board actually names. */
.pr-card .clm-state.untested{color:var(--text-muted)}
/* one line each — the cap is the point of the convention, so the card shows it being kept */
.pr-stmt{font-size:var(--fs-body);font-weight:600;color:var(--navy);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pr-stmt.prim{font-size:var(--fs-lead);font-weight:800}
.pr-cap{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);margin-top:var(--sp-1)}
.pr-verb{font-size:var(--fs-small);color:var(--text-soft);line-height:1.5;margin-top:var(--sp-2);
  border-left:2px solid var(--line-strong);padding-left:var(--sp-3)}
.pr-verb-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;color:var(--text-muted);display:block;margin-bottom:var(--rec-tight)}
.pr-conds{display:grid;grid-template-columns:1fr 1fr;gap:var(--pr-cond-x);margin-top:var(--sp-3)}
.pr-conds:empty{display:none}
.pr-cond-lbl{display:flex;align-items:center;gap:var(--chip-gap);font-family:var(--font-mono);font-size:var(--fs-micro);
  text-transform:uppercase;letter-spacing:0.07em;color:var(--text-muted);margin-bottom:var(--sp-1)}
.pr-cond-tx{font-size:var(--fs-small);line-height:1.45;color:var(--text-soft);padding:var(--rec-tight) 0 var(--rec-tight) var(--sp-2);border-left:2px solid var(--line-strong)}
.pr-cond-tx.brk{border-left-color:var(--red-strong)}
.pr-cond-tx.flf{border-left-color:var(--green)}
/* ── the footer ───────────────────────────────────────────────────────────────────── */
.pr-foot{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-4) var(--pr-x);border-top:1px solid var(--line);flex-shrink:0}
/* ⚠ NEVER VIOLET (SPEC §7): going back is not the thing to do next. */
.pr-back{background:none;border:none;padding:0;cursor:pointer;font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--text-soft);white-space:nowrap;display:inline-flex;align-items:center;gap:var(--chip-gap)}
.pr-back:hover{color:var(--navy);text-decoration:underline}
.hnt-list{position:relative}
/* The spine. Drawn on the list, not per row, so it cannot break between rows. */
.hnt-row{position:relative;padding:var(--sp-4) 0 var(--note-row-b)}
/* ⚠ THE TIMELINE RAIL AND ITS BULLETS ARE GONE. A rail is a second way of saying "these are in order", which the
   dates already say. A KEY note keeps its gold pill, so nothing stops being marked.
   ⚠ session 112 · AND THE HAIRLINE BETWEEN NOTES IS GONE TOO: a note's heading sits on the band a coach message's subject
   wears (his word, 5 Oct), and where rows carry the band the band is what separates them (tokens §2f.1). The band's box is
   three utilities in the markup; .hnt-band is only its layout — the title first, the day at the right end, and on a phone
   the title folds beside the day, not above it. */
.hnt-head{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin-bottom:var(--chip-gap)}
.hnt-band{flex-wrap:nowrap;align-items:flex-start;justify-content:space-between;margin-bottom:var(--sp-2)}
.hnt-sub{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;min-width:0}
.hnt-band .hnt-src{color:var(--navy);overflow-wrap:anywhere}
.hnt-band .hnt-date{flex-shrink:0}
.hnt-src{font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;text-transform:uppercase;letter-spacing:0.04em;color:var(--text-muted);cursor:pointer}
.hnt-src:hover{text-decoration:underline}
.hnt-date{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);white-space:nowrap}
.hnt-prev{font-size:var(--fs-body);line-height:1.6;color:var(--text);max-width:680px}
.hnt-foot{display:flex;align-items:center;gap:var(--sp-4);margin-top:var(--sp-2);flex-wrap:wrap}
.hnt-refs{display:inline-flex;flex-wrap:wrap;gap:var(--sp-3);min-width:0}
.hnt-refs:empty{display:none}
.hnt-refs .q-answers,.hnt-refs .q-from{display:inline-block;margin-top:0;font-size:var(--fs-label);max-width:none}
.hnt-acts{display:flex;gap:var(--sp-4);align-items:center;margin-top:var(--sp-2);opacity:0;transition:opacity .12s}
.hnt-row:hover .hnt-acts{opacity:1}
/* board 03: a Record row's own controls appear on row hover at the desk. Same construct, same
   touch escape below — one way of saying "this row's actions" in three places. */
.rec-a.on-hover{opacity:0;transition:opacity .12s}
.rec-row:hover .rec-a.on-hover,.rec-row:focus-within .rec-a.on-hover{opacity:1}
/* ⚠ NO HOVER ON A PHONE. An action that is invisible-but-tappable is the R2 defect the
   claim card already had to fix; do not let this one repeat it. */
@media (hover:none),(pointer:coarse){ .hnt-acts{opacity:1} .rec-row .rec-a.on-hover{opacity:1} }
/* ⚠ .hnt-compose IS RETIRED (slice 6) and its rules are deleted with it. It styled the
   dashed placeholder that only LOOKED like a composer — the real one is #sp-composer.
   ⚠ .verdict-banner AND ITS .vb-* RULES ARE GONE (Phase 3 step 4, session 64). This
   comment used to say they had to stay "because .vb-mono / .vb-sub are shared". They were
   not shared — a whole-file grep found zero consumers outside this stylesheet. Fifteen
   dead rules survived three sessions on the strength of an unverified sentence. */
/* ═══════════════════════════════════════════════════════════════════════════
   PB SLICE 6 · THE SURFACE REWORK (30 Aug, session 45). His review of slices
   4 and 5 was that the UI is "two notches below what's already there in the
   app". Every block below answers one line of that review, and the line it
   answers is named — so nobody later removes a rule because it looks arbitrary.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The frozen header. "When I scroll down, the top strip should freeze along
   with the navigation tab." .page-header was ALREADY sticky on its own; the tabs
   were not, so the two came apart on scroll. One sticky wrapper keeps them a
   single unit, and the inner header must go static or it sticks inside a stick. */
/* ⚠ THE SLIM HEAD IS A SCROLL-IN OVERLAY, NOT A PERMANENT BAR — and that is the whole of
   his first finding, "why is the old stock page heading still there". The design has ONE
   place that names the stock: the hero. The head is a sticky strip with margin-bottom
   -60px, so it sits ON TOP of the page rather than above it, and it fades in only once
   the hero has scrolled under it (SPEC §1.2). Rendered as a permanent bar it repeats the
   name, the ticker and the position that the hero is already showing, forty pixels apart.
   ⚠ THE NEGATIVE MARGIN IS LOad-BEARING: position:sticky does not leave the flow, so
   without it the strip reserves 60px of blank page above the hero. */
.stock-sticky{position:sticky;top:0;z-index:calc(var(--z-sticky) + 1);background:none;box-shadow:none;margin-bottom:calc(var(--head-h) * -1);opacity:0;pointer-events:none;transition:opacity .15s}
.stock-sticky.stuck{opacity:1;pointer-events:auto}

/* ══ THE CLAIMS ACCORDION · SPEC §1.3 — STICKY LAYER 2 OF 4 (DP-2) ═══════════════════════
   ⚠ IT PULLS ITSELF BACK BY ITS OWN HEIGHT, exactly as the head does, so it occupies no
   layout space and cannot shift the page when it fades in mid-scroll. The pull-back is the
   COLLAPSED bar's height; the expanded list overlays the page, which is what a dropdown is.
   ⚠ AND IT IS A SIBLING OF THE HEAD, NOT A CHILD — a sticky inside a sticky resolves against
   the wrong containing block, the reason .stock-sticky exists at all. */
.clm-acc{position:sticky;top:var(--head-bot);z-index:calc(var(--z-sticky) + 1);
  background:var(--surface);border-bottom:1px solid var(--line);box-shadow:var(--shadow-drop);
  margin-bottom:calc(var(--acc-h) * -1);
  transform:translateY(calc(var(--sp-2) * -1));opacity:0;pointer-events:none;
  transition:transform .2s,opacity .2s}
.clm-acc.on{transform:translateY(0);opacity:1;pointer-events:auto}
.clm-acc:empty{display:none}
.acc-bar{height:var(--acc-h);display:flex;align-items:center;gap:var(--sp-3);padding:0 var(--sp-6);cursor:pointer}
.acc-t{font-size:var(--fs-small);font-weight:700;color:var(--navy)}
.acc-n{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted)}
.acc-dots{display:flex;align-items:center;gap:var(--sp-1)}
/* gold is never a word (§2a) — it is the mark on the bet the thesis rests on */
.acc-star{color:var(--gold-deep);font-size:var(--fs-caption);line-height:1}
/* ⚠ min-width:0 OR THE ELLIPSIS NEVER FIRES. A flex child's min-width is auto = its
   min-content width, so a long statement sizes the strip instead of truncating inside it —
   the .hero-island defect of session 65, which scrolled the page 1882px sideways. */
.acc-lead{flex:1;min-width:0;font-size:var(--fs-small);color:var(--text-soft);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acc-jump{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--accent);
  background:none;border:none;padding:0;cursor:pointer;white-space:nowrap}
.acc-jump:hover{text-decoration:underline;color:var(--accent-hover)}
.acc-chev{font-size:var(--fs-caption);color:var(--text-muted);transition:transform .15s;display:inline-block}
.clm-acc.open .acc-chev{transform:rotate(180deg)}
.acc-list{display:none;border-top:1px solid var(--line);padding:var(--chip-gap) var(--sp-6) var(--sp-3)}
.clm-acc.open .acc-list{display:block}
.acc-row{display:grid;grid-template-columns:var(--acc-rule) var(--acc-k) var(--acc-cid) minmax(0,1fr);
  gap:var(--sp-3);align-items:center;padding:var(--sp-2) 0;cursor:pointer}
.acc-row:hover .acc-stmt{text-decoration:underline}
/* the 8px dot the strip shares with the card becomes the row's marker RULE — same ramp,
   same token, a different shape, so a claim wears one colour everywhere on this page */
.clm-acc .clm-mkdot{width:var(--acc-rule);height:var(--sp-5);border-radius:var(--radius-3xs)}
.clm-acc .clm-mkdot.prim{background:var(--gold-deep)}
/* the board's row pill is inline-flex; .clm-state is a bare tint elsewhere and inherits inline */
.clm-acc .clm-state{display:inline-flex}
.clm-acc .clm-cid.prim{color:var(--navy)}
.acc-stmt{font-size:var(--fs-small);font-weight:600;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acc-stmt.prim{font-weight:800}
/* SPEC §2 gives 390 its own centred Jump row; at 1440 the same action sits in the bar */
.acc-foot{display:none;width:100%;min-height:var(--acc-h);align-items:center;justify-content:center;
  font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--accent);
  background:none;border:none;cursor:pointer}
/* ⚠ SCOPED TO THE STOCK PAGE. .page-header dresses Cockpit, Quarterly Review, the Ledger
   and four more surfaces that are not in this redesign; the IA's slim head is this one. */
.stock-sticky .page-header{position:static;z-index:auto;background:var(--shell);border-bottom-color:var(--line);height:var(--head-h);min-height:0;padding:0 var(--sp-6);align-items:center;gap:var(--sp-5);box-shadow:var(--shadow-sm)}
/* One row at 24px intervals, packed left — the board's head, with Help pushed to the
   right edge by a margin rather than by space-between, so the gap lands after the
   position and not between the name and the chips. */
.stock-sticky .stk-head-id{display:flex;align-items:baseline;gap:var(--sp-3);min-width:0}
.stock-sticky #stock-mini-strip{display:flex;align-items:center;gap:var(--sp-5);min-width:0}
.stock-sticky .page-help{margin-left:auto}
/* The name is 15/700 and the ticker is a mono identifier beside it — not one 20px title
   with the ticker in brackets, which is what the head printed before. */
.stock-sticky .page-title{font-size:var(--fs-pane);font-weight:700}
.stock-sticky .page-subtitle{font-size:var(--fs-caption)}

/* ── The verdict strip. "The verdict strip is wasting the entire 1/4th of the
   top screen… the ideal place for this is on the top strip replacing the
   invested, current grid… only show 3 things." So THREE cells: thesis status,
   decision, conviction — and the money survives as ONE compact chip on the far
   right, because losing the position entirely from a stock page is a different
   change from the one he asked for. */
/* ⚠ THE SLIM HEAD'S STRIP IS BOARD 5a's, MEASURED (session 68): no box, no label-over-value cells.
   Left to right at 10px: the verdict as a navy pill (Inter 13/800 white, 3px 10px, radius 4),
   the story status as an 8px dot + Inter 12/600 uppercase in the state's text-safe colour,
   the conviction chip (his D64-5 — it stays, as a hairline chip), then the position in mono
   12/600 navy. The cell markup and its classes are unchanged (harness I1–I5 pin them); only
   what each cell looks like moved. The mono labels (Thesis · Decision · Conviction) are gone
   from the head — the board has none — and survive as the cells' title tooltips. */
.vstrip{display:flex;align-items:center;gap:10px;min-width:0}
.vstrip-cell{display:flex;align-items:center;min-width:0}
.vstrip-k{display:none}
.vstrip-v{font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;letter-spacing:0.04em;text-transform:uppercase;white-space:nowrap;display:flex;align-items:center;gap:var(--chip-gap)}
.vstrip-v.intact{color:var(--green-strong)} .vstrip-v.watch{color:var(--amber-strong)} .vstrip-v.broken{color:var(--red-strong)}
.vstrip-v.none{color:var(--text-muted)}
.vstrip-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.vstrip-dot.intact{background:var(--green)} .vstrip-dot.watch{background:var(--amber)}
.vstrip-dot.broken{background:var(--red-strong)} .vstrip-dot.none{background:var(--line-strong)}
.vstrip-cell.act{cursor:pointer}
.vstrip-cell.act:hover .vstrip-v{text-decoration:underline}
/* the verdict pill: navy is a label here, not a button (§1.2 draws it; L27 governs buttons) */
.vstrip-v.hd-verdict{background:var(--navy);color:var(--on-brand);font-size:var(--fs-small);font-weight:800;letter-spacing:0;text-transform:none;padding:var(--sp-1) var(--sp-3);border-radius:var(--radius-2xs)}
.vstrip-v.hd-verdict.none{background:var(--surface-sunken);color:var(--text-muted)}
.vstrip-v.hd-conv{color:var(--text-soft);border:1px solid var(--line-strong);border-radius:var(--radius-2xs);padding:var(--sp-1) var(--sp-2);letter-spacing:0;text-transform:none}
.vstrip-v.hd-conv.none{color:var(--text-muted);border-style:dashed}
.vstrip-money{display:flex;align-items:center;min-width:0}
.vstrip-v.hd-pos{font-family:var(--font-mono);font-weight:600;letter-spacing:0;text-transform:none;color:var(--navy)}
.vstrip-v.hd-pos.none{color:var(--accent);font-family:var(--font-ui);font-weight:500}
.vstrip-star{font-size:var(--fs-small);letter-spacing:1px;color:var(--amber)}
/* ⚠ THE STRIP'S THESIS AND DECISION CELLS HIDE ON THE HERO TAB, AND ONLY THERE.
   Step 4 gives the hero its own verdict island. Leaving both on screen would put the
   same verdict twice, forty pixels apart, which reads as a defect rather than as a
   design. The island is the richer surface (it carries the review date, the conclusion
   note and the Review action), so on the hero tab it wins and the strip yields.
   ⚠ The other three tabs have no island, so they keep all four cells — nothing is lost
   anywhere. Conviction and the money chip never hide: conviction is an EDIT surface and
   removing it on one tab is exactly the F-class deletion this phase keeps catching.
   ⚠ Driven by a data attribute set in showStockTab, NOT by a scroll listener. The
   design's slim head fades the verdict in on scroll (SPEC §1.2); that belongs to step 6,
   which retires this header and the tab bar together. Do not build half of it here. */
/* .stock-sticky[data-stock-tab="hero"] .vstrip-onhero{display:none} — RETIRED, session 68: the
   slim head only shows once the hero has scrolled off, so its verdict never doubles the island's. */

/* ═══════════════════════════════════════════════════════════════════════════
   PHASE 3 · STEP 4 — THE HERO AND THE VERDICT ISLAND (session 64)
   SPEC-stock-page §1.1 and §2. Every value is a token; no hex, no font-size
   literal, no radius literal, no z-index — the design lint enforces all four.
   ⚠ THIS IS A RELOCATION AND A RESTYLE, NOT A DEFECT FIX. The verdict was never
   broken: _renderStockStrip already showed the RECORDED decision including Trim
   and Add. What step 4 adds is the review date, the conclusion note and a Review
   action beside it, and what it deletes is STATE.stocks[id].verdict — a field
   written twice and read nowhere.
   ⚠ RETURN STAYS NAVY, NEVER GREEN OR RED (§2b.2 #7, his ruling). The stock page
   reviews reasoning; price colour belongs to the Ledger and the KPI readings. The
   money chip in the header strip keeps its red/green — that is the position
   surface and it is not this one.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ⚠ EVERY SPACING VALUE HERE IS A TOKEN, NOT THE DESIGN'S RAW PX. The spec asks for
   gap 6, margin-top 14 and padding 3/10; the seven-step scale is the system and it wins
   (§1 rule 3), so those snap to --sp-1, --sp-4 and --sp-1/--sp-3. This is not pedantry:
   L14 counts every px/rem spacing declaration in the file and the ceiling only ever
   falls, so eight literals here would have had to be paid for somewhere else. */
.hero-top{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--sp-6);padding-bottom:var(--sp-5);border-bottom:1px solid var(--line);margin-bottom:var(--sp-5)}
.hero-left{display:flex;flex-direction:column;gap:var(--sp-1);min-width:0}
.hero-ticker{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);letter-spacing:0.04em;display:flex;align-items:baseline;flex-wrap:wrap;gap:0 var(--sp-3)}
/* s123 · N8 · the story's active line sits on the ticker's line (his finding: it broke the row of three pickers) */
.hero-ticker .hero-act{letter-spacing:normal}
.hero-act-on{color:var(--green-strong);font-weight:600}
.hero-name{font-family:var(--font-ui);font-weight:800;font-size:var(--fs-title);color:var(--navy);line-height:1.2}
/* session 87 · finding 1: the crumb — wayfinding text, a chevron, the state word in mono */
.story-crumb{display:inline-flex;align-items:center;gap:var(--chip-gap);margin-bottom:var(--sp-2);font-size:var(--fs-small);color:var(--text-muted)}
.story-crumb > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.story-crumb-here{font-family:var(--font-mono);font-size:var(--fs-label);text-transform:uppercase;letter-spacing:0.05em;color:var(--text-soft)}
.stock-sticky .story-crumb{margin-bottom:0}
.hero-chips{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-1);flex-wrap:wrap}
/* The role and conviction chips. Hairline, never filled — a filled chip would read as a
   button, and §2a.1 rations the fill to the one thing you should do next. */
.hero-chip{position:relative;display:inline-flex;align-items:center;gap:var(--sp-1);font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;color:var(--text-soft);padding:var(--sp-1) var(--sp-3);border:1.5px solid var(--line-strong);border-radius:var(--radius-2xs);background:var(--surface);cursor:pointer;white-space:nowrap;max-width:340px}
.hero-chip:hover{border-color:var(--navy-soft)}
.hero-chip.empty{border-style:dashed;color:var(--text-muted)}
.hero-chip-cv{letter-spacing:1px;color:var(--amber)}
.hero-chip-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
/* ⚠ THE ROLE SELECT SITS ON TOP OF THE CHIP AT ZERO OPACITY, filling it. The chip is
   the design's hairline pill; a bare <select> cannot be styled into one across browsers,
   and a custom popover would be a third menu pattern in a file that already has two.
   The native control keeps keyboard access and the mobile picker for free. */
.hero-chip-sel{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;font-size:16px}
.hero-figs{display:flex;gap:var(--sp-5);margin-top:var(--sp-4);flex-wrap:wrap}
.hero-fig-k{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted);margin-bottom:var(--sp-1)}
.hero-fig-v{font-family:var(--font-mono);font-size:var(--fs-lead);font-weight:700;color:var(--navy)}
/* 390 only — the four figure groups collapse to one mono fact line (SPEC §2). */
.hero-factline{display:none;font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:600;color:var(--navy);margin-top:var(--sp-2)}
/* The no-trade nudge (6a): a dashed box, radius 10, padding 10px 14px, the four facts as dashes
   in --text-faint 14/700 mono, then a hairline-divided 13px muted line with two violet links. */
.hero-nofig{display:flex;align-items:center;gap:var(--sp-4);margin-top:var(--sp-4);padding:var(--sp-2) var(--sp-4);border:1px dashed var(--line-strong);border-radius:var(--radius-xs);flex-wrap:wrap}
.hero-nofig-figs{display:flex;gap:var(--wn-x)}
.hero-nofig-v{font-family:var(--font-mono);font-size:var(--fs-body);font-weight:700;color:var(--text-faint)}
.hero-nofig-txt{font-size:var(--fs-small);color:var(--text-muted);line-height:1.5;padding-left:var(--sp-4);border-left:1px solid var(--line);min-width:0}
.hero-nofig-txt .clm-editlink{white-space:normal}

/* The verdict island. §2b.2 #9: navy chrome, and the ONE documented exception to
   §2a.7's two-surface rule. Story status shows at FULL value on navy — the -strong
   twins are derived for light grounds and would go muddy here. */
/* ⚠ max-width IS LOAD-BEARING, AND ITS ABSENCE WAS A LIVE DEFECT (found on staging, session 64).
   With `flex-shrink:0` and no upper bound, this box sizes to MAX-CONTENT. His ALPEX review note is
   408 characters, so the island grew to 2712px and dragged the page 1882px wide — the figures row
   wrapped, and the page scrolled sideways.
   ⚠ THE LESSON: `text-overflow:ellipsis` DOES NOTHING IN AN UNBOUNDED BOX. An ellipsis is not a
   truncation instruction, it is what happens when content meets a WIDTH IT CANNOT HAVE. No width
   limit, no ellipsis — the element simply grows, silently and forever.
   Bounded here as well as at the text, because the note is no longer the only thing that could
   ever sit on this line. */
/* ⚠ FLAT NAVY, NOT THE --chrome GRADIENT. SPEC §1.1 gives the island a solid --navy; the
   gradient is for modal heads and the expiry card. Measured off the prototype: the flat
   navy token, not a gradient. ⚠ NO HEX IN A COMMENT — L6 counts every hex in <style>
   outside :root and it is right to: a value written in prose is a value nobody updates. */
.hero-island{background:var(--navy);border-radius:var(--radius-xs);padding:var(--sp-4) var(--sp-5);min-width:300px;max-width:420px;flex-shrink:0}
.hvi-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4)}
.hvi-k{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.08em;color:var(--on-brand-soft)}
.hvi-review{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:600;color:var(--action-on-dark);background:none;border:none;cursor:pointer;padding:0;white-space:nowrap}
.hvi-review:hover{text-decoration:underline}
.hvi-row{display:flex;align-items:baseline;gap:var(--sp-4);margin-top:var(--sp-2);flex-wrap:wrap}
.hvi-verdict{font-family:var(--font-ui);font-weight:800;font-size:calc(var(--fs-display) * 1.15);color:var(--on-brand);line-height:1.1}
.hvi-verdict.none{font-size:var(--fs-title)}
.hvi-status{display:inline-flex;align-items:center;gap:var(--sp-1);font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;text-transform:uppercase;letter-spacing:0.04em}
.hvi-status.intact{color:var(--green)} .hvi-status.watch{color:var(--amber)} .hvi-status.broken{color:var(--red)}
/* ⚠ THE DOT REUSES .vstrip-dot's GEOMETRY and only overrides the fill. Writing its own
   width/height/border-radius would have been a third box-drawing rule, and the box census
   (§2a.7, lint L18) only falls. It takes currentColor from .hvi-status, which is why the
   state colours here are the FULL-VALUE tokens: on navy the -strong twins go muddy, and
   they are derived for light grounds anyway. */
.hvi-dot{background:currentColor}
.hvi-sub{font-size:var(--fs-small);color:var(--on-brand-soft);margin-top:var(--sp-2);line-height:1.45}
.hvi-date{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--on-brand)}
/* One line, ellipsed, with the full note in the title — his conclusion notes run to
   three hundred characters and the island is not where a paragraph belongs. */
.hvi-note{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── The collapsible claim card. "It needs to have a collapsable card structure
   where one can expand to see break and fulfill condition. The collapsable card
   should be informative with summary of how many break and fullfill conditions
   there are and where does the claim comes from (view source note) and make the
   claim as primary claim." Everything on that list lives in .clm-head. */
.clm-head{display:flex;align-items:flex-start;gap:10px;cursor:pointer;user-select:none}
.clm-chev{font-size:var(--fs-label);color:var(--text-muted);flex-shrink:0;line-height:1.6;transition:transform .16s;width:12px;text-align:center}
.clm-card.open .clm-chev{transform:rotate(90deg)}
.clm-headmain{flex:1;min-width:0}
.clm-sum{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:6px}
.clm-cnt{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);display:inline-flex;align-items:center;gap:var(--sp-1)}
.clm-cnt b{color:var(--text-soft);font-weight:700}
.clm-cnt.none{opacity:0.6}
/* THE CLAIM HEAD'S LINE IS ALL BOXES (board §2, his comment 11 Sep: "View source note grey text
   beside violet Edit looks bad"). Two button-neutral boxes and the bare disclosure chevron;
   the group's step is the board's 8. ⚠ THE WORDS WENT, THE CONTROLS DID NOT — view source note
   is F4, the evidence surface, and Edit is F5. */
.clm-headacts{display:flex;align-items:center;gap:var(--sp-2);flex-shrink:0}
/* Session 56 (S56-3, R2) · at a phone width the head actions — "★ the bet" + "view source
   note" — are a fixed-width sibling of the statement, so a 256px card left the statement
   ~25px and it rendered ONE LETTER PER LINE (seen on MARICO at 390px). Under 640px the
   actions drop beneath the statement.
   ⚠ AMENDED IN SESSION 66, AND THE INDENT WAS THE TELL. The 22px aligned the dropped row
   past the LEADING chevron, and that chevron no longer exists — it moved to the row end
   (his fourth finding), so the row now aligns with the statement itself.
   ⚠ AND THE CHEVRON DOES NOT DROP WITH THEM. Screen 5b keeps it at the card's top right at
   390 while Edit disappears; letting it ride the wrapped row would put the one control that
   says "this opens" below the thing it opens. It is lifted out of the flow instead — which
   also means it never re-creates the fixed-width sibling that squeezed the statement.
   ⚠ AND EDIT IS NOT HIDDEN HERE. Screen 5b drops it at 390 for room, but the wrapped row
   has the whole card width and Edit is a shipped control — hiding it with a media query
   is an F-class deletion done quietly. The design's reason does not survive its layout. */
   ⚠ ITS RULES MOVED into the single 640px block at the foot of the Record's CSS —
   one breakpoint, one place. Nothing about them changed. */
.clm-body{margin-top:0.85rem;padding-top:0.85rem;border-top:1px solid var(--line)}
/* ⚠ THE PRIMARY CARD IS ALWAYS FIRST AND ALWAYS LOOKS IT. His rule: "The primary
   claim should always be the on top." Ordering is enforced in _claimsRanked, not
   here — this only makes the choice visible. */
/* ⚠ THE GOLD PRIMARY TREATMENT IS SCOPED TO `.clm-onpage`, AND THE SCOPE IS THE POINT.
   `.clm-card.primary` is NOT only the stock page's: the extraction-review proposal card
   uses it for the bet being chosen (step 9's surface, which he has not seen redesigned),
   and the thesis-history modal uses it to mean "current version" — a different meaning
   wearing the same class. An unscoped rule here would have restyled both, silently, in a
   step that is supposed to touch one surface. The generic navy `.clm-card.primary` above
   survives for exactly those two.
   ⚠ AND .clm-bet-rail IS NOT DEAD — the proposal card still renders it (line ~17530). It
   is dropped from _claimCardHtml ONLY, where it duplicated the ★ badge ten pixels away.
   The first draft of this comment said the rule was deleted; the grep said otherwise.
   Gold says "load-bearing"; the marker rule still says "which claim this is". Two
   questions, two answers, so only three sides go gold and the left rule is left alone. */
.clm-card.clm-onpage.primary{border-color:var(--gold-deep);border-width:1.5px;border-left-width:3px;box-shadow:none;background:var(--surface)}
/* ⚠ AND THE RING BACK ON TOP OF IT. The line above kills the base card's shadow, and at
   equal specificity 350 lines below .clm-card.clm-onpage.open it was killing the OPEN
   ring too — on the primary card, which is the one card board 5a draws the ring on
   (measured: rgb(44,79,154) 0 0 0 1px inset, which is exactly --sel-ring). Source order
   decides ties; state has to win, so it is restated here where it can. */
.clm-card.clm-onpage.primary.open{box-shadow:var(--sel-ring)}
/* Gold is never a word (3.15:1) — so once the rule is gold the C-id goes NAVY, not gold. */
.clm-card.clm-onpage.primary .clm-cid{color:var(--navy)}
.clm-card.clm-onpage.primary .clm-stmt{font-size:var(--fs-title);font-weight:800;color:var(--navy);line-height:1.25}
/* ══ HIS STEP-5 FINDINGS, 9 September — the card redrawn against the PROTOTYPE ══════════
   He compared what shipped with screen 5a and listed six deviations, then named the rule:
   "the prototype should be reflected as it is with additives that were left in the designs
   like functionalities etc." The reference for every value below is the prototype's own
   markup, not the PNG — design/claude_design_upload/design_handoff_stock_page/prototype/
   Stockport IA.dc.html, artboard 5a — because a PNG cannot tell you a border-width.
   ⚠ EVERY RULE HERE IS SCOPED TO .clm-onpage. .clm-card, .clm-stmt, .clm-primary-badge and
   .clm-state are all shared with the extraction-review proposal card and the thesis-history
   modal. That is the trap that scoped the gold border in step 5 and it has not moved. */

/* 1 · THE MARKER — the claim's own bar colour. ⚠ Session 117, his finding: the 8x8 square before the C-id on the claim card
   is GONE ("not needed"); the C-id tag wears the same ramp as its tint, which is what carries identity once the primary
   card's left rule turns gold. This shape lives on only as the claims strip's row rule (.clm-acc, above). */
.clm-mkdot{width:var(--sp-2);height:var(--sp-2);border-radius:var(--radius-3xs);flex-shrink:0;display:inline-block}
.clm-mkdot.mk1{background:var(--navy-soft)}
.clm-mkdot.mk2{background:var(--mk2)}
.clm-mkdot.mk3{background:var(--mk3)}
.clm-mkdot.mk4{background:var(--mk4)}
.clm-mkdot.mk5{background:var(--mk5)}

/* 2 · ☆ MAKE PRIMARY IS NEUTRAL GREY, NOT VIOLET — his first finding, and it is unchanged:
   violet is Navigate, the thing you should do next (§2b.2 #5), and painting "make this primary"
   violet says the page thinks you should reassign the load-bearing bet, which is exactly what
   the ★ badge on the other card denies. It is an OFFER.
   ⚠ WHAT CHANGED IS WHICH NEUTRAL — HIS RULING, 12 SEP 2026: "for the 4 decisions we can lock
   the v2 board's decision." Board 5a drew the offer at weight 600 on a 1px hairline over
   nothing; the v2 board draws it as badge-mark's UNFILLED TWIN — 500 on a 1.5px hairline over
   the surface — and that is the one that is right, so 5a is superseded on this element alone
   (spec P3-Q2). It has no rule of its own now: every value it used to restate belonged to the
   badge it swaps with, which is why the two still swap in place without the header reflowing,
   and the twin Phase 3 built for this and left unplaced is finally worn.
   ⚠ The hover is the app's, kept: the board draws none for the twin. */
.clm-mkprim:hover{border-color:var(--navy-soft);color:var(--text-soft)}
/* ⚠ THE SCOPED COPY IS GONE. It existed because the card's badge and the two other surfaces'
   badges were drawn at different sizes; badge-mark is ONE component at one size, so the base
   rule now carries the geometry this scoped one used to add and the three agree. */

/* 3 · THE STATE CHIP IS COLOURED, AND IT IS THE CONTROL — his sixth finding. The coloured
   .clm-state pill existed but only the read-only discard shelf ever rendered it; a live card
   got a mono grey <select>, which is why he saw no colour. The pill is now the trigger and a
   Set-state popover is the picker, exactly as SPEC-components §1 draws it.
   ⚠ THE WRITE PATH IS UNCHANGED. Every row still calls claimSetState, which opens the
   state-change modal where the change is clubbed with a note. Turning a picker into a
   prettier picker must not quietly turn a two-step write into a one-click one. */
.clm-statewrap{position:relative;display:inline-block}
/* ⚠ AND IT WEARS THE PILL'S OWN BOX — HIS RULING, 12 SEP 2026: "for the 4 decisions we can lock
   the v2 board's decision." Board 5a narrowed the control's left inset and shrank its chevron;
   the v2 board draws ONE box whether the pill reports or picks, and that is the one that is
   right, so 5a is superseded on this element alone (spec P3-Q3). The chevron's own alpha is not
   part of the ruling and is not touched — it is question 11 on the list. */
.clm-statebtn{border:none;cursor:pointer;display:inline-flex;align-items:center;gap:var(--sp-1);padding:var(--pill-pad);font-family:var(--font-ui)}
.clm-statebtn .sb-chev{font-size:var(--fs-caption);opacity:0.8}
.clm-statepopover{display:none;position:absolute;top:100%;left:0;margin-top:var(--chip-gap);background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-xs);box-shadow:var(--shadow-pop);min-width:190px;padding:var(--sp-1);z-index:var(--z-popover)}
.clm-statepopover.open{display:block}
.clm-statecap{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;color:var(--text-muted);padding:var(--chip-gap) var(--sp-2) var(--sp-1)}
.u-btn-bare{background:none;border:none;padding:0;width:100%;text-align:left}
.clm-staterow{display:flex;align-items:center;gap:var(--sp-2);padding:var(--pop-row-pad);border-radius:var(--radius-2xs);font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text);cursor:pointer}
.clm-staterow:hover{background:var(--surface-tint)}
.clm-staterow.cur{font-weight:700;background:var(--surface-tint)}

/* 4 · THE DISCLOSURE CHEVRON IS ON THE RIGHT — his fourth finding. It gets its OWN class:
   .clm-chev is the history toggle's chevron too, and a `.clm-card.open .clm-chev` rule
   reaches inside the open body and rotates that one as well. Two controls sharing one class
   is how a rule for one silently becomes a rule for both. */
/* ⚠ IT IS THE BARE ICON-BUTTON, not a character in a span — board §2 draws the head's third
   control at 32px with a 16px glyph, and DESIGN lists a disclosure chevron under that
   component. What stays here is the ONE thing the component cannot carry: the rotation, and
   the transition that animates it. ⚠ THE TRANSITION IS WRITTEN OUT IN FULL because this rule
   is declared after the component's and a bare `transition:transform` would silently drop the
   hover fade the component owns. */
.clm-hchev{transition:background .12s,color .12s,transform .16s}
.clm-card.open .clm-hchev{transform:rotate(180deg)}
/* Edit moves up beside it, as the prototype has it — Inter 13/500 violet, the tertiary tier.
   It leaves .clm-actions in the body, where it printed the same verb one click deeper. */

/* 5 · THE COLLAPSED STATEMENT IS ONE LINE — and the box that bounds it is .clm-headmain's
   min-width:0, not this rule. ⚠ text-overflow:ellipsis DOES NOTHING IN AN UNBOUNDED BOX
   (the 1882px hero-island lesson, session 65). The ellipsis is applied to the DISPLAY span
   only, never to .clm-stmt itself, or the edit textarea underneath it gets clipped too.
   ⚠ On a coarse pointer it WRAPS: at a 300-character cap the hover title is how a long claim
   is read, and hover does not exist at 390 (§2b.3). */
.clm-card.clm-onpage .clm-stmt-d{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.clm-card.clm-onpage.open .clm-stmt-d{white-space:normal;overflow:visible;text-overflow:clip}

/* 6 · THE SECTION TITLE — 24px/800 navy with a computed summary under it and the violet
   action at the row end (§1.4). This closes step 5's one shortfall: the section still read
   "What I'm Betting" with a navy pill count. */
.clm-sect-hd{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-3);flex-wrap:wrap}
.clm-sect-t{font-family:var(--font-ui);font-size:var(--fs-section);font-weight:800;color:var(--navy);line-height:1.15}
.clm-sect-sum{font-size:var(--fs-small);color:var(--text-muted);margin-top:var(--sp-1);line-height:1.4}
/* The conditions summary in the spine — one muted sentence, per the prototype, replacing the
   two mono uppercase counts. .clm-cnt is NOT restyled: it dresses the span count in the
   extraction review and two rows in the thesis history. */
.clm-condsum{font-size:var(--fs-small);color:var(--text-muted)}
/* ── What's next (SPEC §1.5) — a sunken band, never a card. It is the one block on this
   page that is about the FUTURE, and it earns a ground of its own rather than a border. */
.wn-card{margin-top:var(--sp-5);background:var(--surface-sunken);border-radius:var(--radius-xs);padding:var(--sp-4) var(--wn-x);display:flex;flex-direction:column;gap:var(--sp-3)}   /* s123 · N7: the content under the title, at every width (a 140px title column left a wide empty strip, worst on a phone) */
.wn-t{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:700;color:var(--navy)}   /* s130 · a section heading beside its plate, the Record's card title size (his item 3) */
.wn-n{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);margin-top:var(--sp-1)}
.wn-rows{display:flex;flex-direction:column;gap:var(--sp-2);min-width:0}
.wn-row{display:flex;align-items:baseline;gap:var(--sp-3);flex-wrap:wrap}
.wn-when{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);min-width:44px;flex-shrink:0}
.wn-txt{font-size:var(--fs-small);color:var(--text);min-width:0}
/* s105 · THE COACH INBOX (spec coach_inbox_spec §3) — built only from the system's parts: the hairline .card is the message,
   the callout eyebrow names its kind, .ev2-mini is every action, .state-panel the empty and failed states, Lucide the ticks.
   Layout and type only here — NO RULE BELOW DRAWS A BOX (L18), and every value is a token. */
.ci-stream{display:flex;flex-direction:column;gap:var(--sp-3)}
.ci-stream > .card{margin-bottom:0}
/* s106 · the Cockpit's block is ONE card for the coach (his finding 1): a head, then each message as a row under a hairline */
.ci-cockpit{display:flex;flex-direction:column;gap:var(--sp-4);margin-bottom:var(--sp-5)}
.ci-hd{display:flex;flex-direction:column;gap:var(--sp-1)}
.ci-hd-s{font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.5;color:var(--text-soft)}
.ci-ck{padding-top:var(--sp-4)}
/* s111 · Home's Coach card: a message is a banded row — the band is the separator (no hairline), one step clear of the row
   above it. On Home a step is ONE line of a checklist: its words fold, its action or its day keeps the right end (the drawing's
   row; on the inbox page a step carries two actions and folds as before). Getting started's caption sits beside its label
   in the sentence voice (words are Inter on Home). */
.ci-row{padding-top:var(--sp-3)}
.ci-row .ci-step{flex-wrap:nowrap}
.ci-row .ci-line{flex:1 1 0}
.ci-kept{font-weight:400;text-transform:none;letter-spacing:0;color:var(--text-muted)}
.ci-cockpit > .ci-acts{margin-top:0}
.ci-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap}
.ci-eb{color:var(--text-muted);min-width:0;flex-wrap:wrap}
/* s110 · the subject band (the inbox page only — its ground, corner and inset are utilities in the markup): the theme and its
   glyph in navy on a live message, today's muted voice on a closed one; the body clears the band by one step more */
.ci-band{flex-wrap:nowrap;align-items:flex-start}   /* the day keeps the band's right end; on a phone the subject folds beside it, not above it */
.ci-band .ci-eb{color:var(--navy)}
.ci-closed .ci-band .ci-eb{color:var(--text-muted)}
.ci-band + .ci-lead,.ci-band + .ci-txt,.ci-band + .ci-steps{margin-top:var(--sp-3)}
.ci-co{font:inherit;letter-spacing:inherit;text-transform:none;text-align:left;color:var(--navy);background:none;border:none;padding:0;cursor:pointer}
.ci-co:hover{text-decoration:underline}
/* s117 · a collated message: each line names its stock, and Home says how many more lines the inbox holds */
.ci-line > .ci-co{font-weight:600}
.ci-more{font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-muted);margin-top:var(--sp-2)}
.ci-when{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);white-space:nowrap}
.ci-txt,.ci-lead{font-family:var(--font-ui);font-size:var(--fs-body);line-height:1.5;color:var(--text);margin-top:var(--sp-2);overflow-wrap:anywhere}
.ci-acts{display:flex;flex-wrap:wrap;gap:var(--sp-4);margin-top:var(--sp-3)}
/* s123 · a filing kept on its story: the same text action, its tick in front */
.ci-acts .ci-saved{display:inline-flex;align-items:center;gap:var(--sp-1)}
.ci-acts .ci-saved > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.ci-steps{display:flex;flex-direction:column;gap:var(--sp-2);margin-top:var(--sp-3)}
.ci-step{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.ci-step > .ic{font-size:var(--icon-glyph-sm);color:var(--text-muted);flex-shrink:0;align-self:center}
.ci-line{font-size:var(--fs-small);color:var(--text);min-width:0;flex:1 1 12rem;overflow-wrap:anywhere}
.ci-btns{display:flex;flex-wrap:wrap;gap:var(--sp-3)}
.ci-step.is-closed .ci-line{color:var(--text-muted)}
.ci-step.is-done > .ic{color:var(--green-strong)}
.ci-closed .ci-txt,.ci-closed .ci-lead{color:var(--text-muted)}
.ci-skip{color:var(--text-muted)}
.ci-moved{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);margin-top:var(--sp-2)}
.ci-since{display:flex;align-items:center;gap:var(--sp-2);font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);text-transform:uppercase;letter-spacing:0.06em}
.ci-since::after{content:"";flex:1;border-top:1px solid var(--line)}
.ci-since > .ic{font-size:var(--icon-glyph-sm)}
.ci-import{margin-bottom:var(--sp-4)}
.ci-in-wn + .ci-in-wn,.ci-steps + .ci-in-wn,.ci-in-wn + .ci-steps{margin-top:var(--sp-4)}
/* ══ THE CLAIMS HEADER — HIS RULING, 12 SEP 2026, BUILT HERE BECAUSE IT IS TWO CHANGES THAT
   MOVE TOGETHER. He spotted it on staging: "Add a claim is still violet text." The v2 board
   makes it the Claims surface's ONE green fill, and the passed-claims chip beside it — a
   hairline holding a violet second word — becomes the neutral GROUP. Shipping the fill next
   to that hairline would have broken rule 13 (a line is all boxes or all text), which is why
   neither could go first. Board 5a draws both the old way and is superseded on the fill; its
   probe carries the ruling. */
.clm-sect-r{display:inline-flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
/* one button-neutral box holding three things: everything but the step is the ladder's */
.clm-passchip{gap:var(--passchip-step)}
.clm-passchip-n{font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:700;color:var(--text-muted)}
.clm-passchip-div{width:1px;height:var(--passchip-rule);background:var(--line-strong);flex-shrink:0}
/* ⚠ THE SECOND WORD IS NO LONGER A COLOUR. It was the violet action inside a statement of
   fact; inside a box there is no second tier to say, and the box IS the control. */
.clm-passchip-a{color:var(--navy);font-weight:600}

/* ══ THE THOUGHT CHAIN (SPEC-components §1) ═══════════════════════════════════════════
   Two renderings of one thing: interlocking rings in the collapsed spine, and a navy island
   in the open card. The rings say HOW MANY moves and WHAT KIND without a word; the island
   says what each one was. */
.clm-chainwrap{display:inline-flex;align-items:center;gap:var(--sp-2)}
/* ⚠ row-reverse, and the rings are printed oldest-first — see the note in _claimCardHtml.
   Newest leftmost AND on top, with no z-index, which this stylesheet does not permit. */
/* ⚠ NEWEST FIRST IN THE DOM, PLAIN ROW, PULLED LEFT — the prototype's construct, not a
   mirror of it. row-reverse put the same rings in the same visual order, but paint order
   follows the DOM: reversed, the NEWER ring overlapped the older, and on the board the
   older overlaps the newer. Same picture, opposite seam. Match the construct. */
.clm-chainrow{display:inline-flex;align-items:center}
.clm-chainring{position:relative;width:16px;height:10px;border:2px solid var(--line-strong);border-radius:var(--radius-ring);box-sizing:border-box;background:var(--surface);flex-shrink:0}
.clm-chainring:not(:first-child){margin-left:-5px}
.clm-chainring.live{border-color:var(--green)}
.clm-chainring.strained{border-color:var(--amber)}
.clm-chainring.broken{border-color:var(--red)}
.clm-chainring.fulfilled{border-color:var(--navy-soft)}
.clm-chainring.untested{border-color:var(--untested-edge)}
.clm-chainlbl{font-size:var(--fs-caption);color:var(--text-muted);white-space:nowrap}

/* The open card is two columns: what would settle the bet, and what has happened to it. */
.clm-body-cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-6);align-items:start}
.clm-body-left{display:flex;flex-direction:column;gap:var(--sp-4);min-width:0}
.clm-chain-island{background:var(--navy);border-radius:var(--radius-xs);padding:var(--sp-4) var(--card-x);min-width:0}
.clm-chain-hd{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-2);margin-bottom:var(--chip-gap)}
.clm-chain-t{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;color:var(--on-brand-soft)}
.clm-chain-n{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--on-brand-soft)}
/* ⚠ THE ISLAND RE-DRESSES THE EXISTING HISTORY ROWS, IT DOES NOT REPLACE THEM. Every note
   link, snapshot button and state chip inside .clm-hev still renders; only the ground changed,
   so every colour that assumed a light ground has to be answered here. */
.clm-chain-island .clm-hev{display:grid;grid-template-columns:var(--sp-2) 86px 1fr;gap:var(--sp-3);align-items:baseline;padding:var(--sp-2) 0;border-bottom:none;border-top:1px solid var(--on-brand-line)}
.clm-chain-island .clm-hev:first-of-type{border-top:none}
/* The row dot is the .clm-dot primitive again — one shape, colours as modifiers. On navy an
   UNTESTED step is white at 35%, not the light ground's hairline. */
.clm-chain-island .clm-dot.untested{background:var(--on-brand-faint)}
.clm-chain-island .clm-hev-date{color:var(--on-brand-soft);width:auto;padding-top:0}
.clm-chain-island .clm-hev-what{color:var(--on-brand)}
.clm-chain-island .clm-hev-why{color:var(--on-brand)}
.clm-chain-island .clm-hev-prev{color:var(--on-brand-soft);border-left-color:var(--on-brand-line)}
.clm-chain-island .clm-hev-snap{background:var(--on-brand-line);color:var(--on-brand-soft)}
/* ⚠ THE "GOLDEN TEXT" HE COULD NOT READ (session 68) WAS NEVER GOLD BY DESIGN. The snapshot
   caption and its "read all of it as it was" action are styled ONCE, for a light surface, in
   --amber-strong — the text-safe amber for --surface — and the island's override above
   repainted the block but not the two elements inside it, so a dark amber sat on navy at ~1.5:1.
   The rule (tokens §2b.3): gold is never a word; on navy a caption is --on-brand-soft and
   an action is --action-on-dark, which is what every other action on this island already is. */
.clm-chain-island .clm-hev-snap b{color:var(--on-brand-soft)}
.clm-chain-island .clm-hev-snapbtn{color:var(--action-on-dark)}
.clm-chain-island .clm-hev-nosnap{color:var(--on-brand-soft)}
/* The list scrolls, the heading does not: a long chain is capped at --chain-max (his ask —
   Shilchar's primary carries six links with snapshots) and scrolls inside the island. */
.clm-chain-list{max-height:var(--chain-max);overflow-y:auto;overscroll-behavior:contain}
.clm-chain-island .ev2-mini{color:var(--action-on-dark)}
.clm-chain-island .ev2-mini:hover{color:var(--action-on-dark)}
.clm-chain-island .clm-nocond{color:var(--on-brand-soft)}
/* ⚠ ON NAVY A STATE IS A WORD, NOT A PILL. The tinted pills are built for a light ground;
   measured on the island, UNTESTED read as grey-on-navy and vanished. The verdict island
   already answers this — the state word at full value on the chrome (§1.1). */
.clm-chain-island .clm-state{background:none;padding:0;color:var(--on-brand-soft);font-weight:600}
.clm-chain-island .clm-state.live{color:var(--action-on-dark)}
.clm-chain-island .clm-state.strained{color:var(--amber)}
.clm-chain-island .clm-state.broken{color:var(--red)}
.clm-chain-island .clm-state.fulfilled{color:var(--on-brand)}
.clm-chain-island .clm-hev-sep{color:var(--on-brand-soft)}
/* s94 · R4-7 · on the island: the note's name is the island's action colour (every action here is), a deleted note is a
   caption, and the thought box takes the island's own neutral — the snapshot box's ground, a white rule. */
.clm-hev .callout-thought{margin-top:var(--sp-2)}
.clm-hev-nosrc{color:var(--text-muted)}
.clm-chain-island .clm-hev-nosrc{color:var(--on-brand-soft)}
.clm-chain-island .callout-thought{background:var(--on-brand-line);border-left-color:var(--on-brand-soft)}
.clm-chain-island .callout-thought .callout-eb{color:var(--on-brand-soft)}
.clm-chain-island .callout-thought .callout-b{color:var(--on-brand)}

/* ══ THE RECORD — step 6 (SPEC §1.6, screens 5a / 5b) ═════════════════════════════════
   The notes timeline and its five sections, replacing the stock page's tab bar. The whole
   page scrolls as one thing now: hero, claims, then the record, with the sections column
   choosing which part of the record is showing rather than which page you are on. */
/* The stock page's content gutter. It does NOT use the .u-p-sp-5-sp-6 utility: this pane
   needs a different gutter at 390 than the utility means everywhere else, and overriding
   a `u-` utility by selector is against the class layer's own rule (§5) as well as losing
   to it on source order. A class that owns its value cannot be beaten by one that does not. */
.stock-pane{padding:var(--sp-6) var(--sp-6) 0;min-width:0}
/* ⚠ ONE GUTTER, OWNED HERE (his finding, session 68: "unnecessary large top and side
   margins"). Board 5a pads <main> ONCE — `32px 32px 0`. This page was stacking three:
   .page's 28/32, this pane's 24/32 and the hero's .tab-pane 24, so the hero sat 76px down
   and 88px in, and The Record (which skipped the third) sat at 64px — not even aligned with
   the hero above it. The page and the hero pane stop adding theirs; this pane is the gutter. */
#page-stock{padding:0}
#page-stock .tab-pane{padding:0}
.rec-wrap{margin-top:var(--sp-6)}
/* ⚠ STICKY LAYER 2 OF 3. It is a SIBLING of .stock-sticky, not a child — see --rec-top. */
.rec-title{position:sticky;top:var(--rec-top);z-index:var(--z-raised);background:var(--shell);padding:var(--sp-3) 0;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.rec-t{font-family:var(--font-ui);font-size:var(--fs-section);font-weight:800;color:var(--navy);line-height:1.15}
.rec-sub{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted)}
/* session 87 · finding 15: the strip's Add note sits at the right edge, on the strip's baseline */
.rec-title-act{margin-left:auto;align-self:center}
/* min-height keeps the two sticky bars engaged on a short section — without it a stock with
   two notes never scrolls and the sections column has nothing to stick to. */
.rec-body{display:grid;grid-template-columns:1fr var(--rec-col-w);gap:0 var(--sp-6);align-items:start;min-height:820px}
/* ⚠ EVERY SECTION CLEARS THE COMPOSER, not only Notes (session 68). #sp-composer is fixed, so it
   takes no space in the flow; only the notes pane carried a bottom pad, and the last rows of
   Organizer, KPIs, the journal and Docs sat under it, unreachable. The footprint is one token. */
.rec-main{min-width:0;padding-bottom:var(--composer-clear)}
.rec-sec{display:none}
.rec-sec.active{display:block}
/* ⚠ STICKY LAYER 3 OF 3. */
.rec-col{position:sticky;top:var(--rec-col-top);padding:var(--sp-4) 0 0 var(--sp-5);border-left:1px solid var(--line);display:flex;flex-direction:column;gap:2px}
.rec-item{display:block;padding:var(--pop-row-pad);border-radius:var(--radius-2xs);cursor:pointer;font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--text-soft);transition:background .12s,color .12s}
.rec-item-row{display:flex;align-items:center;gap:var(--sp-2)}
.rec-sub-line{display:block;font-size:var(--fs-caption);color:var(--text-muted);margin-top:var(--sp-1);padding-left:var(--rec-sub-ic)}
.rec-item.active .rec-sub-line{color:var(--action)}
/* ══ THE RECORD'S FOUR UNDESIGNED SECTIONS — Organizer, KPIs, Buy/Sell journal, Docs ══════
   Claude Design drew the Notes view and dismissed these four in a clause, so there is no
   signed-off layout to build and inventing one is how a design system drifts (A.11). What
   there IS, is a system — and the system has one thing to say about them that is not a guess:
   ⚠ A SURFACE INSIDE A SURFACE MEANS NOTHING (§2a.7). Each of these sections used to be a
   page of white cards; inside the Record they became white cards on a white column inside a
   page, three deep, and that is what reads as "boxes inside boxes". Flattening them is not a
   redesign — it is the same content with one fewer meaningless border, and it applies the
   ruling rather than pre-empting the design session those four still deserve.
   ⚠ ONE RULE, SCOPED TO .rec-sec. Every .card elsewhere in the app is untouched. */
/* ⚠ THE WRAPPER IS FLATTENED, AND A HAIRLINE TAKES OVER FROM IT (session 68's rule, DP-1's
   finish). "Use the existing KPI card, just drop the engulfing card" — his words. Drop a card's
   border, ground and shadow and the blocks inside a pane run together with nothing between
   them, so the rule the card used to draw on four sides now draws on one. */
.rec-sec .card{border:none;background:none;box-shadow:none;padding:0 0 var(--sp-6);margin-bottom:var(--sp-6);border-bottom:1px solid var(--line)}
/* ⚠ AND THE RADIUS GOES WITH THE BOX — its own rule, deliberately. A flattened card that keeps
   --radius-sm draws its one remaining border with CURVED ENDS: a hairline that lifts at both
   tips, which is what the first render of this rule showed (measured, not reasoned — seen in
   the 1440 shot). It is a rule of its own because a declaration block carrying BOTH a radius
   and a border is what L18 counts as a box, so folding this line into the rule above would
   make un-drawing a box read to the lint as drawing one. */
.rec-sec .card{border-radius:0}
/* ⚠ :last-child ALONE CANNOT SEE THE LAST BLOCK. Three of the Organizer's cards sit inside
   #events-section / #questions-section / #rh-wrap — the display-wrappers _refreshEvidenceSummary
   repaints — so every one of them IS its wrapper's last child and cancelled its own rule, while
   the pane's real last block kept one. The pane's last block is what draws no rule. */
.rec-sec > .card:last-child,
.rec-sec > *:last-child > .card,
.rec-sec > *:last-child > * > .card{margin-bottom:0;padding-bottom:0;border-bottom:none}
/* the two summary blocks are ONE band: the rule goes under the pair, never between them */
.rec-sec .ev2-row2{padding-bottom:var(--sp-6);margin-bottom:var(--sp-6);border-bottom:1px solid var(--line)}
.rec-sec .ev2-row2 .card{padding-bottom:0;margin-bottom:0;border-bottom:none;height:100%}

/* ══ THE RECORD ROW · the four sub-sections, built off board 5a ═══════════════════════
   ⚠ ONE CONSTRUCT, NOT FOUR LISTS. Clicking Organizer, KPIs, Buy/Sell journal and Docs in
   the prototype's own sections column shows the same row every time: a key column, a body
   that stacks title → meta → note → claim-ref, and ONE violet action, separated by a 1px
   rule. Nothing on the board is a card. That is what makes the Record read as one surface
   with five views instead of five pages that happen to share a header — and it is why
   these four sections needed no second Claude Design session: the design was already in
   the artefact, behind a click.
   Measured, not guessed: grid 110px / rest / auto, gap 16px, baseline, 14px 0, --line. */
.rec-row{display:grid;grid-template-columns:var(--rec-k) minmax(0,1fr) auto;gap:var(--sp-3);
         align-items:start;padding:var(--rec-row-y) 0;border-bottom:1px solid var(--line)}
.rec-row:last-child{border-bottom:none}
.rec-row.wide-k{grid-template-columns:var(--rec-k-wide) minmax(0,1fr) auto}
/* session 87 · finding 10: a row whose key is one glyph — the sentence takes the rest */
.rec-row.glyph-k{grid-template-columns:var(--icon-glyph) minmax(0,1fr) auto}
.rec-row.glyph-k > .rec-k.with-ic{padding-top:var(--rec-kic-top)}
.rec-g{color:var(--text-muted)}
.rec-g.good{color:var(--green-strong)} .rec-g.bad{color:var(--red-strong)} .rec-g.warn{color:var(--amber-strong)}
/* the key: a date in mono, or — in the Organizer — a word, and then it is a label */
.rec-k{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);white-space:nowrap;padding-top:var(--sp-1)}
/* the key can lead with one Lucide glyph (board 03's question row). .ic is sized in em, so the
   slot states the glyph's size instead of inheriting the key's 11px — and the nudge changes with
   it, because both are centring the key on the body's first line from boxes of different heights. */
.rec-k.with-ic{display:inline-flex;align-items:center;gap:var(--chip-gap);padding-top:var(--rec-kic-top)}
.rec-k > .ic{font-size:var(--icon-glyph)}
.rec-k.word{font-family:var(--font-ui);font-weight:600;font-size:var(--fs-label);letter-spacing:0.04em;
            text-transform:uppercase;white-space:normal}
.rec-b{min-width:0}
.rec-ttl{font-size:var(--fs-body);font-weight:500}
/* a Record section card's title — board 03, and DESIGN rule 14 — and its count, which rides
   INSIDE it so that at 390 it flows after the last word instead of floating beside a wrapped
   title. ⚠ NO LITERAL SPACE BEFORE IT: the margin is the step, the same way the box button's
   gap is (session 76 §11 item 1). */
.rec-card-t{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:700;color:var(--navy)}
.rec-card-n{margin-left:var(--sp-2);vertical-align:middle}
.rec-meta{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);margin-top:var(--rec-tight)}
.rec-note{font-size:var(--fs-small);color:var(--text-soft);margin-top:var(--rec-tight)}
/* which claim this row is about — navy-soft, the same mono C-id the claim card uses, so the
   link between a doc, a trade, a reading and the bet it belongs to is one colour everywhere */
.rec-cref{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--navy-soft);margin-top:var(--sp-1)}
.rec-a{display:flex;align-items:center;gap:var(--sp-4);white-space:nowrap;padding-top:var(--rec-tight)}
/* "Open ›" — board 03 draws the word and its chevron as ONE control, not a word beside a glyph */
.rec-open{display:inline-flex;align-items:center;gap:var(--rec-tight)}
.rec-open > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
/* an event row's body cell: dot · text · pill, the dot resting on the first line */
.rec-evt-b{display:flex;gap:var(--rec-evt-step);align-items:flex-start;flex-wrap:wrap}
.rec-evt-b .ev2-body{flex:1;min-width:0;font-size:var(--fs-body);color:var(--text);line-height:1.55}
/* s123 · an event's link, under its date: the violet text action the Coach's filings wear */
.rec-evt-link{margin-top:var(--rec-tight)}
/* s123 · the bets a record touched — the note's chips, on their own line under the record */
.rec-claimlinks{display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-3);margin-top:var(--rec-tight);min-width:0}
.rec-evt-link > .ev2-mini{display:inline-flex;align-items:center;gap:var(--sp-1)}
.rec-evt-link .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
/* a question row's own title — 14/600, where a note row's is 13/600 */
.rec-qt{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;color:var(--text)}
/* the section's own heading row — a title and one violet action, never a boxed card header */
.rec-sec .rec-hd{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-4);
                 padding-bottom:var(--sp-2);margin-bottom:0}
.rec-sec .rec-hd .label{margin:0;white-space:nowrap}
/* ⚠ THE SUB-SECTIONS' BUTTONS ARE THE LADDER'S, NOT A LOCAL VIOLET (v2, session 73). His 9 Sep
   finding was that the violet buttons were inconsistent, and DP-1 answered it by repainting every
   hairline button inside a Record section as violet text, from three rules in THE RECORD,
   UNLAYERED. v2 names that repaint a defect ("the Record's violet Cancel") and the rules are
   gone: a section head's action is a button-neutral, a Cancel is the hairline it always was
   underneath, and a row's action is a text control written on its own markup. */

/* ══ THE FOUR SUB-SECTIONS — [E] SURFACES (audit §4.2) ══════════════════════════════════
   ⚠ DP-1, session 69. Sessions 67 and 68 moved the Organizer's four lists onto the record
   row, rebuilt KPIs as a five-column table and flattened the journal's stat strips — all of
   it conformed to prototype panes that were never briefed and never designed (audit §1.1:
   "a conformance score against a placeholder is a precise measurement of the wrong thing").
   Those overrides are gone. What is left here is the whole of what an [E] surface is allowed:
   the token pass on the trade table, the duplicate-heading fix, and the flattened wrapper. */
/* ══ SCREEN 08 · THE BUY/SELL JOURNAL (v2 board 08, session 77) ══════════════════════════
   Its notes column's first item is the grammar: "Stat cells kept, as ONE hairline grid (cells
   share borders; no cell has its own box)" — five figures then four, touching, one card corner
   round the pair and the seam between them drawn once. Its fifth is the log: header Inter caps
   on two hairlines, rows on one, no stripes, figures right-aligned, the notes column in Inter
   because they are words. The BOX that used to wrap all of it is gone.
   ⚠ NOTHING HERE IS UNLAYERED AND IT DOES NOT NEED TO BE. 390 has to drop a border from every
   second cell, which no token can express, and a layered width block can only do that if
   nothing unlayered is holding the border — so the cell's border comes off the utility and into
   .jr-cell, and the strips stop wearing .card-plain (whose corner is the wrong one for a pair
   that touches). After that no utility on this screen argues with a rule. */
/* no ground is declared on either strip, which is what the board does: the cells are the
   page showing through its hairlines, and the page is the one that decides its own colour. */
.jr-stats,.jr-stats-b{display:grid;border:1px solid var(--line);background:var(--surface)}
.jr-stats{grid-template-columns:var(--jr-stat-cols);border-radius:var(--radius-sm) var(--radius-sm) 0 0}
.jr-stats-b{grid-template-columns:var(--jr-stat-cols-b);border-radius:0 0 var(--radius-sm) var(--radius-sm)}
/* the seam, and the adjacency IS the condition: the second strip drops its top edge only
   while the first is directly above it. */
.jr-stats + .jr-stats-b{border-top:0}
.jr-cell{padding:var(--jr-cell-pad);border-right:1px solid var(--line)}
.jr-stats .jr-cell:last-child,.jr-stats-b .jr-cell:last-child{border-right:0}
.jr-lbl{font-size:var(--jr-lbl-fs);margin-bottom:0}
.jr-lbl-w{font-weight:400}
.jr-fig{font-family:var(--font-mono);font-size:var(--jr-fig);font-weight:700;line-height:1;
  color:var(--navy);margin-top:var(--jr-fig-mt);white-space:nowrap}
/* the percent rides inside the figure at the body size, muted — it keeps the figure's weight
   and family because the board draws it inside the figure and overrides neither. */
.jr-pct{font-size:var(--fs-body);color:var(--text-muted)}
.jr-sub{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:var(--jr-sub-mt)}
/* CMP is the one editable figure, and a dashed navy-soft underline says so — a geometry cue,
   not a colour. */
.jr-ccy{color:var(--text-muted);font-weight:400}
.jr-cmp{border:0;border-bottom:1.5px dashed var(--navy-soft);margin-top:0}
/* "Log a trade → an action strip…; Add stays the journal's one fill." ⚠ It was painted --shell while the page was white.
   The page is the shell now (session 109), and a closed box is white — so the strip is. */
.jr-strip{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:var(--jr-strip-pad);margin-bottom:var(--jr-strip-mb)}
.jr-strip-hd{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-3)}
.jr-strip-t{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:700;color:var(--navy)}
.jr-strip-hint{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted)}
.jr-fields{display:grid;grid-template-columns:var(--jr-cols);gap:var(--sp-3);align-items:end}
.jr-fields .form-input{padding:var(--jr-fld-pad)}
.jr-fields .jr-amt{background:var(--surface-sunken);border-color:var(--line);color:var(--text-soft)}
.jr-fl{font-size:var(--fs-label)}
.jr-add{display:inline-flex;align-items:center;gap:var(--chip-gap);padding:var(--jr-add-pad)}
.jr-add .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.jr-eb{margin:var(--jr-eb-m)}
#stc-xirr-tab .tx-table th{background:var(--surface-tint);border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;letter-spacing:0.06em;padding:var(--jr-th-pad)}
#stc-xirr-tab .tx-table td{border-bottom:1px solid var(--line);padding:var(--jr-td-pad)}
/* the board's row carries its 16 as PADDING and its 12 as the grid's GAP; a table row can hold
   neither, so the 12 is split across the two cells that face each other and the 16 is put back
   on the two that face the edge. Both of the board's numbers land where it puts them. */
#stc-xirr-tab .tx-table th:first-child,#stc-xirr-tab .tx-table td:first-child{padding-left:var(--jr-row-x)}
#stc-xirr-tab .tx-table th:last-child,#stc-xirr-tab .tx-table td:last-child{padding-right:var(--jr-row-x)}
#stc-xirr-tab .tx-table td.jr-date{font-size:var(--fs-caption);color:var(--text-soft)}
#stc-xirr-tab .tx-table td.jr-num{color:var(--navy)}
/* a note is words, so it is Inter — the cell rule underneath sets mono for the figures */
#stc-xirr-tab .tx-table td.jr-note{font-family:var(--font-ui);line-height:1.5}
.jr-side{background:var(--neutral-fill);color:var(--text-soft);padding:var(--jr-side-pad);display:inline-block}
/* a trade already inside the holdings snapshot — quieter, and excluded from the position */
.tx-hist{background:var(--surface-sunken);opacity:0.75}
/* the row's delete: a bare icon target, red under the pointer. _confirmDialog still gates it. */
.jr-del{width:var(--jr-del);height:var(--jr-del);display:inline-flex;align-items:center;
  justify-content:center;border-radius:var(--radius-2xs);color:var(--text-muted)}
.jr-del .ic{width:var(--icon-glyph);height:var(--icon-glyph)}
.jr-del:hover:not(:disabled){color:var(--red-strong)}
/* s98 · a trade's note is his to write or change: a bare pencil after the words, the delete's sibling (navy under the pointer) */
.jr-note-ed{width:var(--jr-del);height:var(--jr-del);display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;
  border-radius:var(--radius-2xs);color:var(--text-muted);margin-left:var(--sp-1)}
.jr-note-ed .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.jr-note-ed:hover{color:var(--navy)}
/* ⚠ HIS FINDING 1, 9 SEP — "the old stock page heading is duplicative", and it is a FIX, not a
   re-layout, so the restore keeps it. The Record's title bar already says which section you are
   in and how many rows it holds. Only the panes whose heading IS the section name lose it. */
#stc-kpis > div > .card > .row-sb > .label,
#stc-xirr-tab > .u-mono.u-fs-micro{display:none}
/* the eyebrow bar belongs to a boxed card, and the Record's wrappers are not boxed */
.rec-sec .card-title::before{content:none}
.rec-sec .card-title{margin-bottom:var(--sp-3)}
/* A section's own heading is the app's label role; the Record's title bar already says which
   section you are in, so these stay quiet and do not compete with it. */
.rec-sec .card > .row-sb > .label{color:var(--text-muted)}
.rec-item:hover{background:var(--surface-tint);color:var(--text)}
/* ⚠ THE SAME TREATMENT AS THE SIDEBAR'S ACTIVE ITEM — his call, IA §2b.2 #1. Two lists of
   places to go, one way of saying which one you are in. */
.rec-item.active{background:var(--green-soft);color:var(--action);font-weight:600}
/* session 109 · a glyph where the dot was — the main sidebar's row (his ask, 4 Oct): muted at rest, the row's green when open */
.rec-item .ic{width:var(--icon-glyph);height:var(--icon-glyph);color:var(--text-muted)}
.rec-item.active .ic{color:var(--action)}
.rec-lbl{display:contents}   /* at 1440 the word and its count are the row's own items; the phone's bar makes them one line under the glyph */
.rec-cnt{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);margin-left:auto}
.rec-item.active .rec-cnt{color:var(--action)}
/* The 390 bottom bar. Off-screen until the Record is genuinely what you are reading. */
.rec-bar{display:none}

/* ── SESSION 101 · THE PERFORMANCE TAB (spec §4, his order): money summary + what it counts · behaviour gap · three drivers ·
   year by year · stock-level XIRR · the rest. Tokens only; the reused parts (the driver cards, the year chart) keep their own
   rules. Corners come from the u-r-* utilities (the class layer), so no new box-drawing rule is added (§2a.7). The 390 overrides
   sit in the phone block that follows these rules (the stock page's), so they come after the rules they change. ── */
/* session 110 · the status and Refresh live in the page's head; .perf-status is what is left in the page — one amber
   line, only when an update failed or the engine warned */
.perf-head-st{display:flex;align-items:center;gap:var(--sp-3);min-width:0}
.perf-head-st:empty{display:none}
.perf-head-st ~ .page-help{flex-shrink:0}   /* where the row is short of room the status folds; Help is never squeezed */
.perf-head-t{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);line-height:1.5;min-width:11rem;text-align:right}   /* where the head is short of room the status folds to two lines, never to a column of words */
.perf-status{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-4);flex-wrap:wrap}
.perf-status-t{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);min-width:0;flex:1 1 280px;overflow-wrap:anywhere;line-height:1.5}
.perf-status-warn .perf-status-t{color:var(--amber-strong)}
.perf-busy{color:var(--navy);font-weight:700}
.perf-refresh{flex:0 0 auto}
.perf-card{padding:var(--sp-5);margin-bottom:var(--sp-5)}
.perf-card-flush{padding:0;overflow:hidden}
.perf-hd{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-1) var(--sp-3);flex-wrap:wrap;margin-bottom:var(--sp-4)}
.perf-hd-pad{padding:var(--sp-4) var(--sp-5) 0}
.perf-eb{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:700;color:var(--navy)}
.perf-win{font-size:var(--fs-caption);color:var(--text-muted)}
.perf-figs{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--sp-3)}
.perf-fig{background:var(--surface-tint);padding:var(--sp-3) var(--sp-4);min-width:0}
.perf-fig-v{font-family:var(--font-mono);font-size:var(--fs-lead);font-weight:700;color:var(--navy);margin-top:var(--sp-1);overflow-wrap:anywhere}
.perf-fig-v.perf-pos{color:var(--green-strong)}
.perf-fig-v.perf-neg{color:var(--red-strong)}
.perf-fig-s{font-size:var(--fs-micro);color:var(--text-muted);margin-top:var(--sp-1);line-height:1.4}
.perf-pos{color:var(--green-strong)}
.perf-neg{color:var(--red-strong)}
.perf-counts{margin-top:var(--sp-5);border-top:1px solid var(--line);padding-top:var(--sp-4)}
.perf-sub{font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-muted);margin-bottom:var(--sp-2)}
.perf-strip{font-size:var(--fs-small);color:var(--text-soft);display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-2);align-items:baseline;margin-bottom:var(--sp-3)}
.perf-strip strong{color:var(--navy)}
.perf-strip-i{white-space:nowrap}
.perf-tbl .perf-nm{white-space:nowrap}
.perf-dot{color:var(--line-strong)}
.perf-flag,.perf-note{padding:var(--callout-pad);border-left:var(--rule-w) solid var(--amber);background:var(--amber-soft);margin-bottom:var(--sp-3);min-width:0}
.perf-note{border-left-color:var(--line-strong);background:var(--surface-tint)}
.perf-flag-t{font-size:var(--fs-small);font-weight:700;color:var(--text)}
.perf-flag .perf-flag-t{color:var(--amber-strong)}
.perf-flag-b{font-size:var(--fs-caption);color:var(--text-soft);line-height:1.5;margin-top:var(--sp-1)}
.perf-flag-l{margin-top:var(--sp-2)}
.perf-flag-r{display:flex;align-items:baseline;gap:var(--sp-1) var(--sp-3);flex-wrap:wrap;padding:var(--sp-1) 0;border-top:1px solid var(--line)}
.perf-flag-r:first-child{border-top:0}
.perf-flag-d{font-size:var(--fs-caption);color:var(--text-muted);flex:1 1 auto;min-width:0}
.perf-nm{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;color:var(--navy);overflow-wrap:anywhere}
.perf-more{font-size:var(--fs-caption);color:var(--text-muted)}
.perf-acts{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-4)}
.perf-acts-i{display:inline-flex;gap:var(--sp-3);flex-wrap:wrap}
.perf-link{background:none;border:0;padding:0;font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;color:var(--accent);cursor:pointer;text-align:left}
.perf-link:hover{text-decoration:underline;color:var(--accent-hover)}
.perf-limits{margin-top:var(--sp-4)}
.perf-ul{margin:0;padding-left:var(--sp-5);font-size:var(--fs-caption);color:var(--text-soft);line-height:1.55}
.perf-ul li{margin-bottom:var(--sp-1)}
.perf-acc{border:1px solid var(--line);margin-top:var(--sp-3);background:var(--surface);min-width:0}
.perf-acc-card{padding:0}
.perf-acc-bar{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);cursor:pointer;list-style:none}
.perf-acc-bar::-webkit-details-marker{display:none}
.perf-acc-t{font-size:var(--fs-small);font-weight:700;color:var(--navy)}
.perf-acc-n{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);flex:1;min-width:0}
.perf-acc-chev{color:var(--text-muted);transition:transform .15s;display:inline-flex}
.perf-acc[open] > .perf-acc-bar .perf-acc-chev{transform:rotate(180deg)}
.perf-acc-body{padding:0 var(--sp-4) var(--sp-4)}
.perf-tblwrap{overflow-x:auto;max-width:100%}
.perf-tbl{font-size:var(--fs-small)}
.perf-tbl th{font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;text-transform:uppercase;letter-spacing:0.04em;color:var(--text-soft);text-align:left;padding:var(--sp-2) var(--sp-3);border-bottom:2px solid var(--line);background:var(--surface-tint);white-space:nowrap}
.perf-tbl td{padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--line);vertical-align:top}
.perf-num{text-align:right;font-family:var(--font-mono);white-space:nowrap}
.perf-tbl th.perf-num{text-align:right}
.perf-strong{font-weight:700}
.perf-cell-s{font-family:var(--font-ui);font-size:var(--fs-micro);color:var(--text-muted);white-space:normal;font-weight:400}
.perf-tr-warn td{background:var(--amber-soft)}
.perf-nudges{display:grid;gap:var(--sp-2);margin-top:var(--sp-3)}
.perf-nudge{font-size:var(--fs-caption);color:var(--text-soft);line-height:1.5}
.perf-nudge strong{color:var(--text)}
.perf-co{border-top:1px solid var(--line);padding-top:var(--sp-3);margin-top:var(--sp-3)}
.perf-co:first-child{border-top:0;margin-top:0;padding-top:0}
.perf-co-hd{display:flex;align-items:center;gap:var(--sp-1) var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-2)}
.perf-co-n{font-size:var(--fs-caption);color:var(--text-muted);flex:1 1 auto;min-width:0}
.perf-date{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-soft);white-space:nowrap}
.perf-src{font-size:var(--fs-micro);color:var(--text-muted)}
.perf-al-pick{flex:1 1 100%;margin-top:var(--sp-2)}
.perf-al-q{width:100%;max-width:420px}
.perf-al-res{margin-top:var(--sp-2);display:grid;gap:var(--sp-1);max-width:520px}
.perf-al-msg{font-size:var(--fs-caption);color:var(--text-muted)}
.perf-al-opt{display:flex;align-items:baseline;gap:var(--sp-2);text-align:left;background:var(--surface);border:1px solid var(--line);padding:var(--sp-2) var(--sp-3);cursor:pointer;font-family:var(--font-ui);min-width:0}
.perf-al-opt:hover{border-color:var(--action)}
.perf-al-co{font-size:var(--fs-caption);color:var(--text-soft);flex:1;min-width:0}
.perf-al-x{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted)}
.perf-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-3)}
.perf-mc{background:var(--surface-tint);padding:var(--sp-4);text-align:center;min-width:0}
.perf-big{font-family:var(--font-mono);font-size:var(--fs-title);font-weight:700;color:var(--navy);margin:var(--sp-1) 0}
.perf-big.perf-pos{color:var(--green-strong)}
.perf-big.perf-neg{color:var(--red-strong)}
.perf-card-s{font-size:var(--fs-micro);color:var(--text-muted);margin-top:var(--sp-1);line-height:1.4}
.perf-card-s.perf-pos{color:var(--green-strong)}
.perf-card-s.perf-neg{color:var(--red-strong)}
.perf-gap-drag{background:var(--amber-soft)}
.perf-gap-drag .perf-big{color:var(--amber-strong)}
.perf-gap-boost{background:var(--green-soft)}
.perf-gap-boost .perf-big{color:var(--green-strong)}
.perf-gap-b{font-size:var(--fs-small);color:var(--text-soft);line-height:1.55;margin-top:var(--sp-3)}
.perf-fy-note{font-size:var(--fs-caption);color:var(--text-soft);margin-top:var(--sp-3);line-height:1.5}
/* session 110 · the year-by-year bars take their SERIES' colour (his ruling, 4 Oct): XIRR indigo, TWRR mint, Nifty grey; a
   negative bar is the same hue, lighter (it was red for all three, so a bar said "loss" and never said whose); the sign stays
   on the figure, which is still red when negative. The dots are the bar's own colour. Scoped to this page: onboarding's
   reveal draws the same chart and is left as built. */
#perf-fy .ob-fy-bar-fill.xirr,#perf-fy .ob-fy-dot.xirr{background:var(--viz-indigo)}
#perf-fy .ob-fy-bar-fill.twrr,#perf-fy .ob-fy-dot.twrr{background:var(--viz-mint)}
#perf-fy .ob-fy-bar-fill.nifty,#perf-fy .ob-fy-dot.nifty{background:var(--text-faint);opacity:1}
#perf-fy .ob-fy-bar-fill.neg{opacity:.4}
.perf-fy-out{color:var(--amber-strong)}
.perf-line{display:flex;align-items:baseline;gap:var(--sp-3);padding:var(--sp-2) 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
.perf-line-m{flex:1;min-width:0;font-size:var(--fs-small);color:var(--text-soft)}
.perf-line-v{font-family:var(--font-mono);font-size:var(--fs-small);color:var(--amber-strong)}
.perf-two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-5)}
.perf-take{background:var(--chrome);padding:var(--sp-5);margin-bottom:var(--sp-5)}
.perf-take-eb{font-family:var(--font-ui);font-size:var(--fs-label);font-weight:700;text-transform:uppercase;letter-spacing:0.06em;color:var(--on-brand-soft)}
.perf-take-b{font-size:var(--fs-body);line-height:1.65;color:var(--on-brand);margin-top:var(--sp-2)}
.perf-empty{padding:var(--sp-7) var(--sp-6);text-align:center;max-width:640px;margin:0 auto}
.perf-empty-t{font-size:var(--fs-title-sm);font-weight:600;color:var(--navy);margin-top:var(--sp-2)}
.perf-empty-b{font-size:var(--fs-body);color:var(--text-soft);line-height:1.6;margin-top:var(--sp-2)}
.perf-empty .perf-acts{justify-content:center}

/* ── The stock page at 390 — the Record (SPEC §2) AND the claim card (S56-3) ─────── */
@media(max-width:640px){
  /* s101 · the Performance tab at 390 — its figures two by two, its tables scroll inside their own wrapper */
  .perf-head-t{text-align:left}   /* s110 · on a phone the head's status starts the row */
  .perf-figs{grid-template-columns:repeat(2,minmax(0,1fr))}
  .perf-figs .perf-fig:last-child{grid-column:1/-1}
  .perf-cards{grid-template-columns:repeat(2,minmax(0,1fr))}
  .perf-two{grid-template-columns:1fr;gap:0}
  .perf-card{padding:var(--sp-4)}
  .perf-card-flush{padding:0}
  .perf-hd-pad{padding:var(--sp-3) var(--sp-4) 0}
  .perf-big{font-size:var(--fs-lead)}
  .perf-acc-body{padding:0 var(--sp-3) var(--sp-3)}
  .perf-acc-bar{padding:var(--sp-3)}
  .perf-empty{padding:var(--sp-6) var(--sp-4)}
  .ob-driver-grid.perf-drivers-grid{grid-template-columns:1fr}
  .perf-tbl-wide{min-width:520px}
  .perf-strip-i{white-space:normal}
  /* session 90 · the tradebook import at 390: the plan's four counts two by two; a select takes its row */
  .tbi-stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .modal-tbi{--jr-fig:var(--jr-fig-sm);--jr-fig-mt:var(--jr-fig-mt-sm);--jr-lbl-fs:var(--jr-lbl-fs-sm)}   /* s94 · D1 — the journal's 390 sizes */
  .as-dup{flex-wrap:wrap}   /* s94 · D7 — Add Stock's "Open it" goes under the words at 390 (#38) */
  .tbi-lbl{min-width:0;width:100%}
  .tbi-meta .tbi-brk{width:100%}
  .tbi-pick{grid-template-columns:minmax(0,1fr)}
  .tbi-cf-ch{margin-left:0}
  /* the claim head wraps and its actions take their own line; the chevron is lifted to
     the card's top right so it never becomes the fixed-width sibling that squeezed the
     statement to one letter per line on MARICO (S56-3), and the section title drops to
     the 20px the IA asks for at this width. */
  .clm-head{flex-wrap:wrap}
  .clm-headacts{flex-basis:100%;margin-top:var(--chip-gap)}
  .clm-card.clm-onpage{position:relative}
  /* ⚠ AND IT KEEPS THE DESK SIZE HERE, WHICH IS THE ONE ICON-BUTTON THAT DOES. The touch size
     exists so a finger can land on a control; this one is NOT the control — the whole claim
     head toggles the card, and the chevron only says which way it is facing. Pinned at the
     desk size because it is absolutely positioned over the statement here, and measured: a
     touch-sized box sits ON the statement at this width and nowhere else. */
  .clm-card.clm-onpage .clm-hchev{position:absolute;top:var(--sp-3);right:var(--sp-3);width:var(--icon-hit);height:var(--icon-hit)}
  .clm-sect-t{font-size:var(--fs-title)}
  .rec-t{font-size:var(--fs-title)}
  /* SPEC §2 · at 390 the open card stacks: Breaks if, Fulfilled if, then the island. */
  .clm-body-cols{grid-template-columns:1fr;gap:var(--sp-4)}
  /* 6b: the zero-claim card's button stretches full width */
  .clm-empty-cta{align-self:stretch}
  /* 5b's chain row is two columns — the dot, then the date OVER the text — not three: a
     86px date column beside 13px text leaves the text ten characters wide on a phone. */
  .clm-chain-island .clm-hev{grid-template-columns:var(--sp-2) minmax(0,1fr);gap:var(--rec-tight) var(--sp-2)}
  .clm-chain-island .clm-hev > .clm-dot{grid-row:1/3}
  .clm-chain-island .clm-hev-date,.clm-chain-island .clm-hev-main{grid-column:2}
  .clm-chain-island{padding:var(--sp-4)}
  /* His 8 Sep ruling (tokens §2b.3): "hover does not exist at 390. On touch, WRAP; never
     ellipse." The collapsed statement was still nowrap+ellipsis at this width — measured. */
  .clm-card.clm-onpage .clm-stmt-d{white-space:normal;overflow:visible;text-overflow:clip}
  .rec-body{grid-template-columns:1fr}
  /* the column becomes the bottom bar; nothing is stacked into the reading column */
  .rec-col{display:none}
  /* full-bleed sunken band — it is the one header on this page that has to win against a
     wall of note text, and it does it with a ground rather than a rule */
  /* ⚠ FULL-BLEED WITHOUT KNOWING THE PADDING. Measured at 390: the pane's side padding is
     32px, so a fixed -16px pull-back left the band inset by 16 on each side and it read as
     a misaligned card rather than a band. calc(50% - 50vw) is the padding-agnostic form —
     it cannot go stale the next time the page's gutter changes. */
  .rec-title{background:var(--surface-sunken);margin-inline:calc(50% - 50vw);padding:var(--sp-3) var(--sp-4);border-bottom:none;justify-content:flex-start}
  /* And the page's own gutter comes down to the 16 the design asks for at this width —
     32px of side padding was costing 16% of a 390px screen. Scoped to the stock page. */
  .stock-pane{padding:var(--sp-4) var(--sp-4) 0}
  .rec-bar{display:flex;position:fixed;left:0;right:0;bottom:0;height:56px;background:var(--surface);border-top:1px solid var(--line);z-index:var(--z-sticky);transform:translateY(100%);transition:transform .2s ease}
  .rec-bar.up{transform:translateY(0)}
  /* ⚠ AND THE COMPOSER LIFTS WITH IT. Measured at 390: the bar sits 0–56px from the
     bottom and the composer's own bottom is 0, so the bar covered Save — the one
     control the composer is there for. The class is set by _recBarSync, on <body>,
     because the composer is fixed to the viewport and is nobody's sibling. */
  body.rec-bar-up #sp-composer{bottom:56px}
  .rec-bar .rec-item{flex:1;flex-direction:column;justify-content:center;gap:0;padding:0;border-radius:0;text-align:center;font-size:var(--fs-label);min-width:0}
  .rec-bar .rec-item .rec-cnt{margin-left:0;font-size:var(--fs-micro)}
  .rec-bar .rec-item-row{flex-direction:column;gap:var(--sp-1)}
  .rec-bar .rec-lbl{display:flex;align-items:baseline;justify-content:center;gap:var(--sp-1);max-width:100%;min-width:0}
  .rec-bar .rec-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
  .rec-body{min-height:0}
  /* the composer rides above the 56px bar here, so the last row has further to clear */
  .stock-pane{--composer-clear:216px}
  /* board 03's phone card. Set as VALUES because the rules that read them are unlayered and a
     layered rule cannot out-rank one — the token layer can, by changing what it resolves to. */
  .stock-pane{--rec-card-pad:14px 16px 2px;--rec-strip-pad:14px 16px;--rec-card-pad-e:14px 16px 14px;--rec-head-pad:10px}

  /* ── 5b · THE HERO (SPEC §2, measured off the board) ────────────────────────────────
     The figures become one mono 12px fact line with the return in 700 navy; the chips wrap
     under it; the island tightens to 12/16 with a 24px verdict. ⚠ The conviction chip stays
     in the chip row — conviction's edit surface (his D64-5). */
  .hero-top{flex-direction:column;align-items:stretch;gap:var(--sp-4)}
  .hero-figs{display:none}
  .hero-factline{display:block;color:var(--text-soft);font-weight:400}
  .hero-factline b{color:var(--navy);font-weight:700}
  .hero-island{min-width:0;padding:var(--sp-3) var(--sp-4)}
  .hvi-verdict{font-size:var(--fs-section)}

  /* ── 5b · THE SLIM HEAD IS 56px AND TWO LINES ─────────────────────────────────────────
     Line 1: the name (14/700) with the verdict pill at the right edge. Line 2: the story
     status with the position at the right edge. No ticker, no Help, no conviction — the
     board draws none of them at 390 (Help is in the sidebar; conviction is in the hero's
     chip row). The strip and its cells go display:contents so the four cells are laid out
     by the head's own grid. Navy strip 52 + head 56 = 108, the IA's number; it was 159. */
  #page-stock{--head-h:56px}
  /* the navy strip is FIXED at the top on a phone; the head sticks under it, not beneath it */
  .stock-sticky{top:52px}
  .stock-sticky .page-header{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"id verdict" "story pos";gap:var(--sp-1) 10px;padding:0 var(--sp-4);align-content:center;align-items:center}
  .stock-sticky .stk-head-id{grid-area:id}
  .stock-sticky .page-title{font-size:var(--fs-body)}
  .stock-sticky .page-subtitle,.stock-sticky .page-help{display:none}
  .stock-sticky #stock-mini-strip,.stock-sticky .vstrip{display:contents}
  .stock-sticky .vstrip-cell:nth-child(1){grid-area:verdict;justify-self:end}
  .stock-sticky .vstrip-cell:nth-child(2){grid-area:story}
  .stock-sticky .vstrip-cell:nth-child(3){display:none}
  .stock-sticky .vstrip-money{grid-area:pos;justify-self:end}
  .vstrip-v.hd-verdict{font-size:var(--fs-caption);padding:var(--rec-tight) var(--sp-2)}
  .vstrip-v.hd-story{font-size:var(--fs-label)}

  /* ── the Record's rows at 390 ──────────────────────────────────────────────
     ⚠ FIVE FIXED COLUMNS DO NOT FIT IN 390px, and a grid that does not fit does not
     wrap — it shrinks the one flexible track until the KPI name is one letter per
     line. That is exactly what it did. On a phone every record row is a stack: the
     key, then the body, then the action, in reading order, with the 1px rule doing
     the separating that the columns did at 1440. */
  /* ── the claims accordion at 390 (SPEC §2) ────────────────────────────────────────
     44px rows, the page's 16px gutter, and "Jump to claims ↑" leaves the collapsed bar for
     a centred row of its own at the foot of the list: on touch there is no hover to reveal
     which of two adjacent 13px targets you are about to hit. */
  #page-stock{--acc-h:44px}
  .acc-bar{padding:0 var(--sp-4);gap:var(--sp-2)}
  .acc-bar .acc-jump{display:none}
  .acc-list{padding:0 var(--sp-4) var(--sp-2)}
  .acc-row{grid-template-columns:var(--acc-rule) auto minmax(0,1fr);
    grid-template-areas:"rule state body" "rule cid body";
    align-items:start;gap:var(--sp-1) var(--sp-2);min-height:var(--acc-h);padding:var(--sp-3) 0;
    border-bottom:1px solid var(--line)}
  .acc-row:last-child{border-bottom:none}
  .clm-acc .clm-mkdot{grid-area:rule;height:100%}
  .acc-row > span:nth-child(2){grid-area:state}
  .clm-acc .clm-cid{grid-area:cid}
  .acc-stmt{grid-area:body;white-space:normal;overflow:visible;text-overflow:clip}
  .acc-foot{display:flex}
  /* ── the extraction review at 390 — the family's inset card (his ruling, 13 Sep 2026) ──
     One column: the note becomes a bounded box ABOVE the claims rather than a column beside
     them, the statement wraps (there is no hover at 390 to recover an ellipsis — his 8 Sep
     ruling), and the two conditions stack.
     ⚠ IT WAS AN EDGE-TO-EDGE SHEET AND THE REASON DID NOT REACH THIS WIDTH. The exception was
     earned by the two-column comparison, and at 390 .pr-body below is ONE scrolling block —
     the same shape as Thesis history and Note view, which are both inset cards. So the screen
     stops opting out: the overlay's own inset applies, the corners stay, the family's ceiling
     applies, and the only thing said here is the height — auto, so the card grows to its
     content and stops at that ceiling instead of filling the screen whatever is in it. */
  .pr-modal{height:auto}
  .pr-head{padding:var(--sp-4)}
  .pr-x{min-width:var(--sp-7);min-height:var(--sp-7);display:flex;align-items:flex-start;justify-content:flex-end;margin:0}
  .pr-body{display:block;overflow:auto}
  .pr-note{background:none;border-right:none;padding:var(--sp-4) var(--sp-4) 0}
  .pr-note-hd{padding:0 0 var(--sp-2)}
  .pr-note-b{max-height:var(--pr-note-390);overflow:auto;background:var(--surface-sunken);
    border-radius:var(--radius-2xs);padding:var(--sp-3) var(--rec-row-y) var(--sp-5)}
  .pr-note-fade{left:var(--sp-4);right:var(--sp-4);bottom:0;height:var(--sp-6)}
  .pr-props{padding:var(--sp-4);overflow:visible}
  .pr-card{grid-template-columns:var(--pr-tick-390) minmax(0,1fr);padding:var(--rec-row-y)}
  .pr-tick{width:var(--pr-tick-390);height:var(--pr-tick-390)}
  .cr-effs,.cr-move{margin-left:calc(var(--pr-tick-390) + var(--sp-3))}   /* s123 · under the bigger tick at 390 */
  .pr-stmt{white-space:normal;overflow:visible;text-overflow:clip}
  .pr-conds{grid-template-columns:1fr;gap:var(--sp-3)}
  .pr-foot{padding:var(--sp-3) var(--sp-4);flex-wrap:wrap}
  .rec-row,.rec-row.wide-k{grid-template-columns:1fr;gap:var(--sp-1)}
  .rec-row .rec-a{grid-column:1;margin-top:var(--sp-1)}
  /* board 03 at 390: (key … pill) / text / actions, and no dot */
  #stc-monitor .rec-row.wide-k{grid-template-columns:minmax(0,1fr) auto;gap:var(--sp-1) var(--sp-2);padding:var(--sp-3) 0}
  /* session 87 · finding 10: the glyph column is narrow enough to keep on a phone; actions go under the body */
  #stc-monitor .rec-row.glyph-k{grid-template-columns:var(--icon-glyph) minmax(0,1fr);gap:var(--sp-1) var(--sp-2);padding:var(--sp-3) 0}
  #stc-monitor .rec-row.glyph-k > .rec-b{grid-column:2}
  #stc-monitor .rec-row.glyph-k > .rec-a{grid-column:2;margin-top:var(--sp-1)}
  #stc-monitor .rec-row.glyph-k .rec-evt-b{display:flex}
  #stc-monitor .rec-evt-b{display:contents}
  #stc-monitor .rec-evt-b > .ev2-dot{display:none}
  #stc-monitor .rec-row .rec-k{grid-column:1;grid-row:1}
  #stc-monitor .rec-evt-b > .ms-chip{grid-column:2;grid-row:1;justify-self:end}
  #stc-monitor .rec-evt-b > .ev2-body{grid-column:1/-1;grid-row:2}
  #stc-monitor .rec-row > .rec-b{grid-column:1/-1}
  #stc-monitor .rec-row > .rec-a{grid-column:1/-1;gap:var(--rec-act-step)}
  /* ⚠ DP-1: the KPI-table and row-grammar folds that sat here are gone with the constructs
     they folded. The four [E] panes carry session 66's own phone rules again — the signals
     grid drops to one column in the 768px block, and the Organizer's blocks stack there. */
  .th-card,.nr-card{flex-wrap:wrap}
  .th-status{font-size:var(--fs-title);overflow-wrap:normal;word-break:normal}
  .th-counts{margin-left:0;width:100%;flex-direction:row;justify-content:space-between;gap:var(--sp-3);margin-top:var(--sp-3);min-width:0}
  .th-cnt{flex-direction:column;align-items:flex-start;gap:var(--rec-tight);font-size:var(--fs-caption)}
  .th-cnt .th-num{margin-left:0}
  .nr-btns{margin-left:0;width:100%;flex-direction:row;margin-top:var(--sp-3)}
  .nr-btns .nr-btn{flex:1;text-align:center}
  .rh{min-width:78vw;max-width:none}
  .ev2-row2{grid-template-columns:1fr}
  /* the transaction log is real tabular data — it scrolls sideways rather than reflowing */
  #stc-xirr-tab .u-ox{overflow-x:auto}
  #stc-xirr-tab .tx-table{min-width:var(--tx-min)}
  /* ── board 08's phone. The nine stat cells fold into ONE two-column grid — the drawing shows
     six and says in as many words that the other three fold into the same one — so the shared
     hairlines are drawn per cell here rather than per column. The strip's fields go two-up
     with the note and Add across both, and its hint leaves: the drawing does not carry it at
     this width and there is no room to put it. */
  .stock-pane{--jr-stat-cols:var(--jr-stat-cols-sm);--jr-stat-cols-b:var(--jr-stat-cols-sm);
    --jr-cell-pad:var(--jr-cell-pad-sm);--jr-fig:var(--jr-fig-sm);--jr-fig-mt:var(--jr-fig-mt-sm);
    --jr-lbl-fs:var(--jr-lbl-fs-sm);--jr-sub-mt:var(--jr-sub-mt-sm);--jr-eb-m:var(--jr-eb-m-sm);
    --jr-strip-pad:var(--jr-strip-pad-sm);--jr-cols:var(--jr-cols-sm);--jr-add-pad:var(--jr-add-pad-sm);
    --jr-th-pad:var(--jr-th-pad-sm);--jr-td-pad:var(--jr-td-pad-sm);--jr-row-x:var(--jr-row-x-sm)}
  .jr-cell{border-bottom:1px solid var(--line)}
  .jr-cell:nth-child(2n){border-right:0}
  .jr-stats-b .jr-cell:nth-last-child(-n+2){border-bottom:0}
  /* the odd cell spans, so five figures over two columns leave no half-row behind */
  .jr-stats .jr-cell:last-child{grid-column:1/-1}
  /* and the percent drops under its figure at the sub-line's size, which is the drawing's own
     shape at this width and the only one that fits 22px mono into half of 358. */
  .jr-pct{display:block;font-size:var(--fs-micro);font-weight:400;margin-top:var(--sp-1)}
  .jr-strip-hint{display:none}
  .jr-fields .jr-amt-w,.jr-fields .jr-notes,.jr-fields .jr-add-w{grid-column:1/-1}
  .jr-fields .jr-add-w .jr-add{width:100%;justify-content:center}
}
.clm-actions{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:0.9rem;padding-top:0.7rem;border-top:1px dashed var(--line)}

/* ── THE CHAIN ON THE CARD (session 47). His finding: "after marking it I am not
   able to see the chain on the claim… how the claim became strained." The chain
   is the traversable links (v2 §3): every event carries its when and why, the
   linked note is one click away, and an earlier wording renders labelled
   SUPERSEDED — never "v2", which was his other finding. */
.clm-rev{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;padding:2px 7px;border-radius:var(--radius-2xs);background:rgba(44,79,154,0.08);color:var(--navy-soft);border:none;cursor:pointer;white-space:nowrap}
.clm-rev:hover{background:rgba(44,79,154,0.15)}
.clm-rev-s{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;padding:2px 7px;border-radius:var(--radius-2xs);background:var(--surface-tint);color:var(--text-muted);white-space:nowrap}
/* ⚠ .clm-hist / .clm-hist-t / .clm-hist-b WENT WITH THE DISCLOSURE. The chain is not
   hidden behind a toggle any more — it is the island in the open card. Greppped: the
   toggle was their only consumer. */
.clm-hev{display:flex;gap:10px;padding:var(--sp-2) 0;border-bottom:1px dashed var(--surface-tint);align-items:flex-start}
.clm-hev:last-child{border-bottom:none}
.clm-hev-date{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);flex-shrink:0;width:78px;padding-top:2px}
.clm-hev-main{flex:1;min-width:0}
.clm-hev-what{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:var(--fs-small);color:var(--text-soft)}
.clm-hev-why{font-size:var(--fs-small);line-height:1.5;color:var(--text);margin-top:3px}
.clm-hev-prev{font-size:var(--fs-small);line-height:1.5;color:var(--text-soft);font-style:italic;margin-top:3px;border-left:3px solid var(--surface-tint);padding-left:0.6rem}
/* The snapshot quote — what the note said AT LINK TIME. Shown only when the live
   note has been edited since (or deleted): the chain must quote what acted, not
   what the note says now. */
.clm-hev-snap{font-size:var(--fs-caption);line-height:1.5;color:var(--text-soft);margin-top:4px;background:var(--surface-sunken);border-radius:var(--radius-2xs);padding:0.4rem 0.6rem}
.clm-hev-snap b{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;color:var(--amber-strong);font-weight:700}
@keyframes clmflash{0%{box-shadow:0 0 0 3px rgba(44,79,154,0.35)}100%{box-shadow:0 0 0 3px rgba(44,79,154,0)}}
.clm-flash{animation:clmflash 1.4s ease-out}
/* The note→claim direction on The Record: a note that moved a bet says so. Same
   family as .q-answers / .q-from — the question links it sits beside. */
.hnt-claimlink{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--navy-soft);display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;cursor:pointer;background:none;border:none;padding:0;text-align:left}
.hnt-claimlink:hover{text-decoration:underline}
/* The state modal's two ways in: write a new note, or link an existing one. */
.cs-modes{display:flex;gap:6px;margin-bottom:0.8rem}
/* the route modal's Write / Link toggle is chip-select — the box and the chosen ring are the
   component's, and its own rules (a mono 10px chip with a raw navy rgba) go with them. */
.cs-notepick{width:100%;font-family:var(--font-mono);font-size:var(--fs-caption);padding:6px 8px;border:1px solid var(--line);border-radius:var(--radius-2xs);background:var(--surface);color:var(--text);margin-bottom:0.6rem}
/* ── ROUTE A NOTE TO A BET (session 48). Claim rows are radio-like cards; nothing
   is pre-selected, ever. */
/* 15's OPTION CARD — board Modals §15. A 1.5px hairline at radius 10 holding a 16px radio and
   the claim's own sentence at body size; the chosen one is SELECTION GEOMETRY, the ring and the
   navy tint every chosen thing in this app wears, never a coloured fill. The radio is the
   checkbox's measure — the board draws both pick controls at the same 16. */
#cr-claims{display:flex;flex-direction:column;gap:var(--sp-3)}
/* s123 · many bets, each its own way (his finding, 12 Oct): the radio became the extraction review's checkbox, and a ticked
   card opens its own four verdicts and the sentence that says what that verdict will do to THIS bet */
.cr-claim{display:flex;flex-direction:column;gap:var(--sp-2);border:1.5px solid var(--line-strong);border-radius:var(--radius-xs);padding:var(--opt-pad);font-family:var(--font-ui);font-size:var(--fs-body);font-weight:400;line-height:1.55;color:var(--text);background:var(--surface)}
.cr-claim:hover{border-color:var(--navy-soft)}
.cr-claim.on{border-color:var(--navy-soft);box-shadow:var(--sel-ring);background:var(--navy-tint)}
.cr-row{display:flex;align-items:flex-start;gap:var(--sp-3);cursor:pointer}
.cr-row > .pr-tick{flex-shrink:0}
.cr-effs,.cr-move{margin-left:calc(var(--pr-tick) + var(--sp-3))}
.cr-effs{display:flex;flex-wrap:wrap;gap:var(--chip-gap)}
.cr-move{margin-top:0}
/* s125 · NEW-9 — a bet this note (or record) already links to stays in the list, marked: a green tick in a plain box (a link that
   exists is a fact, not a choice), its verdict as the chain draws it, and no hand — it cannot be ticked again */
.cr-claim.cr-done,.cr-claim.cr-done:hover{border-color:var(--line);cursor:default}
.cr-done .cr-row{cursor:default}
.cr-done .pr-tick{border-color:var(--line);color:var(--green-strong)}
/* badge-mark between words rather than on a line of its own — 15 puts THE BET inside the
   sentence it marks, so only the box tightens; the gold, the border and the word do not move. */
.badge-inline{padding:var(--badge-pad-inline);margin-left:var(--sp-1);vertical-align:middle}
.badge-inline > .ic{font-size:var(--fs-label)}
/* ── THE SNAPSHOT BANNER — a note shown AS IT READ at link time. */
#nv-snap-banner{border:1px solid rgba(230,168,50,0.5);border-left:3px solid var(--amber-strong);background:rgba(230,168,50,0.08);border-radius:0 var(--radius-xs) var(--radius-xs) 0;padding:var(--sp-2) var(--sp-3);margin-bottom:0.9rem;font-size:var(--fs-caption);line-height:1.5;color:var(--text-soft)}
#nv-snap-banner b{color:var(--amber-strong);font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em}
/* The chain's read-it affordance + the pre-snapshot honesty line. */
.clm-hev-snapbtn{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--amber-strong);background:none;border:none;cursor:pointer;padding:0;text-decoration:underline;margin-top:3px;display:inline-block}
.clm-hev-nosnap{font-size:var(--fs-caption);line-height:1.5;color:var(--text-soft);margin-top:4px;font-style:italic}

/* ── "Why this claim was extracted", shown INSIDE the source note. His words:
   "instead of designing a new surface to show the evidence sentence it can be
   shown in the view source note itself by simply highlighting the sentences in
   the note for that respective claim." So there is no evidence row anywhere —
   the note IS the surface, and these are the marks on it.
   ⚠ "Evidence" is not a user-facing word any more; it reads as corroboration
   the product is claiming, when it is really the reason the claim exists. */
.nvhl{border-radius:var(--radius-2xs);padding:1px 2px;box-decoration-break:clone;-webkit-box-decoration-break:clone}
.nvhl.statement{background:rgba(42,199,131,0.22);box-shadow:inset 0 -1px 0 var(--green)}
.nvhl.evidence{background:rgba(212,169,73,0.24);box-shadow:inset 0 -1px 0 var(--amber)}
.nvhl.breaks_if{background:rgba(211,91,106,0.18);box-shadow:inset 0 -1px 0 var(--red-strong)}
.nvhl.fulfils_if{background:rgba(44,79,154,0.14);box-shadow:inset 0 -1px 0 var(--navy-soft)}
.nvwhy{border:1px solid var(--line);border-left:3px solid var(--navy-soft);background:var(--surface-sunken);border-radius:0 var(--radius-xs) var(--radius-xs) 0;padding:0.7rem 0.85rem;margin-bottom:1rem}
.nvwhy-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.07em;color:var(--navy-soft);margin-bottom:5px}
.nvwhy-stmt{font-size:var(--fs-body);line-height:1.5;font-weight:600;color:var(--text);margin-bottom:8px}
.nvwhy-legend{display:flex;gap:var(--sp-3);flex-wrap:wrap}
.nvwhy-key{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-soft);display:inline-flex;align-items:center;gap:var(--sp-1)}
.nvwhy-sw{width:11px;height:11px;border-radius:var(--radius-2xs);flex-shrink:0}
.nvwhy-sw.statement{background:rgba(42,199,131,0.45)} .nvwhy-sw.evidence{background:rgba(212,169,73,0.5)}
.nvwhy-sw.breaks_if{background:rgba(211,91,106,0.4)} .nvwhy-sw.fulfils_if{background:rgba(44,79,154,0.3)}
/* session 87 · the review a verdict note came from (finding 9) — it WEARS .nvwhy (one box, not a
   second one drawn the same way); only its rows are its own */
.nvrev-row{display:flex;gap:var(--sp-3);align-items:flex-start;padding:var(--sp-1) 0;font-size:var(--fs-small);line-height:1.45}
.nvrev-k{flex:0 0 var(--nvrev-k);font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.05em;color:var(--text-muted);padding-top:var(--sp-1)}
.nvrev-v{flex:1;min-width:0;color:var(--text)}
.nvrev-vd{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.05em;font-weight:700}
.nvrev-vd.supports{color:var(--green-strong)} .nvrev-vd.strains{color:var(--amber-strong)} .nvrev-vd.breaks{color:var(--red-strong)}
.nvrev-none{font-size:var(--fs-small);color:var(--text-muted)}
/* session 87 · finding 13: a deep-link target clears the sticky stock head */
.rec-jump{scroll-margin-top:calc(var(--head-h) + var(--sp-4))}

/* ── THE COMPOSER **IS** THE NOTE EDITOR (session 46). His review of the slice-6
   composer: "You had to completely copy it with restyling and you have made a mess
   of it. It can now save notes without source. It doesn't have the formatting
   options. Commands don't work in it. You have completely made a new composer."
   So the separate textarea is GONE. #sp-composer holds the editor's own elements
   at two sizes: collapsed (a Claude-style box: #ne-editor at one line, compact
   #ne-source underneath, ⤢ top-right, ↑ send) and expanded (the full editor —
   navy header, source field, toolbar, answers checklist, footer — docked to the
   base and growing upward in place, per his 26 Aug design; never a floating modal).
   .spc-x = expanded-only rows · .spc-c = collapsed-only controls. */
/* ⚠ THE COMPOSER SITS IN THE RECORD'S MAIN COLUMN (board 5a §1.7, session 68). It is fixed —
   that is the ruled deviation, it is the note editor and grows upward — but it is placed where
   the board places it: the left column of the Record grid, 843px, flush with the notes, under a
   wrapper that fades the page to white beneath it. It was a centred 820px box across the whole
   pane, which put it over the thought-chain island as well as the notes. The right padding is
   the sections column plus its two gutters, so the two can never disagree about the column. */
#sp-composer{position:fixed;left:220px;right:0;bottom:0;z-index:calc(var(--z-sticky) + 2);padding:var(--spc-dock-pad);background:var(--spc-halo);pointer-events:none;display:none;transition:transform .2s ease-out}
#sp-composer.on{display:block}
/* ⚠ SCROLLING DOWN TAKES THE DOCK OFF-CANVAS AND SCROLLING UP BRINGS IT BACK (his ask). It is
   gated to the COLLAPSED state on purpose: hiding a composer somebody is typing in is a bug,
   not a behaviour, and the board's own note is about the bar. A draft always returns with it —
   the returning Row A shows the draft's first line where the placeholder was. */
#sp-composer.away{transform:translateY(120%)}
#sp-composer.open.away{transform:none}
/* ⚠ THE SAME CHROME AND THE SAME SHADOW IN ALL THREE STATES. An object does not change its
   elevation by growing, which is why 12 keeps this card and not the modal's navy head and
   float-lg (the written exception, system file §4). Nothing moves sideways; only the height
   changes; the bottom edge is fixed. */
.spc-box{margin:0 auto;pointer-events:auto;background:var(--surface);border:1.5px solid var(--line-strong);border-radius:var(--radius-sm);box-shadow:var(--shadow-composer);display:flex;flex-direction:column;overflow:hidden;max-height:calc(100dvh - var(--sp-7))}
/* .spc-c = collapsed only · .spc-x = shown once the composer is open (active OR expanded) */
#sp-composer:not(.open) .spc-x{display:none !important}
#sp-composer.open .spc-c{display:none !important}
#sp-composer:not(.expanded) .spc-e{display:none !important}
#sp-composer.expanded .spc-a{display:none !important}

/* ── ROW A · the bar, and the head it becomes ──────────────────────────────────────────
   Collapsed it is white and it is the WHOLE composer. Focused it keeps its place, its height
   and its left edge and takes the shell tint and a hairline — his comment, 14 Sep: the head
   tint comes back. The right slot holds one icon button: maximize-2, then x when expanded. */
.spc-rowa{height:var(--spc-rowa-h);flex-shrink:0;display:flex;align-items:center;gap:var(--spc-rowa-gap);padding:var(--spc-rowa-pad)}
#sp-composer.open .spc-rowa{background:var(--shell);border-bottom:1px solid var(--line)}
.spc-pencil{color:var(--navy);flex-shrink:0}
.spc-ph{flex:1;min-width:0;text-align:left;background:none;border:none;padding:0;cursor:text;font-family:var(--font-ui);font-size:var(--fs-pane);font-weight:400;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.spc-ttl{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:700;color:var(--navy);white-space:nowrap}
.spc-sub{font-family:var(--font-mono);font-size:var(--fs-label);font-weight:400;color:var(--text-muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── ROW B · the toolbar, full in both open states (his comment: the width is there) ─────
   Nine Lucide glyphs on three groups. ⚠ THIS IS WHERE NINE EMOJI-AS-ICONS LEAVE the app —
   the link's 🔗, <s>S</s>, ¶, "• List" and "1. List" were the last toolbar the system had
   never drawn, which is exactly why they survived (§11.3). The L40 ceiling falls with them. */
.spc-tb{display:flex;align-items:center;gap:2px;padding:var(--spc-tb-pad);border-bottom:1px solid var(--line);color:var(--text-muted);flex-shrink:0;overflow-x:auto;scrollbar-width:none}
.spc-tb::-webkit-scrollbar{display:none}
.ne-tb-sep{width:1px;height:16px;background:var(--line-strong);margin:0 var(--sp-1);flex-shrink:0}
.ne-fmt-btn{width:var(--spc-tb-hit);height:var(--spc-tb-hit);flex-shrink:0;padding:0;display:inline-flex;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--radius-2xs);color:inherit;cursor:pointer;transition:background .12s,color .12s}
.ne-fmt-btn > .ic{font-size:var(--icon-glyph)}
.ne-fmt-btn:hover{background:var(--surface-tint);color:var(--navy)}
/* ⚠ AN APPLIED FORMAT IS A SELECTION, AND SELECTION IS GEOMETRY (rule 4) — ring and navy tint,
   never a navy fill (rule 11). The old toolbar filled the active button navy. */
.ne-fmt-btn.active{background:var(--navy-tint);color:var(--navy);box-shadow:var(--sel-ring)}
.ne-head-wrap{position:relative;display:inline-flex;flex-shrink:0}

/* ── THE BODY · question callout · SOURCE / CONTEXT as a titled field · the editor ───────
   Source is a FIELD WITH A LABEL above the editor (his comment, 13 Sep — the old 12's
   structure), not the chip-and-popover the first redraw tried and not the collapsed box's
   mono micro-input. */
.spc-body{display:flex;flex-direction:column;gap:var(--spc-body-gap);padding:var(--spc-body-pad);min-height:0;overflow-y:auto;overscroll-behavior:contain}   /* session 87 · finding 14 */
.spc-src .form-input{width:100%}
#ne-editor{min-height:var(--spc-ed-min);max-height:var(--spc-ed-max);overflow-y:auto;overscroll-behavior:contain;outline:none;border:none;background:transparent;padding:0;font-family:var(--font-ui);font-size:var(--fs-pane);line-height:1.6;color:var(--text)}
#sp-composer.expanded #ne-editor{min-height:var(--spc-ed-min-x)}
/* ⚠ SESSION 89 · finding 7: EXPANDED, THE BODY SCROLLS AND THE EDITOR GROWS. The editor's own 60vh
   ceiling kept the open questions and the source field pinned above it (his "sticky … only 60% space
   to write"). Without it the questions and the source go up with the text and the whole body is the
   writing space; the strip below keeps the questions one click away. Active (not expanded) keeps its
   ceiling — a small box at the foot of the page should not grow over it. */
#sp-composer.expanded #ne-editor{max-height:none;overflow-y:visible;flex-shrink:0}   /* shrink:0 — a flex item in the column would otherwise be squeezed to its min-height and spill */
/* sticky insets are measured inside the scroller's PADDING, so top:0 held the strip 16px down — the
   body's own top padding (--spc-body-pad, 16 at both widths). The negative inset puts it on the edge. */
.ne-qdock{position:sticky;top:calc(-1 * var(--sp-4));height:0;margin-bottom:calc(-1 * var(--spc-body-gap));z-index:var(--z-raised)}
/* the collapsed open-question callout: it WEARS callout callout-question (the rule, the radius, the
   violet ground and edge) and adds only its line layout, the eyebrow voice, and an opaque surface under
   the tint — it floats over the text it covers, which is also why it carries the small shadow. */
.ne-qstrip{position:absolute;left:0;right:0;top:0;display:flex;align-items:center;gap:var(--chip-gap);width:100%;border-top:none;border-right:none;border-bottom:none;background:linear-gradient(var(--accent-soft),var(--accent-soft)),var(--surface);box-shadow:var(--shadow-sm);padding:var(--sp-2) var(--sp-3);font-family:var(--font-ui);font-size:var(--fs-label);font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:var(--accent-strong);cursor:pointer;text-align:left}
.ne-qstrip[hidden]{display:none}
.ne-qstrip > .ic{font-size:var(--icon-glyph-sm);stroke-width:2}
.ne-qstrip-go{margin-left:auto;display:inline-flex;align-items:center;gap:var(--sp-1)}
#ne-editor:empty:before{content:attr(data-placeholder);color:var(--text-faint);pointer-events:none}

/* ── ROW F · the footer, and it carries the REAL buttons in every state that has one ─────
   His comment, 13 Sep. There is no send circle: icon-button-fill had exactly one consumer and
   it was that arrow, so the dress state is retired with it (his call, 14 Sep). */
.spc-foot{display:flex;align-items:center;gap:var(--sp-2);padding:var(--spc-foot-pad);border-top:1px solid var(--line);flex-shrink:0}
.spc-cbx{appearance:none;-webkit-appearance:none;margin:0;position:relative;width:var(--cbx);height:var(--cbx);flex-shrink:0;border:1.5px solid var(--line-strong);border-radius:var(--radius-2xs);background:var(--surface);cursor:pointer}
.spc-cbx:checked{background:var(--navy);border-color:var(--navy)}
.spc-cbx:checked:after{content:'';position:absolute;inset:0;margin:auto;width:9px;height:5px;border:solid var(--on-brand);border-width:0 0 2px 2px;transform:rotate(-45deg) translateY(-1px)}
.spc-spacer{flex:1}
/* the board writes "Mark as key entry" at 1440 and "Key entry" at 390 — the same control,
   the shorter word where two buttons share the line with it. Both are in the markup so the
   swap is a media query and never a resize listener. */
.spc-key-short,.spc-save-short{display:none}
/* ── THE COMPOSER AT 390 · the same object, inset 12 in the same transparent haloed dock,
   floating over the list above the bottom bar. 44px hits, 16px text, 'Key entry', [Cancel]
   [Save], the draft status on a line of its own, and the toolbar's first four symbols in
   view with the rest scrolling. */
@media (max-width:900px){
  :root{--nv-w:calc(100vw - 2 * var(--modal-inset))}   /* session 89 · finding 1: the composer is the inset card here */
  #sp-composer{left:0;padding:var(--spc-dock-pad-sm);background:var(--spc-halo-sm)}
  .spc-rowa{padding:var(--spc-rowa-pad-sm);gap:var(--spc-rowa-gap-sm)}
  .spc-ph{font-size:var(--fs-lead)}
  .spc-tb{padding:var(--spc-tb-pad-sm);gap:0}
  .ne-fmt-btn{width:var(--spc-tb-hit-sm);height:var(--spc-tb-hit-sm)}
  .spc-body{padding:var(--spc-body-pad-sm);gap:var(--spc-body-gap-sm)}
  .ne-qdock{margin-bottom:calc(-1 * var(--spc-body-gap-sm))}
  #ne-editor{min-height:var(--spc-ed-min-sm);font-size:var(--fs-lead);line-height:1.5}
  #sp-composer.expanded #ne-editor{min-height:var(--spc-ed-min-x-sm)}
  /* ⚠ TWO LINES, NOT THREE. The draft status takes a full-width line of its OWN at 390 (the
     board draws it under the buttons), so it has to come last in the wrap order — left where
     1440 puts it, at the row's left edge, it breaks the line before the buttons and pushes
     Cancel and Save onto a third. order: is the whole fix; the markup does not move. */
  .spc-foot{padding:var(--spc-foot-pad-sm);flex-wrap:wrap}
  .spc-foot .cbx-row{margin-right:auto;padding:var(--sp-2) 0}
  .spc-foot .modal-draft{order:3;width:100%;text-align:right;margin-right:0}
  .spc-key-long,.spc-save-long{display:none}
  .spc-key-short,.spc-save-short{display:inline}
}
@keyframes spcRise{from{transform:translateY(26px);opacity:0.4}to{transform:none;opacity:1}}
/* Q1 · Unresolved Questions */
/* .q-form / .q-form-btns retired in session 79 — the question form is .sig-add-tile, the
   inline-form tile §4 specifies, and its footer is .sig-tile-foot like its three siblings. */
/* .q-resolved-toggle — styled with .clm-more and .ev2-viewall above: one disclosure tier. */
.q-item-done .ev2-name{color:var(--text-soft);font-weight:500}
.q-answers{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--navy-soft);margin-top:3px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:230px}
/* board 03: "from Q4FY2026 Concall" as one grey line under the question, the SOURCE at 500 in
   --text-soft. It was 11px mono clipped at 230px — a source name is words, and F12's where-from
   link is only useful if you can read which source it names. */
.q-from{font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-muted);margin-top:var(--sp-1);display:block}
.q-from b{font-weight:500;color:var(--text-soft)}
.q-from-a{white-space:normal}   /* s94 · R4-10: a long note name wraps at 390 */
/* The question glyph is plain text, so give it enough weight to read at 0.9rem. */
.ev2-ico.q-ico{font-weight:700}
/* Q1b · existing-note picker. Rebuilt 21 Aug — the first cut was a list of bare bold
   lines that fired on click, which Vikas said "doesn't feel like I am choosing a note".
   Now: a radio per row, a body snippet so the rows are distinguishable, a visible
   selected state, and an explicit Link button. Choosing and committing are separate. */
.q-pick-list{max-height:44vh;overflow-y:auto;overscroll-behavior:contain;margin:var(--sp-2) 0 var(--sp-4);border:1px solid var(--surface-tint);border-radius:var(--radius-xs)}
.q-pick-row{display:flex;gap:10px;align-items:flex-start;width:100%;text-align:left;background:none;border:none;border-bottom:1px solid var(--surface-tint);padding:var(--sp-3) var(--sp-3);cursor:pointer;transition:background 0.12s}
.q-pick-row:last-child{border-bottom:none}
.q-pick-row:hover{background:var(--surface-tint)}
.q-pick-row input{margin-top:3px;flex-shrink:0}
.q-pick-row.on{background:var(--navy-tint)}
.q-pick-main{min-width:0;flex:1}
.q-pick-title{font-size:var(--fs-small);font-weight:600;color:var(--text);display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}
.q-pick-snip{font-size:var(--fs-caption);color:var(--text-soft);margin-top:3px;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.q-pick-date{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:4px}
/* Q1b · the questions a note answers, shown in the READ-ONLY note view modal */
.nv-answers{margin-bottom:var(--sp-4)}
.nv-answers-lbl{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-soft);margin-bottom:0.4rem;display:block}
.nv-answers-item{display:flex;gap:var(--sp-2);align-items:flex-start;font-size:var(--fs-small);line-height:1.45;padding:2px 0;color:var(--text)}
/* Q1b · "Answers:" checklist in the note editor */
/* ⚠ THE CHECKLIST WEARS THE QUESTION'S OWN COLOUR — his comment, 13 Sep, and the callout
   family's rule: a question is violet with circle-help, and one anatomy serves every purpose.
   It was a grey tinted box with a mono label; it is callout-question, which the app already
   builds and had four consumers for. */
.ne-answers-row{display:flex;align-items:center;gap:10px;margin-top:var(--sp-2);font-family:var(--font-ui);font-size:var(--fs-body);line-height:1.5;color:var(--text);cursor:pointer}
.ne-answers-more{margin-top:var(--sp-2)}
.ev2-isub{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}
/* the event row's pill is pill-state above; only its placement is its own. ⚠ QUARTERLY,
   MILESTONE and PENDING are WORDS, so they left mono with the rest of the family (§2a.9). */
.ev2-pill{margin-left:auto;white-space:nowrap;flex-shrink:0}
.ev2-pill.g{background:var(--green-soft);color:var(--green-strong)} .ev2-pill.gold{background:var(--amber-soft);color:var(--amber-strong)} .ev2-pill.navy{background:var(--navy-tint);color:var(--navy-soft)} .ev2-pill.grey{background:var(--neutral-fill);color:var(--text-soft)}
/* .ev2-viewall — styled with .clm-more above: one disclosure tier. */
/* Review History — richer horizontal cards */
/* the review row's state chip — the board's state word: 12/600 uppercase on the soft tint */
.rh-verdict{display:inline-flex;align-items:center;font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;letter-spacing:0.04em;text-transform:uppercase;padding:var(--kpi-chip-pad);border-radius:var(--radius-2xs)}
.rh-verdict.good{background:var(--green-soft);color:var(--green-strong)} .rh-verdict.okay{background:var(--amber-soft);color:var(--amber-strong)} .rh-verdict.bad{background:var(--red-soft);color:var(--red-strong)}
.rh-note{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* Next Review buttons column */
/* Attractive empty state */
/* ⚠ THE EMPTY STATE IS SCREEN 6a's, MEASURED (session 68): left-aligned, padding 32px 0, gap 8,
   max-width 620 — a 16/600 navy line, a 14px --text-soft sentence at 1.6, a 13px muted
   afterword. No icon tile (the tile was a box, and it is gone), no filled button. */
.ev2-empty{display:flex;flex-direction:column;align-items:flex-start;text-align:left;gap:var(--sp-2);padding:var(--sp-6) 0;max-width:620px}
.ev2-empty-t{font-weight:600;font-size:var(--fs-lead);color:var(--navy)}
.ev2-empty-d{font-size:var(--fs-body);color:var(--text-soft);line-height:1.6}
/* session 87 · finding 4: the closing line is BRANDING, not a control — set off by a hairline and
   the brand eyebrow, in the muted italic voice, so it never reads as part of the section above it */
.ev2-foot{display:flex;align-items:baseline;gap:var(--sp-3);margin-top:var(--sp-6);padding-top:var(--sp-4);
  border-top:1px solid var(--line);font-size:var(--fs-small);color:var(--text-muted);font-style:italic}
.ev2-foot-k{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:0.08em;color:var(--action);font-style:normal;flex-shrink:0}
.ev2-empty-after{font-size:var(--fs-small);color:var(--text-muted)}
.ev2-empty-acts{display:flex;gap:var(--sp-4);flex-wrap:wrap;margin-top:var(--sp-1)}
/* The zero-claim card (6a): dashed hairline, radius 10, 32px 24px, centred; the body at 460. */
.clm-empty{display:flex;flex-direction:column;align-items:center;text-align:center;padding:var(--sp-6) var(--sp-5);border:1px dashed var(--line-strong);border-radius:var(--radius-xs);background:var(--surface)}
.clm-empty-t{font-size:var(--fs-lead);font-weight:600;color:var(--navy)}
.clm-empty-d{font-size:var(--fs-small);color:var(--text-soft);line-height:1.6;margin-top:var(--chip-gap);max-width:460px}
.clm-empty-cta{margin-top:var(--sp-5)}
.clm-empty-sec{margin-top:var(--sp-3)}
/* the empty state's call to action IS a button-primary (board §1): the same fill, the same pad */
.ev2-cta{background:var(--action);color:var(--on-action);border:none;border-radius:var(--radius-xs);padding:var(--btn-pad);font-family:var(--font-ui);font-weight:600;font-size:var(--fs-small);line-height:normal;white-space:nowrap;cursor:pointer;transition:background .15s}
.ev2-cta:hover{background:var(--action-hover)}
/* Event char-limit hint */
.ev2-charhint{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--text-muted);text-align:right;margin-top:5px}
.ev2-charhint.warn{color:var(--red-strong)}
/* Row action kebab menu (edit / delete) */
.ev2-kebab-wrap{position:relative;display:inline-block}
/* .ev2-kebab — a row's ⋮ — is a bare icon button (ICON BUTTONS) */
.ev2-kebab-menu{position:absolute;top:100%;right:0;margin-top:4px;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius-xs);box-shadow:0 10px 28px rgba(8,17,32,0.16);z-index:var(--z-popover);min-width:124px;padding:var(--sp-1)}
.ev2-kebab-menu button{display:block;width:100%;text-align:left;background:none;border:none;padding:var(--sp-2) var(--sp-3);font-size:var(--fs-small);color:var(--text);cursor:pointer;border-radius:var(--radius-2xs);font-family:var(--font-ui)}
.ev2-kebab-menu button:hover{background:var(--surface-tint)}
.ev2-kebab-menu button.del{color:var(--red-strong)}
/* Destructive button — button-danger (board §1): flat --red-strong, a white word, no gradient and
   no red shadow (a shadow means the thing floats). The fill exists ONLY as the confirming action
   inside a confirmation dialog, and the dialog's own button (.cfm-danger) is the same component,
   one list. In place, destructive is red text, or the red hairline beside other buttons.
   ⚠ The board draws no hover for it; the brightness step is the app's existing one, kept until
   he rules (Phase 2 run log). */
.btn-danger,.cfm-danger{background:var(--red-strong);color:var(--on-brand);border:none}
.btn-danger:hover,.cfm-danger:hover{filter:brightness(1.05)}
/* Event sentiment picker */
.ev2-sent{display:flex;gap:6px;flex-wrap:wrap}
.ev2-sent button{font-family:var(--font-mono);font-size:var(--fs-label);padding:var(--sp-2) var(--sp-3);border:1.5px solid var(--line-strong);border-radius:var(--radius-xs);color:var(--text-soft);cursor:pointer;background:var(--surface);transition:all .15s}
.ev2-sent button.on[data-s="bull"]{background:var(--green-soft);color:var(--green-strong);border-color:var(--green)}
.ev2-sent button.on[data-s="neutral"]{background:var(--surface-tint);color:var(--text);border-color:var(--line-strong)}
.ev2-sent button.on[data-s="bear"]{background:var(--red-soft);color:var(--red-strong);border-color:var(--red-strong)}
/* In-app confirm dialog */
.cfm-overlay{position:fixed;inset:0;background:var(--scrim);display:flex;align-items:center;justify-content:center;z-index:var(--z-top);padding:var(--sp-4)}
.cfm-box{background:var(--surface);border-radius:var(--radius-sm);padding:1.4rem 1.5rem;max-width:400px;width:100%;box-shadow:0 20px 50px rgba(8,17,32,0.28)}
.cfm-title{font-weight:800;font-size:var(--fs-lead);color:var(--navy);margin-bottom:6px}
.cfm-msg{font-size:var(--fs-body);color:var(--text-soft);line-height:1.5;margin-bottom:1.2rem}
.cfm-btns{display:flex;gap:var(--sp-2);justify-content:flex-end}
/* ══ session 110 · QUARTERLY REVIEW, REBUILT TO ITS BOARD (v4 Pages §Q) ═══════════════════════════════════════════════
   A read-out: one card, one table, a row per held or watchlist story. The card and its head are Performance's (card-plain ·
   perf-card · perf-hd · sec-hd); the table is the Ledger's (.tx-table — Inter heads on the tint band) with Inter cells.
   ⚠ THE COLUMNS ARE SIZED BY WHAT IS IN THEM (his rule for a new table) — not the board's proportional tracks: a chip, a
     pill and a tag are their own width, the name and the note are bounded by their inner blocks (which is what keeps the
     note from taking the whole table and folding the names to a word a line), and the note takes what is left.
   ⚠ NO RULE HERE DRAWS A BOX. The row is the door (cursor, hover tint); its controls are a name, a text action, an icon. */
#page-quarterly .qr-sel{width:auto;min-width:0;cursor:pointer}
/* s115 · this head holds a field (the quarter list), and a field is taller than the text the other heads hold: with the
   head's own padding it measured 64 on staging where every other head is 60. Less padding here, so the head's floor
   decides its height and the title sits where it sits on Home and Performance. The field is not touched. */
#page-quarterly .page-header{padding-top:var(--sp-2);padding-bottom:var(--sp-2)}
.qr-card{container:qr / inline-size}
.qr-card .perf-hd{justify-content:flex-start}   /* the count follows the title and its tag (the board), it is not sent to the far edge */
.qr-table th,.qr-table td{padding-left:var(--sp-3);padding-right:var(--sp-3)}
.qr-table th{white-space:nowrap}
/* the note's column asks for its measure even when no row has a note, so the columns stand on a quarter nobody has reviewed
   where they stand on a reviewed one (the board's Q3). A fixed width would make the column rigid and squeeze the names; this
   is two marks a word-space apart at no height — wide when there is room, one mark when there is not. */
.qr-table th:nth-child(5)::after{content:"· ·";display:block;height:0;overflow:hidden;white-space:normal;word-spacing:34rem}
.qr-table td{font-family:var(--font-ui);padding-top:var(--sp-3);padding-bottom:var(--sp-3);border-bottom:1px solid var(--line)}
.qr-table tbody tr:last-child td{border-bottom:0}
.qr-table .qr-grp td{padding:var(--sp-4) 0 var(--chip-gap);border-bottom:0}
.qr-grp-in{display:flex;align-items:center;gap:var(--sp-2)}
.qr-row{cursor:pointer}
.qr-row:hover td{background:var(--surface-tint)}
.qr-story{min-width:12rem;max-width:18rem}
.qr-nm{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;line-height:1.3;color:var(--navy);background:none;border:none;padding:0;cursor:pointer;text-align:left}
.qr-nm:hover{text-decoration:underline}
.qr-tk{margin-top:var(--sp-1)}
/* the panel's thesis chip, SHOWN: the same state dress at the pill's height, and nothing of its own to press (its cursor is its row's) */
.chip-select-state.is-shown{cursor:inherit;font-size:var(--fs-caption);line-height:1.4;padding:var(--pill-pad)}
.chip-select-state.is-shown > .ic{font-size:var(--fs-caption)}
.qr-pills{display:flex;flex-wrap:wrap;gap:var(--sp-1)}
.qr-dec{display:flex;align-items:center;gap:var(--sp-2)}
.qr-saved{font-family:var(--font-mono);font-size:var(--fs-caption);line-height:1.4;color:var(--text-muted);white-space:nowrap;margin-top:var(--sp-1)}
.qr-dash{font-family:var(--font-mono);color:var(--text-muted)}
.qr-note-t{font-size:var(--fs-small);line-height:1.5;color:var(--text);min-width:11rem;max-width:36rem}
.qr-c-nyr{white-space:nowrap}
.qr-nyr{font-size:var(--fs-small);color:var(--text-muted);margin-right:var(--sp-3)}
.qr-table th:last-child,.qr-table td.qr-c-go{width:1%;padding-left:0;text-align:right}
/* ⚠ THE STACKED FORM IS KEYED ON THE CARD'S OWN WIDTH, NOT THE WINDOW'S. Six columns need about 820px; beside the sidebar a
   1024 window gives the card 626 and a 1180 one 782, so a window breakpoint would either scroll the table sideways on a
   laptop or stack it on a wide phone. Under 52rem of card the table's head goes and each story is a block of its own between
   hairlines — name · chip · chevron, the claims, the decision row, the note. This is the phone's form too (board Q2); no box
   is drawn inside the box. It is a container query: the file gains no media block. */
@container qr (max-width:52rem){
  .qr-table,.qr-table tbody,.qr-table .qr-grp,.qr-table .qr-grp td{display:block}
  .qr-table thead{display:none}
  .qr-table .qr-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;grid-template-areas:"story th go" "cl cl cl" "dec dec dec" "note note note";gap:var(--sp-2);align-items:start;padding:var(--sp-3) 0;border-bottom:1px solid var(--line)}
  .qr-table .qr-row.qr-row-none{grid-template-areas:"story story go" "nyr nyr nyr"}
  .qr-table tbody .qr-row:last-child{border-bottom:0}
  .qr-table .qr-row td{display:block;width:auto;padding:0;border-bottom:0;background:none}
  .qr-table .qr-row td.qr-c-story{grid-area:story}
  .qr-table .qr-row td.qr-c-th{grid-area:th;align-self:center}
  .qr-table .qr-row td.qr-c-cl{grid-area:cl}
  .qr-table .qr-row td.qr-c-dec{grid-area:dec;display:flex;align-items:center;flex-wrap:wrap;gap:var(--sp-1) var(--sp-2)}
  .qr-table .qr-row td.qr-c-note{grid-area:note}
  .qr-table .qr-row td.qr-c-nyr{grid-area:nyr}
  .qr-table .qr-row td.qr-c-go{grid-area:go}
  .qr-c-dec .qr-saved{margin-top:0}
  .qr-story,.qr-note-t{min-width:0;max-width:none}
}
/* ══ session 112 · HOME, ITS SECOND PART (v4 Pages §H; home_spec §0's amendment block) ═══════════════════════════════════
   Two cards under the Coach card — Active positions and Your book — each the system's card with the heading plate.
   ⚠ NO RULE HERE DRAWS A BOX. A tile, the XIRR cell and the failed-read line take their ground and their corner from
     utilities in the markup; a row is a door (cursor, a tint on hover); the chosen tile wears the selection ring.
   ⚠ BOTH CARDS ARE CONTAINERS (`hm`). The money row, the strip and the table re-flow by the CARD's own width, never the
     window's: beside the sidebar a 1024 window leaves the card about 690px, which no window breakpoint can know. */
.hm-card{container:hm / inline-size;margin-bottom:var(--sp-5)}
.hm-hd{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3) var(--sp-4);flex-wrap:wrap}
.hm-hd-l{display:flex;align-items:center;gap:var(--sp-2) var(--sp-3);flex-wrap:wrap;min-width:0}
.hm-count{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-muted)}
/* Active positions: three cells on hairlines, and the XIRR cell set apart on a ground of its own (it counts closed positions too) */
.hm-money{display:grid;grid-template-columns:repeat(3,minmax(0,1fr)) minmax(0,1.15fr);border-top:1px solid var(--line);margin-top:var(--sp-4)}
/* the cells share their rows (a subgrid): a label that folds in one cell cannot push its figure off the line its neighbours' sit on */
.hm-cell{display:grid;grid-template-rows:subgrid;grid-row:span 4;align-content:start;padding:var(--sp-4);min-width:0}
.hm-cell + .hm-cell{border-left:1px solid var(--line)}
.hm-cell:first-child{padding-left:0}
.hm-cell.hm-xirr{border-left:0;margin:var(--sp-2) 0 0 var(--sp-4)}
.hm-fig{font-family:var(--font-mono);font-size:var(--fs-figure-md);font-weight:700;line-height:1;color:var(--navy);white-space:nowrap;font-variant-numeric:tabular-nums;margin-top:var(--sp-2)}
.hm-fig.perf-pos{color:var(--green-strong)}
.hm-fig.perf-neg{color:var(--red-strong)}
.hm-sub{font-family:var(--font-ui);font-size:var(--fs-caption);line-height:1.4;color:var(--text-muted);margin-top:var(--chip-gap)}
.hm-go{margin-top:var(--sp-2)}
/* the import nudge (H1b) and a new user's empty state (H3): the state panel's parts, without its box — the card is the box */
.hm-nudge{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--sp-2);padding:var(--sp-5) var(--sp-4) var(--sp-2);border-top:1px solid var(--line);margin-top:var(--sp-4)}
.hm-empty .hm-nudge{border-top:0;margin-top:0;padding-top:var(--sp-4)}
.hm-nudge .state-d{max-width:26rem}
.hm-doors{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-2);margin-top:var(--sp-2)}
/* Your book: the tabs */
.hb-tabs{display:flex;flex-wrap:wrap;gap:var(--chip-gap)}
.hb-tab{display:inline-flex;align-items:center;gap:var(--chip-gap)}
.hb-filt{font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-soft)}
/* the coverage strip: four equal tiles; the bar is one hue, deeper as more is written — never green, amber or red, which on
   this screen mean intact, on watch and broken. Step 1 is the empty one. */
.hb-strip{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-2);margin-top:var(--sp-4)}
.hb-tile{display:block;width:100%;min-width:0;padding:var(--sp-3) var(--sp-4);border:0;text-align:left;font-family:var(--font-ui);cursor:pointer;background:var(--ladder-soft)}
.hb-tile.is-none{cursor:default}
.hb-tile.on{box-shadow:var(--sel-ring);background:var(--ladder-tint)}
.hb-tile:not(.is-none):not(.on):hover{box-shadow:0 0 0 1px var(--line-strong) inset}
.hb-bar{display:block;height:var(--sp-2)}
/* s122 · ONE gradient split four ways — the ladder's five stops, light cyan to deep indigo; the structure is session 112's (his ruling:
   "don't change the homepage bars … changing its structure which i don't want"), only the colour moves ("a gradient bar so all 4
   bars have visible difference in colors") */
.hb-bar-1{background:linear-gradient(90deg,var(--ladder-0),var(--ladder-1))}
.hb-bar-2{background:linear-gradient(90deg,var(--ladder-1),var(--ladder-2))}
.hb-bar-3{background:linear-gradient(90deg,var(--ladder-2),var(--ladder-3))}
.hb-bar-4{background:linear-gradient(90deg,var(--ladder-3),var(--ladder-4))}
.hb-tile-f{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-2);margin-top:var(--sp-3)}
.hb-tile-n{font-size:var(--fs-small);font-weight:600;line-height:1.3;color:var(--navy)}
.hb-tile-c{font-family:var(--font-mono);font-size:var(--fs-title);font-weight:700;line-height:1;color:var(--navy);font-variant-numeric:tabular-nums}
.hb-tile.is-none .hb-tile-n,.hb-tile.is-none .hb-tile-c{color:var(--text-muted)}
/* the read failed: the notice, on the error's ground (the strip is not drawn at all) */
.notice.notice-err{background:var(--red-soft)}
.notice.notice-err > .state-disc{color:var(--red-strong)}
.hb-miss{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-3);margin-top:var(--sp-4)}
.hb-miss-t{display:flex;flex-direction:column;gap:var(--sp-1);min-width:0;flex:1 1 12rem}
.hb-miss-b{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;color:var(--text)}
.hb-miss-d{font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.5;color:var(--text-soft)}
/* ══ session 120 · PAYMENTS — the Plan page, the plans, the limit prompt and the picker (behind _payOn: staging while Razorpay
   is in test mode). NO RULE HERE DRAWS A BOX: the card, the notice, the chips and the three modals are the system's; these
   rules are layout and type. A sentence is Inter; a price and a date beside a story's name are figures (mono, right). ══ */
.sb-menu .nav-item[hidden],.hero-act[hidden],.hm-count[hidden],.page-header .btn[hidden]{display:none}
.hero-act{font-family:var(--font-ui);font-size:var(--fs-caption);color:var(--text-muted);white-space:nowrap}
.hero-first{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-4)}
.fb-line{font-family:var(--font-ui);font-size:var(--fs-caption);color:var(--amber-strong);margin-top:var(--sp-3)}
.modal-sub-words{font-family:var(--font-ui);font-size:var(--fs-caption);line-height:1.4;color:var(--on-brand-soft);margin-top:var(--sp-1)}
.pl-tbl{margin-top:var(--sp-3)}
.pl-tbl th.pl-num,.pl-tbl td.pl-num{text-align:right;white-space:nowrap}
.pl-go{font-size:var(--fs-small);color:var(--navy);white-space:normal;text-align:left}
.pl-gone{font-family:var(--font-ui);color:var(--text-muted)}
.pl-none{font-family:var(--font-ui);font-size:var(--fs-small);color:var(--text-muted);margin-top:var(--sp-3)}
.pl-def{font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.5;color:var(--text-soft);margin-top:var(--sp-4);max-width:44rem}
.pl-nt{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-4)}
.pl-nt.pl-nt-in{margin:var(--sp-4) 0 0}
.pl-nt-t{display:flex;flex-direction:column;gap:var(--sp-1);min-width:0;flex:1 1 12rem}
.pl-nt-b{font-family:var(--font-ui);font-size:var(--fs-body);font-weight:600;color:var(--text)}
.pl-nt-d{font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.5;color:var(--text-soft)}
.pl-why{font-family:var(--font-ui);font-size:var(--fs-caption);color:var(--text-muted)}
.pl-foot{font-family:var(--font-ui);font-size:var(--fs-caption);line-height:1.5;color:var(--text-muted);margin:var(--sp-3) 0 0}
.pl-picks{display:flex;flex-direction:column;gap:var(--sp-2)}
.pl-pick{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);width:100%;text-align:left;white-space:normal}
.pl-pick:disabled{opacity:.5;cursor:default}
.pl-pick-d{font-family:var(--font-mono);font-size:var(--fs-label);color:var(--text-muted);white-space:nowrap}
/* ── s122 · THE PLANS ON THE PLAN PAGE — three cards side by side (one column when the section is narrow: the box decides, not the
   window); each wears its tier — Free plain · Hobby the ladder's ground · Pro the navy island, the hero's verdict island (a written
   exception to §2c.1, his ruling: a plan card wears its tier's ground). No shadow: nothing floats. ── */
.pl-sec{container:plc / inline-size;margin-bottom:var(--sp-6)}
.pl-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-4)}
.pl-cards > .card{display:flex;flex-direction:column;gap:var(--sp-2);margin:0;padding:var(--sp-5)}
.pl-cards > .card.pl-hobby{background:var(--ladder-soft);border-color:var(--ladder-line)}
.pl-cards > .card.pl-pro{background:var(--navy);border-color:var(--navy)}
.pl-card-n{display:flex;align-items:center;gap:var(--sp-2);font-family:var(--font-ui);font-size:var(--fs-title);font-weight:700;color:var(--navy)}
.pl-card-p{display:flex;align-items:baseline;gap:var(--sp-1)}
.pl-card-amt{font-family:var(--font-mono);font-size:var(--fs-display);font-weight:700;color:var(--navy)}
.pl-card-per{font-family:var(--font-ui);font-size:var(--fs-caption);color:var(--text-muted)}
/* the stories line is THE feature of a plan (his finding: "blurry and small") — a tick, the lead size, 600, full colour */
.pl-card-f{display:flex;align-items:center;gap:var(--sp-2);font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:600;color:var(--navy)}
.pl-card-f > .ic{width:var(--icon-glyph);height:var(--icon-glyph);color:var(--green-deep)}
.pl-card-act{display:flex;flex-direction:column;align-items:stretch;gap:var(--sp-1);margin-top:auto;padding-top:var(--sp-3)}
.pl-card-act .btn{width:100%;justify-content:center}
.pl-pro .pl-card-n,.pl-pro .pl-card-amt,.pl-pro .pl-card-f{color:var(--on-brand)}
.pl-pro .pl-card-per,.pl-pro .pl-why{color:var(--on-brand-soft)}
.pl-pro .pl-card-f > .ic{color:var(--action-on-dark)}
/* s130 r3 · what every plan has: under the limit, a step quieter (body size, soft ink, the small tick) */
.pl-card-fs{display:flex;flex-direction:column;gap:var(--sp-1);margin:0;padding:0;list-style:none}
.pl-card-fs > li{display:flex;align-items:flex-start;gap:var(--sp-2);font-family:var(--font-ui);font-size:var(--fs-body);color:var(--text-soft)}
.pl-card-fs > li > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm);flex-shrink:0;translate:0 var(--sp-1);color:var(--green-deep)}
.pl-pro .pl-card-fs > li{color:var(--on-brand-soft)}
.pl-pro .pl-card-fs > li > .ic{color:var(--action-on-dark)}
.pl-sec > .pl-cards-def{margin:var(--sp-4) auto 0;text-align:center}
@container plc (max-width:40rem){ .pl-cards{grid-template-columns:minmax(0,1fr)} }
/* the refund promise: as long as its words (his finding), amber's ground and words — his choice of colour (12 Oct) */
.pl-refund-row{display:flex;justify-content:center;margin-top:var(--sp-4)}
.pl-refund{display:inline-flex;align-items:center;flex-wrap:wrap;justify-content:center;gap:var(--sp-2);padding:var(--sp-2) var(--sp-4);background:var(--amber-soft);color:var(--amber-strong);font-family:var(--font-ui);font-size:var(--fs-small);font-weight:500;text-align:center}
.pl-refund b{font-weight:700}
.pl-refund > .ic{width:var(--icon-glyph-sm);height:var(--icon-glyph-sm)}
.pl-sec > .pl-foot{text-align:center}
.pl-back{margin-bottom:var(--sp-4)}
/* true of the account: green on a light ground; ON NAVY a white pill with a navy word (his finding: the green form "is not visible on
   navy plan") — on navy green is the action's colour, and the island says its facts in white */
.pill-state.current{background:var(--green-soft);color:var(--green-strong)}
.pill-state.current.pill-ondark{background:var(--on-brand);color:var(--navy)}
/* his verdict (Hold · Add · Trim · Exit) in a row: the verdict island's word, small — the same for every verdict */
.pill-state.verdict{background:var(--navy);color:var(--on-brand)}
/* the plan chip — Free plain · Hobby the ladder's tint · Pro navy with gold */
.pill-plan{display:inline-block;font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;line-height:1.4;text-transform:uppercase;letter-spacing:0.04em;padding:var(--pill-pad);border-radius:var(--radius-2xs);white-space:nowrap}
.pill-plan.free{background:transparent;box-shadow:0 0 0 1px var(--line-strong) inset;color:var(--text-soft)}
.pill-plan.hobby{background:var(--ladder-tint);color:var(--ladder-3)}
.pill-plan.pro{background:var(--navy);color:var(--gold-on-navy)}
.pl-head-st{display:inline-flex;align-items:baseline;gap:var(--sp-2)}
/* the account row: his name, then his plan's chip at the tight tag size (its line 14px, so the row keeps its 44px); the sync line
   says something only when a write did not land */
.sb-acct-chip{display:flex}
.sb-acct-chip[hidden]{display:none}
.sb-acct-chip > .pill-plan{font-size:var(--fs-micro);line-height:1.2;padding:var(--tag-pad-tight)}
/* the story banner above the account row: how many active stories the plan has left, what they are (the info icon), the way to more */
.sb-plan{margin:0 var(--sp-2) var(--sp-2);padding:var(--sp-2) var(--sp-3) var(--sp-3);background:var(--ladder-soft);display:flex;flex-direction:column;gap:var(--sp-2)}
.sb-plan[hidden]{display:none}
.sb-plan-hd{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);min-width:0}
.sb-plan-t{font-family:var(--font-ui);font-size:var(--fs-small);font-weight:600;color:var(--navy)}
.sb-plan-bar{display:block;height:var(--sp-1);background:var(--ladder-tint);overflow:hidden}
.sb-plan-fill{display:block;height:100%;background:var(--ladder-2)}
.sb-plan .sb-plan-go{width:100%;justify-content:center}
.sb-plan.is-out{background:var(--amber-soft)}
.sb-plan.is-out .sb-plan-fill{background:var(--amber)}
/* the active-stories popup: what a story and an active story are (the description callout), then the stories */
.pl-defs{display:flex;flex-direction:column}
.pl-def-i + .pl-def-i{margin-top:var(--sp-3)}
.pl-pick.is-shown{cursor:default}
.pl-pick.is-shown:hover{border-color:var(--line);color:var(--text-soft)}
/* the table — the Ledger's (.tx-table: Inter heads on the tint band), on automatic layout.
   ⚠ HIS RULE FOR A NEW TABLE: words left, figures right with their head, a tag, a chip and a pill their own width, columns
     sized by what is in them — never the board's proportional tracks. The name and the passed story's reason are bounded by
     an inner block's measure, which is what keeps one long line from taking the table. */
.hb-wrap{margin-top:var(--sp-4)}
.hb-table th,.hb-table td{padding-left:var(--sp-3);padding-right:var(--sp-3)}
.hb-table th{white-space:nowrap}
.hb-table td{font-family:var(--font-ui);padding-top:var(--sp-3);padding-bottom:var(--sp-3);border-bottom:1px solid var(--line);vertical-align:middle}
.hb-table tbody tr:last-child td{border-bottom:0}
.hb-table .hb-grp td{padding:var(--sp-4) 0 var(--chip-gap);border-bottom:0}
.hb-table th.hb-h-num,.hb-table td.hb-c-money{text-align:right;white-space:nowrap}
.hb-table th:last-child,.hb-table td.hb-c-go{width:1%;padding-left:0;text-align:right}
.hb-row{cursor:pointer}
.hb-row:hover td{background:var(--surface-tint)}
.hb-row.hb-flat{cursor:default}
.hb-row.hb-flat:hover td{background:none}
.hb-pos{min-width:9rem;max-width:17rem}
.hb-tk{display:flex;align-items:center;gap:var(--sp-2)}
.hb-sym{font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:700;line-height:1.2;color:var(--navy);overflow-wrap:anywhere}
/* the company's name is cut to its column, and asks for no width of its own (it would otherwise set the column's least width) */
.hb-nm{width:0;min-width:100%;font-size:var(--fs-caption);line-height:1.4;color:var(--text-muted);margin-top:var(--sp-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hb-m1{display:flex;align-items:baseline;justify-content:flex-end;gap:var(--sp-2);white-space:nowrap}
.hb-val{font-family:var(--font-mono);font-size:var(--fs-body);font-weight:700;line-height:1.2;color:var(--navy);font-variant-numeric:tabular-nums}
.hb-gain{font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:700}
.hb-m2{font-family:var(--font-mono);font-size:var(--fs-caption);line-height:1.4;color:var(--text-muted);margin-top:var(--sp-1);white-space:nowrap}
.hb-none{font-family:var(--font-ui);font-size:var(--fs-small);line-height:1.5;color:var(--text-muted)}
.hb-v1{display:flex;align-items:center;flex-wrap:wrap;gap:var(--chip-gap)}
.hb-day{font-family:var(--font-mono);font-size:var(--fs-caption);line-height:1.4;color:var(--text-muted);white-space:nowrap;margin-top:var(--sp-1)}
.hb-c-day .hb-day{margin-top:0}
.hb-why{font-size:var(--fs-small);line-height:1.5;color:var(--text);min-width:12rem;max-width:40rem}
/* ⚠ THE STACKED FORM, BY THE CARD'S WIDTH. Under 48rem of card the money row is two by two, the strip is two by two, the
   table's head goes and each story is a block of its own between hairlines — the name and the chevron, the money on a
   band, the claims, the verdict. No box is drawn inside the box (the Quarterly Review's rule, board_changes 117). */
@container hm (max-width:48rem){
  .hm-money{grid-template-columns:repeat(2,minmax(0,1fr))}
  .hm-cell{padding:var(--sp-3)}
  .hm-cell:nth-child(3){padding-left:0;border-left:0;border-top:1px solid var(--line)}
  .hm-cell.hm-xirr{margin:0}
  .hm-go > .text-action{white-space:normal;text-align:left}
  .hm-fig{font-size:var(--fs-figure-md-sm)}
  .hb-strip{grid-template-columns:repeat(2,minmax(0,1fr))}
  .hb-table,.hb-table tbody,.hb-table .hb-grp,.hb-table .hb-grp td,.hb-table .hb-nil,.hb-table .hb-nil td{display:block}
  .hb-table thead{display:none}
  .hb-table .hb-row{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"pos go" "money money" "cl cl" "v v";gap:var(--sp-2);align-items:start;padding:var(--sp-3) 0;border-bottom:1px solid var(--line)}
  .hb-table.hb-t-watchlist .hb-row{grid-template-areas:"pos go" "cl cl" "v v"}
  .hb-table.hb-t-passed .hb-row{grid-template-areas:"pos go" "why why" "day day"}
  .hb-table .hb-row.hb-flat{grid-template-areas:"pos pos" "money money"}
  .hb-table tbody .hb-row:last-child{border-bottom:0}
  .hb-table .hb-row td{display:block;width:auto;padding:0;border-bottom:0;background:none;text-align:left;white-space:normal}
  .hb-table .hb-row.hb-flat td:empty{display:none}
  .hb-table .hb-row td.hb-c-pos{grid-area:pos}
  .hb-table .hb-row td.hb-c-money{grid-area:money}
  .hb-table .hb-row td.hb-c-cl{grid-area:cl}
  .hb-table .hb-row td.hb-c-v{grid-area:v}
  .hb-table .hb-row td.hb-c-why{grid-area:why}
  .hb-table .hb-row td.hb-c-day{grid-area:day}
  .hb-table .hb-row td.hb-c-go{grid-area:go}
  .hb-money{background:var(--surface-tint);padding:var(--sp-2) var(--sp-3)}
  .hb-m1{justify-content:flex-start}
  .hb-m2{white-space:normal}
  .hb-pos,.hb-why{min-width:0;max-width:none}
}
@media(max-width:768px){
  /* an icon button's square grows to the 44px touch target; the glyph stays 16 (v2 board §3) */
  .icon-btn,.spc-expand,.ev2-kebab,.sig-expand,.modal-close,.tm-close{width:var(--icon-hit-touch);height:var(--icon-hit-touch)}
  /* ══ THE MODAL AT 390 — v2 board §7, decided once for every modal ═══════════════════════
     A card inset 12px on every side, radius kept, head and footer PINNED and only the body
     scrolling. No bottom sheet, no full-screen takeover. The head compresses so the first
     field is never below the fold, and the sub-line takes one line with an ellipsis.
     ⚠ THIS BLOCK SITS BELOW THE BASE RULES IT OVERRIDES, which is the only reason it applies:
     a media block does not raise specificity, so one declared above its base rule never wins. */
  .modal-overlay{padding:var(--modal-inset)}
  /* ⚠ THE :not() IS GONE AND THAT IS THE RULING, NOT A TIDY. It existed for one reason — to
     stop this line clipping the review's full-height sheet — and his 13 Sep ruling retired the
     sheet, so eleven modals now take one ceiling. It still wins by SOURCE ORDER: this sits
     below .pr-modal's own 88vh at equal specificity, which is the whole of why it applies. */
  .modal-box,.tm-box{max-height:calc(100dvh - var(--modal-inset) * 2)}
  .modal-header,.tm-head{padding:var(--modal-head-pad-sm);gap:var(--sp-2)}
  .modal-title,.tm-headline{font-size:var(--fs-title-sm)}
  .modal-sub{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .modal-close,.tm-close{margin:var(--modal-close-pull-sm)}
  .modal-body,.tm-body{padding:var(--modal-body-pad-sm)}
  .modal-body.modal-stack{gap:var(--modal-stack-sm)}
  /* at 390 the one action fills the width, as the board draws it */
  .sup-mail{width:100%;justify-content:center;padding:var(--btn-pad-sm)}
  .modal-footer,.tm-foot{padding:var(--modal-foot-pad-sm);flex-wrap:wrap}
  /* ⚠ THE LADDER AT 390, AND IT IS THE LADDER — not a footer rule (v3 §10 self-check).
     Ordered as the ladder is ordered, so a fill beats a hairline beats the box, and the
     KPI card's button-row exception below still wins because it comes later. */
  .btn{padding:var(--btn-pad-sm)}
  .btn-secondary,.btn-outline-action,.btn-danger-outline{padding:var(--btn-pad-line-sm)}
  .btn-neutral{padding:var(--btn-pad-neutral-sm)}
  /* board 22 at 390: the body tightens, the KPI row stops being a grid and stacks, its field
     goes to 16px (the iOS rule) and its three verdicts share the width as equal targets. */
  /* ⚠ NO HOVER AT 390, SO THE TEXT ITSELF IS THE TRIGGER (his call, 14 Sep). The panel stops
     floating and opens IN FLOW directly beneath the row it belongs to, inset 12, full width,
     at 16px reading type. The row's own action is untouched — a row opens from its key column
     and its actions, never from its text, so the tap the peek takes was nobody else's. */
  /* ⚠ NO SHADOW HERE, AND THAT IS RULE 5 BEATING A DRAWING. §1: "A shadow means the thing
     floats" — and §1's own preamble says a drawing that breaks one of these is wrong, not
     innovative. At 1440 the peek floats over the page and carries float·pop; at 390 it is
     inserted between two rows and pushes them apart, so it floats over nothing. Board §10's
     390 frame draws the shadow anyway. Reported, not absorbed: the edge and the ground are
     what separate it there, which is what a level-1 surface gets. */
  .peek,.peek.chip{position:static;width:auto;max-width:none;margin:var(--sp-2) var(--modal-inset) 0;box-shadow:none}
  .peek-t{font-size:var(--fs-lead)}
  /* field-sm exists only where a row grid does, and no row grid survives 390 */
  .field-sm,.sig-comp-row input{font-size:var(--fs-lead);padding:var(--fld-pad)}
  .qtr-body{padding:var(--qtr-body-pad-sm)}
  .qtr-eyebrow{margin:var(--qtr-eb-m-sm)}
  .qtr-body > .qtr-eyebrow:first-child{margin-top:var(--qtr-eb-top1-sm)}
  .row.qtr-kpi,.row.qtr-kpi.qtr-ms{display:block;padding:var(--qtr-kpi-pad-sm)}
  /* board 22 at 390: period and value share ONE line, half each, at the full field size —
     field-sm is a ≥768 component and the iOS 16px rule outranks a grid. */
  .qtr-kpi-fields{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2);margin-top:var(--qtr-kpi-step)}
  .qtr-kpi .field-mono,.qtr-kpi .sig-select{font-size:var(--fs-lead)}
  .qtr-kpi .qtr-chips{margin-top:var(--sp-2)}
  .qtr-kpi .qtr-chips > .chip-select-state{flex:1;justify-content:center}
  /* the milestone's four verdicts are a 2×2 grid at 44px, as the board draws them */
  .qtr-ms .qtr-chips{display:grid;grid-template-columns:1fr 1fr;gap:var(--chip-gap)}
  /* 390: the two conditions stack and the three verdicts share the width as equal targets */
  .qtr-claim{padding:var(--qtr-clm-pad-sm)}
  .qtr-clm-conds{grid-template-columns:1fr;gap:var(--sp-2)}
  .qtr-claim .qtr-chips > .chip-select-state{flex:1;justify-content:center}
  .qtr-dec{grid-template-columns:1fr;gap:var(--sp-4)}
  .qtr-stars .star-rating > button > .ic{font-size:var(--star-conv-sm)}
  .qtr-stars{height:auto;flex-wrap:wrap}
  /* board 04 at 390: one column, a 16px card, and the button row at the touch height */
  .sig-grid{grid-template-columns:1fr}
  .sig-card{padding:var(--sp-4)}
  .sig-logbtn{height:var(--sig-btn-h-sm);padding:var(--sig-btn-pad-sm)}
  /* board 05 at 390: the tile tightens and the two kind cards stack — the app's 640 rule already
     stacks .sig-kindgrp, so only the two paddings move. */
  .sig-add-tile{padding:var(--sig-tile-pad-sm)}
  .sig-kind{padding:var(--sig-kind-pad-sm)}
  /* 15's option cards tighten with the body they sit in (board Modals §15, 390) */
  .cr-claim{padding:var(--opt-pad-sm)}
  #conv-modal-stars{gap:var(--sp-4)}
  #conv-modal-stars > span > .ic{font-size:var(--star-conv-sm)}
  /* Events: date sits above the note, note takes full width */
  .ev2-ev{flex-wrap:wrap;gap:var(--sp-2)}
  .ev2-date{width:100%;order:-1;padding-top:0;margin-bottom:1px}
  .ev2-dot{margin-top:6px}
  .ev2-body{flex:1 1 0;min-width:0;overflow-wrap:anywhere}
  .ev2-ev .ev2-act{padding-top:0;align-self:center}
  /* Review history cards fill the width on mobile */
  /* s110 · Quarterly Review on a phone: the select takes the line under the title, Help beside it (the stories' stacked form
     is keyed on the card's width, above) */
  #page-quarterly .page-header{padding-top:var(--sp-4);padding-bottom:var(--sp-4)}   /* s115 · a phone's head keeps the padding every phone head has */
  #page-quarterly .page-header > .row-c{width:100%}
  #page-quarterly .qr-sel{flex:1 1 auto}
}
}
/* ═══════════════════════════════════════════════════════════════════════════
   PHASE 2 — THE INLINE STYLES, FOLDED (3 Sep 2026, session 60). harness/p2_fold_inline.py
   Everything above sits in @layer base. These rules are UNLAYERED so they outrank the
   base layer regardless of specificity — the standing an inline attribute had — and
   JS el.style writes still outrank them. Composites first (named primitives), then
   one-declaration utilities. Nothing here may carry a raw hex, size, radius or z.
   ⚠ New markup uses these; a new inline style attribute that is not display:none or ${…} fails
   harness/harness_design_lint.mjs.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ══ THE RECORD, UNLAYERED ══════════════════════════════════════════════════════════════
   ⚠ THESE TWO RULES CANNOT LIVE IN @layer base. The utility block below is unlayered, so it
   outranks the whole base layer no matter how much selector you put in front of a rule up
   there — .row-sb beat "#stc-kpis .card .row-sb.row-sb", which is not a specificity anyone
   would expect to lose. The rules that have to beat a u- utility belong down here with them,
   and they are ordered before the utilities so a deliberate u- on an element still wins.
   ⚠ THE VIOLET CANCEL IS GONE (v2 board §2, session 73: "the Record's violet Cancel is a
   defect"). Three rules here repainted EVERY hairline button inside a Record section as violet
   text — the Cancels, and the section heads' Add buttons with them. The heads are boxes now, a
   Cancel is the hairline it always was underneath, and the Docs row controls are the text tiers
   written on their own markup. Nothing is re-coloured by where it sits. The lint (L45) keeps
   the repaint from coming back. */
#stc-kpis .card .row-sb{justify-content:flex-end;padding-top:var(--sp-4)}   /* session 87 · finding 3 */
/* session 89 · finding 2: "The QR review section is merging with the record underline; the same spacing
   should be given, just like how KPIs have been corrected". The Organizer opens on the review strip,
   which sat flush on the line; Docs opened on its title the same way. Both get the KPIs' 16. */
/* s94 · R4-9 (his Round 4: "the spacing between the record section underline and the organizer tab's first section… and b/w
   the record underline and the buy/sell journal top grid are not equal"). Measured on his Kalyan: Organizer 16, the journal
   8 (an EMPTY hint line's 8px margin collapsed out through the pane), Notes 0. All five sections clear it by 16 now; the
   hint keeps its margin only when it says something. */
#stc-notes,#stc-monitor,#stc-docs,#stc-xirr-tab{padding-top:var(--sp-4)}
#xirr-db-hint:not(:empty){margin-bottom:var(--sp-2)}
#stc-xirr-tab .tx-table tr,#stc-xirr-tab .tx-table thead tr{background:none}

/* ══ SCREEN 03 · THE ORGANIZER'S SECTIONS ARE CARDS AGAIN (v2 board 03, session 77) ══════
   His review, 11 Sep: "Organizer looks bad; sections merge; use cards" — and DESIGN rule 14
   makes it general: inside The Record every section is a level-1 card with a 16/700 title, its
   count as a tag and one box at the right. Session 68 flattened them for the opposite reason
   (a white card on a white column inside a page, three deep) and that reading still holds for
   the sections nobody had drawn. This one is drawn, so it is built.
   ⚠ SCOPED TO THIS SECTION, THREE TIMES OVER. (1) The base .card rule carries a shadow and
   whether a card sitting in the page may have one is HIS open question, unruled — a phase that
   was not asked to decide it must not. (2) .card has 19 markup consumers and 10 of them are
   outside the Record entirely. (3) KPIs, the journal and Docs are later screens with drawings
   of their own; they stay flattened until theirs is built, which is the pacing he asked for.
   ⚠ AND IT LIVES DOWN HERE, UNLAYERED, BECAUSE THAT IS THE ONLY PLACE IT CAN WIN. The
   flattening rules sit in @layer base; an unlayered rule beats every layered one at any
   specificity, and no amount of selector up there would have done it. */
#stc-monitor .card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);
  box-shadow:none;padding:var(--rec-card-pad);margin-bottom:var(--sp-4);border-bottom:1px solid var(--line)}
/* the strip has one line of content and no row list to close it */
#stc-monitor .nr-card{padding:var(--rec-strip-pad)}
/* a section whose body is an empty state closes nothing, so the card closes itself */
#stc-monitor .rec-card-empty{padding:var(--rec-card-pad-e)}
/* the head row: title · count, and one box at the right, 12px clear of the first rule */
#stc-monitor .card > .row-sb{padding-bottom:var(--rec-head-pad);margin-bottom:0}
/* board 03 rules ABOVE each row — the head's 12px and the first row's rule make the break */
#stc-monitor .rec-row{border-top:1px solid var(--line);border-bottom:none}
/* …and the last row of a LIST closes it, which is what the card's 4px bottom padding sits under */
#stc-monitor .rec-list .rec-row:last-child{border-bottom:1px solid var(--line)}
/* the Resolved disclosure is a row of the list, so it carries the list's rule and not a margin */
#stc-monitor .rec-resolved{border-top:1px solid var(--line);padding:var(--rec-res-pad)}
#stc-monitor .rec-resolved .q-resolved-toggle{margin-top:0}
/* the review panel is the Record's card with its head full-bleed, so it owns its own padding */
#stc-monitor .qtr-panel{padding:0;overflow:hidden}
/* the empty state inside a card draws no box of its own: page → card → panel would be three
   deep, which DESIGN rule 6 forbids. ⚠ NO RADIUS IN THIS RULE — dropping the border is what
   un-draws the box, and a radius beside a border is what L18 would count as drawing one. */
#stc-monitor .state-panel{border:0;padding:var(--rec-empty-pad);gap:var(--sp-2)}
#stc-monitor .state-d{max-width:var(--rec-empty-w)}

/* composites */
.t-label{color:var(--text-muted);font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase}
/* session 107 · on the two pages built after the eyebrow went to Inter, the label composite speaks the eyebrow's voice.
   The composite itself stays as it is for the pages that are waiting to be redrawn (Home, Quarterly Review) and for onboarding.
   The Flying Blind page's two blocks joined in the same session (its story note is the stock page's own component: not scoped). */
#page-xirr .t-label,#page-ledger .t-label,#fb-steps .t-label,#empty-pos-data .t-label,#page-quarterly .t-label,.hm .t-label{font-family:var(--font-ui);font-size:var(--fs-caption);font-weight:600;letter-spacing:0.06em}   /* session 110 · Quarterly Review, rebuilt, joined · session 112 · the new Home (.hm) joined; the old Home, gate shut, is not touched */
.t-empty{color:var(--text-muted);font-size:var(--fs-small);text-align:center}
.th-mono{color:var(--text-muted);font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:700;letter-spacing:.08em;padding:10px;text-align:left;text-transform:uppercase}
/* the small textarea's own box went here; one field size serves every surface (v2 board §5). Session 130 (his finding of
   14 Oct, "the textbox inside update guidance form is smaller than what we have everywhere"): the small field .fld went too —
   its nine uses (the KPI cards' log and update forms, their pop-outs, Performance's alias search) are .fld-lg. */
/* UX-31 (Phase 2): the Audit Trail's kind label — SETUP / REVIEW DUE / SIGNALS UPDATED — had the
   width of its word, so titles began at four different x positions. One width, left-aligned. */
/* The segmented filter chip (the Audit Trail's Pending / Completed, the financials' Quarterly / Annual / YoY):
   the chosen segment was a --green FILL — selection by hue, the thing UX-30 closed everywhere else.
   Now the ring + navy tint that .sig-seg button.on already wears. */
.seg-chip{font-family:var(--font-mono);font-weight:700;border:1.5px solid var(--line);background:var(--surface);color:var(--text-soft);cursor:pointer;transition:all .15s}
.seg-chip:hover{border-color:var(--navy-soft);color:var(--navy)}
.seg-chip.on{background:var(--navy-tint);color:var(--navy);border-color:var(--navy-soft);box-shadow:var(--sel-ring)}
.trail-kind{padding:var(--sp-1) var(--sp-2);white-space:nowrap;flex-shrink:0;min-width:118px;text-align:left}
.card-plain{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-xs)}
.row-sb{align-items:center;display:flex;justify-content:space-between}
.row-c{align-items:center;display:flex}
.acts-end{display:flex;gap:6px;justify-content:flex-end}
.tbl{border-collapse:collapse;width:100%}
.sec-h{color:var(--navy);font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:800}
.sec-hd-main{font-size:var(--sec-fs);font-weight:800;line-height:1.2}   /* session 109 · a page-level card's title, beside its plate — unlayered, so it beats the title's own class. Its size is --sec-fs: the title role, and the title role's phone size under 768 (set on :root there, because a layered phone rule could not out-rank this one) */
.fig{color:var(--navy);font-family:var(--font-mono);font-size:var(--fs-lead);font-weight:700}
.fig-lg{font-family:var(--font-mono);font-size:var(--fs-display);font-weight:700}
.chip-mono{border-radius:var(--radius-2xs);font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;line-height:1.4;letter-spacing:0.03em}
.u-trunc{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* utilities */
.u-ff-inh{font-family:inherit}
.u-mono{font-family:var(--font-mono)}
.u-ui{font-family:var(--font-ui)}
.u-fs-body{font-size:var(--fs-body)}
.u-fs-caption{font-size:var(--fs-caption)}
.u-fs-display{font-size:var(--fs-display)}
.u-fs-display129{font-size:calc(var(--fs-display) * 1.29)}
.u-fs-label{font-size:var(--fs-label)}
.u-fs-lead{font-size:var(--fs-lead)}
.u-fs-micro{font-size:var(--fs-micro)}
.u-fs-small{font-size:var(--fs-small)}
.u-fs-title{font-size:var(--fs-title)}
.u-fw400{font-weight:400}
.u-fw500{font-weight:500}
.u-fw600{font-weight:600}
.u-fw700{font-weight:700}
.u-fw800{font-weight:800}
.u-italic{font-style:italic}
.u-up{text-transform:uppercase}
.u-ls03{letter-spacing:.03em}
.u-ls04{letter-spacing:.04em}
.u-ls05{letter-spacing:.05em}
.u-ls06{letter-spacing:.06em}
.u-ls07{letter-spacing:.07em}
.u-ls08{letter-spacing:.08em}
.u-ls1{letter-spacing:.1em}
.u-lh1{line-height:1}
.u-lh12{line-height:1.2}
.u-lh13{line-height:1.3}
.u-lh14{line-height:1.4}
.u-lh145{line-height:1.45}
.u-lh15{line-height:1.5}
.u-lh155{line-height:1.55}
.u-lh16{line-height:1.6}
.u-lh165{line-height:1.65}
.u-ta-c{text-align:center}
.u-ta-l{text-align:left}
.u-ta-r{text-align:right}
.u-td-none{text-decoration:none}
.u-td-u{text-decoration:underline}
.u-nowrap{white-space:nowrap}
.u-preline{white-space:pre-line}
.u-va-m{vertical-align:middle}
.u-va-t{vertical-align:top}
.u-c-amber-ondark{color:var(--amber)}
.u-c-amber-strong{color:var(--amber-strong)}
.u-c-green-strong{color:var(--green-strong)}
.u-c-line-strong{color:var(--line-strong)}
.u-c-navy{color:var(--navy)}
.u-c-navy-soft{color:var(--navy-soft)}
.u-c-on-action{color:var(--on-action)}
.u-c-on-brand{color:var(--on-brand)}
.u-c-ondark35{color:var(--on-brand-faint)}
.u-c-ondark45{color:rgba(255,255,255,0.45)}
.u-c-ondark85{color:rgba(255,255,255,0.85)}
.u-c-red-strong{color:var(--red-strong)}
.u-c-text{color:var(--text)}
.u-c-text-muted{color:var(--text-muted)}
.u-c-text-soft{color:var(--text-soft)}
.u-bg-action{background:var(--action)}
.u-bg-amber{background:var(--amber)}
.u-bg-amber-soft{background:var(--amber-soft)}
.u-bg-amber-strong{background:var(--amber-strong)}
.u-bg-chrome{background:var(--chrome)}
.u-bg-green{background:var(--green)}
.u-bg-green-soft{background:var(--green-soft)}
.u-bg-green-wash{background:linear-gradient(180deg,rgba(42,199,131,0.05),rgba(255,255,255,0))}
.u-bg-green-wash5{background:rgba(42,199,131,0.05)}
.u-bg-line-strong{background:var(--line-strong)}
.u-bg-navy{background:var(--navy)}
.u-bg-navy-soft{background:var(--navy-soft)}
.u-bg-navy-tint{background:var(--navy-tint)}
/* --amber and --red as FILLS. The set had --green but not its two siblings, so a state dot in
   amber or red had nowhere to go. These are backgrounds on a glyph, never text: L28 governs the
   u-c-* colour utilities precisely because --amber and --red measure 2.19:1 and 3.36:1 as words. */
.u-bg-red{background:var(--red)}
.u-bg-red-soft{background:var(--red-soft)}
.u-bg-red-strong{background:var(--red-strong)}
.u-bg-rgba255_255_255_0_6{background:rgba(255,255,255,0.6)}
.u-bg-rgba27_58_107_0_04{background:rgba(27,58,107,0.04)}
.u-bg-rgba42_199_131_0_04{background:rgba(42,199,131,0.04)}
.u-bg-scrim{background:rgba(0,0,0,0.45)}
.u-bg-surface{background:var(--surface)}
.u-bg-surface-raised{background:var(--surface-raised)}
.u-bg-surface-sunken{background:var(--surface-sunken)}
.u-bg-surface-tint{background:var(--surface-tint)}
.u-bg-t{background:transparent}
.u-bg-text-muted{background:var(--text-muted)}
.u-bg-viz-heat{background:var(--viz-heat)}
.u-bg0{background:none}
.u-op-0_35{opacity:0.35}
.u-op-0_4{opacity:0.4}
.u-op-0_6{opacity:0.6}
.u-op-1{opacity:1}
.u-b-1-dashed-green{border:1px dashed var(--green)}
.u-b-1-dashed-line{border:1px dashed var(--line)}
.u-b-1-solid-amber{border:1px solid var(--amber)}
.u-b-1-solid-line{border:1px solid var(--line)}
.u-b-1-solid-line-strong{border:1px solid var(--line-strong)}
.u-b-1-solid-navy{border:1px solid var(--navy)}
.u-b-1-solid-red-strong{border:1px solid var(--red-strong)}
.u-b-1-solid-surface-tint{border:1px solid var(--surface-tint)}
.u-b-1_5-solid{border:1.5px solid}
.u-b-1_5-solid-amber{border:1.5px solid var(--amber)}
.u-b-1_5-solid-green{border:1.5px solid var(--green)}
.u-b-1_5-solid-line-strong{border:1.5px solid var(--line-strong)}
.u-b-1_5-solid-red-strong{border:1.5px solid var(--red-strong)}
.u-b-2-dashed-line-strong{border:2px dashed var(--line-strong)}
.u-b-2-solid-green{border:2px solid var(--green)}
.u-b-ondark15{border:1px solid rgba(255,255,255,0.15)}
.u-b0{border:none}
.u-bb-1-dotted-text-muted{border-bottom:1px dotted var(--text-muted)}
.u-bb-1-solid-line{border-bottom:1px solid var(--line)}
.u-bb-1-solid-surface-tint{border-bottom:1px solid var(--surface-tint)}
.u-bb-1-solid-transparent{border-bottom:1px solid transparent}
.u-bb-2-dashed-line-strong{border-bottom:2px dashed var(--line-strong)}
.u-bb-2-solid-line{border-bottom:2px solid var(--line)}
.u-bt-1-solid-line{border-top:1px solid var(--line)}
.u-bt-1_5-solid-amber{border-top:1.5px solid var(--amber)}
.u-bl-2-solid-line-strong{border-left:2px solid var(--line-strong)}
.u-bl-3-solid-amber{border-left:3px solid var(--amber)}
.u-bl-3-solid-line-strong{border-left:3px solid var(--line-strong)}
.u-br-1-solid-line{border-right:1px solid var(--line)}
.u-bc-red-strong{border-color:var(--red-strong)}
.u-r-0-radius-xs-radius-xs-0{border-radius:0 var(--radius-xs) var(--radius-xs) 0}
.u-r-2xs{border-radius:var(--radius-2xs)}
.u-r-sm{border-radius:var(--radius-sm)}
.u-r-xs{border-radius:var(--radius-xs)}
.u-r-pill{border-radius:var(--radius-pill)}
.u-round{border-radius:50%}
/* .u-card-shadow went here (session 77, Phase 8): a utility whose only job was to raise an
   element that sits in the page. Nothing in the page is raised any more. */
.u-float-lg{box-shadow:0 20px 50px rgba(0,0,0,0.18)}
.u-float-needle{box-shadow:0 0 0 2px var(--surface),0 1px 4px rgba(0,0,0,0.2)}
.u-float-xl{box-shadow:0 24px 60px rgba(15,34,66,0.28)}
.u-float-xxl{box-shadow:0 28px 72px rgba(0,0,0,0.22)}
.u-ol-none{outline:none}
.u-block{display:block}
.u-contents{display:contents}
.u-flex{display:flex}
.u-grid{display:grid}
.u-ib{display:inline-block}
.u-iflex{display:inline-flex}
.u-ai-c{align-items:center}
.u-ai-end{align-items:end}
.u-ai-fe{align-items:flex-end}
.u-ai-fs{align-items:flex-start}
.u-ai-s{align-items:start}
.u-ai-st{align-items:stretch}
.u-jc-c{justify-content:center}
.u-jc-fe{justify-content:flex-end}
.u-jc-sb{justify-content:space-between}
.u-wrap{flex-wrap:wrap}
.u-col{flex-direction:column}
.u-f1{flex:1}
.u-f1a{flex:1 1 auto}
.u-shrink0{flex-shrink:0}
.u-as-flex-start{align-self:flex-start}
.u-gtc-1fr-1fr{grid-template-columns:1fr 1fr}
.u-gtc-1fr-1fr-1fr-1fr-1fr{grid-template-columns:1fr 1fr 1fr 1fr 1fr}
.u-gtc-1fr-1fr-auto{grid-template-columns:1fr 1fr auto}
.u-gtc-2fr-1fr-1fr-28{grid-template-columns:2fr 1fr 1fr 28px}
.u-gtc-repeat4_1fr{grid-template-columns:repeat(4,1fr)}
.u-gc-1s-1{grid-column:1/-1}
.u-gap-10{gap:10px}
.u-gap-1_25r{gap:1.25rem}
.u-gap-6{gap:6px}
.u-gap-sp-1{gap:var(--sp-1)}
.u-gap-sp-2{gap:var(--sp-2)}
.u-gap-sp-3{gap:var(--sp-3)}
.u-gap-sp-4{gap:var(--sp-4)}
.u-gap-sp-5{gap:var(--sp-5)}
.u-m--3-0-sp-2{margin:-3px 0 var(--sp-2)}
.u-m-0-0-0_85r{margin:0 0 0.85rem}
.u-m-0-0-1_1r{margin:0 0 1.1rem}
.u-m-0-0-sp-1{margin:0 0 var(--sp-1)}
.u-m-0-0-sp-2{margin:0 0 var(--sp-2)}
.u-m-0-0-sp-3{margin:0 0 var(--sp-3)}
.u-m-0-auto-0_9r{margin:0 auto 0.9rem}
.u-m-0-auto-1_1r{margin:0 auto 1.1rem}
.u-m-0-auto-sp-3{margin:0 auto var(--sp-3)}
.u-m-0-sp-3-sp-1{margin:0 var(--sp-3) var(--sp-1)}
.u-m-0-sp-3-sp-3{margin:0 var(--sp-3) var(--sp-3)}
.u-m-0_4r-0{margin:0.4rem 0}
.u-m-0_4r-0-sp-1{margin:0.4rem 0 var(--sp-1)}
.u-m-0_6r-0{margin:0.6rem 0}
.u-m-0_9r-0-sp-2{margin:0.9rem 0 var(--sp-2)}
.u-m-1_1r-0-sp-2{margin:1.1rem 0 var(--sp-2)}
.u-m-6-0{margin:6px 0}
.u-m-auto{margin:auto}
.u-m-sp-1-0-0_6r{margin:var(--sp-1) 0 0.6rem}
.u-m-sp-1-sp-2-0{margin:var(--sp-1) var(--sp-2) 0}
.u-m-sp-3-0{margin:var(--sp-3) 0}
.u-m-sp-3-0-2{margin:var(--sp-3) 0 2px}
.u-m0{margin:0}
.u-mx-auto{margin:0 auto}
.u-mt-0{margin-top:0}
.u-mt-0_4r{margin-top:0.4rem}
.u-mt-0_6r{margin-top:0.6rem}
.u-mt-0_85r{margin-top:0.85rem}
.u-mt-0_9r{margin-top:0.9rem}
.u-mt-1{margin-top:1px}
.u-mt-10{margin-top:10px}
.u-mt-14{margin-top:14px}
.u-mt-1_1r{margin-top:1.1rem}
.u-mt-1_25r{margin-top:1.25rem}
.u-mt-2{margin-top:2px}
.u-mt-6{margin-top:6px}
.u-mt-sp-1{margin-top:var(--sp-1)}
.u-mt-sp-2{margin-top:var(--sp-2)}
.u-mt-sp-3{margin-top:var(--sp-3)}
.u-mb-0{margin-bottom:0}
.u-mb-0_15r{margin-bottom:0.15rem}
.u-mb-0_35r{margin-bottom:0.35rem}
.u-mb-0_4r{margin-bottom:0.4rem}
.u-mb-0_65r{margin-bottom:0.65rem}
.u-mb-0_6r{margin-bottom:0.6rem}
.u-mb-0_85r{margin-bottom:0.85rem}
.u-mb-0_9r{margin-bottom:0.9rem}
.u-mb-10{margin-bottom:10px}
.u-mb-14{margin-bottom:14px}
.u-mb-1_1r{margin-bottom:1.1rem}
.u-mb-1_25r{margin-bottom:1.25rem}
.u-mb-2{margin-bottom:2px}
.u-mb-20{margin-bottom:20px}
.u-mb-28{margin-bottom:28px}
.u-mb-6{margin-bottom:6px}
.u-mb-sp-1{margin-bottom:var(--sp-1)}
.u-mb-sp-2{margin-bottom:var(--sp-2)}
.u-mb-sp-3{margin-bottom:var(--sp-3)}
.u-mb-sp-4{margin-bottom:var(--sp-4)}
.u-mb-sp-5{margin-bottom:var(--sp-5)}
.u-ml-0{margin-left:0}
.u-ml-10{margin-left:10px}
.u-ml-2{margin-left:2px}
.u-ml-6{margin-left:6px}
.u-ml-auto{margin-left:auto}
.u-ml-sp-1{margin-left:var(--sp-1)}
.u-ml-sp-2{margin-left:var(--sp-2)}
.u-ml-sp-3{margin-left:var(--sp-3)}
.u-ml-sp-4{margin-left:var(--sp-4)}
.u-mr-sp-1{margin-right:var(--sp-1)}
.u-p-0-sp-1{padding:0 var(--sp-1)}
.u-p-0-sp-6{padding:0 var(--sp-6)}
.u-p-0_85r-1_25r{padding:0.85rem 1.25rem}
.u-p-0_85r-sp-4{padding:0.85rem var(--sp-4)}
.u-p-1-sp-1{padding:1px var(--sp-1)}
.u-p-1-sp-2{padding:1px var(--sp-2)}
.u-p-10-14{padding:10px 14px}
.u-p-10-18{padding:10px 18px}
.u-p-10-sp-3{padding:10px var(--sp-3)}
.u-p-10-sp-4{padding:10px var(--sp-4)}
.u-p-14{padding:14px}
.u-p-14-18{padding:14px 18px}
.u-p-14-sp-3-sp-2{padding:14px var(--sp-3) var(--sp-2)}
.u-p-14-sp-4{padding:14px var(--sp-4)}
.u-p-18{padding:18px}
.u-p-1_15r-1_25r{padding:1.15rem 1.25rem}
.u-p-1_1r-0_6r{padding:1.1rem 0.6rem}
.u-p-1_1r-1_25r{padding:1.1rem 1.25rem}
.u-p-1_1r-sp-5{padding:1.1rem var(--sp-5)}
.u-p-1_1r-sp-5-0_85r{padding:1.1rem var(--sp-5) 0.85rem}
.u-p-1_25r{padding:1.25rem}
.u-p-1_25r-sp-5{padding:1.25rem var(--sp-5)}
.u-p-1_2r-0{padding:1.2rem 0}
.u-p-1_3r-0_6r{padding:1.3rem 0.6rem}
.u-p-1_75r{padding:1.75rem}
.u-p-1_75r-sp-6{padding:1.75rem var(--pg-pad-x)}
.u-p-1_9r-1_9r-1_7r{padding:1.9rem 1.9rem 1.7rem}
.u-p-2{padding:2px}
.u-p-2-6{padding:2px 6px}
.u-p-2-sp-1{padding:2px var(--sp-1)}
.u-p-2-sp-2{padding:2px var(--sp-2)}
.u-p-20{padding:20px}
.u-p-2_2r-0{padding:2.2rem 0}
.u-p-2_75r-sp-6{padding:2.75rem var(--sp-6)}
.u-p-40{padding:40px}
.u-p-6-10{padding:6px 10px}
.u-p-6-14{padding:6px 14px}
.u-p-6-18{padding:6px 18px}
.u-p-6-20{padding:6px 20px}
.u-p-6-sp-2{padding:6px var(--sp-2)}
.u-p-6-sp-3{padding:6px var(--sp-3)}
.u-p-6-sp-4{padding:6px var(--sp-4)}
.u-p-sp-1{padding:var(--sp-1)}
.u-p-sp-1-10{padding:var(--sp-1) 10px}
.u-p-sp-1-14{padding:var(--sp-1) 14px}
.u-p-sp-1-sp-2{padding:var(--sp-1) var(--sp-2)}
.u-p-sp-1-sp-3{padding:var(--sp-1) var(--sp-3)}
.u-p-sp-2{padding:var(--sp-2)}
.u-p-sp-2-0{padding:var(--sp-2) 0}
.u-p-sp-2-0_85r{padding:var(--sp-2) 0.85rem}
.u-p-sp-2-10{padding:var(--sp-2) 10px}
.u-p-sp-2-14{padding:var(--sp-2) 14px}
.u-p-sp-2-18{padding:var(--sp-2) 18px}
.u-p-sp-2-22{padding:var(--sp-2) 22px}
.u-p-sp-2-34-sp-2-10{padding:var(--sp-2) 34px var(--sp-2) 10px}
.u-p-sp-2-sp-3{padding:var(--sp-2) var(--sp-3)}
.u-p-sp-2-sp-4{padding:var(--sp-2) var(--sp-4)}
.u-p-sp-3{padding:var(--sp-3)}
.u-p-sp-3-10{padding:var(--sp-3) 10px}
.u-p-sp-3-14{padding:var(--sp-3) 14px}
.u-p-sp-3-18{padding:var(--sp-3) 18px}
.u-p-sp-3-1_1r{padding:var(--sp-3) 1.1rem}
.u-p-sp-3-sp-4{padding:var(--sp-3) var(--sp-4)}
.u-p-sp-4{padding:var(--sp-4)}
.u-p-sp-4-0{padding:var(--sp-4) 0}
.u-p-sp-4-1_1r{padding:var(--sp-4) 1.1rem}
.u-p-sp-4-1_25r{padding:var(--sp-4) 1.25rem}
.u-p-sp-5{padding:var(--sp-5)}
.u-p-sp-5-sp-4{padding:var(--sp-5) var(--sp-4)}
.u-p-sp-5-sp-6{padding:var(--sp-5) var(--sp-6)}
.u-p-sp-6{padding:var(--sp-6)}
.u-p-sp-7{padding:var(--sp-7)}
.u-p0{padding:0}
.u-pl-6{padding-left:6px}
.u-pl-sp-2{padding-left:var(--sp-2)}
.u-pt-14{padding-top:14px}
.u-w-10{width:10px}
.u-w-100{width:100px}
.u-w-120{width:120px}
.u-w-13{width:13px}
.u-w-130{width:130px}
.u-w-140{width:140px}
.u-w-180{width:180px}
.u-w-22{width:22px}
.u-w-28{width:28px}
.u-w-30{width:30px}
.u-w-34{width:34px}
.u-w-36{width:36px}
.u-w-4{width:4px}
.u-w-80{width:80px}
.u-w-88{width:88px}
.u-w-9{width:9px}
.u-w-90{width:90px}
.u-w100{width:100%}
.u-minw-100{min-width:100px}
.u-minw-110{min-width:110px}
.u-minw-120{min-width:120px}
.u-minw-160{min-width:160px}
.u-minw-200{min-width:200px}
.u-minw-38{min-width:38px}
.u-minw-400{min-width:400px}
.u-minw-500{min-width:500px}
.u-minw-60{min-width:60px}
.u-minw-700{min-width:700px}
.u-minw-72{min-width:72px}
.u-minw-76{min-width:76px}
.u-minw-80{min-width:80px}
.u-minw-90{min-width:90px}
.u-minw0{min-width:0}
.u-maxw-120{max-width:120px}
.u-maxw-150{max-width:150px}
.u-maxw-160{max-width:160px}
.u-maxw-170{max-width:170px}
.u-maxw-180{max-width:180px}
.u-maxw-230{max-width:230px}
.u-maxw-440{max-width:440px}
.u-maxw-480{max-width:480px}
.u-maxw-500{max-width:500px}
.u-maxw-560{max-width:560px}
.u-maxw-640{max-width:640px}
.u-maxw-none{max-width:none}
.u-h-10{height:10px}
.u-h-100p{height:100%}
.u-h-13{height:13px}
.u-h-18{height:18px}
.u-h-22{height:22px}
.u-h-28{height:28px}
.u-h-30{height:30px}
.u-h-8{height:8px}
.u-h-9{height:9px}
.u-h-auto{height:auto}
.u-minh-14{min-height:14px}
.u-maxh-80vh{max-height:80vh}
.u-maxh-90vh{max-height:90vh}
.u-abs{position:absolute}
.u-fixed{position:fixed}
.u-rel{position:relative}
.u-top--4{top:-4px}
.u-top-12{top:12px}
.u-top-50p{top:50%}
.u-right-14{right:14px}
.u-right-9{right:9px}
.u-inset0{inset:0}
.u-z-modal3{z-index:calc(var(--z-modal) + 3)}
.u-tf-translatex-50p{transform:translateX(-50%)}
.u-tf-translatey-50p{transform:translateY(-50%)}
.u-oh{overflow:hidden}
.u-ox{overflow-x:auto}
.u-oy{overflow-y:auto}
.u-help{cursor:help}
.u-noallow{cursor:not-allowed}
.u-pointer{cursor:pointer}
.u-norz{resize:none}
.u-rzv{resize:vertical}
.u-tr-all-_15s{transition:all .15s}
.u-tr-all-_2s{transition:all .2s}
.u-tr-background-_15s{transition:background .15s}
.u-tr-background-_1s{transition:background .1s}
.u-tr-border-color-_15s{transition:border-color .15s}
.u-tr-transform-_2s{transition:transform .2s}
.u-bbox{box-sizing:border-box}
.u-pe0{pointer-events:none}
.u-us-none{user-select:none}
.u-bf-blur8{backdrop-filter:blur(8px)}
.u-wbf-blur8{-webkit-backdrop-filter:blur(8px)}

