/*
 * dh.css — the Data Halo design system: tokens + components for the rail world.
 * Born 2026-07-21 from the Server Console rail sitting (mockups/server-console-rail.html);
 * grew the feed shape + the rule-of-two generalizations at the Activity rail sitting the same
 * day (mockups/activity-rail.md is that decision index). Generalized so far: dh-card (the
 * surface card), dh-filter (the toolbar filter input), dh-seg (segmented control). Judged and
 * deliberately NOT generalized: the two toolbars (console's is an in-card bezel strip, the
 * feed's is a standalone instrument card — different species); category chips vs role chip
 * (filter button vs status label); theme-seg's merge into dh-seg waits for its next touch.
 * No Bootstrap, no Font Awesome, no icon fonts: native elements + inline SVG + these tokens
 * (the 2026-07-20 rulings). Light + dark via prefers-color-scheme with data-theme override.
 */
:root {
    --ground: #eef0f3;
    --surface: #ffffff;
    /* surface-2 is THE INPUT WELL (RULED Mark 2026-08-13, from the justify-input specimen):
       every text-entry control must visibly differ from what it sits on. Card-dwellers wear
       surface-2; rail-dwellers (rail-filter, rail-search) and inputs inside surface-2 zones
       (builder-row) wear surface — the point is the DIFFERENCE, not the token. An input that
       matches its background is a bug. */
    --surface-2: #f5f6f8;
    --line: #d8dce3;
    --line-soft: #e4e7ec;
    --ink: #1c2430;
    --ink-2: #4a5568;
    /* ink-3 darkened #7b8494 → #636e7f (the specimen-board sitting, 2026-08-13): the whisper
       register measured 3.3–3.8 against every Light background — under the 4.5 normal-text bar
       on text that is almost always 11–13px. This value clears 4.5 on ground/surface/surface-2
       (4.52/5.16/4.77); btn-fill at 4.15 carries only verb-btn ICONS (a 3.0-bar shape). */
    --ink-3: #636e7f;
    /* accent = THE BRAND BLUE in Light (Mark, 2026-08-13, the specimen-board sitting's close:
       "the primary button color could be a bit more saturated"). The old #2d4d75 grey-navy was
       the last register still off the mark's hue after the day pulled links and btn-fill brand-
       ward. #224193 improves every ratio (white labels 8.64 → 9.35) — saturation AND darkness
       moved together. accent-soft/check-fill washes re-based to the same RGB below. In Light,
       accent and --link now coincide by design; the tokens stay forked (Dark differs, and verbs
       vs links may diverge again). */
    --accent: #224193;
    --accent-ink: #ffffff;
    /* accent-soft α 0.10 → 0.18 in Light (Mark's project-home catch, 2026-08-13, the specimen-board
       sitting): the hover wash on rail doors/links read near-invisible — a 1.17 step off white.
       0.18 composites to 1.34; accent text on the wash (selected chips/segs) still measures 6.4.
       This is the hover AND selected register (55 sites) — strengthen together, never fork them. */
    --accent-soft: rgba(34, 65, 147, 0.18);
    /* the LINK register (Mark's project-home catch, 2026-08-13, the specimen-board sitting):
       accent was doing double duty as control color AND hyperlink color, and the desaturated
       navy read "almost grey — not clear it's a link." Links now wear the BRAND blue
       (--logo-primary's #224193) — unmistakably a hyperlink, and it ties the palette to the
       mark. Controls (buttons, checkboxes, selected states, verbs) stay on --accent; only
       navigation TEXT wears --link. Dark keeps the accent value for now — its own sitting. */
    --link: #224193;
    /* gold/warn darkened #a97a10 → #8c6c00 (the docket ruling + same-day re-saturation): the gold register
       measured 3.3–3.8 as small text (eyebrow, via-tags, Admin chip, decide-seg, fate-swept,
       warm clocks). First cut #8a6410 read "a bit too brown" in emphasis words (Mark's eyeball)
       — #8c6c00 pushes hue 41° → 46° and saturation to 100%: true gold, not brown. Surface 4.93
       passes; ground-dwellers (day dividers, fork light) sit 4.32 — bold uppercase, accepted.
       gold-line stays bright #c9a227 — the jewelry keeps its shine, only the WORDS darkened. */
    --gold: #8c6c00;
    --gold-line: #c9a227;
    --good: #2e7d46;
    --good-soft: rgba(46, 125, 70, 0.12);
    --warn: #8c6c00;
    --warn-soft: rgba(169, 122, 16, 0.14);
    /* bad darkened #a83a32 → #96302a (the docket ruling): danger labels on the strengthened
       btn-fill sat at 4.00 — now 4.82; white-on-red danger-btn improves 6.33 → 7.63. */
    --bad: #96302a;
    --bad-soft: rgba(150, 48, 42, 0.12);
    --mute: #5c6675;
    /* mute-soft α 0.12 → 0.18 (Mark's manifests walk, 2026-08-13): the quiet-pill wash was
       near-invisible on white (1.06) — same faintness accent-soft was cured of this morning,
       and Dark already runs its mute wash at 0.18. All quiet pills inherit together. */
    --mute-soft: rgba(92, 102, 117, 0.18);
    --map-grid: #dfe3e9;
    --map-water: #d4e0e8;
    --shadow: 0 1px 2px rgba(16, 21, 29, 0.06), 0 8px 24px rgba(16, 21, 29, 0.07);
    /* the button-presence cue (Abby's note, 2026-07-29): standalone buttons wear a filled
       ground + this whisper of shadow so they read as PRESSABLE against a white card —
       classic-page muscle memory expects buttons to stand off the background. The quiet
       registers (in-table .row-verb, icon buttons, segs) stay flat by design. */
    /* native controls follow the theme (Mark's checkbox catch, 2026-07-30): without a declared
       color-scheme the browser draws form controls in LIGHT UA style regardless of our tokens —
       an unchecked checkbox is a glaring white square on a dark room (accent-color only tints the
       CHECKED state). Declared per theme block, exactly parallel to the tokens, so checkboxes,
       radios, selects, scrollbars, and file inputs all render dark-appropriate in Dark. */
    color-scheme: light;
    /* button presence (2026-07-29 register, STRENGTHENED 2026-07-30 — Mark: surface-2 on a white
       card is barely a step in Light; STRENGTHENED AGAIN 2026-08-13 at the specimen-board sitting —
       Mark: #e2e7ee "does not pop enough to indicate buttons." #c7d1de moves fill-vs-card from
       1.24 to 1.54; ink-2 labels hold 4.87, ink-3 icons 3.34 — above their bars. Third time this
       register needed more presence: resist the instinct to quiet it back down.
       Re-hued same day (Mark: "could lean blue-er"): #cad1e5 is the BRAND blue #224193 at a 24%
       tint — identical weight (pop 1.53), every text ratio a hair better, but the hue now ties
       to the mark like the --link register does. Weight and hue are separate dials here.
       De-greyed further same day (Mark's walk: "could become less grey"): a pure tint desaturates
       as it lightens, so #c2cdee bends toward the blue at HELD luminance — sat 34% → 56%, pop
       1.58, labels 4.75 / icons 3.26 / danger 4.00 all hold. Next stop if wanted: #bec9f0 (62%),
       which costs the danger label (3.86) and starts reading periwinkle. */
    --btn-fill: #c2cdee;
    /* btn-ink — the verb-button LABEL ink (Mark, same walk: "the button text can also be less
       grey, moving in the direction of our link text"). 70% brand / 30% ink-2: unmistakably
       blue, but a step short of full brand so secondary verbs don't impersonate the primary
       (which speaks white-on-brand). 5.62 on btn-fill, 8.89 on surface. Dark = its ink-2
       value, zero dark change. Further stops if wanted: #28448d (85%), #224193 (full). */
    --btn-ink: #2e4786;
    /* btn-hover — hover DEEPENS, never lightens (the inversion fix, Mark's docket ruling
       2026-08-13): accent-soft is lighter than the strengthened btn-fill, so filled buttons
       faded on hover. Derived, not hardcoded — follows accent and btn-fill per theme.
       Only for controls RESTING on btn-fill; ground-dwellers keep accent-soft (it darkens them). */
    --btn-hover: color-mix(in srgb, var(--accent) 14%, var(--btn-fill));
    --check-fill: rgba(34, 65, 147, 0.20);
    /* check-line is THE CONTROL-OUTLINE TOKEN (RULED Mark 2026-08-13, the specimen-board
       sitting, generalized from the Tie Ins catch): every INTERACTIVE control — inputs,
       selects, textareas, verb/ghost/chip buttons, segs, filter chips, dropdown summaries —
       wears this border. --line is for SURFACES ONLY: cards, dialogs, popovers, tables,
       notes, readonly displays. Dashed borders are their own register (the not-yet-born).
       New controls take --check-line; if a control ships on --line, that is a bug. */
    --check-line: #b3c0d2;
    --btn-shadow: 0 1px 3px rgba(16, 21, 29, 0.14);
    --radius: 10px;
    /* the category hue ramp (Activity rail sitting, 2026-07-21): identity colors for receipt
       category dots. Small marks need higher chroma than text tokens, so these do NOT alias
       --good/--gold (ruled at the sitting — the aliases pulled import/qc to text saturation).
       cron has no fill of its own: it renders HOLLOW (see .dot.cat-cron) — machine time wears
       an outline, no human hand, no fill. */
    --cat-import: #2e8b4f;
    --cat-export: #2f6fc4;
    --cat-read: #8a8f9c;
    --cat-edit: #8046c8;
    --cat-qc: #cfa004;
    --cat-admin: #cc5a14;
    --cat-auth: #c23b7e;
    --cat-cron: #5c6675;
    --cat-system: #a1242e;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      color-scheme: dark;
      --ground: #10151d;
      --surface: #1a2230;
      --surface-2: #202a3a;
      --btn-fill: #263349;
      --btn-ink: #aab4c4;
      --check-fill: rgba(111, 154, 208, 0.26);
      --check-line: #44546f;
      --line: #2c3749;
      --line-soft: #242e3f;
      --ink: #e8ecf2;
      --ink-2: #aab4c4;
      /* dark whisper/mute/accent/bad lifted (the Dark docket, Mark 2026-08-13 — mirrors the
         Light day: whispers 4.13→5.36 on surface, mute chips 2.84→5.19, links/accent-as-text
         3.74→4.96 on surface-2, danger labels 3.73→4.33 on btn-fill). Washes deliberately KEEP
         the old darker RGB: in Dark, a wash re-based to a lighter parent lightens the chip's
         ground and eats the text gain — measured, not guessed. */
      --ink-3: #8b96ab;
      --accent: #6f9ad0;
      --accent-ink: #0e141d;
      --accent-soft: rgba(91, 132, 184, 0.14);
      --link: #6f9ad0;
      --gold: #c9a227;
      --gold-line: #c9a227;
      --good: #43a860;
      --good-soft: rgba(67, 168, 96, 0.16);
      --warn: #d9a521;
      --warn-soft: rgba(217, 165, 33, 0.15);
      --bad: #e07a6a;
      --bad-soft: rgba(217, 106, 91, 0.16);
      --mute: #8894a5;
      --mute-soft: rgba(107, 118, 134, 0.18);
      --map-grid: #232d3d;
      --map-water: #1c2836;
      --shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 30px rgba(0, 0, 0, 0.35);
      --cat-import: #4cbf72;
      --cat-export: #6aa4e8;
      --cat-read: #7e8aa0;
      --cat-edit: #ab8ae0;
      --cat-qc: #e2b626;
      --cat-admin: #e07b2e;
      --cat-auth: #e070ac;
      --cat-cron: #8b96a8;
      --cat-system: #d96a5b;
    }
  }
  :root[data-theme="light"] {
    color-scheme: light;
    --ground: #eef0f3; --surface: #ffffff; --surface-2: #f5f6f8; --btn-fill: #c2cdee; --btn-ink: #2e4786;
    --check-fill: rgba(34, 65, 147, 0.20); --check-line: #b3c0d2;
    --line: #d8dce3; --line-soft: #e4e7ec;
    --ink: #1c2430; --ink-2: #4a5568; --ink-3: #636e7f;
    --accent: #224193; --accent-ink: #ffffff; --accent-soft: rgba(34,65,147,0.18); --link: #224193;
    --gold: #8c6c00; --gold-line: #c9a227;
    --good: #2e7d46; --good-soft: rgba(46,125,70,0.12);
    --warn: #8c6c00; --warn-soft: rgba(169,122,16,0.14);
    --bad: #96302a; --bad-soft: rgba(150,48,42,0.12);
    --mute: #5c6675; --mute-soft: rgba(92,102,117,0.18);
    --map-grid: #dfe3e9; --map-water: #d4e0e8;
    --shadow: 0 1px 2px rgba(16,21,29,0.06), 0 8px 24px rgba(16,21,29,0.07);
    --cat-import: #2e8b4f; --cat-export: #2f6fc4; --cat-read: #8a8f9c; --cat-edit: #8046c8;
    --cat-qc: #cfa004; --cat-admin: #cc5a14; --cat-auth: #c23b7e; --cat-cron: #5c6675; --cat-system: #a1242e;
  }
  :root[data-theme="dark"] {
    color-scheme: dark;
    --ground: #10151d; --surface: #1a2230; --surface-2: #202a3a; --btn-fill: #263349; --btn-ink: #aab4c4;
    --check-fill: rgba(111, 154, 208, 0.26); --check-line: #44546f;
    --line: #2c3749; --line-soft: #242e3f;
    --ink: #e8ecf2; --ink-2: #aab4c4; --ink-3: #8b96ab;
    --accent: #6f9ad0; --accent-ink: #0e141d; --accent-soft: rgba(91,132,184,0.14); --link: #6f9ad0;
    --gold: #c9a227; --gold-line: #c9a227;
    --good: #43a860; --good-soft: rgba(67,168,96,0.16);
    --warn: #d9a521; --warn-soft: rgba(217,165,33,0.15);
    --bad: #e07a6a; --bad-soft: rgba(217,106,91,0.16);
    --mute: #8894a5; --mute-soft: rgba(107,118,134,0.18);
    --map-grid: #232d3d; --map-water: #1c2836;
    --shadow: 0 1px 2px rgba(0,0,0,0.35), 0 10px 30px rgba(0,0,0,0.35);
    --cat-import: #4cbf72; --cat-export: #6aa4e8; --cat-read: #7e8aa0; --cat-edit: #ab8ae0;
    --cat-qc: #e2b626; --cat-admin: #e07b2e; --cat-auth: #e070ac; --cat-cron: #8b96a8; --cat-system: #d96a5b;
  }

  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }
  body {
    background: var(--ground);
    color: var(--ink);
    font-family: 'Ubuntu', 'Segoe UI', system-ui, sans-serif;
    font-size: 15px;
    line-height: 1.5;
  }
  .mono { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-variant-numeric: tabular-nums; }
  /* screen-reader-only (2026-08-24, the point-room sitting): the point-search combobox's live
     status <p> wears Bootstrap's .visually-hidden name, but only the classic world defines it —
     in the token worlds (rail mount, frame mount) the "N matching points" line rendered as
     visible text. One house rule, same contract as Bootstrap's. */
  .visually-hidden {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
  }
  a { color: var(--link); }
  a:focus-visible, button:focus-visible { outline: 2px solid var(--gold-line); outline-offset: 2px; }

  /* the house placeholder (Mark, 2026-07-30, the chiefs sitting): the UA's dead-neutral gray
     jumps out as not-our-theme — placeholders are hints, so they speak the hint register's
     blue-cast gray. opacity:1 beats Firefox's default ~54% fade (illegible in one browser,
     fine in another, is exactly the kind of drift this file exists to end). */
  ::placeholder { color: var(--ink-3); opacity: 1; }

  /* the house scrollbar (Mark, 2026-07-30, same sitting): the standard scrollbar-color property,
     thumb on the blue-cast control-line token — the blue-cast principle again ("because the cast
     of our UI is blue, totally unsaturated grays leap out"). Inherited from :root on purpose —
     the page bar, the rail, textareas, and table overflows all wear it; browsers without the
     property (pre-121 Chrome) keep the color-scheme-appropriate UA bar, a graceful floor.
     scrollbar-width stays default on the document (a thin main bar annoys) and thins only the
     small internals where the fat bar eats real estate. */
  :root { scrollbar-color: var(--check-line) transparent; }
  .rail, .roster-ta { scrollbar-width: thin; }

  /* the house checkbox (Mark, 2026-07-30, the validation sitting's tail): color-scheme stopped the
     white-square blast, but a UA-drawn box is colorless — it ties to nothing. appearance:none makes
     BOTH states ours: unchecked wears the accent-soft wash (the house blue leaning, quiet at
     47-rows scale), checked fills accent with a drawn check. One recipe for every rail checkbox —
     the per-room classes (.sel-box/.feat-check/.col-check/.att-row) keep only their sizes; their
     accent-color declarations stay as inert fallback. Locked columns keep their mute variant. */
  input[type="checkbox"] {
    appearance: none; -webkit-appearance: none;
    width: 15px; height: 15px; flex: none;
    border: 1px solid var(--check-line); border-radius: 4px;
    background: var(--check-fill);
    cursor: pointer; margin: 0; position: relative; vertical-align: -2px;
  }
  input[type="checkbox"]:hover { border-color: var(--accent); }
  /* locked = visibly untouchable (Mark's catch, 2026-08-15+1, Attributed Joints boundary rows):
     the label's muting alone left the BOX looking clickable — the box itself mutes and the cursor
     says so, the same .55/not-allowed pair .primary-btn:disabled already wears */
  input[type="checkbox"]:disabled { opacity: 0.55; cursor: not-allowed; }
  input[type="checkbox"]:disabled:hover { border-color: var(--check-line); }
  input[type="checkbox"]:focus-visible { outline: 2px solid var(--gold-line); outline-offset: 2px; }
  input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
  input[type="checkbox"]:checked::after {
    content: ""; position: absolute; inset: 0;
    background: var(--accent-ink);
    -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><path d="M2.6 6.4 5 8.8l4.4-5.4" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>') center / 11px 11px no-repeat;
    mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><path d="M2.6 6.4 5 8.8l4.4-5.4" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>') center / 11px 11px no-repeat;
  }
  .col-check.locked input[type="checkbox"] { cursor: default; }
  .col-check.locked input[type="checkbox"]:checked { background: var(--mute); border-color: var(--mute); }

  /* the house radio (Mark's walk catch, 2026-08-07, the transfer rotation): the checkbox's sibling —
     a UA-drawn radio is the same colorless grey the checkbox recipe cured, so both states go ours on
     the same tokens: unchecked wears the accent-soft wash and blue-leaning line, checked fills accent
     with a punched dot. Bare by the checkbox's own "one recipe" reasoning. */
  input[type="radio"] {
    appearance: none; -webkit-appearance: none;
    width: 15px; height: 15px; flex: none;
    border: 1px solid var(--check-line); border-radius: 50%;
    background: var(--check-fill);
    cursor: pointer; margin: 0; vertical-align: -2px;
  }
  input[type="radio"]:hover { border-color: var(--accent); }
  input[type="radio"]:focus-visible { outline: 2px solid var(--gold-line); outline-offset: 2px; }
  input[type="radio"]:checked {
    background: var(--accent); border-color: var(--accent);
    box-shadow: inset 0 0 0 3px var(--surface);
  }

  .shell { display: flex; max-width: 1500px; margin: 0 auto; align-items: stretch; }
  .wrap { flex: 1; min-width: 0; max-width: 1240px; margin: 0 auto; padding: 0 24px 64px; }

  /* ---------- left rail (xhalo #32 — one rail, one base) ---------- */
  .rail {
    width: 244px; flex: none;
    border-right: 1px solid var(--line);
    padding: 16px 12px 20px;
    display: flex; flex-direction: column; gap: 2px;
    font-size: 13.5px;
    position: sticky; top: 0; max-height: 100vh; overflow-y: auto;
    /* min-height keeps the user chip glued to the viewport bottom even when the page content is
       short — the mockup's notes section masked this (its pages were always taller than 100vh) */
    min-height: 100vh;
  }
  /* ---------- mobile: the rail becomes the hamburger drawer (the ruled answer, 2026-07-20) ---------- */
  .menu-btn {
    display: none; background: none; border: 1px solid var(--check-line); border-radius: 8px;
    color: var(--btn-ink); padding: 5px 11px; cursor: pointer; font-size: 17px; line-height: 1.2;
    font-family: inherit; flex: none;
  }
  .drawer-backdrop {
    position: fixed; inset: 0; z-index: 79; background: rgba(8, 12, 18, 0.5);
    opacity: 0; pointer-events: none; transition: opacity 200ms ease;
  }
  @media (max-width: 1000px) {
    .rail {
      position: fixed; top: 0; left: 0; bottom: 0; z-index: 80;
      background: var(--ground); max-height: none;
      transform: translateX(-105%); transition: transform 200ms ease;
    }
    .rail.open { transform: none; box-shadow: var(--shadow); }
    .rail .rail-collapse { display: none; }  /* the drawer is always full-width; collapse is a desktop idea */
    .menu-btn { display: inline-flex; }
    .drawer-backdrop.show { opacity: 1; pointer-events: auto; }
  }
  @media (prefers-reduced-motion: reduce) { .rail { transition: none; } }
  .rail-top { display: flex; align-items: center; gap: 4px; padding: 2px 4px 12px 8px; }
  /* the logo — the real mark, tokenized: blue path rides --logo-primary so dark mode can lift it;
     the gold is the brand's own #d9ab28 and holds in both modes (it IS the house gold) */
  :root { --logo-primary: #224193; --logo-gold: #d9ab28; }
  @media (prefers-color-scheme: dark) { :root { --logo-primary: #e8ecf2; } }
  :root[data-theme="light"] { --logo-primary: #224193; }
  :root[data-theme="dark"] { --logo-primary: #e8ecf2; }
  .rail .wordmark { flex: 1; min-width: 0; display: flex; align-items: center; }
  .rail .wordmark a { display: block; line-height: 0; }

  /* the logo's All Projects caption (interior rail only, 2026-08-25+1) — the wordmark absorbed the
     standalone All Projects row: the caption labels what a click on the logo means. Own line-height
     because the anchor zeroes it for the svg lockup; hides with the lockup when collapsed. */
  .logo-caption { display: block; line-height: 1.2; font-size: 10.5px; color: var(--ink-3); margin-top: 3px; letter-spacing: .02em; }
  .rail .wordmark a:hover .logo-caption { color: var(--ink-2); }
  .logo-lockup { width: 108px; height: auto; display: block; }
  .logo-lockup .lg-a { fill: var(--logo-primary); }
  .logo-lockup .lg-b { fill: var(--logo-gold); }
  .logo-mark { width: 32px; height: 32px; display: none; border-radius: 6px; }
  .rail-collapse {
    background: none; border: none; border-radius: 6px; cursor: pointer;
    color: var(--ink-3); font-size: 14px; padding: 3px 5px; font-family: inherit; flex: none;
    display: inline-flex; align-items: center;
  }
  .rail-collapse:hover { background: var(--accent-soft); color: var(--ink); }

  /* collapsed rail — door icons only (desktop-only idea; the mobile drawer is always full) */
  @media (min-width: 1001px) {
    .rail.collapsed { width: 60px; padding: 16px 9px 20px; }
    .rail.collapsed .rail-top { flex-direction: column; gap: 10px; padding: 2px 0 8px; align-items: center; }
    .rail.collapsed .wm-text, .rail.collapsed .rail-filter, .rail.collapsed .rail-head,
    .rail.collapsed .rail-proj, .rail.collapsed .rail-link .lbl, .rail.collapsed .rail-link .whisper,
    .rail.collapsed .user-chip .uname, .rail.collapsed .user-chip .caret,
    .rail.collapsed .rail-new .lbl { display: none; }
    .rail.collapsed .rail-pin-hint { display: none; }
    .rail.collapsed .logo-caption { display: none; }
    .rail.collapsed .rail-link { justify-content: center; padding: 8px 0; }
    .rail.collapsed .rail-new { padding: 8px 0; margin: 10px 2px 2px; }
    .rail.collapsed .user-chip { border: none; background: none; padding: 4px; justify-content: center; }
    .rail.collapsed .logo-lockup { display: none; }
    .rail.collapsed .logo-mark { display: block; margin: 0 auto; }
  }
  .rail-link {
    display: flex; align-items: center; gap: 9px;
    padding: 6px 10px; border-radius: 7px;
    color: var(--ink-2); text-decoration: none;
  }
  .rail-link:hover { background: var(--accent-soft); color: var(--ink); }
  .rail-link .ico { width: 16px; text-align: center; color: var(--ink-3); flex: none; }
  .rail-link .whisper { margin-left: auto; font-size: 11px; color: var(--ink-3); }
  .rail-link.active {
    background: var(--accent-soft); color: var(--ink); font-weight: 500;
    box-shadow: inset 2.5px 0 0 var(--accent);
  }
  .rail-head {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 14px 10px 4px;
  }
  .rail-filter {
    margin: 10px 6px 4px;
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface); color: var(--ink-3);
    padding: 6px 10px; font-size: 12.5px; font-family: inherit;
  }
  .rail-new {
    margin: 10px 6px 2px; padding: 8px 10px;
    border: none; border-radius: 8px;
    background: var(--accent); color: var(--accent-ink); font-family: inherit;
    font-size: 13px; font-weight: 600; cursor: pointer;
    display: flex; align-items: center; justify-content: center; gap: 7px;
    box-shadow: var(--shadow);
  }
  .rail-new:hover { filter: brightness(1.1); }
  .rail-proj {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 10px; border-radius: 7px;
    color: var(--ink-2); text-decoration: none;
    white-space: nowrap; overflow: hidden;
  }
  .rail-proj:hover { background: var(--accent-soft); color: var(--ink); }
  .rail-proj .t { overflow: hidden; text-overflow: ellipsis; }
  .rail-proj .pin { color: var(--gold); flex: none; font-size: 11px; }
  .rail-proj .whisper { margin-left: auto; font-size: 11px; color: var(--ink-3); flex: none; }

  /* the interior rail's zero-pins whisper (the Pinned shortlist, 2026-08-25) — teaches the
     affordance without claiming a place; hidden with the rest of the row text when collapsed */
  .rail-pin-hint { padding: 3px 10px 6px; font-size: 11px; color: var(--ink-3); line-height: 1.35; }

  /* ---- the INTERIOR rail (the Focus contract — transitions canary, RULED 2026-07-22):
     inside a project the portfolio collapses to the ◂ All Projects standing door and the rail
     becomes the project's — identity block, Project Home, door groups (the dashboard's ratified
     intent groups; current group open, current room active). Room doors carry no icons by
     ruling (25+ rooms would demand a glyph junk drawer); the group heads carry the taxonomy. */
  /* the identity-door (v81, Mark's merge ruling 2026-08-12 — variant B of
     mockups/rail-home-merge.html, superseding the same day's v80 promoted row pre-deploy):
     the title card IS the way home — project title + home glyph + button dress in ONE element.
     Replaces .proj-ident (inert identity) + the promoted Project Home row; the gesture is the
     Home-tile / Server-Console one: click the project's name, land on its front page. */
  .ident-door {
    display: flex; align-items: flex-start; gap: 8px;
    text-decoration: none;
    margin: 8px 0 6px; padding: 10px 12px;
    /* the button dress COMPLETED (Mark, 2026-08-13, the specimen-board sitting): v81 ruled the
       title card IS the way home — "button dress in ONE element" — but it shipped on surface
       white with a hairline. Now it wears the full verb register: brand-tinted btn-fill,
       the control outline (today's ruling), the button shadow. The .pa alias rides ink-2,
       not ink-3 — the whisper measured 3.38 on the tinted fill. */
    border: 1px solid var(--check-line); border-radius: 9px;
    background: var(--btn-fill);
    box-shadow: var(--btn-shadow);
  }
  .ident-door .ico { color: var(--accent); flex: none; margin-top: 2px; width: 16px; text-align: center; }
  .ident-door:hover { border-color: var(--accent); background: var(--btn-hover); }
  .ident-door.active { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 2.5px 0 0 var(--accent); }
  .ident-door .id-text { min-width: 0; display: block; }
  /* overflow-wrap:anywhere is the fence behind the wbr_underscores filter (2026-08-26): the filter
     marks break points after underscores (Jason's long underscored titles), and anywhere only fires
     for a fragment that STILL cannot fit — an unbroken no-underscore title never escapes the card */
  .ident-door .pt { display: block; color: var(--ink); font-weight: 600; font-size: 14px; line-height: 1.3; overflow-wrap: anywhere; }
  .ident-door .pt .pin { color: var(--gold); font-size: 11px; margin-left: 5px; }
  .ident-door .pa { display: block; font-size: 11px; color: var(--ink-2); margin-top: 2px; }
  @media (min-width: 1001px) {
    .rail.collapsed .ident-door { justify-content: center; padding: 8px 0; margin: 8px 0 4px; }
    .rail.collapsed .ident-door .id-text { display: none; }
    .rail.collapsed .ident-door .ico { margin-top: 0; }
  }
  details.rail-group > summary {
    list-style: none; cursor: pointer;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 10px 10px 4px;
    display: flex; align-items: center; gap: 6px;
  }
  details.rail-group > summary::-webkit-details-marker { display: none; }
  details.rail-group > summary::before {
    content: "▸"; font-size: 9px; transition: transform 150ms ease; color: var(--ink-3);
  }
  details.rail-group[open] > summary::before { transform: rotate(90deg); }
  .rail-door {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 10px 4px 26px; border-radius: 7px;
    /* brightened from plain ink-2 (Abby's second ask, 2026-08-13 — the rail's popped-open door
       text read dim at 13px): rest sits partway up toward ink (9.3/11.5 measured vs ink-2's
       6.6/8.8) while hover/active keep full ink, so the lift register survives */
    color: color-mix(in srgb, var(--ink) 45%, var(--ink-2)); text-decoration: none; font-size: 13px;
    white-space: nowrap; overflow: hidden;
  }
  .rail-door:hover { background: var(--accent-soft); color: var(--ink); }
  /* the inset bar joins the interior doors (Mark's catch, 2026-08-13): rail-link.active and
     ident-door.active carried it from the mockups, but the room doors — the rail you actually
     live in — never received it. The bar is the "you are here" eyebrow on every active register. */
  .rail-door.active { background: var(--accent-soft); color: var(--ink); font-weight: 500; box-shadow: inset 2.5px 0 0 var(--accent); }
  .rail-door .step {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-size: 10.5px;
    color: var(--ink-3); flex: none;
  }
  /* the return glyph on a lit door whose current page is a CHILD (Mark+Abby, 2026-07-30):
     lit reads "you are here" by web convention — the glyph says "this door returns you" */
  .rail-door .ret { flex: none; color: var(--ink-3); }
  .rail-door.active:hover .ret { color: var(--accent); }
  /* per-door bust badges on the QC Workflow doors (Jason's request, 2026-08-13): the scorecard's
     v-busts register at rail size — priority visible from inside any room. A door with no badge
     is merely quiet, never a "clean" claim (posture lives on the tile/scorecard). Mono per the
     de-mono rule's carve-out: aligned digits, not a name. */
  .rail-door .busts {
    margin-left: auto; flex: none;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-size: 10.5px; font-weight: 700; line-height: 1.7;
    background: var(--warn-soft); color: var(--warn);
    border-radius: 999px; padding: 0 7px;
  }
  /* the line fork (Mark's ruling 2026-08-08, kin-pair sitting): a one-Line-ID-at-a-time door
     forks per-line on multi-line projects — the door name TOGGLES the fold (classic's
     dropdown-button behavior, walk-confirmed); rotating ▸ per the caret convention (folds
     reveal in place; row-menus float and wear ▾). Single-line projects render plain doors. */
  .rail-fork summary { list-style: none; cursor: pointer; user-select: none; }
  .rail-fork summary::-webkit-details-marker { display: none; }
  .rail-fork summary::after {
    content: "▸"; margin-left: auto; font-size: 9px; color: var(--ink-3);
    transition: transform 120ms ease;
  }
  .rail-fork[open] summary::after { transform: rotate(90deg); }
  /* line names wear the body face, never mono (the de-mono rule — DXF walk 2026-07-28:
     names never wear mono, only aligned digits; the mockup's mono children were a dated artifact) */
  .rail-line {
    display: block; padding: 3px 10px 3px 40px; border-radius: 7px;
    /* one register up from ink-3 (Abby's brightening, 2026-08-13) — still a step dimmer than
       the doors above, so the parent/child ladder holds */
    color: var(--ink-2); text-decoration: none; font-size: 12px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .rail-line:hover { background: var(--accent-soft); color: var(--ink); }
  /* the viewed line lights up in its fork (Mark's catch 2026-08-11) — same register as .rail-door.active */
  /* the viewed line wears GOLD (RULED Mark 2026-08-12, same day as the production trial:
     "it ties in to the Line ID selector in an intuitive way" — the fork light and the room's
     gold decide-seg are the same decide-grain fact, and now they match) */
  .rail-line.active { background: var(--warn-soft); color: var(--gold); font-weight: 700; box-shadow: inset 2.5px 0 0 var(--gold-line); }
  @media (prefers-reduced-motion: reduce) { .rail-fork summary::after { transition: none; } }
  .rail.collapsed .rail-group { display: none; }
  /* the rail-borne classic retreat (Mark's retreat-watch, 2026-08-13): .retreat-link's whisper
     dress, seated under the identity door — an escape hatch, not a door. TEMPORARY: dies with
     the retreat instrument at classic's shed date. */
  .rail-retreat { margin: 0 10px 4px; font-size: 11.5px; align-self: flex-start; }
  .rail.collapsed .rail-retreat { display: none; }

  .user-chip {
    margin-top: auto; display: flex; align-items: center; gap: 9px;
    padding: 8px 10px; border: 1px solid var(--check-line); border-radius: 9px;
    background: var(--surface); cursor: pointer; font-family: inherit;
    font-size: 13px; color: var(--ink-2); text-align: left;
  }
  .user-chip:hover { border-color: var(--accent); }
  .user-chip .caret { margin-left: auto; color: var(--ink-3); font-size: 11px; }
  .user-chip .avatar {
    width: 26px; height: 26px; border-radius: 50%; flex: none;
    background: var(--accent-soft); color: var(--accent);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 700;
  }

  /* ---------- user menu — native Popover API (the no-Bootstrap dropdown).
     left/bottom here are the no-JS fallback only — dh.js re-anchors to the chip on open,
     because the centered .shell drifts off viewport-left on monitors wider than 1500px. ---------- */
  .user-menu {
    position: fixed; left: 14px; bottom: 66px; margin: 0; inset-inline-end: auto; inset-block-start: auto;
    width: 228px; padding: 6px;
    background: var(--surface); color: var(--ink-2);
    border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow);
    font-size: 13px; font-family: inherit;
  }
  .um-head { padding: 8px 10px 2px; }
  .um-head b { color: var(--ink); font-weight: 600; display: block; }
  .um-head .mono { font-size: 11.5px; color: var(--ink-3); }
  .um-group {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--ink-3); padding: 10px 10px 3px;
  }
  .um-item {
    display: flex; gap: 9px; align-items: center;
    padding: 6px 10px; border-radius: 6px;
    color: var(--ink-2); text-decoration: none; cursor: pointer;
    background: none; border: none; width: 100%; text-align: left; font: inherit;
  }
  .um-item:hover { background: var(--accent-soft); color: var(--ink); }
  .um-item .ico { width: 15px; text-align: center; color: var(--ink-3); flex: none; display: inline-flex; justify-content: center; align-items: center; }
  .um-item .ico svg { display: block; }
  .um-sep { border-top: 1px solid var(--line-soft); margin: 6px 4px; }
  .theme-seg { display: flex; padding: 2px 10px 8px; }
  .theme-seg button {
    flex: 1; font-size: 11.5px; padding: 4px 0; cursor: pointer; font-family: inherit;
    border: 1px solid var(--check-line); background: none; color: var(--ink-2); margin-left: -1px;
  }
  .theme-seg button:first-child { border-radius: 6px 0 0 6px; margin-left: 0; }
  .theme-seg button:last-child { border-radius: 0 6px 6px 0; }
  .theme-seg button.on { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); position: relative; z-index: 1; }

  /* ---------- page header ---------- */
  .proj-head { padding: 24px 0 20px; border-bottom: 1px solid var(--line); margin-bottom: 22px; }
  /* the child-room back link — tip-top of the head, the in-page twin of the rail door's
     ic-return (born room-scoped as .ce-back at the Code Editor rotation; Mark saw it at the
     build walk — "It's great" — and ruled the house-wide spread same day, 2026-08-21: every
     room whose rail door wears ic-return wears this too). It survives where the rail doesn't
     travel — phones, collapsed rails. */
  .room-back { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
    color: var(--ink-3); text-decoration: none; margin-bottom: 4px; }
  .room-back:hover { color: var(--accent); }
  .room-back svg { width: 11px; height: 11px; }
  .proj-head .title-row { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
  h1 {
    margin: 0; font-size: 30px; font-weight: 700; letter-spacing: -0.01em;
    text-wrap: balance;
  }
  .server-whisper { margin-left: auto; font-size: 13px; color: var(--ink-3); }
  .head-sub { font-size: 13.5px; color: var(--ink-2); margin-top: 5px; }
  .head-sub .mono { color: var(--ink); font-weight: 500; }

  .eyebrow {
    font-size: 11px; font-weight: 700; letter-spacing: 0.11em;
    color: var(--gold); text-transform: uppercase;
  }

  /* ---------- dh-card: the surface card (rule-of-two name, generalized from console-card
     at the Activity re-base). Doctrine: cards contain instruments and excerpts; rivers run
     on the ground (Activity sitting, ninth pass). ---------- */
  .dh-card {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow);
  }
  /* THE BARE DEFAULT (flip-the-default ruling, Mark 2026-08-07 — after the FOURTH naked-head
     catch: roles → geopackage → calendar → File Meta, the last post-deploy). The old convention
     ("no bare .card-head; every room scopes its own") produced a dozen copy-pasted, verbatim-
     identical scoped rules AND a silent bug class with no grep shape — a card whose CSS forgot
     its copy shipped a raw-text head only an eye could catch. The default IS that convergent
     dress; a room now scopes a rule only where it truly DIVERGES (feet had already breached the
     convention by accident — two duplicate bare .card-foot rules, consolidated here). */
  .card-head {
    padding: 14px 20px 0;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3);
    display: flex; align-items: center; gap: 8px;
  }
  .card-foot { margin-top: 14px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .card-foot .foot-hint, .card-foot .hint { font-size: 12px; color: var(--ink-3); }
  /* the card head's right seat — GENERALIZED 2026-08-14 (the XLSX room was the FOURTH specimen;
     the pg-card copy carried the "generalization candidate at its next touch" flag — paid here,
     the three scoped copies below retired). Body = the fullest (table-card's) variant. */
  .card-head .hd-right {
    margin-left: auto; text-transform: none; letter-spacing: 0; font-weight: 400;
    font-size: 12px; color: var(--ink-3); display: inline-flex; gap: 8px; align-items: center;
  }
  /* dh-filter: the toolbar filter/search input (generalized from the console's .filter) */
  .dh-filter {
    flex: 1; min-width: 180px; max-width: 340px;
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 7px 11px; font-size: 13px; font-family: inherit;
  }
  .dh-filter:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  /* the ×-to-clear (RULED house-wide 2026-08-20, the Codes & Features sitting): dh.js auto-wraps
     every nameless text input.dh-filter at load. The wrap TAKES OVER the input's layout duties
     (the base flex/min/max profile above) so flex toolbars and block containers both keep their
     shape; the input inside just fills it. Rooms that cap .dh-filter differently want a matching
     .dh-filter-wrap cap beside their rule (see .lset-toolbar). [hidden] guard is load-bearing —
     the × is a styled button and would otherwise defeat its own retirement. */
  .dh-filter-wrap { position: relative; display: inline-flex; flex: 1; width: 100%; min-width: 180px; max-width: 340px; }
  .dh-filter-wrap > .dh-filter { flex: 1; width: 100%; min-width: 0; max-width: none; padding-right: 30px; }
  .dh-filter-clear {
    position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
    background: none; border: none; cursor: pointer; color: var(--ink-3);
    font-size: 16px; line-height: 1; padding: 2px 7px; border-radius: 5px; font-family: inherit;
  }
  .dh-filter-clear:hover { color: var(--ink); background: var(--accent-soft); }
  .dh-filter-clear[hidden] { display: none; }
  /* dh-seg: segmented control of links/buttons (second specimen: the Activity outcome filter) */
  .dh-seg { display: inline-flex; border: 1px solid var(--check-line); border-radius: 7px; overflow: hidden; }
  .dh-seg a, .dh-seg button {
    background: none; border: none; border-right: 1px solid var(--line);
    color: var(--ink-2); padding: 6px 13px; font-size: 12.5px; cursor: pointer;
    font-family: inherit; text-decoration: none;
  }
  .dh-seg a:last-child, .dh-seg button:last-child { border-right: 0; }
  .dh-seg .on { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
  /* the AM fence renders as DISABLED options, never absence (roles sitting, 2026-07-22) */
  .dh-seg button:disabled { opacity: 0.55; cursor: not-allowed; }  /* 0.55 not 0.45 (docket ruling 2026-08-13): disabled stays quiet but its label stays readable */
  /* decide-seg: the GOLD decision register (born role-seg at the roles sitting 2026-07-22;
     generalized at the transitions canary the same day — the rule of two, paid). Gold marks
     the seg that SHAPES THE VERB (role to apply, Line ID to walk) — accent read too subtle
     for a room's one decision; gold is the house emphasis register. Filter segs (Activity's
     outcome filter) keep their accent. Consumers: roles editor, transitions. */
  .dh-seg.decide-seg .on { background: var(--warn-soft); color: var(--gold); }
  /* wrap-seg: a seg whose member count is DATA, not a fixed vocabulary — one pill per Line ID.
     Eight named lines overflowed the CSV Builder's Features card at ees (an Encompass user's
     catch, 2026-09-04): a no-wrap inline-flex shrank the pills until their names broke
     mid-word. So this seg wraps as a chip cloud — each pill carries its own border and
     radius, a name never breaks, a second row reads clean. The gold register is unchanged.
     Consumers: every seg built from the project's Line IDs (csv/shp/gpkg builders, the
     begin-end, onjoint and duplicate selectors). Fixed-vocabulary segs never wear it. */
  .dh-seg.wrap-seg { flex-wrap: wrap; gap: 6px; border: 0; border-radius: 0; overflow: visible; }
  .dh-seg.wrap-seg a, .dh-seg.wrap-seg button,
  .dh-seg.wrap-seg a:last-child, .dh-seg.wrap-seg button:last-child {
    border: 1px solid var(--check-line); border-radius: 7px; white-space: nowrap;
  }
  .dh-seg.wrap-seg .on { border-color: var(--gold); }
  /* the role LADDER (Mark, 2026-07-22): identical pills left rank to six characters of small
     text — authority now reads as fill density, not hue (the Activity shape-channel lesson).
     Admin gold-edged (the apex), Manager FILLED (carries power), Contributor outlined (the
     base .role-chip), Viewer muted. Second consumer: the console's My Role column, next touch. */
  .role-chip.r-manager { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
  .role-chip.r-viewer { color: var(--mute); border-color: var(--mute); background: var(--mute-soft); }
  .role-chip.r-admin { color: var(--gold); border-color: var(--gold-line); background: var(--warn-soft); }

  /* ---------- the console's dense table (the fourth base shape) ---------- */
  .console-toolbar {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 13px 18px; border-bottom: 1px solid var(--line-soft);
  }
  .console-toolbar .clock-whisper { margin-left: auto; font-size: 12px; color: var(--ink-3); }

  /* contained grid: the card owns BOTH scroll axes; header and identity column are sticky */
  .table-wrap { position: relative; }
  .table-scroll { overflow: auto; max-height: min(70vh, 640px); border-radius: 0 0 var(--radius) var(--radius); }
  table.console { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
  .console th {
    text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 10px 13px 8px; white-space: nowrap;
    position: sticky; top: 0; z-index: 2; background: var(--surface);
    box-shadow: inset 0 -1px 0 var(--line);
  }
  .console th:first-child { left: 0; z-index: 3; }
  .console td {
    padding: 9px 13px; border-top: 1px solid var(--line-soft);
    vertical-align: top; color: var(--ink-2); white-space: nowrap;
  }
  .console tbody tr:first-child td { border-top: none; }
  .console tbody tr:hover td { background: color-mix(in srgb, var(--accent) 9%, var(--surface)); }
  .console td.proj-cell {
    white-space: normal; min-width: 220px;
    position: sticky; left: 0; z-index: 1; background: var(--surface);
  }
  /* scrolled-state affordances: the pinned column casts a shadow once you've scrolled;
     a fade at the right edge says "there's more" until you reach it */
  .table-scroll.h-scrolled .console th:first-child,
  .table-scroll.h-scrolled .console td.proj-cell { box-shadow: 6px 0 10px -6px rgba(8, 12, 18, 0.4); }
  .table-scroll.h-scrolled .console th:first-child { box-shadow: inset 0 -1px 0 var(--line), 6px 0 10px -6px rgba(8, 12, 18, 0.4); }
  .scroll-fade {
    position: absolute; top: 0; bottom: 0; right: 0; width: 38px;
    background: linear-gradient(to right, transparent, var(--surface));
    pointer-events: none; border-radius: 0 0 var(--radius) 0;
    transition: opacity 150ms ease;
  }

  a.proj-open { color: var(--ink); font-weight: 500; text-decoration: none; }
  a.proj-open:hover { color: var(--link); text-decoration: underline; }
  a.proj-join { color: var(--link); font-weight: 500; text-decoration: none; }
  a.proj-join:hover { text-decoration: underline; }
  .xref-line { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; display: flex; align-items: center; gap: 5px; }
  .xref-line svg { width: 11px; height: 11px; flex: none; color: var(--gold); }

  /* the People cell — three roles folded into one column; absent roles simply absent */
  .ppl-cell { white-space: normal; min-width: 185px; }
  .ppl { font-size: 12.5px; line-height: 1.45; white-space: nowrap; }
  .ppl .ppl-role {
    display: inline-block; min-width: 50px;
    font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em;
    text-transform: uppercase; color: var(--ink-3);
  }

  .role-chip {
    font-size: 10.5px; padding: 0 8px; border-radius: 999px;
    border: 1px solid var(--accent); color: var(--accent);
    background: var(--accent-soft); font-weight: 500;
    margin-left: 8px; vertical-align: 1px; white-space: nowrap;
  }

  .days { font-family: 'Ubuntu Mono', 'Consolas', monospace; font-variant-numeric: tabular-nums; }
  .days.warm { color: var(--warn); font-weight: 500; }
  .days.hot { color: var(--bad); font-weight: 500; }
  .days.none { font-family: inherit; font-style: italic; color: var(--ink-3); }
  .broom { width: 13px; height: 13px; color: var(--warn); vertical-align: -2px; margin-left: 5px; }

  /* the blade note — Auto-Archive dissolved into the activity cell (ruled at the sitting):
     "353 d ago · archives in 12 d" — one clock, its consequence as a subordinate clause */
  .sep-dot { color: var(--ink-3); margin: 0 5px; }
  .blade-note { color: var(--ink-3); font-size: 12px; }
  .blade-note.soon { color: var(--bad); font-weight: 600; }

  /* ---------- archives (companion #3, 2026-07-21): the shelf's verbs + the second clock ---------- */
  /* the restore threshold — a POST button dressed as the console's accent title (same threshold grammar:
     the console's title joins; this one restores) */
  button.proj-restore {
    background: none; border: none; padding: 0; margin: 0;
    font-family: inherit; font-size: inherit; line-height: inherit; text-align: left;
    color: var(--accent); font-weight: 500; cursor: pointer; white-space: normal;
  }
  button.proj-restore:hover { text-decoration: underline; }
  .delete-verb {
    background: none; border: none; font-family: inherit; font-size: 12.5px;
    color: var(--bad); cursor: pointer; padding: 2px 6px; border-radius: 6px;
  }
  .delete-verb:hover { background: var(--bad-soft); }
  /* takeover — a stewardship verb, not a destructive one: accent, one click, reversible */
  .takeover-verb {
    background: none; border: none; font-family: inherit; font-size: 12.5px;
    color: var(--accent); cursor: pointer; padding: 2px 6px; border-radius: 6px;
  }
  .takeover-verb:hover { background: var(--accent-soft); }
  .delete-na { color: var(--ink-3); cursor: help; }
  /* the auto mark — machine time wears an outline, never a fill (the Activity cron ruling's second surface) */
  .auto-mark {
    font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--mute); border: 1px solid var(--mute); border-radius: 999px;
    padding: 0 6px; margin-left: 6px; vertical-align: 1px;
  }
  .arch-none { color: var(--ink-3); cursor: help; }

  .archive-verb {
    background: none; border: none; font-family: inherit; font-size: 12.5px;
    color: var(--bad); cursor: pointer; padding: 2px 6px; border-radius: 6px;
  }
  .archive-verb:hover { background: var(--bad-soft); }

  tr.dissolving { transition: opacity 320ms ease; opacity: 0; }

  /* ---------- media rooms (companions #4+#5, 2026-07-22): the file table's grammar ---------- */
  .toolbar-verbs { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
  .verb-btn {
    background: var(--btn-fill); border: 1px solid var(--check-line); color: var(--btn-ink);
    box-shadow: var(--btn-shadow);
    border-radius: 8px; padding: 6px 12px; font-size: 12.5px; cursor: pointer; font-family: inherit;
    display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
  }
  .verb-btn:hover { border-color: var(--accent); background: var(--btn-hover); color: var(--ink); }
  .verb-btn svg { width: 13px; height: 13px; color: var(--ink-3); }
  .verb-btn:hover svg { color: var(--accent); }
  .verb-btn.danger { color: var(--bad); }
  .verb-btn.danger svg { color: var(--bad); }
  .verb-btn.danger:hover { border-color: var(--bad); background: var(--bad-soft); color: var(--bad); }
  .verb-btn:disabled { opacity: 0.55; cursor: default; }
  .verb-btn:disabled:hover { border-color: var(--line); background: none; color: var(--bad); }
  .door-link { font-size: 12.5px; color: var(--link); text-decoration: none; padding: 6px 4px; }
  .door-link:hover { text-decoration: underline; }

  .fname { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-size: 12.5px; word-break: break-all; }
  a.fname { color: var(--link); text-decoration: none; }
  a.fname:hover { text-decoration: underline; }
  .fname.dead { color: var(--ink-3); cursor: help; }
  .file-whisper { font-size: 11.5px; color: var(--ink-3); margin-top: 1px; }
  .file-whisper .aname { color: var(--ink-2); }
  .file-whisper .orphan { color: var(--warn); }

  .kind { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; }
  .kind svg { width: 13px; height: 13px; color: var(--ink-3); flex: none; }

  /* fate pills — machine policy wears an outline, never a fill (the cron ruling's third surface);
     the swept pill alone carries a fill wash because it is the one that predicts a deletion */
  .fate-kept {
    font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--mute); border: 1px solid var(--mute); border-radius: 999px; padding: 0 8px;
  }
  .fate-swept {
    font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--warn); border: 1px solid var(--warn); border-radius: 999px; padding: 0 8px;
    background: var(--warn-soft);
  }
  .fate-tobin {
    font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--warn); border: 1px solid var(--warn); border-radius: 999px; padding: 0 8px;
  }

  .sel-box { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }

  .accent-btn {
    background: var(--accent); color: var(--accent-ink); border: none;
    border-radius: 8px; padding: 7px 16px; font-size: 13.5px; font-weight: 500;
    cursor: pointer; font-family: inherit;
  }
  .accent-btn:hover { filter: brightness(1.1); }
  .dlg-list { margin: 8px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--ink-3); }
  .dlg-list .mono { color: var(--ink-2); }

  /* ---------- phone: the table becomes cards (the folds made each row card-shaped already) ---------- */
  @media (max-width: 640px) {
    .wrap { padding: 0 12px 48px; }
    h1 { font-size: 24px; }
    .table-scroll { max-height: none; overflow: visible; }
    .scroll-fade { display: none; }
    .console, .console tbody, .console tbody tr, .console td { display: block; }
    .console thead { display: none; }
    .console tbody tr {
      position: relative; margin: 10px 2px; padding: 4px 0 8px;
      border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
    }
    .console td { border-top: none; padding: 3px 14px; white-space: normal; }
    .console td.proj-cell { position: static; min-width: 0; padding: 10px 96px 3px 14px; }
    .console tbody tr:hover td { background: none; }
    /* the two label-less cells grow labels matching the Team cell's grammar */
    .console td:nth-child(2)::before { content: 'Last Used'; }
    .console td:nth-child(3)::before { content: 'Client'; }
    .console td:nth-child(2)::before, .console td:nth-child(3)::before {
      display: inline-block; min-width: 62px;
      font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em;
      text-transform: uppercase; color: var(--ink-3);
    }
    .ppl .ppl-role { min-width: 62px; }
    .ppl { white-space: normal; }
    /* the verb sits top-right of the card, clear of the title */
    .console td:nth-child(5) { position: absolute; top: 8px; right: 8px; padding: 0; }

    /* archives (six columns — Project · Last Used · Archived · Client · Team · Delete):
       its own cell labels; Team returns to the flow and the verb (cell 6) takes the corner */
    .console.archives td:nth-child(3)::before { content: 'Archived'; }
    .console.archives td:nth-child(4)::before {
      content: 'Client';
      display: inline-block; min-width: 62px;
      font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em;
      text-transform: uppercase; color: var(--ink-3);
    }
    .console.archives td:nth-child(5) { position: static; top: auto; right: auto; padding: 3px 14px; }
    .console.archives td:nth-child(6) { position: absolute; top: 8px; right: 8px; padding: 0; }

    /* media rooms: File · Kind · Size · Modified · Cleanup, and the bin's Snapshot · Size · Deleted · Select */
    .console.media td:nth-child(2)::before { content: 'Kind'; }
    .console.media td:nth-child(3)::before { content: 'Size'; }
    .console.media td:nth-child(4)::before { content: 'Modified'; }
    .console.media td:nth-child(5)::before { content: 'Cleanup'; }
    .console.bin td:nth-child(2)::before { content: 'Size'; }
    .console.bin td:nth-child(3)::before { content: 'Deleted'; }
    .console.media td:nth-child(2)::before, .console.media td:nth-child(3)::before,
    .console.media td:nth-child(4)::before, .console.media td:nth-child(5)::before,
    .console.bin td:nth-child(2)::before, .console.bin td:nth-child(3)::before {
      display: inline-block; min-width: 66px;
      font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em;
      text-transform: uppercase; color: var(--ink-3);
    }
    .console.media td:nth-child(5) { position: static; top: auto; right: auto; padding: 3px 14px; }
    /* the bin checkbox takes the card corner */
    .console.bin td:nth-child(4) { position: absolute; top: 8px; right: 8px; padding: 0; }
  }

  /* ---------- the activity feed — the THIRD base shape (Activity rail sitting, 2026-07-21).
     The river runs NAKED on the ground; only the toolbar is a dh-card (cards contain
     instruments and excerpts; rivers run on the ground). Class names match activity_rows.html
     verbatim — the Load-more fragment contract predates the re-base and must keep appending. */
  .feed-toolbar {
    display: flex; flex-direction: column; gap: 10px;
    padding: 13px 18px; margin-bottom: 10px;
  }
  .feed-toolbar .row1 { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
  .feed-toolbar form { flex: 1; min-width: 200px; max-width: 380px; display: flex; }
  .chips { display: flex; gap: 6px; flex-wrap: wrap; }
  .chip {
    display: inline-flex; align-items: center; gap: 6px;
    border: 1px solid var(--check-line); border-radius: 999px;
    background: none; color: var(--ink-2);
    font-size: 12px; padding: 3px 11px; text-decoration: none; font-family: inherit;
  }
  .chip .n { color: var(--ink-3); font-variant-numeric: tabular-nums; }
  .chip.on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
  .chip.zero { opacity: 0.55; }
  /* 9px + a hairline ring seats the paler hues on white (sitting, sixth pass) */
  .dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none;
    box-shadow: inset 0 0 0 1px rgba(16, 21, 29, 0.12); }
  .dot.cat-import { background: var(--cat-import); } .dot.cat-export { background: var(--cat-export); }
  .dot.cat-read { background: var(--cat-read); } .dot.cat-edit { background: var(--cat-edit); }
  .dot.cat-qc { background: var(--cat-qc); } .dot.cat-admin { background: var(--cat-admin); }
  .dot.cat-auth { background: var(--cat-auth); } .dot.cat-system { background: var(--cat-system); }
  .dot.cat-none { background: var(--mute); }
  /* cron is HOLLOW (sitting, seventh pass): machine time wears an outline — no human hand,
     no fill; rhymes with the via-tags where cron/shell are already the quiet pair */
  .dot.cat-cron { background: transparent; box-shadow: inset 0 0 0 2px var(--cat-cron); }

  .feed { padding: 2px 4px 8px; }
  /* day dividers in the gold eyebrow register (sitting, third pass) — inserted browser-side */
  .day {
    font-size: 11px; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase;
    color: var(--gold); padding: 18px 8px 6px; border-bottom: 2px solid var(--line);
  }
  .rcpt {
    display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
    padding: 7px 8px; border-bottom: 1px solid var(--line-soft);
    border-left: 3px solid transparent; cursor: pointer; font-size: 13.5px;
  }
  .rcpt:hover { background: var(--accent-soft); }
  .rcpt.err { border-left-color: var(--bad); background: color-mix(in srgb, var(--bad) 5%, transparent); }
  .rcpt.rej { border-left-color: var(--gold-line); background: color-mix(in srgb, var(--gold) 4%, transparent); }
  .rcpt .cat {
    display: inline-flex; align-items: center; gap: 6px;
    flex: 0 0 4.8rem; font-size: 11px; color: var(--ink-3);
  }
  /* accent = clickable (sitting, first pass) — this page's one navigation affordance */
  .rcpt .proj { font-weight: 500; color: var(--link); text-decoration: none; white-space: nowrap; }
  .rcpt .proj:hover { text-decoration: underline; }
  .rcpt .proj.plain { color: var(--ink-3); font-weight: 400; }
  .rcpt .who { font-weight: 600; color: var(--ink); white-space: nowrap; }
  .rcpt .act { color: var(--ink-2); }
  .rcpt .when { margin-left: auto; color: var(--ink-3); font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
  .dchip {
    font-family: 'Ubuntu Mono', monospace; font-size: 11px;
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: 4px;
    padding: 0 5px; color: var(--ink-3);
  }
  .via-tag {
    font-size: 10.5px; padding: 1px 7px; border-radius: 4px; font-weight: 600;
    background: var(--warn-soft); color: var(--gold); border: 1px solid var(--gold-line);
  }
  .via-tag.via-cron, .via-tag.via-shell { background: var(--mute-soft); color: var(--mute); border-color: var(--line); }
  .out-tag { font-size: 10.5px; padding: 1px 7px; border-radius: 4px; font-weight: 600; }
  .out-tag.out-error { background: var(--bad-soft); color: var(--bad); border: 1px solid var(--bad); }
  .out-tag.out-rejected { background: var(--warn-soft); color: var(--warn); border: 1px solid var(--gold-line); }

  .raw {
    display: none; background: var(--surface-2); border: 1px solid var(--line-soft);
    border-left: 3px solid var(--mute); border-radius: 0 7px 7px 0;
    margin: 0 0 6px 5.4rem; padding: 10px 14px; font-size: 12px; color: var(--ink-2); overflow-x: auto;
  }
  .raw.open { display: block; }
  .raw .rawjson { margin: 0; font-family: 'Ubuntu Mono', monospace; white-space: pre-wrap; color: var(--ink-2); line-height: 1.5; }
  .explain { margin-top: 8px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .explain button {
    background: var(--accent-soft); border: 1px solid var(--accent); color: var(--accent);
    border-radius: 7px; padding: 5px 12px; font-size: 12px; font-family: inherit;
  }
  .explain button:disabled { opacity: 0.5; cursor: not-allowed; }
  .hooknote { font-size: 11px; color: var(--ink-3); }

  /* the seam — a quiet boundary, deliberately not a billboard (sitting, third pass) */
  .seam {
    display: flex; align-items: center; gap: 12px; margin: 22px 0 4px;
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em;
    color: var(--accent);
  }
  .seam::before, .seam::after { content: ""; flex: 1; border-top: 1px dashed var(--accent); opacity: 0.5; }
  .rcpt.lean { opacity: 0.66; cursor: default; padding-top: 5px; padding-bottom: 5px; }
  .rcpt.lean:hover { background: none; }
  .rcpt.lean .who { font-weight: 500; }

  .loadmore { display: flex; align-items: center; gap: 12px; padding: 14px 4px 16px; }
  .empty-note { color: var(--ink-3); font-size: 13px; padding: 16px 8px; }
  .window-note { font-size: 13.5px; color: var(--ink-2); }

  @media (max-width: 640px) {
    .feed { padding: 2px 0 8px; }
    .rcpt { padding: 8px 6px; }
    .rcpt .cat { flex-basis: auto; }
    .raw { margin-left: 0; }
    .server-whisper { display: none; }
  }

  /* ---------- the passage bar — the gold navigation thread at the viewport's tippy top
     (Activity rail sitting, fourth/fifth passes; base furniture, every rail page inherits).
     WHY, Mark's words verbatim: "it lets the user know something is happening — don't panic."
     The rail world's heir to base_v5_3's processing-alert spinner, but automatic. ---------- */
  .loadbar {
    position: fixed; top: 0; left: 0; right: 0; height: 5px; z-index: 120;
    background: var(--gold-line);
    transform: scaleX(0); transform-origin: 0 50%;
    opacity: 0; transition: transform 200ms ease, opacity 300ms ease;
    box-shadow: 0 1px 0 color-mix(in srgb, var(--gold) 50%, transparent),
                0 0 10px color-mix(in srgb, var(--gold-line) 55%, transparent);
    pointer-events: none;
  }
  @media (prefers-reduced-motion: reduce) { .loadbar { transition: opacity 300ms ease; } }

  /* ---------- outcome region (aria-live — the js-snackbar heir) ---------- */
  .outcome-region {
    position: fixed; left: 24px; bottom: 24px; z-index: 70;
    display: flex; flex-direction: column; gap: 8px; max-width: min(440px, calc(100vw - 48px));
  }
  .outcome {
    display: flex; align-items: baseline; gap: 10px;
    background: var(--surface); border: 1px solid var(--line);
    border-left: 3px solid var(--good);
    border-radius: 9px; box-shadow: var(--shadow);
    padding: 10px 14px; font-size: 13.5px; color: var(--ink-2);
  }
  .outcome.err { border-left-color: var(--bad); }
  .outcome b { color: var(--ink); font-weight: 600; }
  .outcome .x {
    margin-left: auto; background: none; border: none; cursor: pointer;
    color: var(--ink-3); font-size: 15px; line-height: 1; padding: 0 2px; font-family: inherit;
  }
  .outcome .x:hover { color: var(--ink); }
  /* visible spaces (spaces_as_characters): the real space stays in the markup; the faint middle
     dot is pure decoration, inheriting the value's own color — editors' show-whitespace idiom */
  .dh-sp { white-space: pre; position: relative; }
  .dh-sp::before {
    content: '\00B7'; position: absolute; left: 50%; top: 50%;
    transform: translate(-50%, -50%); opacity: .45; pointer-events: none;
  }

  /* the Undo button — gold register (the classic toast wore bg-warning for undo) */
  .outcome .undo-btn {
    margin-left: 6px; padding: 2px 10px; border-radius: 6px; cursor: pointer;
    border: 1px solid var(--gold-line); background: transparent; color: var(--ink);
    font-family: inherit; font-weight: 600; font-size: 12.5px;
  }
  .outcome .undo-btn:hover { background: color-mix(in srgb, var(--gold) 15%, transparent); }
  .outcome .undo-btn:disabled { opacity: .5; cursor: default; }

  /* Chatbase anchor — canvas-corner, never the rail */
  .cb-anchor {
    position: fixed; right: 26px; bottom: 24px;
    width: 46px; height: 46px; border-radius: 50%;
    background: var(--accent); color: var(--accent-ink);
    display: flex; align-items: center; justify-content: center;
    font-size: 19px; box-shadow: var(--shadow); cursor: pointer;
  }

  /* ---------- native <dialog> chrome — creation (the port specimen) + the archives delete confirm
     + the Progress gap-filter (joined 2026-08-12: shipped shell-class-less and rendered UA-default —
     the .dlg-* innards dress only the interior; every house dialog needs a shell class on this rule) ---------- */
  dialog.create-dlg, dialog.del-dlg, dialog.gap-dlg {
    background: var(--surface); color: var(--ink);
    border: 1px solid var(--line); border-radius: 12px;
    box-shadow: var(--shadow); padding: 0;
    width: min(460px, calc(100vw - 40px));
  }
  dialog.create-dlg::backdrop, dialog.del-dlg::backdrop, dialog.gap-dlg::backdrop { background: rgba(8, 12, 18, 0.55); }
  dialog.del-dlg, dialog.gap-dlg { width: min(430px, calc(100vw - 40px)); }
  .dlg-head h2 { margin: 0; font-size: 16px; font-weight: 700; }
  .dlg-grave { margin-top: 9px; font-size: 12.5px; color: var(--ink-3); }
  .dlg-head { display: flex; align-items: center; gap: 10px; padding: 14px 18px 0; }
  .dlg-close {
    margin-left: auto; background: none; border: none; cursor: pointer;
    color: var(--ink-3); font-size: 17px; line-height: 1; padding: 2px 6px; border-radius: 6px; font-family: inherit;
  }
  .dlg-close:hover { background: var(--accent-soft); color: var(--ink); }
  .dlg-body { padding: 12px 18px 4px; display: flex; flex-direction: column; gap: 13px; }
  /* dialog-narrative emphasis wears gold (Mark's polish 2026-08-11, from the Delete Points
     dialog): italics alone let the eye gloss over the option words a narrative offers
     (a filename, "everything") — the gold lead says "these are things you can type" */
  .dlg-body em { color: var(--gold); }
  .fld label { font-size: 12px; font-weight: 600; color: var(--ink-2); display: block; margin-bottom: 4px; }
  .fld input[type="text"] {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 8px 10px; font-size: 14px; font-family: inherit;
  }
  .fld input[type="text"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  /* File inputs wear the field family (Abby, 2026-07-29): the bare native control floats
     unanchored — the bordered box with an integrated browse segment is the recognizable
     "pick a file" shape (the classic pages' form-control look, kept on purpose). */
  .fld input[type="file"] {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink-2);
    font-size: 13px; font-family: inherit; padding: 0; cursor: pointer;
  }
  .fld input[type="file"]::file-selector-button {
    background: var(--accent-soft); color: var(--ink);
    border: none; border-right: 1px solid var(--line);
    padding: 8px 13px; margin-right: 10px;
    font-size: 13px; font-family: inherit; cursor: pointer;
  }
  .fld input[type="file"]:hover::file-selector-button { background: var(--accent); color: var(--accent-ink); }
  .fld input[type="file"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .hint { font-size: 11.5px; color: var(--ink-3); margin-top: 5px; }
  .hint.ok { color: var(--good); }
  .hint.taken { color: var(--warn); }
  .file-chip {
    border: 1.5px dashed var(--line); border-radius: 7px;
    padding: 9px 11px; font-size: 12.5px; color: var(--ink-3); cursor: pointer;
  }
  .file-chip:hover { border-color: var(--accent); color: var(--ink-2); }
  .chk { display: flex; gap: 8px; align-items: baseline; font-size: 13px; color: var(--ink-2); }
  .dlg-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 18px 18px; }
  .ghost-btn {
    background: var(--btn-fill); border: 1px solid var(--check-line); color: var(--btn-ink);
    box-shadow: var(--btn-shadow);
    border-radius: 8px; padding: 7px 14px; font-size: 13px; cursor: pointer; font-family: inherit;
    /* anchors wear this class too (Reset Dates, Gap Map/Report) — a button dress never underlines,
       and line-height pins to the button UA default so an anchor's inherited 1.5 body line-height
       can't render it taller than its <button> companions */
    text-decoration: none; display: inline-block; line-height: normal;
  }
  .ghost-btn:hover { border-color: var(--accent); background: var(--btn-hover); }
  /* the sleepy dress, promoted at the rule of three (ps-save + both drill rooms, 2026-08-23):
     same 0.55/not-allowed pair primary-btn and checkboxes wear; hover stays quiet while asleep */
  .ghost-btn:disabled { opacity: 0.55; cursor: not-allowed; }
  .ghost-btn:disabled:hover { border-color: var(--check-line); background: none; }
  .primary-btn {
    background: var(--accent); color: var(--accent-ink); border: none;
    box-shadow: var(--btn-shadow);
    border-radius: 8px; padding: 7px 16px; font-size: 13.5px; font-weight: 500;
    cursor: pointer; font-family: inherit;
    text-decoration: none; display: inline-block;  /* the class was born on <button>; anchors wearing it drop the underline (kin-pair walk catch) */
  }
  .primary-btn:hover { filter: brightness(1.08); }
  .primary-btn:disabled { opacity: 0.55; cursor: not-allowed; }
  .fmt-chip.chip-ico { display: inline-flex; align-items: center; gap: 5px; }
  .danger-btn {
    background: var(--bad); color: var(--accent-ink); border: none;  /* accent-ink not #fff (Dark docket 2026-08-13): white on Dark's salmon measured 3.41; accent-ink = white in Light, dark ink in Dark (6.30) */
    border-radius: 8px; padding: 7px 16px; font-size: 13.5px; font-weight: 500;
    cursor: pointer; font-family: inherit;
    box-shadow: var(--btn-shadow);  /* consolidated from the delete-dialog's duplicate rule (2026-08-13) — the presence register all filled buttons wear */
  }
  .danger-btn:hover { filter: brightness(1.08); }
  .danger-btn:disabled { opacity: 0.55; cursor: wait; }  /* busy-while-deleting, from the consolidated duplicate */

  /* ---------- the What's New tile (2026-07-22 rework — mockups/whats-new-rail.md note 1)
     Rail furniture above the user chip, present only while a note is newer than the user's
     Readmark; gone entirely when read. When present it takes the chip's auto-margin so the
     pair sits glued to the rail's bottom together. ---------- */
  .rail-tile {
    margin-top: auto; margin-bottom: 6px; padding: 10px 12px 11px;
    border: 1px solid var(--gold-line); border-radius: 9px;
    background: var(--surface); box-shadow: var(--shadow);
    position: relative;
  }
  .rail-tile + .user-chip { margin-top: 0; }
  .rail.collapsed .rail-tile { display: none; }
  .rail-tile:hover { background: var(--accent-soft); }
  .tile-link { display: block; text-decoration: none; }
  .tile-link .tile-eyebrow {
    display: flex; align-items: center; gap: 7px;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--gold);
  }
  .tile-link .tile-title {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
    margin-top: 3px; font-size: 13px; color: var(--ink); font-weight: 500; line-height: 1.35;
  }
  .tile-link .tile-more { display: block; margin-top: 2px; font-size: 11.5px; color: var(--ink-3); }
  .tile-x-form { position: absolute; top: 6px; right: 7px; margin: 0; z-index: 1; }
  .tile-x {
    background: none; border: none; cursor: pointer;
    color: var(--ink-3); font-size: 13px; line-height: 1; padding: 2px 4px;
    border-radius: 5px; font-family: inherit;
  }
  .tile-x:hover { background: var(--mute-soft); color: var(--ink); }

  /* ---------- What's New page: the note cards + the superuser composer ---------- */
  .post { padding: 18px 22px 16px; margin-bottom: 16px; }
  .post .post-meta { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--ink-3); }
  .new-pill {
    font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--gold); border: 1px solid var(--gold-line); border-radius: 999px; padding: 0 8px;
  }
  .post h2.post-title { margin: 6px 0 8px; font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }
  .post .post-body { font-size: 14.5px; color: var(--ink-2); max-width: 72ch; overflow-wrap: break-word; }
  .post .post-body p { margin: 0 0 10px; }
  .post .post-body p:last-child { margin-bottom: 0; }
  .post .post-foot { margin-top: 12px; display: flex; }
  .post .del-verb {
    margin-left: auto;
    background: none; border: 1px solid var(--check-line); color: var(--bad);
    border-radius: 7px; padding: 4px 11px; font-size: 12px; cursor: pointer; font-family: inherit;
  }
  .post .del-verb:hover { border-color: var(--bad); background: var(--bad-soft); }
  .list-tail { font-size: 12.5px; color: var(--ink-3); padding: 4px 4px 0; max-width: 72ch; }
  .composer { margin-bottom: 22px; }
  .composer .comp-head {
    padding: 13px 18px 0;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3);
  }
  .composer .comp-body { padding: 10px 18px 14px; display: flex; flex-direction: column; gap: 10px; }
  .comp-title {
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 8px 12px; font-size: 14px; font-family: inherit; width: 100%;
  }
  .comp-title:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .comp-foot { display: flex; align-items: center; gap: 12px; }
  .comp-foot .comp-hint { font-size: 12px; color: var(--ink-3); }
  @media (max-width: 640px) {
    .post { padding: 14px 16px 12px; }
  }

  /* ---------- People + My Profile (companions #7+#8, 2026-07-22 — mockups/people-profile-rail.md).
     The roster wears the console's dense-table grammar the Activity way: naked on the ground,
     NO header row (every cell is self-labeled — clock sentences, the ppl fold), toolbar in its
     own compact card. Reused verbatim: .console td machinery, .proj-cell/.proj-open (identity),
     .ppl/.ppl-role (the fold), .role-chip (the "you" chip), .days, dialog chrome. ---------- */
  /* the third toolbar species: single-row standalone instrument card (console's is an in-card
     bezel, the feed's is a column card) — pair with .dh-card in markup */
  .roster-toolbar {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 13px 18px; margin-bottom: 10px;
  }
  .roster-toolbar .clock-whisper { margin-left: auto; font-size: 12px; color: var(--ink-3); }
  /* naked variant: the page owns the one scroll axis; the sticky identity column re-grounds */
  .table-scroll.bare { max-height: none; overflow: visible; overflow-x: auto; border-radius: 0; }
  .console.roster tbody tr:hover td { background: color-mix(in srgb, var(--accent) 9%, var(--ground)); }
  .console.roster td.proj-cell { background: var(--ground); min-width: 230px; }
  .console.roster td { padding: 10px 13px; }

  .person-sub { font-size: 11.5px; color: var(--ink-3); margin-top: 1px; }
  .badge-star { color: var(--gold); font-size: 11px; margin-left: 6px; cursor: default; }
  .badge-am { color: var(--accent); font-size: 11px; margin-left: 6px; cursor: default; }
  /* the People head's legend for the two marks (2026-09-05) — a whisper after the sub-line */
  .head-sub .badge-legend { display: block; margin-top: 3px; font-size: 12px; color: var(--ink-3); }
  .head-sub .badge-legend .badge-star, .head-sub .badge-legend .badge-am { margin-left: 0; }
  /* the deactivated flag — .role-chip's bad-state sibling (an account state, not an error) */
  .flag-chip {
    font-size: 10.5px; padding: 0 8px; border-radius: 999px;
    border: 1px solid var(--bad); color: var(--bad);
    background: var(--bad-soft); font-weight: 500;
    margin-left: 8px; vertical-align: 1px; white-space: nowrap;
  }
  tr.row-off td, tr.row-off td a.proj-open { color: var(--ink-3); }
  .ppl-none { font-size: 12.5px; font-style: italic; color: var(--ink-3); }
  /* clock-note: the subordinate clause after a clock ("· stale") — .blade-note's kin; the
     third sibling earns the generalized name */
  .clock-note { color: var(--ink-3); font-size: 12px; }
  .clock-note.stale { color: var(--warn); }

  /* row verbs — the takeover/delete-verb family generalized with variants */
  .row-verb {
    background: none; border: none; font-family: inherit; font-size: 12.5px;
    color: var(--accent); cursor: pointer; padding: 2px 7px; border-radius: 6px;
    text-decoration: none; display: inline-block;
  }
  .row-verb:hover { background: var(--accent-soft); }
  .row-verb.danger { color: var(--bad); }
  .row-verb.danger:hover { background: var(--bad-soft); }
  .row-verb.good { color: var(--good); }
  .row-verb.good:hover { background: var(--good-soft); }
  /* a row verb that can't fire (zero-run export rows) dims like its row — no fill, no hand */
  .row-verb:disabled { opacity: 0.55; cursor: not-allowed; background: none; }

  /* ---------- My Profile: the two cards + field family (also worn by the New User dialog) ---------- */
  .prof-card { margin-bottom: 18px; }
  /* divergence only: 13px head padding from its own early dress (harmonize or shed at the room's next touch) */
  .prof-card .card-head { padding: 13px 20px 0; }
  .prof-card .card-body { padding: 12px 20px 16px; }
  .field-row { display: flex; gap: 14px; flex-wrap: wrap; }
  .field { flex: 1; min-width: 200px; max-width: 300px; }
  .dlg-body .field { max-width: none; min-width: 0; }
  .field label { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-2); margin-bottom: 4px; }
  .field label .lock { color: var(--ink-3); font-size: 11px; }
  .field label .hint { margin-top: 0; }
  .field input {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 8px 11px; font-size: 14px; font-family: inherit;
  }
  .field input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .field input[readonly] { color: var(--ink-3); cursor: not-allowed; background: var(--ground); }
  .field-note { font-size: 11.5px; color: var(--ink-3); margin-top: 4px; line-height: 1.35; }
  .field-err { font-size: 12px; color: var(--bad); margin-top: 4px; min-height: 16px; }
  .field-pair { display: flex; gap: 10px; }
  .field-pair .field { min-width: 0; }
  .pw-wrap { position: relative; }
  .pw-wrap input { padding-right: 58px; }
  /* password reveal: an explicit click, never hover — shoulder-surf-proof by default */
  .pw-reveal {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    background: none; border: none; cursor: pointer; font-family: inherit;
    font-size: 11px; color: var(--accent); padding: 3px 6px; border-radius: 5px;
  }
  .pw-reveal:hover { background: var(--accent-soft); }
  .door-card { padding: 14px 20px; display: flex; align-items: center; gap: 14px; margin-bottom: 18px; text-decoration: none; }
  .door-card .door-ico {
    width: 34px; height: 34px; border-radius: 8px; flex: none;
    background: var(--accent-soft); color: var(--accent);
    display: inline-flex; align-items: center; justify-content: center; font-size: 16px;
  }
  .door-card .door-ico svg { width: 15px; height: 15px; }
  .door-card .door-text { flex: 1; min-width: 0; }
  .door-card .door-text b { color: var(--ink); font-weight: 600; display: block; font-size: 14.5px; }
  .door-card .door-text span { font-size: 12.5px; color: var(--ink-3); }
  .door-card .go { color: var(--ink-3); font-size: 14px; }
  a.door-card:hover { border-color: var(--accent); }
  a.door-card:hover .go { color: var(--accent); }

  .staff-banner {
    display: flex; align-items: center; gap: 10px;
    border: 1px solid var(--gold-line); border-radius: var(--radius);
    background: var(--warn-soft); color: var(--ink-2);
    padding: 9px 16px; font-size: 13px; margin-bottom: 18px;
  }
  .staff-banner b { color: var(--ink); }

  /* ---- the interior-contract empty state (transitions canary, RULED 2026-07-22): unconfigured
     never dresses as clean, and THE EMPTY ROOM TEACHES — it leads with the room's purpose
     sentence (page_meta's own purpose line rendered human-side), then the gold gap banner,
     then a door card to the fix. Every interior room inherits this shape. */
  .room-purpose { margin: 0 0 14px; font-size: 13.5px; color: var(--ink-2); max-width: 66ch; }
  .precondition {
    display: flex; align-items: baseline; gap: 10px;
    border: 1px solid var(--gold-line); border-radius: var(--radius);
    background: var(--warn-soft); color: var(--ink-2);
    padding: 12px 18px; font-size: 13.5px; margin-bottom: 18px;
  }
  .precondition b { color: var(--ink); }

  /* ---- the transitions builder (the first interior room, 2026-07-22) */
  .line-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
  .line-row .lbl { font-size: 12px; color: var(--ink-2); font-weight: 500; }
  .line-row .count-whisper { font-size: 12px; color: var(--ink-3); }
  .att-list { border-top: 1px solid var(--line-soft); margin-top: 4px; }
  .att-row {
    display: flex; align-items: center; gap: 12px;
    padding: 8px 4px; border-bottom: 1px solid var(--line-soft);
    cursor: pointer;
  }
  .att-row:hover { background: var(--accent-soft); }
  .att-row input[type="checkbox"] {
    width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; flex: none; margin: 0;
  }
  .att-row .num {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-size: 12px;
    color: var(--ink-3); width: 22px; text-align: right; flex: none;
  }
  .att-row .nm { color: var(--ink); font-size: 14px; }
  .walk-whisper { font-size: 12px; color: var(--ink-3); margin-top: 10px; line-height: 1.5; }
  .am-textarea {
    width: 100%; min-height: 200px; resize: vertical;
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 9px 12px; font-size: 13px; font-family: 'Ubuntu Mono', monospace;
  }
  .consequences { margin: 4px 0; padding: 10px 14px 10px 28px; border: 1px solid var(--line-soft); border-radius: 8px; background: var(--surface-2); font-size: 12.5px; }
  .consequences li { margin: 3px 0; }
  .consequences b { color: var(--ink); }

  @media (max-width: 640px) {
    /* the roster's phone cards: cells are self-labeled sentences, so NO ::before labels —
       neutralize the generic console labels (they say Last Used/Client, the console's truth) */
    .console.roster td:nth-child(2)::before, .console.roster td:nth-child(3)::before { content: none; }
    .console.roster td.proj-cell { background: var(--surface); }
    .roster-verbs { padding-top: 6px; }
  }

  /* ── Offset Reporting: the map-bearing interior room (offsets rotation, 2026-07-22 —
     design of record: mockups/offsets-rail.md). Topology class (b): the rail wraps
     business around the offset_map iframe; controls above, map full-bleed below. The
     map pane's content is the iframe's own (tile-light in both themes — it's a tile
     map, and pretending otherwise is dishonest chrome). */
  .map-card { margin-bottom: 18px; overflow: hidden; }
  .controls-row {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 12px 20px 14px;
  }
  .controls-row .lbl { font-size: 12px; color: var(--ink-2); font-weight: 500; }
  .controls-row form { margin-left: auto; }
  .buf { display: inline-flex; align-items: stretch; border: 1px solid var(--check-line); border-radius: 7px; overflow: hidden; }
  .buf button {
    width: 30px; cursor: pointer; font-family: inherit; font-size: 15px; line-height: 1;
    border: none; background: none; color: var(--btn-ink);
  }
  .buf button:hover { background: var(--accent-soft); color: var(--ink); }
  .buf input {
    width: 62px; text-align: center; font-family: 'Ubuntu Mono', 'Consolas', monospace;
    font-size: 13.5px; color: var(--ink); background: var(--surface);
    border: none; border-left: 1px solid var(--line); padding: 6px 0;
    -moz-appearance: textfield; appearance: textfield;
  }
  .buf input::-webkit-outer-spin-button, .buf input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
  .buf input:focus { outline: 2px solid var(--gold-line); outline-offset: -2px; }
  .buf .unit {
    display: inline-flex; align-items: center; padding: 0 9px;
    border-left: 1px solid var(--line); border-right: 1px solid var(--line);
    background: var(--surface-2); font-size: 12px; color: var(--ink-3);
  }
  .map-pane { position: relative; height: 500px; border-top: 1px solid var(--line); }
  .map-pane iframe { display: block; width: 100%; height: 100%; border: none; }
  .map-card .card-foot {
    margin-top: 0; padding: 10px 20px 12px;
    border-top: 1px solid var(--line-soft);
  }
  .map-card .card-foot .foot-right { margin-left: auto; }
  @media (max-width: 640px) {
    .map-pane { height: 380px; }
    .controls-row form { margin-left: 0; }
  }

  /* ---------- the QC rooms (begend canary, docket closed 2026-07-27): the bust-table shape
     the six QC siblings inherit — rules table + findings table + run paint + the api fold.
     mockups/begend-rail.md is the decision record. ---------- */
  .table-card { margin-bottom: 18px; overflow: visible; }
  /* Phones: the table pans INSIDE its card (Mark's ruling 2026-08-14, the wide-table sitting —
     dress 1 fleet-wide, the chiefs-scoped rule folded in): thirteen rooms' qc-tables bled past
     their card edge on narrow screens. The census fact the ruling leaned on: NO page nests a
     dropdown inside a .table-card today (the Tolerance menu rides the ident card above the
     tables; the Tally Table's colvis lives in .t-card, out of this rule's scope) — a future
     in-card menu would CLIP under this rule, so the rotation that adds one upgrades its page
     to a .table-scroll wrapper around the table instead */
  @media (max-width: 900px) { .table-card { overflow-x: auto; } }
  .table-card .card-foot { margin-top: 0; padding: 10px 20px 12px; border-top: 1px solid var(--line-soft); }
  .table-card .card-foot .foot-right { margin-left: auto; }
  .table-card .controls-row .primary-btn { margin-left: auto; }
  .dh-select {
    font-family: inherit; font-size: 13px; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--check-line); border-radius: 7px;
    padding: 6px 10px; min-width: 150px;
  }
  .dh-select:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }

  .qc-table { width: 100%; border-collapse: collapse; font-size: 13.5px; margin-top: 10px; }
  .qc-table th {
    text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 8px 12px; border-bottom: 1px solid var(--line);
  }
  .qc-table td { padding: 7px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
  .qc-table tbody tr:hover { background: var(--surface-2); }
  .qc-table td:first-child, .qc-table th:first-child { padding-left: 20px; }
  .qc-table td:last-child, .qc-table th:last-child { padding-right: 20px; }

  /* the bust-badge vocabulary: a rule that RAN and found nothing is a real verdict (green);
     the no-rules state is NEUTRAL — zero rules must never dress as zero busts */
  .bust-pill {
    display: inline-flex; align-items: center; gap: 5px;
    background: var(--bad-soft); color: var(--bad);
    border-radius: 999px; padding: 1px 10px; font-size: 12px; font-weight: 700; white-space: nowrap;
  }
  .clean-pill { display: inline-flex; align-items: center; gap: 5px; color: var(--good); font-size: 12.5px; font-weight: 600; white-space: nowrap; }
  .whisper-chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--mute-soft); color: var(--mute);
    border-radius: 999px; padding: 1px 9px; font-size: 11px; font-weight: 600; white-space: nowrap;
  }
  .neutral-state {
    display: flex; align-items: baseline; gap: 10px;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface-2); color: var(--ink-2);
    padding: 12px 18px; font-size: 13.5px; margin-bottom: 18px;
  }
  .neutral-state b { color: var(--ink); }

  /* the rule's name IS the door (Abby's muscle-memory note, 2026-07-29): accent-blue text
     link, hover underline for the affordance — the header says "click to Open" */
  .rule-open { text-decoration: none; font-weight: 500; white-space: nowrap; }
  .rule-open:hover { text-decoration: underline; text-underline-offset: 2px; }
  .rule-del-form { margin: 0; display: inline; }
  .rule-del {
    background: none; border: none; cursor: pointer; color: var(--ink-3);
    font-size: 14px; font-family: inherit; padding: 2px 6px; border-radius: 6px;
  }
  .rule-del:hover { background: var(--bad-soft); color: var(--bad); }
  .chip-btn {
    display: inline-flex; align-items: center; gap: 7px;
    border: 1px solid var(--check-line); border-radius: 8px; background: var(--btn-fill);
    box-shadow: var(--btn-shadow);
    color: var(--btn-ink); padding: 6px 13px; font-size: 12.5px; font-weight: 500;
    cursor: pointer; font-family: inherit; text-decoration: none;
  }
  .chip-btn:hover { border-color: var(--accent); color: var(--ink); }
  /* the arrow-into-tray sprite (Mark, 2026-07-29): the text-glyph .dl smudge retired */
  .chip-btn svg { width: 13px; height: 13px; color: var(--ink-3); flex: none; }
  .chip-btn:hover svg { color: var(--accent); }

  /* the def room: switcher (sibling-room door), verdict line, findings run paint */
  .def-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 12px 20px 2px; }
  .def-bar .sep { color: var(--ink-3); padding: 0 2px; }
  .def-title { font-size: 13.5px; color: var(--ink); }
  details.def-switcher { position: relative; }
  details.def-switcher > summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
    border: 1px solid var(--check-line); border-radius: 8px; background: var(--surface);
    padding: 6px 13px; font-size: 13.5px; color: var(--ink);
  }
  details.def-switcher > summary::-webkit-details-marker { display: none; }
  details.def-switcher > summary .caret { color: var(--ink-3); font-size: 11px; }
  details.def-switcher[open] > summary { border-color: var(--accent); }
  .switch-menu {
    position: absolute; top: calc(100% + 5px); left: 0; z-index: 40; min-width: 320px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
    box-shadow: var(--shadow); padding: 5px;
  }
  .switch-menu a {
    display: flex; align-items: center; gap: 6px;
    padding: 7px 11px; border-radius: 7px; text-decoration: none;
    color: var(--ink-2); font-size: 13px; white-space: nowrap;
  }
  .switch-menu a:hover { background: var(--accent-soft); color: var(--ink); }
  .switch-menu a .tail { margin-left: auto; padding-left: 14px; }
  .verdict { font-size: 13.5px; font-weight: 600; }
  .verdict.bad { color: var(--bad); }
  .verdict.good { color: var(--good); }
  .def-empty { padding: 10px 20px 16px; }
  .def-empty .neutral-state { margin-bottom: 0; }

  .fnd-row td { transition: opacity .35s ease; }
  .fnd-row.dissolving td { opacity: 0; }
  .fnd-row.flagged { background: var(--bad-soft); }
  .qc-table tbody tr.fnd-row.flagged:hover { background: var(--bad-soft); }
  .fnd-row.flagged td { border-bottom-color: transparent; }
  .fnd-row.run-start td { border-top: 2px solid var(--bad); }
  .fnd-row.run-end td { border-bottom: 2px solid var(--bad); }
  .fnd-row.flagged td:first-child { border-left: 3px solid var(--bad); padding-left: 17px; }
  /* the right edge closes the run's box — the left spine's mirror (padding gives back the 3px) */
  .fnd-row.flagged td:last-child { border-right: 3px solid var(--bad); padding-right: 17px; }
  .run-tag {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--bad); color: #fff;
    border-radius: 999px; padding: 0 9px; font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.04em; text-transform: uppercase; margin-left: 9px; white-space: nowrap;
  }
  /* the chip dress (xhalo #70, the dupe-atts .grp-ignore's kin, 2026-08-19): Ignore is a
     neutral verb — the red underline wore the bust register beside the run-tag that already
     carries it. Same recipe as .grp-ignore, this room's margins kept. */
  .run-ignore {
    display: inline-flex; align-items: center;
    border: 1px solid var(--check-line); border-radius: 7px; background: var(--btn-fill);
    box-shadow: var(--btn-shadow);
    color: var(--btn-ink); padding: 3px 10px; font-size: 11.5px; font-weight: 600;
    cursor: pointer; font-family: inherit; margin-left: 9px; white-space: nowrap;
  }
  .run-ignore:hover { border-color: var(--accent); color: var(--ink); }
  .row-del {
    /* control-line, not card-line (Mark's tie-in catch, 2026-08-13): --line is a card/table
       hairline (1.11 off white) and vanishes as a CONTROL boundary; --check-line is the house
       control-outline token (the checkbox recipe's border). Second consumer beyond checks. */
    border: 1px solid var(--check-line); border-radius: 7px; background: var(--surface);
    color: var(--btn-ink); padding: 3px 11px; font-size: 12px; cursor: pointer; font-family: inherit;
  }
  .row-del:hover { border-color: var(--bad); color: var(--bad); }
  .row-del:disabled { opacity: 0.55; cursor: default; }
  /* accent at REST since 2026-08-04 (Mark's manifests-walk ruling: blue is the reflex for
     what's open-able — a link that only turns blue on hover teaches nothing at a glance).
     Born color:inherit at the begend rotation; the muted look lost to the reflex. */
  .pt-link { text-decoration: none; color: var(--link); white-space: nowrap; }
  .pt-link:hover { text-decoration: underline; text-underline-offset: 2px; }

  /* the duplicates cluster shape (duplicates-rail.md docket 3, 2026-07-31): the GROUPED
     bust-lister's one new table organ — a value-header row per shared value, member rows
     beneath (the classic page's per-cluster thead, dressed). grp-blank is bracket B's
     humanized blank header; the value itself stays counted. */
  .grp-head td { padding: 14px 12px 6px; border-bottom: 1px solid var(--line); background: none; }
  .qc-table tbody tr.grp-head:hover { background: none; }
  .grp-head .grp-val {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-size: 14px; font-weight: 700; color: var(--bad);
  }
  .grp-head .grp-val.grp-blank { font-family: inherit; font-style: italic; }
  .grp-head .grp-count { color: var(--ink-3); font-size: 12px; margin-left: 9px; }
  /* re-dressed as the house outlined verb chip (Abby's walk, 2026-08-19): red underlined text
     read as a WARNING sitting in an already-red cluster header — but Ignore is a neutral verb,
     so it wears the chip-btn recipe at row scale (the sf-table verb-cell size), not the bust
     register. Hover stays accent, matching every other verb chip. */
  .grp-ignore {
    display: inline-flex; align-items: center;
    border: 1px solid var(--check-line); border-radius: 7px; background: var(--btn-fill);
    box-shadow: var(--btn-shadow);
    color: var(--btn-ink); padding: 3px 10px; font-size: 11.5px; font-weight: 600;
    cursor: pointer; font-family: inherit; margin-left: 12px; white-space: nowrap;
  }
  .grp-ignore:hover { border-color: var(--accent); color: var(--ink); }
  /* scope column: 'Whole project' where the classic said nothing — Each-fanned rows and
     project-wide rows must read differently at a glance */
  .scope-plain { color: var(--ink-3); font-size: 12.5px; white-space: nowrap; }
  /* the line whispered beside the station on a project-wide rule (a cross-line duplicate is
     a true bust under the default job-wide posture — bracket A lore) */
  .line-whisper { color: var(--ink-3); font-size: 11.5px; margin-left: 7px; }
  /* the per-row map door (the only QC room with one — a map legitimately wants its own tab) */
  .file-link { color: var(--ink-2); text-decoration: none; font-size: 13px; white-space: nowrap; }
  .file-link:hover { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }

  /* the On-Joint pair registers (onjoint-rail.md docket 3, 2026-08-02): every finding row is a
     PAIR — the feature's value wears the bust register (it is the wrong one; the XLSX has
     painted it that way since the assessment port), the weld's value is the authority, plain.
     st-whisper = the weld's station whispered beside its point id; echo-plain = the rules
     table's Must-echo column (the def's fourth dimension). */
  .val-feature {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-size: 13.5px; font-weight: 700; color: var(--bad); white-space: nowrap;
  }
  .val-feature.val-blank { font-family: inherit; font-style: italic; font-weight: 500; }
  .val-weld {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-size: 13.5px; color: var(--ink); white-space: nowrap;
  }
  .echo-plain { color: var(--ink-2); font-size: 13px; white-space: nowrap; }
  .echo-plain b { color: var(--ink); font-weight: 600; }
  /* a label + its seg wrap as ONE flex item, so a controls-row wrap can never strand the label
     at a row's end with the control on the next line (Mark's On-Joint walk catch, 2026-08-02) */
  .seg-group { display: inline-flex; align-items: center; gap: 10px; }
  .st-whisper { color: var(--ink-3); font-size: 11.5px; margin-left: 7px; }
  /* the no-alignment / no-weld muted badge (docket 6c): last-computed, never current */
  .bust-pill.muted { background: var(--mute-soft); color: var(--mute); }

  /* the ignore instrument (POST-by-value, bracket B) */
  .ignore-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 20px 14px; }
  .ig-chip-form { margin: 0; display: inline; }
  .ig-chip {
    display: inline-flex; align-items: center; gap: 7px;
    background: var(--mute-soft); color: var(--mute);
    border-radius: 999px; padding: 3px 6px 3px 12px; font-size: 12.5px; font-weight: 600;
  }
  .ig-chip button {
    background: none; border: none; cursor: pointer; color: var(--mute);
    font-size: 12px; line-height: 1; padding: 2px 5px; border-radius: 50%; font-family: inherit;
  }
  .ig-chip button:hover { background: var(--surface); color: var(--ink); }
  .ig-none { font-size: 12.5px; color: var(--ink-3); }
  .ig-add { display: inline-flex; margin-left: auto; }
  .ig-add input {
    font-family: inherit; font-size: 12.5px; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--check-line); border-radius: 7px 0 0 7px;
    padding: 5px 10px; width: 160px;
  }
  .ig-add input:focus { outline: 2px solid var(--gold-line); outline-offset: -1px; }
  .ig-add button {
    border: 1px solid var(--check-line); border-left: none; border-radius: 0 7px 7px 0;
    background: var(--surface-2); color: var(--btn-ink); font-family: inherit;
    font-size: 12.5px; padding: 5px 12px; cursor: pointer;
  }
  .ig-add button:hover { background: var(--accent-soft); color: var(--ink); }

  /* the api fold dress — SURVIVING TENANT ONLY: the API folds themselves retired 2026-08-12
     (Mark's one-stop-shop ruling — the API Reference room owns the teaching; usage testimony:
     one sporadic consumer, the folds were noise for everyone else). The class lives on for the
     manifest query list's merged-exports fold, which wears this collapse dress but is export
     links, not API teaching. Folds in general stay case-by-case. */
  details.api-fold {
    border: 1px solid var(--line-soft); border-radius: var(--radius);
    background: var(--surface-2); margin-bottom: 18px;
  }
  details.api-fold > summary {
    list-style: none; cursor: pointer; padding: 10px 18px;
    font-size: 12.5px; color: var(--ink-3); display: flex; align-items: center; gap: 8px;
  }
  details.api-fold > summary::-webkit-details-marker { display: none; }
  details.api-fold > summary::before { content: "▸"; font-size: 9px; transition: transform 150ms ease; }
  details.api-fold[open] > summary::before { transform: rotate(90deg); }
  details.api-fold .fold-body { padding: 2px 18px 14px; font-size: 12.5px; color: var(--ink-2); }
  details.api-fold .fold-body p { margin: 8px 0 0; }
  details.api-fold pre {
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 7px;
    padding: 10px 13px; font-size: 12px; overflow-x: auto; margin: 0;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; color: var(--ink-2); line-height: 1.5;
  }

  dialog.import-dlg, dialog.restamp-dlg {
    border: 1px solid var(--line); border-radius: 12px; padding: 0;
    background: var(--surface); color: var(--ink); box-shadow: var(--shadow);
    width: min(460px, calc(100vw - 40px));
  }
  dialog.import-dlg::backdrop, dialog.restamp-dlg::backdrop { background: rgba(8, 12, 18, 0.55); }

  /* ---------- the chiefs room (rotation 2026-07-30; design of record: mockups/chiefs-rail.md).
     Curator textarea left (unchanged by ruling), reality right: the census (never-used dimmed,
     never hidden) and the strangers shelf (begend Not-marked lineage — a work surface, not a
     verdict; when empty, the clean state is SPOKEN in the verdict bar, not rendered). ---------- */
  .chiefs-grid { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 18px; align-items: start; }
  /* minmax(0,1fr), not 1fr — the ph-hero phone lesson (2026-08-14): a bare 1fr bottoms out at
     min-content, and the chief cards propped to 490px inside a 366px column (confirmed live).
     The tables' own phone dress is the house .table-card rule (the wide-table sitting) */
  @media (max-width: 900px) { .chiefs-grid { grid-template-columns: minmax(0, 1fr); } }
  .roster-card .card-body { padding: 12px 20px 16px; }
  .roster-ta {
    width: 100%; min-height: 320px; resize: vertical;
    background: var(--surface-2); color: var(--ink);
    border: 1px solid var(--check-line); border-radius: 7px;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-size: 13px; line-height: 1.6;
    padding: 10px 12px;
  }
  .roster-ta:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .roster-foot { margin-top: 12px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .roster-foot .hint { font-size: 12px; color: var(--ink-3); }
  .chief-name { font-weight: 500; color: var(--ink); }
  .qc-table tr.unused td { color: var(--ink-3); }
  .qc-table tr.unused .chief-name { color: var(--ink-3); font-weight: 400; }
  .qc-table .nopts { font-size: 12.5px; font-style: italic; }
  .verb-cell { text-align: right; white-space: nowrap; }
  .verb-cell .row-verb + .row-verb, .verb-cell .adopt-form + .row-verb { margin-left: 6px; }
  .adopt-form { display: inline; margin: 0; }
  .shelf-card .shelf-sub { padding: 4px 20px 0; font-size: 12.5px; color: var(--ink-3); max-width: 72ch; }
  .clean-clause { color: var(--good); }
  .restamp-preview {
    border: 1px solid var(--gold-line); border-radius: 8px;
    background: var(--warn-soft); color: var(--ink-2);
    padding: 9px 14px; font-size: 12.5px;
  }
  .restamp-preview b { color: var(--ink); }

  @media (max-width: 640px) {
    .qc-table { font-size: 12.5px; }
    .ig-add { margin-left: 0; }
    .ig-add input { width: 130px; }
  }

  /* ---------- the point drawer (2026-07-27): the rail-world heir of the base_v5_3 point
     offcanvas. A native <dialog> docked right; the chromeless point-world pages (point.html
     and its satellites) live in the iframe exactly as they did in the offcanvas — their
     Bootstrap internals never leak into base_v6 (the leaflet_main topology answer applied).
     Interior rooms only (base_v6 renders it under rail_project). ---------- */
  dialog.point-drawer {
    position: fixed; inset: 0 0 0 auto; margin: 0; padding: 0;
    height: 100vh; max-height: 100vh;
    width: min(500px, calc(100vw - 32px)); max-width: 100vw;
    border: none; border-left: 1px solid var(--line); border-radius: 0;
    background: var(--surface); color: var(--ink);
    box-shadow: var(--shadow);
    display: none; flex-direction: column;
  }
  dialog.point-drawer[open] { display: flex; }
  dialog.point-drawer::backdrop { background: rgba(8, 12, 18, 0.45); }
  .pd-head {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 14px; border-bottom: 1px solid var(--line-soft); flex: none;
  }
  .pd-head .pd-title {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--ink-3);
  }
  /* the payload breathes — the offcanvas's p-3 heir; flex stretch minus margins does the width */
  dialog.point-drawer iframe { flex: 1; width: auto; margin: 8px 14px 14px; border: none; display: block; }

  /* ---------- the exporter shapes (2026-07-28, geopackage rotation — geopackage-rail.md):
     the feature-picker, column-picker, and blast-radius verb the export suite inherits.
     The filter segs reuse .dh-seg.decide-seg (gold — they shape the verb, by ruling). ---------- */
  .picker-card, .columns-card { margin-bottom: 18px; }
  /* heads ride the bare default (flip-the-default, 2026-08-07); the bordered in-card foot is this family's divergence */
  .picker-card .card-foot, .columns-card .card-foot { margin-top: 0; padding: 10px 20px 12px; border-top: 1px solid var(--line-soft); }
  .filters-row {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    padding: 12px 20px 4px;
  }
  /* the seg's SUBJECT, not row noise (Mark's catch: "Parked" didn't read as parked-points) —
     the card-head small-caps register, so "label of a thing" stays one house voice */
  .filters-row .lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-2); white-space: nowrap;
  }
  /* label + seg wrap as one unit — a stranded label above a wrapped seg is worse than a quiet one */
  .filters-row .filter-group { display: inline-flex; align-items: center; gap: 10px; }
  .picker-cols { display: flex; gap: 0; align-items: flex-start; flex-wrap: wrap; }
  .picker-half { flex: 1 1 320px; min-width: 0; }
  .picker-half + .picker-half { border-left: 1px solid var(--line-soft); }
  .picker-half .qc-table { margin-top: 6px; }
  .picker-half .qc-table td { padding: 6px 12px; }
  .picker-half .qc-table tbody tr:last-child td { border-bottom: none; }
  .picker-half .qc-table td:last-child, .picker-half .qc-table th:last-child { width: 40px; }
  .qc-table .num { text-align: right; }
  .qc-table th.sel-count {
    text-align: right; font-weight: 600; color: var(--ink-2);
    text-transform: none; letter-spacing: 0; font-size: 11.5px;
    /* "N of M" is one fact — never stacks, even beside a wrapping name column (the KMZ
       sketches card, 2026-08-22) */
    white-space: nowrap;
  }
  .count-badge {
    display: inline-flex; align-items: center;
    background: var(--mute-soft); color: var(--mute);
    border-radius: 999px; padding: 0 9px; font-size: 11.5px; font-weight: 600;
  }
  /* a layer filtered to zero dims rather than lying (the storefront facet grammar) */
  .picker-half tr.zero { opacity: 0.45; }
  .picker-half tr.zero .count-badge { background: transparent; border: 1px dashed var(--line); }
  .feat-check { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
  .col-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 3px 22px; padding: 10px 20px 14px;
  }
  .col-check { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--ink-2); }
  .col-check input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; flex: none; }
  .col-check.locked { color: var(--ink-3); }
  .col-check.locked input { accent-color: var(--mute); cursor: default; }
  .col-check .lock { font-size: 10px; color: var(--ink-3); }
  .verb-foot { align-items: center; }
  .verb-foot .epsg { font-size: 12px; color: var(--ink-3); max-width: 52ch; }
  .verb-foot .epsg b { color: var(--ink-2); font-weight: 600; }
  .verb-foot .primary-btn { margin-left: auto; }

  /* ---------- the linework room shapes (2026-07-28, dxf-3d-rail rotation — dxf-3d-rail.md):
     the layer plan (the mint — Chain colors travel into CAD), the layer identity pane
     (name + ACI grid, per-Assignment memory), and the runs summary. Cards reuse the
     .picker-card/.columns-card scoping above (the scoped-class lesson, honored by reuse). ---------- */
  .layer-plan { margin-top: 6px; }
  .layer-plan td { padding: 7px 12px; }
  .layer-plan tbody tr:last-child td { border-bottom: none; }
  /* a line with zero runs dims rather than lying (the storefront facet grammar) */
  .layer-plan tr.zero { opacity: 0.45; }
  .layer-plan .layer-name { font-weight: 600; color: var(--ink); }
  /* the verb IS the row's last cell (the for-each shape — one server-rendered verb per line);
     it wears the house .row-verb register (the takeover family) — N filled pills would shout */
  .layer-plan .verb-col { text-align: right; width: 1%; white-space: nowrap; }
  .ident-body { display: flex; gap: 28px; flex-wrap: wrap; padding: 12px 20px 14px; }
  .ident-field { display: flex; flex-direction: column; gap: 6px; }
  /* the control's SUBJECT wears the card-head small-caps register (the filter-label grammar) */
  .ident-field .lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-2);
  }
  .layer-input {
    font-size: 14px; padding: 7px 12px; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink); width: 230px; max-width: 100%;
  }
  .layer-input:focus { outline: 2px solid var(--gold-line); outline-offset: 1px; }
  .aci-grid { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
  .aci {
    width: 26px; height: 26px; border-radius: 6px; cursor: pointer;
    border: 1px solid rgba(0,0,0,0.22); padding: 0;
  }
  .aci.on { outline: 3px solid var(--gold-line); outline-offset: 1px; }
  .aci:hover { transform: scale(1.1); }
  @media (prefers-reduced-motion: reduce) { .aci:hover { transform: none; } }
  .memory-whisper { font-size: 12px; color: var(--ink-3); padding: 0 20px 4px; }
  .memory-whisper b { color: var(--ink-2); font-weight: 600; }
  .run-sum { display: flex; gap: 20px; flex-wrap: wrap; padding: 10px 20px 0; font-size: 13px; color: var(--ink-2); }
  .run-sum b { color: var(--ink); font-weight: 600; }
  .dxf-verb-foot { border-top: none; }

  /* ---------- Attributed Joints room (2026-08-15+1, build-attributed-joints.md): only what the
     linework family doesn't already own — the vertex picker's check grid and the instructive
     card's prose. Everything else reuses .picker-card, .layer-plan, the ident pair, .check-row
     and .dh-select (the scoped-class lesson, honored by reuse). NOTE the first cut of this very
     comment ate the rule below it: a glob-then-slash in prose ("ident-star-slash") spells the
     comment CLOSER, so the parser woke mid-sentence, read the tail as a selector, and swallowed
     .aj-picker's block whole — never write asterisk-slash inside a comment. ---------- */
  .aj-picker {
    padding: 12px 20px 6px;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 0 28px;
  }
  .aj-picker .check-row { margin-bottom: 8px; }
  .aj-picker .check-row label b { color: var(--ink); }
  .aj-teach { padding: 12px 20px 16px; font-size: 13.5px; color: var(--ink-2); max-width: 72ch; }
  .aj-teach b { color: var(--ink); }
  /* the quiet secondary verb sits at the foot's far edge, off the hint's reading line */
  .aj-recount { margin-left: auto; }
  /* the export verbs wear the primary dress like the other export rooms (Mark, 2026-08-15+1);
     the pair just needs its gap — scoped so the DXF room's row-verb chips stay theirs */
  .aj-verbs .primary-btn + .primary-btn { margin-left: 6px; }

  /* ================= Fieldwork Calendar — the house-baked month grid =================
     The engine-swap rotation (fieldwork-calendar-rail.md, 2026-07-29): FullCalendar +
     bootstrap-icons CDNs died for this section. Pills wear per-chief colors via the
     --pill-c/--pill-bg custom properties set inline by the room's renderer. */
  /* head rides the bare default (flip-the-default, 2026-08-07); the bordered foot is the divergence */
  .cal-card .card-foot { margin-top: 0; padding: 10px 20px 12px; border-top: 1px solid var(--line-soft); }
  .leg { display: inline-flex; gap: 8px; flex-wrap: wrap; align-items: center; }
  .leg-chip {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 12px; padding: 3px 12px 3px 9px; cursor: pointer; font-family: inherit;
    border: 1px solid var(--check-line); border-radius: 999px;
    background: var(--surface); color: var(--ink-2);
  }
  .leg-chip .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
  .leg-chip .ct { color: var(--ink-3); font-size: 11px; }
  .leg-chip:hover { border-color: var(--accent); color: var(--ink); }
  .leg-chip.on { background: var(--accent-soft); border-color: var(--accent); color: var(--ink); font-weight: 600; }

  .cal-bar {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 12px 20px 12px;
  }
  .cal-title { font-size: 17px; font-weight: 700; color: var(--ink); min-width: 150px; }
  .cal-nav {
    background: var(--surface); border: 1px solid var(--check-line); border-radius: 7px;
    color: var(--btn-ink); cursor: pointer; font-family: inherit;
    font-size: 14px; padding: 3px 11px; line-height: 1.4;
  }
  .cal-nav:hover { border-color: var(--accent); color: var(--ink); }
  /* the jump select declares itself (Mark, 2026-07-29: ‹ › is standard fare, but "this lists
     only months with data" was discover-by-experiment — the Abby lens: explicit labeled
     controls over hidden affordances). Label wears the house small-caps register; the label +
     select wrap as ONE unit (the stranded-label lesson, filters-row precedent). */
  .cal-jump-group { display: inline-flex; align-items: center; gap: 8px; }
  .cal-jump-group .lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-2);
  }
  .cal-jump {
    font-family: inherit; font-size: 12.5px; color: var(--ink-2);
    background: var(--surface-2); border: 1px solid var(--check-line); border-radius: 7px;
    padding: 4px 8px; cursor: pointer;
  }
  .cal-latest {
    background: none; border: none; color: var(--accent); cursor: pointer;
    font-family: inherit; font-size: 12.5px; text-decoration: underline; padding: 0;
  }
  .cal-empty-note { font-size: 12.5px; color: var(--ink-3); margin-left: auto; }

  .cal { border-top: 1px solid var(--line); }
  .cal-dow {
    display: grid; grid-template-columns: repeat(7, 1fr);
    background: var(--surface-2); border-bottom: 1px solid var(--line);
  }
  .cal-dow div {
    padding: 5px 8px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-3); text-align: right;
  }
  .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
  .cal-day {
    min-height: 96px; padding: 5px 6px 7px;
    border-bottom: 1px solid var(--line-soft); border-right: 1px solid var(--line-soft);
    background: var(--surface);
  }
  .cal-day:nth-child(7n) { border-right: none; }
  .cal-day.wknd { background: var(--surface-2); }
  .cal-day.out { background: var(--ground); }
  .cal-day.out .dnum { opacity: 0.45; }
  .cal-day.today .dnum {
    background: var(--gold-line); color: #171207; border-radius: 999px;
    padding: 0 6px; font-weight: 700;
  }
  .dnum {
    display: inline-block; font-size: 11px; color: var(--ink-3);
    font-family: 'Ubuntu Mono', 'Consolas', monospace; margin-bottom: 2px;
  }

  .pill {
    display: block; text-decoration: none;
    font-size: 11.5px; line-height: 1.35;
    color: var(--ink-2);
    background: var(--pill-bg, var(--mute-soft));
    border-left: 3px solid var(--pill-c, var(--mute));
    border-radius: 4px;
    padding: 2px 7px; margin-top: 3px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .pill b { color: var(--ink); font-weight: 600; }
  .pill:hover { outline: 1px solid var(--pill-c, var(--mute)); color: var(--ink); }
  .pill.dim { opacity: 0.25; }
  .more-btn {
    display: block; width: 100%; text-align: left; cursor: pointer;
    background: none; border: none; font-family: inherit;
    font-size: 11px; color: var(--accent); padding: 2px 7px 0; margin: 0;
  }
  .more-btn:hover { text-decoration: underline; }
  .cal-day.expanded .pill.over { display: block; }
  .pill.over { display: none; }

  .shelf {
    display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
    padding: 10px 20px 12px; border-top: 1px solid var(--line-soft);
    background: var(--warn-soft);
    border-radius: 0 0 var(--radius) var(--radius);
    font-size: 12.5px; color: var(--ink-2);
  }
  .shelf .shelf-lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--warn); flex: none;
  }
  .shelf .pill { display: inline-block; margin-top: 0; }
  .shelf .why { color: var(--ink-3); font-size: 12px; }

  @media (max-width: 640px) {
    .cal-day { min-height: 74px; }
    .pill { font-size: 10.5px; }
  }

  /* =================== Validation room (the first QC-sibling rotation, 2026-07-30;
     design of record: mockups/validation-rail.html + validation-rail.md) =================== */
  .table-card .verdict-bar { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; padding: 12px 20px 0; }
  .table-card .verdict-ctx { font-size: 12.5px; color: var(--ink-3); }
  /* verbs live at the TOP on long tables (Mark's ruling 2026-07-30): a bust list can run to
     hundreds of rows and a card-foot verb scrolls out of reach — the classic page's own
     placement, kept for its functional reason. Foot chips remain right for SHORT tables
     (begend's rules list); QC siblings with long findings tables inherit this bar. */
  .table-card .verbs-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 20px 2px; }
  .table-card .verbs-bar .hint { font-size: 12px; color: var(--ink-3); }
  .table-card .verbs-bar .foot-right { margin-left: auto; }
  .val-att i { color: var(--ink-3); }
  .val-att-none { color: var(--ink-3); }
  .val-issue { color: var(--bad); font-weight: 500; font-size: 13px; }
  /* qc-owner + qc-clean: born val-* at the validation rotation; renamed at the rule-of-two
     moment (duplicates = the second consumer, 2026-07-31) — the Owned By cell and the earned
     clean card are FAMILY registers, not validation's own. */
  .qc-owner { color: var(--ink-2); font-size: 13px; white-space: nowrap; }
  .qc-table th.sel-head { white-space: nowrap; }
  .qc-table th.sel-head label { cursor: pointer; margin-left: 6px; }
  .qc-table td.sel-cell { text-align: center; }
  /* the clean card (bracket A): the room exists when the news is good, and earns its green by
     naming its evidence */
  .qc-clean { padding: 20px; margin-bottom: 18px; }
  .qc-clean .clean-line { display: flex; align-items: baseline; gap: 10px; font-size: 15px; font-weight: 600; color: var(--good); }
  .qc-clean .clean-ctx { margin: 8px 0 0; font-size: 13.5px; color: var(--ink-2); max-width: 66ch; }
  .qc-clean .clean-foot { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--line-soft); display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .qc-clean .clean-foot .hint { font-size: 12px; color: var(--ink-3); }
  .qc-clean .clean-foot .foot-right { margin-left: auto; }

  /* =================== Tie Ins room (the fourth QC-sibling rotation, 2026-08-03;
     design of record: mockups/clusters-rail.html + clusters-rail.md). The ONE-ROOM specimen:
     no rules room — per-line sections (EXPANDED, bracket A) hold pair cards, and each pair is
     the room's soul: facts line + two point rows + the justify row. =================== */
  .room-verbs { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
  .room-verbs .hint { font-size: 12px; color: var(--ink-3); }
  .room-verbs .foot-right { margin-left: auto; }
  .line-card { margin-bottom: 18px; }
  .line-head {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 13px 20px 11px; border-bottom: 1px solid var(--line-soft);
  }
  /* the line name wears GOLD (Mark's walk catch, 2026-08-03): on a multi-line project the eye
     needs the collection boundaries to jump — the name is the wayfinding anchor between
     sections. Renders only on multi-line pages (single-line has no section furniture). */
  .line-head .line-name { font-size: 15px; font-weight: 700; color: var(--gold); }
  .line-head .clear-all { margin-left: auto; }
  /* a clean line compresses to one clean row (bracket A) — never an empty card */
  .line-clean { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 13px 20px; }
  .line-clean .line-name { font-size: 15px; font-weight: 700; color: var(--gold); }
  .line-clean .ctx { font-size: 12.5px; color: var(--ink-3); }

  .pair {
    border-bottom: 1px solid var(--line-soft);
    padding: 12px 20px 14px; overflow: hidden;
    transition: opacity .35s ease, max-height .35s ease;
  }
  .pair.dh-dissolving { opacity: 0; }
  .pair:last-of-type { border-bottom: none; }
  .pair-facts { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
  .pair-code { font-weight: 700; color: var(--ink); font-size: 14px; white-space: nowrap; }
  .pair-metric { font-size: 12.5px; color: var(--ink-2); }
  .pair-metric .mono { color: var(--ink); }
  /* the Same-attributes pill — graduated from the classic parenthetical: identical attributes
     mean the same physical point shot twice, the room's strongest signal */
  .atts-pill {
    display: inline-flex; align-items: center; gap: 5px;
    background: var(--bad-soft); color: var(--bad);
    border-radius: 999px; padding: 1px 10px; font-size: 11.5px; font-weight: 700; white-space: nowrap;
  }
  .pair-facts .fact-right { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .pair-link {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12.5px; color: var(--accent); text-decoration: none; white-space: nowrap;
  }
  .pair-link:hover { text-decoration: underline; text-underline-offset: 2px; }
  .pair-link svg { flex: none; }

  details.tol-menu { position: relative; display: inline-block; }
  details.tol-menu > summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
    border: 1px solid var(--check-line); border-radius: 7px; background: var(--btn-fill);
    padding: 3px 10px; font-size: 12px; color: var(--btn-ink); white-space: nowrap;
  }
  details.tol-menu > summary::-webkit-details-marker { display: none; }
  details.tol-menu > summary .caret { color: var(--ink-3); font-size: 10px; }
  details.tol-menu[open] > summary { border-color: var(--accent); }
  .tol-list {
    position: absolute; top: calc(100% + 5px); right: 0; z-index: 40; min-width: 150px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
    box-shadow: var(--shadow); padding: 5px; max-height: 300px; overflow-y: auto;
  }
  .tol-list button {
    display: block; width: 100%; text-align: left;
    background: none; border: none; cursor: pointer; font-family: inherit;
    padding: 6px 11px; border-radius: 7px;
    color: var(--ink-2); font-size: 12.5px; white-space: nowrap;
  }
  .tol-list button:hover { background: var(--accent-soft); color: var(--ink); }
  .tol-list button.ignore { color: var(--bad); }
  .tol-static { font-size: 12px; color: var(--ink-3); font-style: italic; white-space: nowrap; }

  .pair-table { width: 100%; border-collapse: collapse; font-size: 13.5px; margin-top: 6px; }
  .pair-table th {
    text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 5px 10px 5px 0; border-bottom: 1px solid var(--line-soft);
  }
  .pair-table td { padding: 6px 10px 6px 0; vertical-align: middle; }
  .pair-table tr:hover td { background: var(--surface-2); }
  .pair-table .verb-cell { text-align: right; white-space: nowrap; }
  .code-whisper { color: var(--ink-3); font-size: 12px; }

  .justify-row { display: flex; align-items: center; gap: 9px; margin-top: 9px; }
  .justify-input {
    flex: 1; min-width: 0;
    font-family: inherit; font-size: 13px; color: var(--ink);
    /* surface-2 well, not surface (Mark's dark walk, 2026-08-13): on the card the surface fill
       was invisible — the field family's well is what says "type here" */
    background: var(--surface-2); border: 1px solid var(--check-line); border-radius: 7px;
    padding: 6px 11px;
  }
  .justify-input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .justify-btn {
    background: var(--btn-fill); border: 1px solid var(--check-line); color: var(--btn-ink);
    border-radius: 7px; padding: 6px 14px; font-size: 12.5px; cursor: pointer; font-family: inherit;
    white-space: nowrap;
  }
  .justify-btn:hover { border-color: var(--accent); background: var(--btn-hover); color: var(--ink); }
  .justify-btn:disabled { opacity: 0.5; cursor: wait; }

  .just-zone { padding: 10px 20px 13px; border-top: 1px solid var(--line-soft); }
  .just-zone .zone-lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3); margin-bottom: 7px;
  }
  .just-pill {
    display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
    background: var(--mute-soft); color: var(--ink-2);
    border-radius: 999px; padding: 3px 7px 3px 13px; font-size: 12.5px;
    margin: 0 8px 6px 0;
  }
  .just-pill b { color: var(--ink); font-weight: 600; }
  .just-pill .quote { font-style: italic; }
  .just-pill .restore-form { margin: 0; display: inline; }
  .just-pill .restore {
    background: none; border: 1px solid var(--check-line); border-radius: 999px;
    color: var(--ink-3); font-size: 11px; padding: 1px 9px; cursor: pointer; font-family: inherit;
  }
  .just-pill .restore:hover { border-color: var(--accent); color: var(--accent); }

  /* the middle-point new-pair reload hint (the classic mechanic, rail dress) */
  .reload-hint {
    display: none; align-items: baseline; gap: 10px;
    border: 1px solid var(--gold-line); border-radius: var(--radius);
    background: var(--warn-soft); color: var(--ink-2);
    padding: 10px 18px; font-size: 13px; margin: 10px 20px 14px;
  }

  /* =================== Ahead-Back room (the fifth and LAST QC-sibling rotation, 2026-08-03;
     design of record: mockups/aheadback-rail.html + aheadback-rail.md). The SPREADSHEET
     specimen: the contenteditable grid is the room's soul — bust cells scream and edit in
     place, blue = edited this visit (the classic register kept), and the live repaint
     silences both diagonal cells of a fixed pair. Line grammar + gold names inherited from
     the Tie Ins block above. =================== */
  .rules-card { margin-bottom: 18px; }
  .rules-card .rule-zone {
    padding: 10px 20px 13px;
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  }
  .rules-card .rule-zone + .card-head { border-top: 1px solid var(--line-soft); padding-top: 12px; }
  .def-chip {
    display: inline-flex; align-items: center; gap: 7px;
    background: var(--mute-soft); color: var(--ink-2);
    border-radius: 999px; padding: 2px 7px 2px 12px; font-size: 12.5px; font-weight: 600;
  }
  .def-chip .chip-form { margin: 0; display: inline-flex; }
  .def-chip .x {
    background: none; border: none; cursor: pointer; font-family: inherit;
    color: var(--ink-3); font-size: 12px; line-height: 1; padding: 2px 5px; border-radius: 999px;
  }
  .def-chip .x:hover { background: var(--accent-soft); color: var(--accent); }
  /* the orphaned pair wears its warning ON the chip (bracket A): a chain that is not being
     checked must say so persistently — the classic transient flash vanished on next load */
  .def-chip.orphan {
    background: var(--warn-soft); color: var(--warn);
    border: 1px solid var(--gold-line);
  }
  .def-chip.orphan .why { font-weight: 400; font-size: 11.5px; }
  .def-chip.orphan .why b { color: var(--warn); }
  /* the builder wears the dashed border of the NOT-YET-BORN (the house convention minted at the
     "+ New Project" ruling, applied inline at Mark's walk catch 2026-08-03): amid the built pair
     chips, the dashed enclosure is what marks "this is where a new one is born" at a glance */
  .rules-card .builder-row {
    display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0;
    border: 1px dashed var(--line); border-radius: 9px;
    background: var(--surface-2); padding: 5px 10px;
  }
  .rules-card .builder-row .sep { font-size: 12px; color: var(--ink-3); }
  .rules-card .builder-row select, .rules-card .builder-row input[type="text"] {
    font-family: inherit; font-size: 12.5px; color: var(--ink);
    background: var(--surface); border: 1px solid var(--check-line); border-radius: 7px;
    padding: 5px 9px;
  }
  .rules-card .builder-row select:focus, .rules-card .builder-row input:focus {
    outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent);
  }
  .rules-card .add-btn {
    background: var(--btn-fill); border: 1px solid var(--check-line); color: var(--btn-ink);
    border-radius: 7px; padding: 5px 13px; font-size: 12.5px; cursor: pointer; font-family: inherit;
    white-space: nowrap; box-shadow: var(--btn-shadow);
  }
  .rules-card .add-btn:hover { border-color: var(--accent); background: var(--btn-hover); color: var(--ink); }
  .rules-card .zone-hint { font-size: 12px; color: var(--ink-3); flex-basis: 100%; }

  /* the stretch — one map-framed run of adjacent busted welds */
  .stretch { padding: 12px 20px 16px; border-bottom: 1px solid var(--line-soft); }
  .stretch:last-of-type { border-bottom: none; }
  .stretch-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
  .stretch-name { font-weight: 700; color: var(--ink); font-size: 13.5px; white-space: nowrap; }
  .stretch-meta { font-size: 12.5px; color: var(--ink-2); white-space: nowrap; }
  .stretch-meta .mono { color: var(--ink); }
  .stretch-head .fact-right { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; }
  .stretch-link {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12.5px; color: var(--accent); text-decoration: none; white-space: nowrap;
  }
  .stretch-link:hover { text-decoration: underline; text-underline-offset: 2px; }
  .stretch-link svg { flex: none; }

  /* the grid — the spreadsheet itself. Cell registers: bust (screaming, editable), pending
     (in flight — the cell never claims a save that didn't happen), edited (blue, the classic
     meaning kept), error (revert-and-red), partner-glow (the hover's diagonal pointer). */
  /* the fence (Equitrans census, 2026-08-22): a wide pair roster scrolls inside the card —
     the ancestor spreadsheet's own answer — instead of walking out of the card paint */
  .ab-scroll { overflow-x: auto; }
  .ab-grid { width: 100%; border-collapse: collapse; font-size: 13.5px; margin-top: 6px; }
  .ab-grid th {
    /* headers wrap at their underscore seams (the template's underscore_breaks filter) —
       nowrap here once let eight long ALL_CAPS names force a 1500px table (same census) */
    text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-3); vertical-align: bottom;
    padding: 5px 10px 5px 0; border-bottom: 1px solid var(--line-soft);
  }
  .ab-grid td { padding: 5px 10px 5px 0; vertical-align: middle; }
  .ab-grid tr:hover td { background: var(--surface-2); }
  .ab-grid td.att { min-width: 86px; }
  .ab-grid td.att > div { border-radius: 6px; padding: 2px 8px; min-height: 1.4em; }
  .ab-grid td.att.cell-bust > div {
    background: var(--bad-soft); color: var(--bad); font-weight: 700;
  }
  .ab-grid td.att.cell-bust > div[contenteditable="true"] { cursor: text; }
  .ab-grid td.att.cell-bust > div[contenteditable="true"]:focus {
    background: var(--warn-soft); outline: 1px solid var(--gold-line); color: var(--ink);
  }
  .ab-grid td.att.cell-edited > div {
    background: var(--accent-soft); color: var(--accent); font-weight: 600;
  }
  .ab-grid td.att.cell-pending > div { opacity: 0.55; }
  .ab-grid td.att.cell-error > div { background: var(--bad-soft); color: var(--ink); outline: 1px solid var(--bad); }
  .ab-grid td.att.partner-glow > div { outline: 2px solid var(--gold-line); }
  .bust-pill.all-clear { background: var(--good-soft); color: var(--good); }

  /* the standing-alone shelf (bracket B): the counted-but-never-listed welds, listed */
  .shelf { padding: 10px 20px 14px; border-top: 1px dashed var(--line); }
  .shelf .zone-lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3); margin-bottom: 2px; display: flex; align-items: center; gap: 8px;
  }
  .shelf .shelf-hint { font-size: 12px; color: var(--ink-3); margin: 0 0 4px; }

  /* =================== The manifests pair (the SIXTH QC-sibling rotation + the first
     Configuration-family Xref room, 2026-08-04; design of record: mockups/manifests-rail.md,
     four brackets ratified at the walk). Two rooms share this section: Manifest Queries
     (verdict table + the re-seated builder) and Manifest Management (the tally shelf). */

  /* the warn-toned whisper (feeds-nothing tallies, and any future soft caution chip) */
  .warn-chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--warn-soft); color: var(--warn);
    border-radius: 999px; padding: 1px 9px; font-size: 11px; font-weight: 600; white-space: nowrap;
  }

  /* ---- the query table (Manifest Queries) ---- */
  .q-card { margin-bottom: 18px; }
  .q-summary {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 13px 20px 11px; border-bottom: 1px solid var(--line-soft);
    font-size: 13px; color: var(--ink-2);
  }
  .q-summary .fact { white-space: nowrap; }
  .q-summary .fact b { color: var(--ink); }
  .q-summary .fact .miss { color: var(--warn); font-weight: 600; }
  .q-summary .fact-right { margin-left: auto; font-size: 12px; color: var(--ink-3); }
  .q-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
  .q-table th {
    text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 9px 12px 7px 20px; border-bottom: 1px solid var(--line-soft); white-space: nowrap;
  }
  .q-table th.num, .q-table td.num { text-align: right; }
  .q-table td { padding: 10px 12px 10px 20px; vertical-align: middle; border-bottom: 1px solid var(--line-soft); }
  .q-table tbody tr:last-child td { border-bottom: none; }
  .q-table tbody tr:hover td { background: var(--surface-2); }
  .q-ident .q-name { font-weight: 600; font-size: 13.5px; display: flex; align-items: center; gap: 7px; }
  .q-ident .q-join { font-size: 11.5px; color: var(--ink-3); margin-top: 1px; }
  .q-ident .q-join .mono { color: var(--ink-2); }
  .q-scope { display: flex; flex-direction: column; gap: 3px; align-items: flex-start; }
  .q-table td.num .good { color: var(--good); font-weight: 600; }
  .q-table td.num .miss { color: var(--warn); font-weight: 600; }
  .q-table td.num .none { color: var(--ink-3); }
  /* the special-query type glyph (walk catch): tally-vs-tally and 3D Inverse run different
     machinery than a survey-vs-tally check — the tinted badge leads the eye, the row text
     keeps the words (glyph leads, words stay faithful — the two-channel rule) */
  .q-type {
    display: inline-flex; align-items: center; justify-content: center;
    width: 21px; height: 21px; border-radius: 6px; flex: none;
    background: var(--accent-soft); color: var(--accent);
  }
  .q-type svg { width: 13px; height: 13px; }

  /* the row-verb menu — native <details> popover, light-dismissed by dh page script */
  .row-verbs { display: flex; gap: 6px; align-items: center; justify-content: flex-end; }
  details.row-menu { position: relative; display: inline-block; }
  /* RULED 2026-08-05 (Mark, the Tally Table walk): a summary that opens a DROPDOWN wears the
     down-caret — the typical hint for the behavior (the user-chip's affordance, made the rule).
     Rides ::after on every row-menu so no site opts in by markup; no color of its own, so it
     follows the summary's open-state accent flip. Disclosure folds (api-fold, reduce-fold,
     rail-group) keep their rotating ▸ — they reveal content in place, a caret would lie. */
  details.row-menu > summary::after { content: "▾"; margin-left: 5px; font-size: 9.5px; }
  details.row-menu > summary {
    list-style: none; cursor: pointer;
    border: 1px solid var(--check-line); border-radius: 7px; background: var(--btn-fill);
    color: var(--btn-ink); padding: 3px 10px; font-size: 11.5px; white-space: nowrap;
  }
  details.row-menu > summary::-webkit-details-marker { display: none; }
  details.row-menu > summary:hover { border-color: var(--accent); color: var(--ink); }
  details.row-menu[open] > summary { border-color: var(--accent); color: var(--accent); }
  details.row-menu .menu-pop {
    /* z above Leaflet's panes/controls (≤1000): the kin-pair map card hosts a Leaflet whose
       tile panes share this stacking context — a z-30 pop opened INVISIBLY under the tiles
       (Mark's dress note 2026-08-08; the first fix landed in a lower-specificity duplicate
       and never applied — this house rule is the one that wins) */
    position: absolute; right: 0; top: calc(100% + 4px); z-index: 1200;
    background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
    box-shadow: var(--shadow); min-width: 170px; padding: 6px;
  }
  details.row-menu .menu-pop form { margin: 0; }
  details.row-menu .menu-pop .mi {
    display: block; width: 100%; text-align: left; background: none; border: none;
    font-family: inherit; font-size: 12.5px; color: var(--ink-2); padding: 5px 10px;
    border-radius: 6px; cursor: pointer; text-decoration: none;
  }
  details.row-menu .menu-pop .mi:hover { background: var(--accent-soft); color: var(--ink); }
  /* the row's CURRENT value, marked in its own menu (the tolerance filter's "what is it now") */
  details.row-menu .menu-pop .mi.on { color: var(--accent); font-weight: 600; }
  details.row-menu .menu-pop .mh {
    font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-3); padding: 5px 10px 3px;
  }

  /* ---- the builder — the dashed border of the NOT-YET-BORN at CARD scale (the aheadback
     inline convention's first card-scale inheritor): amid the built rows above it, the
     dashed enclosure marks "this is where a new one is born" at a glance ---- */
  .builder-card {
    border: 1.5px dashed var(--line); border-radius: var(--radius);
    background: var(--surface-2); margin-bottom: 18px;
  }
    .builder-body { padding: 12px 20px 16px; display: flex; gap: 26px; flex-wrap: wrap; }
  .builder-body .cluster { flex: 1; min-width: 220px; }
  .builder-body .cl-lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3); margin-bottom: 7px;
  }
  .builder-body .fld { margin-bottom: 9px; }
  .builder-body .fld label { font-size: 11.5px; font-weight: 400; color: var(--ink-3); margin-bottom: 2px; }
  .fld select {
    width: 100%; font-family: inherit; font-size: 12.5px; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 7px;
    padding: 5px 9px;
  }
  .fld select:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .pair-arrow { text-align: center; color: var(--ink-3); font-size: 12px; margin: 2px 0 4px; }
  .reco {
    flex-basis: 100%; font-size: 12.5px; border-radius: 8px; padding: 8px 13px;
    border: 1px solid var(--gold-line); background: var(--warn-soft); color: var(--ink-2);
  }
  .reco b { color: var(--gold); }
  .reco.low b { color: var(--warn); }
  .builder-foot { flex-basis: 100%; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
  .builder-foot .hint { font-size: 12px; color: var(--ink-3); }
  .builder-foot form { margin: 0; }

  /* ---- the tally shelf (Manifest Management) ---- */
  .m-card { margin-bottom: 18px; }
  .m-row { border-bottom: 1px solid var(--line-soft); }
  .m-row:last-child { border-bottom: none; }
  .m-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 12px 20px 8px; }
  /* the filename is a gold LABEL, not a door — a SITUATIONAL exception to name-as-door
     (2026-08-11; the principle stands elsewhere): link-blue was drowning the tally name's
     importance, and the Table chip already provides the door. Gold = the house identity
     register, .line-name kin */
  .m-name { font-weight: 600; font-size: 14px; color: var(--gold); }
  .m-facts { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
  .m-head .fact-right { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
  .m-head .fact-right form { margin: 0; display: inline-flex; }
  /* columns display OPEN, never folded (the walk's catch): the header row is the quickest
     malformed-import tell — blank headers, Unnamed: N, one mega-column from a bad parse */
  .col-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 0 20px 14px; }
  .col-chips .cols-lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3); margin-right: 2px;
  }
  .col-chip {
    /* full ink + a hairline (Mark's walk catch, 2026-08-13): column names are diagnostic
       content — the malformed-import tell — not decoration; the washed-out dress buried them */
    background: var(--mute-soft); color: var(--ink); border: 1px solid var(--line); border-radius: 4px;
    padding: 1px 7px; font-size: 11.5px; font-weight: 500;  /* via-tag geometry (Mark, 2026-08-13): data labels wear the rounded rectangle, not the pill */
  }
  .col-chip.blank { font-style: italic; color: var(--warn); background: var(--warn-soft); border-color: var(--gold-line); }  /* the bust signal wears warn, not a whisper (docket ruling — a blank header IS the malformed-import tell) */

  /* the xref head zone (bracket D — the three-state pattern the Xref families inherit) */
  .xref-zone {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 12px 20px; border-bottom: 1px solid var(--line-soft);
    font-size: 13px; color: var(--ink-2);
  }
  .xref-zone .x-lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3);
  }
  .xref-zone .fact-right { margin-left: auto; }
  details.row-menu .menu-pop input.menu-filter {
    width: 100%; font-family: inherit; font-size: 12px; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--check-line); border-radius: 6px;
    padding: 4px 8px; margin: 2px 0 4px;
  }

  /* the upload instrument — the room's birth verb, dh field family */
  .upload-zone { padding: 12px 20px 16px; display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
  .upload-zone .fld { flex: 1; min-width: 260px; margin: 0; }
  .upload-zone form { display: contents; }
  .upload-side { flex-basis: 100%; font-size: 12px; color: var(--ink-3); max-width: 76ch; }

  /* =================== Manifests DETAIL rooms (three siblings behind the dispatcher,
     2026-08-04; design of record: mockups/manifests-details-rail.html + .md, all six
     brackets ruled same-day). The identity card is the list's q-ident grammar transplanted
     — a query reads identically on its row and in its room; the vs columns tint the two
     compared values; the golden-Blank refusal renders as a .forbid note, never a checkbox. */
  .ident-card { margin-bottom: 18px; }
  .ident-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 14px 20px 4px; }
  .ident-row .q-type { width: 26px; height: 26px; border-radius: 7px; }
  .ident-row .q-type svg { width: 15px; height: 15px; }
  .ident-row .q-name { font-weight: 600; font-size: 16px; }
  .ident-row .q-scope { display: inline-flex; gap: 6px; flex-wrap: wrap; align-items: center; }
  .ident-row .ident-tools { margin-left: auto; }
  .ident-join { padding: 0 20px 10px; font-size: 12.5px; color: var(--ink-3); }
  .ident-join .mono { color: var(--ink-2); }
  /* the tally filename is a DOOR (datatable, new tab) — the .mono register rule above was
     out-ranking .pt-link's at-rest accent (two classes beat one), muting exactly the signal
     "blue is the reflex for what's open-able" exists to give (Mark's walk, 2026-08-04) */
  .ident-join a.pt-link { color: var(--link); }
  .ident-facts {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 9px 20px 12px; border-top: 1px solid var(--line-soft);
    font-size: 13px; color: var(--ink-2);
  }
  .ident-facts .fact { white-space: nowrap; }
  .ident-facts .fact b { color: var(--ink); }
  .ident-facts .miss { color: var(--warn); font-weight: 600; }
  .ident-facts .fact-right { margin-left: auto; font-size: 12px; color: var(--ink-3); }
  /* (.table-card .card-head .hd-right retired 2026-08-14 — generalized to bare .card-head .hd-right) */
  /* the two compared values wear a quiet tint — the row's subject, side by side */
  .qc-table th.vs, .qc-table td.vs { background: var(--surface-2); }
  .qc-table .val-blank { font-style: italic; color: var(--ink-3); }
  /* the non-matchable notes (golden Blank + forbidden character): quiet refusals, not errors */
  .forbid { color: var(--ink-3); font-size: 12px; font-style: italic; white-space: nowrap; }
  .join-x {
    background: none; border: none; cursor: pointer; color: var(--ink-3);
    font-size: 12px; padding: 0 3px; font-family: inherit; line-height: 1;
  }
  .join-x:hover { color: var(--bad); }
  .miss-val { color: var(--warn); font-style: italic; font-size: 12.5px; }
  .le-tag { font-size: 10.5px; color: var(--ink-3); font-weight: 600; margin-left: 3px; }
  .delta-over { color: var(--bad); font-weight: 700; }
  .delta-under { color: var(--accent); font-weight: 700; }
  .delta-ok { color: var(--good); font-weight: 700; font-size: 12px; }
  /* the inverse filter sentence — the room's tolerance instrument, dressed as prose */
  .filter-line {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 10px 20px 2px; font-size: 13px; color: var(--ink-2);
  }
  form.filter-line { margin: 0; }
  .filter-line input[type="number"] {
    width: 90px; font-family: 'Ubuntu Mono', 'Consolas', monospace; font-size: 13px;
    color: var(--ink); background: var(--surface-2); border: 1px solid var(--check-line);
    border-radius: 7px; padding: 4px 9px;
  }
  .filter-line input[type="number"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .filter-line .hint { font-size: 12px; color: var(--ink-3); }
  /* a button that reads as a pt-link (the show-all flip, the in-table Map/ignore verbs) */
  button.flip-link { background: none; border: none; padding: 0; cursor: pointer; font-family: inherit; font-size: inherit; }
  .ig-card { margin-bottom: 18px; }
  /* frozen header inside the contained scroll (Mark, 2026-08-04 — the console's recipe
     inherited): a 105-row Not Found table scrolls its column names out of reach. Scoped to
     qc-tables that opted INTO .table-scroll (today: the three detail rooms; a sibling that
     wraps its table later inherits for free). border-collapse flips to separate (collapsed
     borders don't stick) and the head's line rides an inset shadow, the console's answer. */
  .table-scroll .qc-table { border-collapse: separate; border-spacing: 0; margin-top: 0; }
  .table-scroll .qc-table th {
    position: sticky; top: 0; z-index: 2;
    background: var(--surface);
    border-bottom: none;
    box-shadow: inset 0 -1px 0 var(--line);
  }
  .table-scroll .qc-table th.vs { background: var(--surface-2); }
  /* ============ the Tally Table room (manifests-children rotation, 2026-08-05 — design of
     record mockups/manifests-children-rail.md). DataTables 2.x runs the ENGINE with no vendor
     CSS on the page — everything below is the house's own dress: sort carets, filter row,
     info line, menus. The vendor pair loads page-level from static/vendor/ (jQuery is a
     page-level guest in the rail world — never base furniture). ============ */
  .title-file { font-size: 16px; color: var(--ink-2); }
  .t-card { margin-bottom: 18px; }
  /* head rides the bare default (flip-the-default, 2026-08-07); wrap is this card's divergence */
  .t-card .card-head { flex-wrap: wrap; }
  .t-card .card-head .whisper-chip, .t-card .card-head .warn-chip { text-transform: none; letter-spacing: 0; }
  /* (.t-card .card-head .hd-right retired 2026-08-14 — generalized to bare .card-head .hd-right) */
  .tt-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 20px; }
  .tt-search input {
    font-family: inherit; font-size: 13px; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--check-line); border-radius: 8px;
    padding: 6px 11px; width: 240px; max-width: 100%;
  }
  .tt-search input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .tt-right { margin-left: auto; display: inline-flex; gap: 8px; align-items: center; flex-wrap: wrap; }
  .filter-whisper { padding: 0 20px 10px; font-size: 12px; color: var(--ink-3); }
  .filter-whisper .mono { color: var(--ink-2); }
  .tt-scroll { max-height: 72vh; border-top: 1px solid var(--line-soft); }
  .tt-table td { white-space: nowrap; padding: 6px 12px 6px 14px; font-size: 13px; }
  /* two sticky tiers: the title row holds a fixed 33px height so the filter row can pin under it */
  .tt-table thead tr:first-child th { height: 33px; box-sizing: border-box; white-space: nowrap; }
  .tt-table thead tr.filter-row th {
    top: 33px; padding: 5px 8px 7px 10px; vertical-align: middle;
    box-shadow: inset 0 -1px 0 var(--line);
  }
  .tt-table thead tr.filter-row input {
    width: 100%; min-width: 72px; font-family: 'Ubuntu Mono', 'Consolas', monospace; font-size: 12px;
    color: var(--ink); background: var(--surface-2); border: 1px solid var(--line-soft);
    border-radius: 6px; padding: 3px 7px;
  }
  .tt-table thead tr.filter-row input:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  /* a bad regex outlines red instead of silently matching nothing */
  .tt-table thead tr.filter-row input.re-bad { border-color: var(--bad); outline-color: var(--bad); }
  /* the Unnamed:N header — a data-carrying blank-header column (the klandis class): the
     malformed-import tell wears the warn ink, same lesson as the shelf's --blank-- chip */
  .tt-table th.tt-unnamed { color: var(--warn); }
  /* DataTables 2.x ordering classes, dressed by tokens */
  .tt-table thead th.dt-orderable-asc, .tt-table thead th.dt-orderable-desc { cursor: pointer; }
  .tt-table thead th.dt-orderable-asc:hover, .tt-table thead th.dt-orderable-desc:hover { color: var(--ink); }
  .tt-table thead th span.dt-column-order { display: inline-block; width: 12px; color: var(--ink-3); }
  .tt-table thead th.dt-ordering-asc span.dt-column-order::before { content: "▲"; font-size: 8px; margin-left: 4px; color: var(--accent); }
  .tt-table thead th.dt-ordering-desc span.dt-column-order::before { content: "▼"; font-size: 8px; margin-left: 4px; color: var(--accent); }
  .t-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 20px 12px; border-top: 1px solid var(--line-soft); }
  .t-foot .dt-info { font-size: 12.5px; color: var(--ink-3); }
  /* the colvis menu rides the house details.row-menu; the checkbox rows scope above its .mi */
  details.row-menu .menu-pop label.mi { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-2); padding: 4px 10px; border-radius: 6px; cursor: pointer; }
  details.row-menu .menu-pop label.mi:hover { background: var(--accent-soft); color: var(--ink); }
  details.row-menu .menu-pop label.mi input { accent-color: var(--accent); margin: 0; }
  .tt-colvis .menu-pop { max-height: 320px; overflow-y: auto; }

  /* the Reduce fold — the instrument the standalone room folded into (bracket B) */
  .reduce-fold { margin-bottom: 18px; }
  details.reduce-fold > summary {
    list-style: none; cursor: pointer;
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 13px 20px; font-size: 13.5px; color: var(--ink-2);
  }
  details.reduce-fold > summary::-webkit-details-marker { display: none; }
  details.reduce-fold > summary::before { content: "▸"; font-size: 10px; color: var(--ink-3); transition: transform 150ms ease; align-self: center; }
  details.reduce-fold[open] > summary::before { transform: rotate(90deg); }
  details.reduce-fold > summary b { color: var(--ink); font-weight: 600; }
  details.reduce-fold > summary .sum-side { font-size: 12.5px; color: var(--ink-3); }
  .reduce-body { padding: 2px 20px 16px; }
  .col-picks { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0 12px; }
  .col-pick {
    display: inline-flex; align-items: center; gap: 7px;
    border: 1px solid var(--check-line); border-radius: 999px; background: var(--btn-fill);
    color: var(--btn-ink); padding: 4px 13px; font-size: 12.5px; cursor: pointer;
    font-family: 'Ubuntu Mono', 'Consolas', monospace;
  }
  .col-pick:hover { border-color: var(--accent); color: var(--ink); }
  .col-pick input { accent-color: var(--accent); width: 14px; height: 14px; margin: 0; }
  .col-pick.picked { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 500; }
  .reduce-verb { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
  .reduce-count { font-size: 13px; color: var(--ink-2); }
  .reduce-count b { color: var(--ink); }
  .reduce-teach { margin: 10px 0 0; font-size: 12.5px; color: var(--ink-3); max-width: 76ch; }

  /* ---------- the rail point search (2026-08-05, the combobox sitting — organ ruled rail-interior) ----------
     point_search_combobox.html mounted in rail_interior below Project Home. The include's own
     <style> speaks the token bridge (--dhps-* fall through to dh tokens here); this stanza is
     the rail-specific dress: the input wears the .rail-filter grammar, and the listbox goes
     IN-FLOW — .rail is overflow-y:auto, so an absolute overlay would be clipped at the rail
     edge; a transient in-flow list under the input (the sidebar-search pattern) scrolls with
     the rail instead. Option rows stack vertically: 244px is too narrow for the two-column
     id/whisper row the wide worlds use. */
  .rail-search { margin: 10px 6px 4px; }
  .rail-search #dhPointSearchIcon { display: none; }   /* the icon chip is classic-world dress (FA lives only there) */
  .rail-search #dhPointSearchInput {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface); color: var(--ink);
    padding: 6px 10px; font-size: 12.5px; font-family: inherit;
  }
  .rail-search #dhPointSearchInput::placeholder { color: var(--ink-3); }
  .rail-search #dhPointSearchListbox {
    position: static; width: auto; min-width: 0; max-width: none;
    margin: 4px 0 0; max-height: 40vh; box-shadow: none;
  }
  .rail-search #dhPointSearchListbox [role="option"] {
    flex-direction: column; align-items: flex-start; gap: 1px;
    padding: 5px 9px; font-size: 12.5px;
  }
  .rail-search #dhPointSearchListbox .opt-desc { text-align: left; font-size: 11.5px; }
  .rail-search #dhPointSearchListbox .opt-none,
  .rail-search #dhPointSearchListbox .opt-more { padding: 5px 9px; font-size: 11.5px; }
  @media (min-width: 1001px) {
    .rail.collapsed .rail-search { display: none; }   /* rides the collapsed-rail hide list */
  }

  /* ==================== Import Points (the importer's rotation, 2026-08-06) ====================
     Design of record: mockups/point-import-rail.md (walked + ratified same day). The room keeps
     the classic heart: form left in the classic control order, proof pane right — the file map
     is the first correctness check, so the frame gets the room's width. Field-family additions
     (date, textarea) are family-grade and sit bare beside their text/file siblings; everything
     else scopes to the import room; heads ride the bare default (flip-the-default, 2026-08-07). */
  .import-grid { display: flex; gap: 20px; align-items: flex-start; }
  .import-form-card { width: 330px; flex: none; }
  .import-proof-card { flex: 1; min-width: 0; position: sticky; top: 16px; }
  @media (max-width: 1240px) {
    .import-grid { flex-direction: column; }
    .import-form-card { width: 100%; }
    .import-proof-card { position: static; width: 100%; }
  }
  .import-form { padding: 12px 20px 18px; }
  .import-form .fld { margin-bottom: 12px; }
  .fld input[type="date"] {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 8px 10px; font-size: 14px; font-family: inherit;
  }
  .fld input[type="date"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  /* number joins the family (Code Editor rotation, 2026-08-21 — the gap surfaced when the
     room's Numeric Min/Max rendered in the browser-default dress beside styled siblings) */
  .fld input[type="number"] {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 8px 10px; font-size: 14px; font-family: inherit;
  }
  .fld input[type="number"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .fld textarea {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 8px 10px; font-size: 14px; font-family: inherit; resize: vertical;
  }
  .fld textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .hint.warn { color: var(--warn); }
  .import-submit { width: 100%; margin: 2px 0 14px; padding: 9px 16px; font-weight: 600; }
  .check-row { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
  .check-row input[type="checkbox"] { margin-top: 3px; flex: none; }
  .check-row label { font-size: 13.5px; color: var(--ink); cursor: pointer; }
  .check-row input[type="checkbox"]:disabled + label { color: var(--ink-3); cursor: not-allowed; }
  .check-row .fine { display: block; font-size: 12px; color: var(--ink-3); margin-top: 2px; }
  .shift-callout {
    border: 1px solid var(--warn); background: var(--warn-soft);
    border-radius: 8px; padding: 10px 12px; margin-top: 4px;
    font-size: 12.5px; color: var(--ink-2);
  }
  .shift-callout b { color: var(--warn); }
  .shift-callout p { margin: 2px 0; }
  .shift-callout .check-row { margin: 0 0 6px; }
  .import-proof { padding: 12px 16px 16px; }
  .import-frame {
    width: 100%; height: 800px; display: block;
    border: 1px solid var(--line-soft); border-radius: 8px; background: var(--surface-2);
  }
  .import-ref-card { margin: 20px 0 48px; }
  .import-ref-teach { padding: 10px 20px 4px; font-size: 13.5px; color: var(--ink-2); }
  .import-ref-teach b { color: var(--ink); }
  .import-ref-folds { padding: 0 20px 14px; }
  details.col-group { border-top: 1px solid var(--line-soft); }
  details.col-group:first-of-type { border-top: none; }
  details.col-group > summary {
    list-style: none; cursor: pointer; padding: 9px 2px;
    font-size: 13.5px; color: var(--ink-2); display: flex; align-items: center; gap: 8px;
  }
  details.col-group > summary::-webkit-details-marker { display: none; }
  details.col-group > summary::before {
    content: "\25B8"; font-size: 10px; color: var(--ink-3); transition: transform 150ms ease;
  }
  details.col-group[open] > summary::before { transform: rotate(90deg); }
  details.col-group > summary .fmt { color: var(--warn); font-size: 12px; margin-left: 4px; }
  .col-group .col-chips { padding: 0 2px 10px 20px; }
  /* the in-page ready state (walk catch 2026-08-06): the classic logo_screen placeholder
     stretched at this pane's aspect and carried no instruction — the mockup's ghost + prose
     render here in rail dress; the frame appears on Submit */
  .import-ready {
    height: 800px; border: 1px solid var(--line-soft); border-radius: 8px;
    background: var(--surface-2);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 14px; padding: 40px;
  }
  .import-ready .ghost { width: 150px; height: auto; opacity: 0.16; }
  .import-ready .ghost .lg-a { fill: var(--ink); }
  .import-ready .ghost .lg-b { fill: var(--gold-line); }
  .import-ready p { margin: 0; font-size: 13.5px; color: var(--ink-3); text-align: center; max-width: 380px; }
  .import-ready p b { color: var(--ink-2); }
  .import-frame[hidden] { display: none; }
  /* author display:flex beats the hidden attribute — the [hidden] guard the frame already had,
     applied to its sibling (import walk catch #2, 2026-08-06) */
  .import-ready[hidden] { display: none; }
  /* the working state (Abby's soother, 2026-08-17): on Submit the pane narrates instead of
     unveiling a blank frame — the ghost pulses, the prose swaps, and an elapsed counter proves
     the passage is alive. Indeterminate on purpose: the stack is synchronous, so an honest
     percent doesn't exist; a counting number is the strongest not-hung signal we can give.
     Tuned same day after Mark's live patch walk (only the counter registered): the counter is
     the HERO — big and gold, the passage vocabulary — the prose brightens, and the pulse runs
     wide and quick enough to read as activity, not as a drifting watermark. */
  .import-ready.working .ghost { animation: import-pulse 1.3s ease-in-out infinite alternate; }
  @keyframes import-pulse { from { opacity: 0.12; } to { opacity: 0.75; } }
  @media (prefers-reduced-motion: reduce) { .import-ready.working .ghost { animation: none; opacity: 0.28; } }
  .import-ready.working p { color: var(--ink-2); }
  .import-ready .elapsed {
    font-size: 26px; font-weight: 600; color: var(--gold-line);
    font-variant-numeric: tabular-nums;
  }
  /* the prose pair and the counter toggle by attribute — same guard family as the pane itself */
  .import-ready p[hidden], .import-ready .elapsed[hidden] { display: none; }

  /* ==================== the verdict frame (import proof pane, 2026-08-06 evening) ====================
     The house-dressed heir of the Bootstrap modal_frame for the importer only (Mark's ruling: the
     room has the rail and its theme selector, so the frame speaks the tokens). Standalone document
     rendered inside the mapFrame iframe; everything scopes under body.verdict-frame, vf- prefixed —
     dh.css already owns a bare .verdict (the Validation def room), so no shared names here. */
  body.verdict-frame { background: var(--ground); color: var(--ink); margin: 0; padding: 0; font-size: 14px; }
  .verdict-frame .vf-refusal-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 10px 16px; font-size: 13.5px;
    background: var(--bad-soft); border-bottom: 1px solid var(--bad);
  }
  .verdict-frame .vf-refusal-head b { color: var(--bad); }
  .verdict-frame .vf-dl {
    margin-left: auto; font-size: 12.5px; font-weight: 500; cursor: pointer;
    background: var(--surface); border: 1px solid var(--check-line); color: var(--btn-ink);
    border-radius: 7px; padding: 4px 12px; font-family: inherit; white-space: nowrap;
  }
  .verdict-frame .vf-dl:hover { border-color: var(--accent); color: var(--ink); }
  .verdict-frame .vf-refusal-list { padding: 4px 16px 14px; }
  .verdict-frame details.vf-group { border-bottom: 1px solid var(--line-soft); }
  .verdict-frame details.vf-group:last-child { border-bottom: none; }
  .verdict-frame details.vf-group > summary {
    list-style: none; cursor: pointer; padding: 10px 2px;
    font-size: 13.5px; color: var(--ink); display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  }
  .verdict-frame details.vf-group > summary::-webkit-details-marker { display: none; }
  .verdict-frame details.vf-group > summary::before {
    content: "\25B8"; font-size: 10px; color: var(--ink-3); transition: transform 150ms ease; flex: none;
  }
  .verdict-frame details.vf-group[open] > summary::before { transform: rotate(90deg); }
  .verdict-frame .vf-count {
    margin-left: auto; flex: none; font-size: 12px; font-weight: 700;
    color: var(--bad); background: var(--bad-soft);
    border-radius: 999px; padding: 1px 10px;
  }
  .verdict-frame .vf-sample { font-size: 12px; color: var(--ink-3); }
  .verdict-frame .vf-ids {
    padding: 0 2px 12px 20px; font-size: 12.5px; color: var(--ink-2);
    line-height: 1.9; word-break: break-word;
  }
  .verdict-frame .vf-more { color: var(--ink-3); font-style: italic; }
  .verdict-frame .vf-center {
    min-height: 92vh; display: flex; align-items: center; justify-content: center; padding: 24px;
  }
  .verdict-frame .vf-card {
    max-width: 480px; width: 100%; border-radius: 8px; padding: 16px 18px;
    font-size: 13.5px; color: var(--ink); line-height: 1.55;
  }
  .verdict-frame .vf-card.bad { border: 1px solid var(--bad); background: var(--bad-soft); }
  .verdict-frame .vf-card.good { border: 1px solid var(--good); background: var(--good-soft); }
  .verdict-frame .vf-card.info { border: 1px solid var(--line); background: var(--mute-soft); }
  .verdict-frame .vf-undo {
    display: inline-block; margin-top: 10px; font-weight: 600; color: var(--accent);
    background: var(--surface); border: 1px solid var(--check-line); border-radius: 7px;
    padding: 5px 13px; text-decoration: none;
  }
  .verdict-frame .vf-undo:hover { border-color: var(--accent); }

  /* ---------- the Survey Files family (rotation 2026-08-06; design of record:
     mockups/survey-files-rail.html + survey-files-rail.md — all thirteen rulings ratified
     same-day). Three rooms: the hub (house table — bracket A's DataTables heir), the Meta
     Editor (labeled form + the divergence honesty lines), File Contents (the vendored Tally
     pair's second room — it reuses the tt- family wholesale, nothing minted for it here). */

  /* the sandbox banner — the invisible fence gets a voice (a ratified fix, not a bracket) */
  .sandbox-note {
    display: flex; align-items: baseline; gap: 10px;
    border: 1px solid var(--line); border-left: 3px solid var(--gold-line);
    border-radius: var(--radius); background: var(--surface);
    padding: 10px 16px; font-size: 13px; color: var(--ink-2); margin-bottom: 18px;
  }
  .sandbox-note b { color: var(--ink); }

  /* the house click-sort head (bracket A) — the ~25-line vanilla engine lives page-level;
     this is only its dress. The gold arrow shows on the active column, either direction. */
  .qc-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
  .qc-table th.sortable:hover { color: var(--ink); }
  .qc-table th.sortable .arr { font-size: 9px; margin-left: 4px; opacity: 0; }
  .qc-table th.sortable[aria-sort] .arr { opacity: 1; color: var(--gold); }

  /* the ✦ crosslink dot — a file carrying a meta comment; its text lives on the shelf below */
  .has-note { color: var(--gold); font-size: 11px; margin-left: 5px; vertical-align: 1px; cursor: default; }

  /* row verbs as labeled chips (bracket E) — compact inside table rows */
  .sf-table th.sf-verbs { text-align: right; padding-right: 20px; }
  .sf-table .verb-cell { padding-right: 20px; }
  .sf-table .verb-cell .chip-btn { padding: 3px 10px; font-size: 12px; }
  .sf-table .verb-cell .chip-btn + .chip-btn { margin-left: 6px; }
  .sf-table .verb-cell .chip-btn svg { width: 12px; height: 12px; }

  /* the shelf's comment cell — the note reads as a note; the door rides the text */
  .sf-cmt { color: var(--ink-2); font-style: italic; }
  .sf-cmt a { color: inherit; }

  /* the PNEZD/PENZD letter-pair emphasis — classic's teaching device, named a keeper */
  .swap-pair { color: var(--gold); font-weight: 700; }

  /* ---- the Meta Editor room (bracket G's honesty lines ride .hint.warn, already minted) */
  .meta-grid { display: flex; gap: 20px; align-items: flex-start; }
  .meta-form-card { width: 360px; flex: none; }
  /* head rides the bare default (flip-the-default, 2026-08-07 — this card's naked head was the FOURTH catch that ruled it) */
  .meta-aside { flex: 1; min-width: 0; }
  @media (max-width: 1000px) {
    .meta-grid { flex-direction: column; }
    .meta-form-card, .meta-aside { width: 100%; }
  }
  .parked-badge {
    display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: 0.05em;
    background: var(--warn-soft); color: var(--warn);
    border-radius: 4px; padding: 0 6px; vertical-align: 1px;
  }
  .meta-facts { padding: 12px 20px 16px; font-size: 13.5px; color: var(--ink-2); }
  .meta-facts .fact-row { display: flex; gap: 10px; padding: 4px 0; align-items: center; }
  .meta-facts .fact-row .k { width: 110px; flex: none; color: var(--ink-3); font-size: 12.5px; }
  .meta-facts .fact-row .v { color: var(--ink); display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }

  /* ---------- the Members family: Members + its Transfer child (2026-08-07; design of record
     mockups/members-rail.html + members-rail.md, walked and ratified same day). Reused verbatim:
     .console.roster machinery + .proj-cell (the identity cell — a person here), .roster-toolbar,
     .dh-seg.decide-seg, .sel-box, .role-chip ladder, .badge-star/.badge-am, .flag-chip,
     .whisper-chip, .ppl-none, .clock-note, .person-sub, .door-card, .seg-group. ---------- */
  /* .you-chip — the actor's own row, People's "(you)" said as a pill; minted here (first bare use) */
  .you-chip {
    font-size: 10.5px; padding: 0 8px; border-radius: 999px;
    border: 1px solid var(--accent); color: var(--accent);
    background: var(--accent-soft); font-weight: 500;
    margin-left: 8px; vertical-align: 1px; white-space: nowrap;
  }
  .seg-label {
    font-size: 12px; color: var(--ink-3); font-weight: 700;
    letter-spacing: 0.07em; text-transform: uppercase; white-space: nowrap;
  }
  .am-hint { font-size: 12px; color: var(--ink-3); }
  .am-hint .badge-am { margin-left: 0; }
  /* the seat glyphs: a row the actor can NEVER touch says why in the checkbox seat */
  .mbr-star { color: var(--gold); font-size: 13px; cursor: default; }
  .mbr-lock { color: var(--ink-3); display: inline-flex; cursor: default; }
  .mbr-data { text-align: right; font-size: 12px; color: var(--ink-3); }
  .mbr-data .mono { color: var(--ink-2); }
  /* the Add-people shelf — strangers behind an explicit affordance (bracket A) */
  details.mbr-shelf { margin: 18px 0; }
  details.mbr-shelf > summary {
    list-style: none; cursor: pointer;
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 13px 20px;
    font-size: 13.5px; color: var(--ink-2);
  }
  details.mbr-shelf > summary::-webkit-details-marker { display: none; }
  details.mbr-shelf > summary::before {
    content: "▸"; font-size: 10px; color: var(--ink-3); transition: transform 150ms ease;
    align-self: center;
  }
  details.mbr-shelf[open] > summary::before { transform: rotate(90deg); }
  details.mbr-shelf > summary b { color: var(--ink); font-weight: 600; }
  details.mbr-shelf > summary .sum-side { font-size: 12.5px; color: var(--ink-3); }
  details.mbr-shelf .shelf-whisper { padding: 0 20px 8px; font-size: 12px; color: var(--ink-3); max-width: 76ch; }
  details.mbr-shelf .mbr-shelf-body { padding: 0 6px 10px; }
  /* shelf rows sit on a CARD (the shelf is furniture, unlike the naked roster) — re-surface them */
  details.mbr-shelf .console.roster td.proj-cell { background: var(--surface); }
  details.mbr-shelf .console.roster tbody tr:hover td { background: color-mix(in srgb, var(--accent) 9%, var(--surface)); }

  /* the Transfer room: two cards, from→to pick-lists, held narrating verbs */
  .tx-card { margin-bottom: 18px; }
  .tx-body { margin: 0; padding: 12px 20px 16px; display: flex; gap: 26px; flex-wrap: wrap; }
  .tx-col { flex: 1; min-width: 220px; }
  .tx-col-wide { flex: 1.4; }
  .tx-col-verb { flex: 1.2; min-width: 250px; display: flex; flex-direction: column; gap: 10px; justify-content: flex-end; }
  .tx-pick-head {
    font-size: 12px; color: var(--ink-3); font-weight: 700;
    letter-spacing: 0.07em; text-transform: uppercase; margin-bottom: 6px;
  }
  .tx-pick-list { display: flex; flex-direction: column; gap: 2px; }
  .tx-pick-list label {
    display: flex; align-items: baseline; gap: 9px;
    padding: 5px 9px; border-radius: 7px; cursor: pointer;
    font-size: 13.5px; color: var(--ink-2);
  }
  .tx-pick-list label:hover { background: var(--accent-soft); color: var(--ink); }
  .tx-pick-list input { accent-color: var(--accent); flex: none; align-self: center; }
  .tx-pick-list .pname { color: var(--ink); font-weight: 500; }
  .tx-pick-list .pcount { margin-left: auto; font-size: 12px; color: var(--ink-3); }
  .tx-pick-list label.zero .pname { color: var(--ink-3); font-weight: 400; }
  .tx-whisper { font-size: 12.5px; color: var(--ink-3); max-width: 46ch; }
  .tx-whisper.warn { color: var(--warn); }
  .tx-whisper b { color: var(--ink-2); }
  .tx-ids {
    width: 100%; min-height: 150px; resize: vertical;
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 9px 12px; font-size: 13px; font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
  }
  .tx-ids:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .tx-file { margin-top: 10px; font-size: 12.5px; color: var(--ink-3); }
  .tx-file input { font-family: inherit; font-size: 12px; color: var(--ink-2); margin-top: 4px; }
  @media (max-width: 640px) {
    .tx-body { gap: 14px; }
    .mbr-data { text-align: left; }
  }

  /* ============================== HOME (the kin pair, 2026-08-08) ==============================
     The non-project landing: recognition tiles + the Around-the-Server preview band.
     Design of record: mockups/home-page.md + the 08-08 walk rulings. Shared design-system
     pieces minted here and worn by both kin: .gate-note (a fenced surface names its own gate),
     .sect-head (eyebrow + companion whisper beside it, never below), the vital-sign bands. */

  /* the gate label (walk convention 2026-08-08): hint ink riding the small-caps register —
     role fences state a standing rule; setting fences render conditionally with per-project
     phrasing. Bare by design: any fenced card on any page wears it. */
  .gate-note { color: var(--ink-3); font-weight: 500; letter-spacing: 0.06em; font-size: 11px; text-transform: none; }

  .sect-head { display: flex; align-items: baseline; gap: 10px; margin: 26px 0 14px; }
  .sect-head .eyebrow { font-size: 12px; flex: none; }
  /* companion text shares the row and wraps its OWN words (Mark's placement ruling: beside, not below) */
  .sect-head .count { flex: 1; min-width: 12ch; font-size: 12.5px; color: var(--ink-3); }

  .spacer { flex: 1; }
  .card-link { font-size: 13px; color: var(--link); text-decoration: none; white-space: nowrap; }
  .card-link:hover { text-decoration: underline; }

  /* ---- the ghost tile's frame (the tile GRID retired 2026-08-17 — "nix the grid altogether,
     list mode only"; the .tile shell survives solely as the ghost's dress, the first-run
     empty state a new Authorized Manager lands on) ---- */
  .tile-grid {
    display: grid; gap: 16px;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  }
  .tile {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 10px; box-shadow: var(--shadow);
    padding: 10px 12px 12px; min-width: 0;
    display: flex; flex-direction: column; gap: 3px;
  }
  /* the pin: 16px ruled at the 08-08 walk ("ever so slightly grown"), inherited by the row */
  .prow .pin-btn {
    background: none; border: none; cursor: pointer; font-family: inherit;
    font-size: 16px; color: var(--ink-3); padding: 2px 4px; flex: none;
    border-radius: 5px; line-height: 1;
  }
  .prow .pin-btn.pinned { color: var(--gold); }
  .prow .pin-btn:hover { background: var(--accent-soft); }
  /* the QC glyph dress — identity in the SHAPE, state in the color (one vocabulary with the
     dashboard scorecard's state circles) */
  .prow .g {
    width: 20px; height: 20px; border-radius: 50%; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .prow .g svg { width: 11px; height: 11px; }
  .prow .g-clean { background: var(--good-soft); color: var(--good); }
  .prow .g-busts { background: var(--warn-soft); color: var(--warn); }
  .prow .g-off { background: var(--mute-soft); color: var(--ink-3); border: 1px dashed var(--line); }
  /* the ghost tile: the empty-state first-run only (dashed = the not-yet-born) */
  .ghost-tile {
    border-style: dashed; background: none; cursor: pointer; font-family: inherit;
    align-items: center; justify-content: center; min-height: 150px; gap: 6px;
    color: var(--ink-2); font-size: 14px;
  }
  .ghost-tile:hover { border-color: var(--accent); color: var(--ink); }
  .ghost-tile .ghost-plus { font-size: 26px; color: var(--accent); line-height: 1; }

  /* ---- list mode: the row is the tile flattened (build 2026-08-17; design of record
     mockups/home-list-mode.md — the sitting's rulings) ----
     AUTO-BY-N, no toggle: the view flips to list ABOVE 20 projects (one threshold with the
     filter box, so the high-N instruments arrive together); grid stays the recognition surface
     below it. FLAT rows: hairline dividers inside one surface — classic accordion's density,
     ~17 rows per screen against the grid's ~8. Pinned separation: the pinned group is its own
     surface above the A-Z surface, both wearing the rail's group-head grammar. */

  .proj-filter { margin: 0 0 14px; }
  .proj-filter .dh-filter { width: 100%; max-width: 340px; }
  .proj-filter .match-note { margin-left: 10px; font-size: 12px; color: var(--ink-3); }

  .proj-list {
    display: flex; flex-direction: column;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 10px; box-shadow: var(--shadow);
    /* overflow VISIBLE (was hidden — Mark's live catch 2026-09-05): the Sunsetting kebab's pop
       on a lower row runs past the card's bottom edge and a clipping card cut it off. The
       rounded corners the clip used to enforce ride the first/last rows instead. */
  }
  .proj-list .prow { border-bottom: 1px solid var(--line-soft); }
  .proj-list .prow:first-child { border-radius: 9px 9px 0 0; }
  .proj-list .prow:last-child { border-bottom: 0; border-radius: 0 0 9px 9px; }
  .proj-list .prow:first-child:last-child { border-radius: 9px; }
  .proj-list .prow:hover { background: var(--accent-soft); }
  .list-head {
    font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-3); margin: 0 0 7px 4px;
  }
  .list-head + .proj-list { margin-bottom: 18px; }
  .proj-list:last-child { margin-bottom: 0; }

  .prow {
    display: grid; align-items: center; cursor: pointer;
    /* thumb · name · delta · glyphs · whisper · pin — the 225px custody-stat column retired
       2026-08-25 (Mark's ruling: the whisper is the invitation; the counts were the page's
       full-scan query) */
    grid-template-columns: 46px minmax(0, 1fr) 80px 182px 104px 30px 26px;
    gap: 12px; padding: 5px 12px; min-width: 0;
  }
  /* the Sunsetting kebab (2026-09-05) — a row-menu wearing the pin's quiet dress: no border, no
     caret (the three dots ARE the dropdown hint; the 08-05 caret rule is for WORD summaries),
     ink-3 until hover. Fenced verbs are click-disabled and whisper-taught, never hidden. */
  .prow details.sun-menu > summary.kebab {
    border: none; background: none; padding: 3px 4px; border-radius: 5px; line-height: 0;
    color: var(--ink-3); display: inline-flex; align-items: center;
  }
  .prow details.sun-menu > summary.kebab::after { content: none; }
  .prow details.sun-menu > summary.kebab:hover { background: var(--accent-soft); color: var(--ink); }
  .prow details.sun-menu[open] > summary.kebab { color: var(--accent); }
  .prow details.sun-menu .menu-pop { min-width: 230px; }
  .prow details.sun-menu .menu-pop .mi:disabled { color: var(--ink-3); cursor: not-allowed; background: none; }
  .prow details.sun-menu .menu-pop .mi-whisper { font-size: 11px; color: var(--ink-3); padding: 0 10px 6px; line-height: 1.35; }
  .prow details.sun-menu .menu-pop .sun-more { border-top: 1px solid var(--line-soft); margin-top: 4px; padding-top: 7px; border-radius: 0 0 6px 6px; }
  .prow details.sun-menu .menu-pop .mi-sub { color: var(--ink-3); font-size: 11px; margin-left: 4px; }
  .prow.dissolving { transition: opacity 320ms ease; opacity: 0; }
  /* the filter hides rows, empty surfaces, and their heads; every one of them carries an author
     display value, so these [hidden] guards are load-bearing (the silently-defeated-hidden
     house rule — this build is where it bit its third and fourth times) */
  .prow[hidden] { display: none; }
  .list-head[hidden] { display: none; }
  .proj-list[hidden] { display: none; }
  .prow .p-thumb {
    width: 46px; height: 36px; border-radius: 5px; overflow: hidden; flex: none;
    border: 1px solid var(--line-soft); background: var(--surface-2);
    position: relative; display: block;
  }
  .prow .p-thumb svg { position: absolute; inset: 0; width: 100%; height: 100%; }
  /* alignment-less: the teaching gray at icon size — dashed says "add an alignment," wordless */
  .prow .p-thumb.thumb-none { border-style: dashed; }
  /* title big and left — the muscle-memory column; thumb LEFT of it (ruled: "the adjacency to
     the project title is natural") */
  .prow .p-name { min-width: 0; display: flex; align-items: baseline; gap: 8px; }
  .prow .p-title {
    font-weight: 600; font-size: 15px; color: var(--ink); text-decoration: none;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
  }
  .prow .p-title:hover { color: var(--link); }
  .prow .p-zone { font-size: 11.5px; color: var(--ink-3); flex: none; }
  .prow .p-delta { font-size: 12.5px; color: var(--good); white-space: nowrap; }
  .prow .p-glyphs { display: flex; gap: 6px; }
  .prow .p-whisper { font-size: 11.5px; color: var(--ink-3); text-align: right; white-space: nowrap; }
  .no-match { padding: 18px 4px; font-size: 13px; color: var(--ink-3); }

  /* progressive narrowing, then the two-line phone collapse (dress-grade first cut — the walk
     may re-rule what the row keeps at each width). The stat column's retirement freed 225px,
     so the old 1150px delta-drop breakpoint is gone — the delta now survives to 860px */
  @media (max-width: 1000px) { .prow .p-zone { display: none; } }
  @media (max-width: 860px)  { .prow { grid-template-columns: 46px minmax(0, 1fr) 80px 182px 30px 26px; } .prow .p-whisper { display: none; } }
  @media (min-width: 761px)  { .prow .p-meta { display: contents; } }
  @media (max-width: 760px) {
    .prow { grid-template-columns: 46px minmax(0, 1fr) 30px 26px; }
    .prow .p-meta { grid-column: 2; display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; }
    .prow .p-whisper { text-align: left; }
  }

  /* ---- the Around-the-Server band ---- */
  .home-grid { display: grid; gap: 16px; grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .home-grid .span-3 { grid-column: span 3; }
  .home-grid .span-4 { grid-column: span 4; }
  .home-grid .span-5 { grid-column: span 5; }
  .home-grid .span-7 { grid-column: span 7; }
  @media (max-width: 980px) { .home-grid .span-3, .home-grid .span-4, .home-grid .span-5, .home-grid .span-7 { grid-column: span 12; } }
  .home-grid .card-body { padding: 10px 18px 16px; }
  .home-grid .big { font-size: 24px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.15; }
  .home-grid .big-sub { font-size: 13.5px; font-weight: 400; color: var(--ink-3); font-family: 'Ubuntu', 'Segoe UI', system-ui, sans-serif; }
  .home-grid .sub { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
  .home-grid .tick-row { display: flex; gap: 10px; padding: 5px 0; font-size: 13px; align-items: baseline; }
  .home-grid .tick-row .who { color: var(--accent); font-weight: 500; flex: none; }
  .home-grid .tick-row .what { color: var(--ink-2); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .home-grid .tick-row .when { color: var(--ink-3); font-size: 12px; flex: none; }
  .home-grid .proj-chip {
    flex: none; font-size: 11.5px; color: var(--link); text-decoration: none;  /* link ink (2026-08-13): a nav chip is a link — its cousins all went brand blue */
    border: 1px solid var(--line); border-radius: 999px; padding: 0 9px; white-space: nowrap;
  }
  .home-grid .proj-chip:hover { border-color: var(--accent); color: var(--ink); }
  /* the vital-sign bands (Console + People, one instrument) */
  .home-grid .bands {
    display: flex; height: 9px; border-radius: 5px; overflow: hidden;
    margin-top: 12px; gap: 2px;
  }
  .home-grid .bands i { display: block; }
  .home-grid .b-fresh { background: var(--good); }
  .home-grid .b-mid { background: var(--gold-line); }
  .home-grid .b-stale { background: var(--warn); }
  .home-grid .b-none { background: var(--mute-soft); }
  .home-grid .band-legend { display: flex; gap: 6px 14px; flex-wrap: wrap; margin-top: 8px; font-size: 11.5px; color: var(--ink-3); }
  .home-grid .band-legend .k { display: inline-flex; align-items: center; gap: 5px; }
  .home-grid .band-legend .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
  .home-grid .foot-line {
    margin-top: 10px; font-size: 12.5px; color: var(--ink-2);
    border-top: 1px solid var(--line-soft); padding-top: 9px;
  }
  .home-grid .foot-line b { color: var(--warn); font-weight: 500; }
  .home-grid .article-title { font-weight: 600; font-size: 14.5px; margin-top: 2px; }
  .home-grid .article-snip { font-size: 13px; color: var(--ink-2); margin-top: 4px; }

  /* ======================= PROJECT HOME (the kin pair's second half, 2026-08-08) =======================
     The re-imagined project dashboard: state-first canvas on the interior rail. Design of record:
     mockups/dashboard-reimagined.md + the walk. Scoped .ph-* / room-local; shares .gate-note,
     .sect-head vocabulary, and the qc_glyphs symbols with Home. (.ph-map, not .map-card — that
     bare class belongs to another room; the mirror-trap census caught the collision.) */

  .proj-head .alias-chip {
    font-size: 12.5px; color: var(--ink-3); border: 1px solid var(--line);
    border-radius: 6px; padding: 1px 8px; flex: none;
  }
  .proj-head .head-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
  /* one size for the verb row (walk catch): anchors and <button> compute different heights
     from the same padding — pin the box so Notes (icon-bearing <a>), Snapshot (<button>), and
     A&S (<a>) sit identical */
  .proj-head .head-actions .ghost-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    text-decoration: none; height: 33px; padding: 0 14px; line-height: 1;
  }
  /* the pin star (2026-09-04): a square ghost button so it reads as a verb in the row, the
     star itself in the row's ink until pinned — then the gold every other pin star wears */
  .proj-head .head-actions .pin-star { width: 33px; padding: 0; font-size: 17px; color: var(--ink-3); }
  .proj-head .head-actions .pin-star.pinned { color: var(--gold); }
  /* the retreat link: present but quiet (dotted register) — Receipt-logged, the verdict instrument */
  .retreat-link { font-size: 12.5px; color: var(--ink-3); text-decoration: none; border-bottom: 1px dotted var(--ink-3); }
  .retreat-link:hover { color: var(--ink-2); }
  .facts { display: flex; gap: 6px 22px; flex-wrap: wrap; margin-top: 10px; font-size: 13.5px; color: var(--ink-2); }
  .facts .f b { color: var(--ink-3); font-weight: 500; font-size: 11px; letter-spacing: 0.07em; display: block; }
  .facts .f-whisper { color: var(--ink-3); font-size: 12px; }
  .setup-whisper { margin-top: 10px; font-size: 13px; color: var(--ink-3); }
  .setup-whisper a { color: var(--link); text-decoration: none; }
  .setup-whisper a:hover { text-decoration: underline; }

  .ph-hero { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(300px, 1fr); gap: 16px; margin-bottom: 16px; }
  /* minmax(0,1fr), not 1fr (Mark's phone catch #2, 2026-08-14): a bare 1fr bottoms out at
     min-content, and the map head's nowrap chip row (487px) propped every hero card open to
     489px inside a 366px column — the ph-grid cards compacted because their tracks already
     wear the 0 floor. The chips wrap instead (below) — compact by reflowing, never by clipping */
  @media (max-width: 980px) { .ph-hero { grid-template-columns: minmax(0, 1fr); } }
  .ph-hero .card-head { flex-wrap: wrap; row-gap: 6px; }
  .ph-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
  /* the full height chain (walk catch): card flexes column -> body flex:1 fills it -> frame
     flex:1 fills the body -> the absolute svg letterboxes inside. Each link load-bearing. */
  .ph-map { display: flex; flex-direction: column; }
  .ph-map .card-body { padding: 10px 12px 12px; flex: 1; display: flex; flex-direction: column; }
  /* the frame OWNS the height (walk catch: a tall viewBox was inflating the row) — the svg is
     absolute so its intrinsic aspect never drives layout; the card conforms to the companion
     column and the shape letterboxes inside (preserveAspectRatio meet) */
  .ph-map .map-frame {
    border-radius: 7px; overflow: hidden; border: 1px solid var(--line-soft);
    flex: 1; display: flex; min-height: 280px; background: var(--surface-2);
    position: relative;
  }
  /* the locked Leaflet fills the frame; NO bare svg rule here — Leaflet positions its own
     overlay svg with transforms, and a forced inset/100% rule shoves the linework off-view
     (the walk's invisible-alignment catch: the dead hand-rolled preview's CSS was the culprit) */
  .ph-map #phMap { position: absolute; inset: 0; }
  /* Leaflet's internal panes run z 400–1000; without a stacking context of their own they float
     over the phone rail drawer (z 80 — Mark's phone catch, 2026-08-14). Isolating the container
     seals the whole stack inside, so every Leaflet map — Project Home's preview, the Offsets
     room's, any future one — layers as one ordinary element under the rail and the scrim */
  .leaflet-container { isolation: isolate; }
  .ph-map .map-empty { align-items: center; justify-content: center; color: var(--ink-3); font-size: 13px; border-style: dashed; }
  .ph-map .map-legend { padding: 9px 6px 0; font-size: 12.5px; color: var(--ink-2); }

  .ph-hero .card-body, .ph-grid .card-body { padding: 10px 18px 16px; }
  .ph-hero .big { font-size: 24px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.15; }
  .ph-hero .delta-up { color: var(--good); font-size: 14px; font-weight: 500; margin-left: 8px; font-family: 'Ubuntu', 'Segoe UI', system-ui, sans-serif; }
  .ph-hero .sub, .ph-grid .sub { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
  .sect-label {
    font-size: 11px; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--ink-3); margin: 13px 0 3px;
  }
  .row-link {
    display: flex; align-items: center; gap: 12px;
    padding: 8px 6px; border-top: 1px solid var(--line-soft);
    text-decoration: none; color: var(--ink); border-radius: 6px; font-size: 14px;
  }
  .row-link:first-of-type { border-top: none; }
  a.row-link:hover, summary.row-link:hover { background: var(--accent-soft); }
  .row-link .r-meta { margin-left: auto; font-size: 12.5px; color: var(--ink-3); white-space: nowrap; }
  .row-link .r-meta.r-empty { font-style: italic; }
  .row-link.row-danger { border-top: 1px solid var(--line); margin-top: 4px; }
  .row-link.row-danger:hover { background: var(--warn-soft); }
  .row-link.row-static { cursor: default; color: var(--ink-3); }
  .chip-row { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 4px; }
  .fmt-chip {
    display: inline-block; border: 1px solid var(--check-line); border-radius: 6px; padding: 3px 10px;
    font-size: 12.5px; color: var(--btn-ink); background: var(--btn-fill); cursor: pointer;
    text-decoration: none; font-family: inherit; box-shadow: var(--btn-shadow);
  }
  .fmt-chip:hover { border-color: var(--accent); color: var(--ink); }
  /* project_home rides the HOUSE details.row-menu component (the near-duplicate block that
     lived here was a census miss — its positioning/z NEVER applied, out-specified by the house
     rule; deleted 2026-08-08). Only the pieces the house doesn't carry stay: */
  /* full row width for the wrapper AND the summary (Mark's catch: hover pill + separator both
     curtailed — the house details.row-menu is inline-block shrink-fit, toolbar heritage).
     .ph-grid joined 2026-08-14: the Deep Reads card's per-line forks (the door cards' return)
     ride the same dress as the hero's Progress & Gaps row */
  .ph-hero .card-body > details.row-menu, .ph-grid .card-body > details.row-menu { border-top: 1px solid var(--line-soft); display: block; width: 100%; }
  /* a summary wearing .row-link dresses as a ROW, not the house chip (Mark's eye + the pane's:
     the Progress selector rendered as a tiny bordered pill among full rows — the chip border was
     the "clipped outline"; the row register hover-highlights full-width like its siblings) */
  .ph-hero details.row-menu > summary.row-link, .ph-grid details.row-menu > summary.row-link {
    border: none; background: none; border-radius: 6px;
    padding: 8px 6px; font-size: 14px; color: var(--ink); white-space: normal;
    display: flex; align-items: center; gap: 12px; width: 100%;
  }
  .ph-hero details.row-menu > summary.row-link .r-meta, .ph-grid details.row-menu > summary.row-link .r-meta { margin-left: auto; }
  .ph-hero details.row-menu > summary.row-link::after, .ph-grid details.row-menu > summary.row-link::after { margin-left: 0; }
  .ph-hero details.row-menu > summary.row-link:hover, .ph-grid details.row-menu > summary.row-link:hover { border-color: transparent; background: var(--accent-soft); color: var(--ink); }
  .ph-hero details.row-menu[open] > summary.row-link, .ph-grid details.row-menu[open] > summary.row-link { border-color: transparent; }
  .ph-hero .card-body > details.row-menu > summary.row-link, .ph-grid .card-body > details.row-menu > summary.row-link { border-top: none; }
  /* seam repairs around a fork row (the Deep Reads card is the first place a fork LEADS a card
     or is FOLLOWED by plain rows): a fork opening a card carries no top border, and the anchor
     right after a fork gets its separator back (a.row-link:first-of-type stripped it — the fork
     is a details, so that anchor is the card's first <a> despite not being the first row) */
  .ph-hero .card-body > details.row-menu:first-child, .ph-grid .card-body > details.row-menu:first-child { border-top: none; }
  .ph-hero .card-body > details.row-menu + a.row-link, .ph-grid .card-body > details.row-menu + a.row-link { border-top: 1px solid var(--line-soft); }
  /* the Drill pair's numbered steps (the rail's .step carried down to card altitude, 2026-08-14):
     the digit sits in the glyph column, so the label rail stays aligned with the icon rows */
  .row-link .step { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-size: 11px; color: var(--ink-3); flex: none; width: 14px; text-align: center; }
  .row-menu .menu-pop a { display: block; padding: 6px 12px; border-radius: 6px; text-decoration: none; color: var(--ink-2); font-size: 13px; }
  .row-menu .menu-pop a:hover { background: var(--accent-soft); color: var(--ink); }

  .notes-card { margin-bottom: 16px; }
  .notes-card .card-head .eyebrow { display: inline-flex; align-items: center; gap: 7px; }
  .notes-card .rich-note { padding: 8px 18px 14px; font-size: 14px; color: var(--ink-2); }
  .notes-card .rich-note p { margin: 4px 0; }

  .ph-grid { display: grid; gap: 16px; grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .ph-grid .span-4 { grid-column: span 4; }
  .ph-grid .span-5 { grid-column: span 5; }
  .ph-grid .span-7 { grid-column: span 7; }
  .ph-grid .span-12 { grid-column: span 12; }
  @media (max-width: 980px) { .ph-grid .span-4, .ph-grid .span-5, .ph-grid .span-7 { grid-column: span 12; } }
  .qc-row {
    display: flex; align-items: center; gap: 12px;
    padding: 8px 6px; border-top: 1px solid var(--line-soft);
    text-decoration: none; color: var(--ink); border-radius: 6px;
  }
  .qc-row:first-of-type { border-top: none; }
  .qc-row:hover { background: var(--accent-soft); }
  .qc-row .st {
    width: 22px; height: 22px; border-radius: 50%; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .qc-row .st-clean { background: var(--good-soft); color: var(--good); }
  .qc-row .st-busts { background: var(--warn-soft); color: var(--warn); }
  .qc-row .st-off { background: var(--mute-soft); color: var(--ink-3); border: 1px dashed var(--line); }
  .qc-row .qc-name { font-weight: 500; flex: 1; min-width: 0; }
  /* the verdict pills: bust-badge amber; clean = an earned bare green word; "configure" = the
     invitation verb in the dashed not-yet-born pill (Mark's (d) refinement) */
  /* verdict pills wear v-* names — .qc-clean/.qc-busts are the QC ROOMS' bare card classes
     (the mirror trap's second .row-verb: a one-word span inherited 20px card padding and blew
     the row to 94px; caught by geometry probe at the live walk, multitest) */
  .qc-row .qc-count { font-size: 12.5px; flex: none; }
  .qc-row .v-busts { background: var(--warn-soft); color: var(--warn); font-weight: 700; border-radius: 999px; padding: 1px 10px; }
  .qc-row .v-clean { color: var(--good); }
  .qc-row .v-off { color: var(--ink-3); border: 1px dashed var(--mute); border-radius: 999px; padding: 0 10px; font-size: 12px; }
  .qc-row .qc-go { color: var(--ink-3); flex: none; font-size: 15px; }

  .ph-grid .member { display: flex; align-items: baseline; gap: 10px; padding: 5px 0; font-size: 14px; }
  .ph-grid .member .who { color: var(--ink); }
  .ph-grid .member .m-role { margin-left: auto; font-size: 12px; color: var(--ink-3); }
  .ph-grid .ticker { border-top: 1px solid var(--line-soft); margin-top: 10px; padding-top: 10px; }
  /* the full-width People card reads in TWO columns when the ticker is present (Mark's walk
     catch at the three-across trial: span-12 rows threw the role and the timestamp a full
     canvas away from their names) — members beside activity, each column near the old span-7
     reading distance; the separator rotates from a top border to a left one. Single column
     below the grid collapse, and for viewers (no ticker) the members keep the plain body. */
  @media (min-width: 981px) {
    .ph-grid .people-body.has-ticker { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 0 28px; align-items: start; }
    .ph-grid .people-body.has-ticker .ticker { border-top: none; margin-top: 0; padding-top: 0; border-left: 1px solid var(--line-soft); padding-left: 28px; }
  }
  .ph-grid .tick-row { display: flex; gap: 10px; padding: 4px 0; font-size: 13px; align-items: baseline; }
  .ph-grid .tick-row .who { color: var(--accent); font-weight: 500; flex: none; }
  .ph-grid .tick-row .what { color: var(--ink-2); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ph-grid .tick-row .when { color: var(--ink-3); font-size: 12px; flex: none; }

  .viewer-note {
    margin-top: 18px; padding: 12px 16px; border: 1px dashed var(--line);
    border-radius: 10px; font-size: 13px; color: var(--ink-3);
  }

  #snapshotDialog { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); color: var(--ink); max-width: 460px; padding: 0; }
  #snapshotDialog::backdrop { background: rgba(10, 14, 20, 0.55); }
  #snapshotDialog .dlg-body { padding: 12px 18px 18px; font-size: 14px; color: var(--ink-2); }

  /* ============================== LOGIN (the front door, 2026-08-08) ==============================
     Standalone chromeless document (no rail — no session); the first token-dressed surface an
     unauthenticated visitor meets. Wordmark above a single card, contact whisper below. */
  .login-shell {
    min-height: 100vh; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 18px; padding: 24px;
  }
  .login-shell .login-mark { width: 118px; height: auto; }
  .login-alert {
    max-width: 340px; width: 100%; font-size: 13.5px; color: var(--warn);
    border: 1px solid var(--warn); border-radius: 8px; padding: 9px 14px;
    background: var(--warn-soft);
  }
  .login-card { width: 100%; max-width: 340px; }
  .login-form { display: flex; flex-direction: column; gap: 5px; padding: 12px 18px 18px; }
  .login-form label {
    font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
    color: var(--ink-3); margin-top: 8px;
  }
  .login-form input.dh-filter { width: 100%; font-size: 15px; padding: 8px 12px; }
  .login-btn { margin-top: 16px; width: 100%; font-size: 14.5px; }
  .login-contact { max-width: 340px; text-align: center; font-size: 12.5px; color: var(--ink-3); line-height: 1.6; }

  /* Project Home dialog family (Delete Points rotated home 2026-08-08 — the row was BOUNCING
     to classic instead of opening a modal) + the row-as-button dress and the danger verb */
  .row-link.row-btn { background: none; border-left: none; border-right: none; border-bottom: none; width: 100%; font-family: inherit; font-size: 14px; text-align: left; cursor: pointer; }
  #deleteDialog { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); color: var(--ink); max-width: 480px; padding: 0; }
  #deleteDialog::backdrop { background: rgba(10, 14, 20, 0.55); }
  #deleteDialog .dlg-body { padding: 12px 18px 18px; font-size: 13.5px; color: var(--ink-2); }
  /* max-width: none — the .dh-filter base caps at 340px (Mark: the textarea sat lopsided vs the narrative) */
  #deleteDialog textarea.dh-filter { width: 100%; max-width: none; font-family: inherit; font-size: 13.5px; resize: vertical; }
  /* the file input wears the house .fld dress (the members-walk mint) — no bespoke rule needed */
  #deleteDialog .dlg-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }
  /* consolidated: this room's verbatim .fmt-chip.chip-ico + .danger-btn duplicates folded into the base rules (2026-08-13) */

  /* the composer's live stored-HTML counter (the 2026-08-09-eve overflow fix) */
  .composer .comp-count { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }

  /* =================== Line Settings and IDs (rail rotation 2026-08-11;
     design of record: mockups/line-settings-rail.html + line-settings-rail.md).
     Adopts the house per-line register (.line-card / .line-head / .line-name gold — the
     gold-as-landmark canon, Tie Ins' mint) and the .builder-card dashed birth enclosure;
     everything room-specific wears .lset-. The primary card renders HEADLESS in single-line
     mode by ruling — see the template comment before "improving" that. =================== */
  .lset-whisper { font-size: 13px; color: var(--ink-2); max-width: 80ch; margin: 0 0 18px; }
  .lset-whisper b { color: var(--ink); }
  .lset-vnote { margin: 0 0 18px; }
  .lset-builder { padding: 14px 20px; }
  .lset-brow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .lset-blbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--ink-3); white-space: nowrap;
  }
  .lset-brow input[type="text"] {
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 7px 11px; font-size: 13.5px; width: 220px;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; text-transform: uppercase;
  }
  .lset-brow input[type="text"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .lset-brow input[type="text"]:disabled { opacity: 0.55; }
  .lset-check { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-2); cursor: pointer; white-space: nowrap; }
  .lset-hint { font-size: 12.5px; color: var(--ink-3); margin-top: 8px; max-width: 76ch; }
  .lset-hint.err { color: var(--bad); }
  .lset-toolbar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 13px 18px; margin-bottom: 14px; }
  .lset-toolbar .dh-filter { flex: 1; min-width: 180px; max-width: 320px; }
  /* the ×-wrap's matching cap — this room's 320 out-cascades the wrap's inner max-width:none reset,
     so the WRAP must wear the same cap or the × drifts 20px past the input's edge */
  .lset-toolbar .dh-filter-wrap { max-width: 320px; }
  .lset-count { margin-left: auto; font-size: 12px; color: var(--ink-3); }
  .line-card.lset-headless .lset-body { padding-top: 16px; }
  .lset-right { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; }
  .lset-right form { margin: 0; }
  .lset-lock { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--ink-3); }
  .lset-lock svg { flex: none; }
  .lset-body { padding: 10px 20px 16px; }
  .lset-style-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
  .lset-ctl { display: inline-flex; align-items: center; gap: 7px; flex-wrap: nowrap; }
  .lset-clbl { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
  /* the room's headline fact (ruled 2026-08-11): the Station Gap label wears the STRONG ink at
     normal weight — color alone draws the eye to the number users come to find and fix (bold
     was tried at the sitting and pulled back) */
  .lset-gap-lbl { font-size: 12.5px; color: var(--ink); white-space: nowrap; }
  .lset-body select {
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 5px 8px; font-size: 12.5px; font-family: inherit; cursor: pointer;
  }
  .lset-body select:disabled, .lset-body input:disabled { opacity: 0.55; cursor: not-allowed; }
  .lset-swatch { width: 42px; height: 28px; padding: 2px; cursor: pointer; border: 1px solid var(--check-line); border-radius: 7px; background: var(--surface-2); }
  .lset-preview {
    flex: 1; min-width: 160px; height: 28px; display: block; border-radius: 6px;
    background:
      linear-gradient(45deg, var(--line-soft) 25%, transparent 25%, transparent 75%, var(--line-soft) 75%),
      linear-gradient(45deg, var(--line-soft) 25%, transparent 25%, transparent 75%, var(--line-soft) 75%);
    background-size: 12px 12px; background-position: 0 0, 6px 6px;
  }
  .lset-gap-row { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
  .lset-gap-row input[type="number"] {
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 5px 9px; font-size: 13px; width: 90px;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-variant-numeric: tabular-nums;
  }
  .lset-gap-row input[type="number"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .lset-update { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; }
  .lset-dirty { font-size: 12px; color: var(--warn); display: none; }
  .line-card.dirty .lset-dirty { display: inline; }
  @media (max-width: 640px) { .lset-update { margin-left: 0; } }

  /* ---------- the API Reference room (v79 — xhalo #50; design of record:
     mockups/api-reference-rail.md, walked 2026-08-12). Reference furniture grown to a page:
     one entry per feed under the token card. The feed NAME wears gold at sans weight (the
     house label register — tally-shelf/line-name kin: a label, not a door; the path chip and
     the fold are the interactions). Chips are facts, not verbs: JSON/file species, the
     sandbox cut, the per-line address, the manager write fence. ---------- */
  .apiref-token .card-body p { margin: 0 0 10px; font-size: 14px; color: var(--ink-2); max-width: 80ch; }
  .apiref-token .card-body p:last-child { margin-bottom: 0; }
  .apiref-token .card-body b { color: var(--ink); }
  .apiref-token .card-body { padding: 12px 20px 16px; }
  .apiref-role { font-size: 13px; color: var(--ink-3); }
  .apiref-role b { color: var(--gold); font-weight: 600; }
  .apiref-token, .apiref-group { margin-bottom: 20px; }
  .apiref-gnote { margin-left: 4px; font-size: 12px; color: var(--ink-3); text-transform: none; letter-spacing: 0; font-weight: 400; }

  .apiref-feed { border-top: 1px solid var(--line-soft); padding: 13px 20px 14px; }
  .apiref-group .apiref-feed:first-of-type { border-top: none; margin-top: 6px; }
  .apiref-fhead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
  .apiref-fname { color: var(--gold); font-size: 14px; font-weight: 600; letter-spacing: 0.01em; }
  .apiref-path {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-size: 12.5px; color: var(--ink-2); cursor: pointer;
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: 5px; padding: 0 7px;
  }
  .apiref-path:hover { border-color: var(--accent); color: var(--ink); }
  .apiref-path.done { color: var(--good); border-color: var(--good); }
  .apiref-chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--mute-soft); color: var(--mute);
    border-radius: 999px; padding: 1px 9px; font-size: 11px; font-weight: 600; white-space: nowrap;
  }
  .apiref-chip.c-line { background: var(--accent-soft); color: var(--accent); }
  .apiref-chip.c-write { background: var(--warn-soft); color: var(--warn); }
  .apiref-chip.c-file { background: var(--good-soft); color: var(--good); }
  .apiref-returns { margin: 6px 0 0; font-size: 13.5px; color: var(--ink-2); max-width: 82ch; }

  details.apiref-fold { margin-top: 8px; }
  details.apiref-fold > summary {
    list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; color: var(--accent);
  }
  details.apiref-fold > summary::-webkit-details-marker { display: none; }
  details.apiref-fold > summary::before { content: "▸"; font-size: 9px; transition: transform 150ms ease; }
  details.apiref-fold[open] > summary::before { transform: rotate(90deg); }

  .apiref-copyseat { position: relative; margin-top: 8px; }
  pre.apiref-call {
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: 8px;
    padding: 12px 14px; margin: 0;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-size: 13px; line-height: 1.55; color: var(--ink); overflow-x: auto;
  }
  pre.apiref-call .prm { color: var(--gold); }
  .apiref-copy {
    position: absolute; top: 8px; right: 8px;
    background: var(--btn-fill); border: 1px solid var(--check-line); color: var(--btn-ink);
    border-radius: 6px; padding: 2px 10px; font-size: 11.5px; cursor: pointer; font-family: inherit;
  }
  .apiref-copy:hover { border-color: var(--accent); background: var(--btn-hover); }
  .apiref-copy.done, .apiref-path.done { color: var(--good); border-color: var(--good); }

  table.apiref-lines { border-collapse: collapse; margin: 10px 0 0; font-size: 13px; width: 100%; max-width: 640px; }
  table.apiref-lines th {
    text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-3); padding: 4px 14px 4px 0; border-bottom: 1px solid var(--line);
  }
  table.apiref-lines td { padding: 6px 14px 6px 0; border-bottom: 1px solid var(--line-soft); vertical-align: baseline; }
  table.apiref-lines tr:last-child td { border-bottom: none; }
  .apiref-line {
    color: var(--gold); font-size: 13px; letter-spacing: 0.04em;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-weight: 700; white-space: nowrap;
  }
  .apiref-whisper { font-size: 12.5px; color: var(--ink-3); margin: 8px 0 0; max-width: 78ch; }

  /* ================= Assignment & Sunsetting (rail rotation 2026-08-11 — the walked room:
     mockups/assignment-sunsetting-rail.md). Three cards; verb rows carry label + consequence
     left, verb right; a .fenced row is a taught fence (disabled verb, impersonal whisper —
     the locked-door-teaches species). Reuses the house dialog family (.del-dlg, .dlg-*),
     .danger-btn, .gate-note, .chk. ================= */
  .asun-card { margin-bottom: 20px; }
  .asun-card .card-body { padding: 12px 20px 18px; }
  .assigned-line { font-size: 17px; margin: 2px 0 6px; color: var(--ink); }
  .role-teach { font-size: 13.5px; color: var(--ink-2); max-width: 72ch; margin: 0 0 4px; }
  .chair-line { font-size: 13px; color: var(--ink-3); margin: 0; }
  .chair-line b { color: var(--ink-2); font-weight: 600; }

  .verb-rows { margin-top: 10px; }
  .verb-row {
    display: flex; align-items: center; gap: 16px;
    padding: 13px 0; border-top: 1px solid var(--line-soft);
  }
  .verb-rows .verb-row:first-child { border-top: none; }
  .verb-row .vr-text { flex: 1; min-width: 0; }
  .verb-row .vr-name { font-size: 14px; font-weight: 600; color: var(--ink); }
  .verb-row .vr-sub { font-size: 12.5px; color: var(--ink-2); max-width: 62ch; margin-top: 1px; }
  .verb-row .vr-seat { flex: none; display: inline-flex; align-items: center; gap: 10px; }
  .verb-row.fenced .vr-name { color: var(--ink-2); }
  .fence-whisper { font-size: 12.5px; color: var(--ink-3); font-style: italic; max-width: 62ch; margin-top: 1px; }
  .fence-whisper a { font-style: normal; white-space: nowrap; }
  .snap-good { color: var(--good); }
  .snap-warn { color: var(--warn); }
  /* the destructive-verb ghost: quiet until armed, red-leaning so the hand knows the register */
  .ghost-btn.danger { color: var(--bad); }
  .ghost-btn.danger:hover:not(:disabled) { border-color: var(--bad); background: var(--bad-soft); }

  .token-teach { font-size: 13.5px; color: var(--ink-2); max-width: 74ch; margin: 0 0 12px; }
  .token-teach b { color: var(--ink); }
  .token-seat { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; }
  .token-field {
    flex: 1; min-width: 240px;
    border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface-2); color: var(--ink);
    padding: 8px 12px; font-size: 13.5px; letter-spacing: 0.04em;
    display: flex; align-items: center; overflow: hidden; white-space: nowrap;
  }
  .token-field.empty { color: var(--ink-3); font-style: italic; letter-spacing: 0; }
  .token-after { font-size: 12.5px; color: var(--ink-3); margin: 10px 0 0; max-width: 74ch; }
  /* the reveal seat: the copy-once secret, gold-fenced and PERSISTENT for this render only
     (the session pop) — never the outcome region, whose auto-fade would eat it */
  .reveal {
    margin-top: 14px; padding: 12px 14px;
    border: 1.5px solid var(--gold-line); border-radius: 9px;
    background: var(--warn-soft);
  }
  .reveal .rv-head { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gold); margin-bottom: 6px; }
  .reveal .rv-seat { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
  .reveal .rv-token {
    flex: 1; min-width: 240px; padding: 7px 11px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 7px;
    font-size: 13.5px; letter-spacing: 0.04em; overflow-x: auto; white-space: nowrap;
  }
  .reveal .rv-sub { font-size: 12.5px; color: var(--ink-2); margin-top: 8px; }

  @media (max-width: 640px) {
    .verb-row { flex-direction: column; align-items: flex-start; gap: 8px; }
  }

  /* ---------- Progress & Gaps — the chart-bearing room (rail rotation 2026-08-12;
     design of record mockups/progress-gaps-rail.md). The chart itself is CanvasJS
     reading these tokens at render (the room-theme ruling); this block dresses the
     business around it. ---------- */
  .pg-controls {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 12px 20px 4px;
  }
  .pg-controls .lbl { font-size: 12px; color: var(--ink-2); font-weight: 500; }
  .pg-rule { width: 1px; align-self: stretch; background: var(--line-soft); }
  /* the date-window instrument is ONE flex item: a long line seg wraps the row and the
     whole group survives the wrap together (the walk's pre-walk polish) */
  .win-group { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .win-arrow { color: var(--ink-3); }
  .date-in {
    height: 32px; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink); font-family: inherit; font-size: 13px;
    padding: 0 8px;
  }
  .date-in:focus { outline: 2px solid var(--gold-line); outline-offset: -1px; }
  .def-row {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 20px 12px;
  }
  .def-row form { display: inline-flex; }
  .knob-whisper { font-size: 11.5px; color: var(--ink-3); }
  .knob-whisper a { color: var(--link); }
  /* horizontal padding keeps the first/last station labels off the card edges; no rules above
     or below the chart — the whitespace does the separating (both Mark's production catches) */
  .pg-chart { height: 500px; margin-top: 8px; padding: 0 20px; }
  /* the room's cards breathe (Mark's production catch 2026-08-12): dh.css's bare .card-foot has
     no padding and .dh-card no bottom margin — text sat on the borders and the cards touched */
  .pg-block { margin-bottom: 20px; }
  .pg-body { padding: 12px 20px 18px; }
  .pg-card .card-foot {
    font-size: 12px; color: var(--ink-3);
    margin-top: 0; padding: 10px 20px 12px;
  }
  .pg-card .card-foot .foot-right { margin-left: auto; }

  /* the coverage tables keep their words; the total row wears strong ink UN-bolded —
     "the white and the gold does the work" (Mark at the walk; the Line Settings register) */
  .cov-wrap { display: flex; gap: 20px; align-items: flex-start; }
  .cov-table { flex: 1; min-width: 0; border-collapse: collapse; width: 100%; }
  .cov-table th {
    text-align: left; font-size: 11px; font-weight: 700; letter-spacing: 0.07em;
    text-transform: uppercase; color: var(--ink-3);
    padding: 6px 14px 6px 0; border-bottom: 1px solid var(--line);
  }
  .cov-table td {
    padding: 7px 14px 7px 0; font-size: 13.5px; color: var(--ink-2);
    border-bottom: 1px solid var(--line-soft);
  }
  .cov-table .miles { font-style: italic; color: var(--ink-3); }
  .cov-table tr.total td {
    border-bottom: none; border-top: 2px solid var(--line);
    color: var(--ink); font-size: 13.5px; padding-top: 10px;
  }
  .cov-table tr.total .pct { color: var(--gold); font-style: italic; }
  .cov-verbs { flex: none; width: 172px; display: flex; flex-direction: column; gap: 8px; }
  .cov-verbs .ghost-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    text-decoration: none;
  }
  .cov-verbs .ghost-btn svg { flex: none; }
  .pg-clean { color: var(--good); font-weight: 600; }
  @media (max-width: 760px) {
    .cov-wrap { flex-direction: column; }
    .cov-verbs { width: 100%; }
    .pg-chart { height: 380px; }
  }

  /* ================= Vertical Profile (rail rotation 2026-08-13 — the chart-in-rail
     inheritor: mockups/vertical-profile-rail.md, brackets ruled same day). Reuses the
     Progress chart family whole (.pg-card/.pg-block/.pg-body/.pg-controls/.pg-chart,
     .card-foot, the theme-token chart recipe) plus .field, .chk, .precondition. Mints
     only this room's own furniture: the saved-views shelf (a chart instrument — it
     rides the chart card, bracket B) and the two deliverable cards' checkbox columns.
     ================= */
  .sv-row {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 20px 12px;
    /* no rule above — the whitespace does the separating (the Progress round-two lesson,
       repeated here on Mark's live-render catch 2026-08-13) */
    font-size: 12.5px;
  }
  .sv-row .lbl { font-size: 12px; color: var(--ink-2); font-weight: 500; }
  .sv-chip {
    display: inline-flex; align-items: center;
    border: 1px solid var(--check-line); border-radius: 999px;
    background: var(--surface); padding: 2px 4px 2px 2px;
  }
  .sv-chip .sv-apply {
    background: none; border: none; cursor: pointer; font-family: inherit;
    font-size: 12.5px; color: var(--ink-2); padding: 2px 6px 2px 10px;
    border-radius: 999px;
  }
  .sv-chip .sv-apply:hover { background: var(--accent-soft); color: var(--ink); }
  .sv-chip .sv-apply .who { font-size: 10.5px; color: var(--ink-3); }
  .sv-chip form { display: inline-flex; }
  .sv-chip .sv-x {
    background: none; border: none; cursor: pointer; color: var(--ink-3);
    font-size: 11px; line-height: 1; padding: 4px 6px; font-family: inherit; border-radius: 50%;
  }
  .sv-chip .sv-x:hover { color: var(--bad); background: var(--bad-soft); }
  .sv-save { display: inline-flex; gap: 8px; align-items: center; margin-left: auto; flex-wrap: wrap; }
  .sv-save input[type="text"] {
    height: 30px; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink); font-family: inherit; font-size: 12.5px;
    padding: 0 10px; width: 160px;
  }
  @media (max-width: 760px) { .sv-save { margin-left: 0; } }

  /* (the chart card head's right seat: the .pg-card scoped .hd-right — the THIRD specimen that
     carried the generalization-candidate flag — retired 2026-08-14 when the XLSX room arrived as
     the fourth; bare .card-head .hd-right now rules, defined beside .card-head's base) */
  /* the two deliverables side by side for discoverability (Mark's post-build ask):
     auto-fit, so a restricted viewer's lone hydro card spans the full row */
  .vp-rep-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 20px; align-items: start; margin-bottom: 20px;
  }
  .vp-rep-grid .vp-rep { margin-bottom: 0; }
  .vp-rep { margin-bottom: 20px; }
  .vp-rep .rep-note { font-size: 12.5px; color: var(--ink-2); margin: 0 0 12px; max-width: 72ch; }
  .vp-rep .field { margin-bottom: 12px; }
  .vp-rep .field .lite { color: var(--ink-3); font-weight: 400; }
  .vp-warn { margin-bottom: 12px; }
  .vp-verb { display: flex; align-items: center; gap: 10px; margin: 2px 0 4px; }
  .vp-verb .ghost-btn { display: inline-flex; align-items: center; }
  .chk-cols { display: flex; gap: 30px; flex-wrap: wrap; margin-top: 14px; }
  .chk-col { min-width: 160px; }
  .chk-col .col-lbl { font-size: 12px; color: var(--ink-2); font-weight: 500; margin-bottom: 2px; }
  .chk-col .col-whisper { font-size: 11px; color: var(--ink-3); font-style: italic; margin-bottom: 6px; }
  .chk-col .chk { padding: 2px 0; }

  /* ================= XLSX Workbooks (rail rotation 2026-08-14 — design of record:
     mockups/xlsx-workbooks-rail.md, walked + ratified, eight rulings; replaces the classic
     three-box "Tabbed XLSX" page). The room's argument: the TABS are the product, so each
     card leads with a working miniature of the actual workbook — an Excel-style bottom tab
     strip + real headers + real first rows. Gold ATT headers mark the positional columns
     whose decoder is the Legend sheet (the mixed-schema lesson); feature sheets' named att
     headers wear the same gold (the attribute register, one voice across both cards). ================= */
  .xlsx-card { margin-bottom: 22px; }
  .xlsx-card .card-body { padding: 12px 20px 16px; }
  /* bordered in-card foot — the exporter family's divergence (picker-card kin) */
  .xlsx-card .card-foot { margin-top: 0; padding: 12px 20px 14px; border-top: 1px solid var(--line-soft); }
  /* the control's SUBJECT wears the small-caps register (the filter-label grammar) */
  .xlsx-card .card-head .lbl {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-2);
  }
  .fact-chip {
    display: inline-flex; align-items: center; gap: 4px;
    background: var(--mute-soft); color: var(--mute);
    border-radius: 999px; padding: 1px 9px; font-size: 11px; font-weight: 600; white-space: nowrap;
    text-transform: none; letter-spacing: 0;
  }
  /* ---- the workbook miniature: a real slice of the file, tab strip in Excel's own furniture ---- */
  .wb-preview {
    border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
    background: var(--surface); margin: 10px 0 4px;
  }
  /* wide sheets pan INSIDE the preview (the wide-table rule, born ruled) */
  .sheet-scroll { overflow-x: auto; }
  .mini-sheet { border-collapse: collapse; width: 100%; font-size: 11.5px; }
  .mini-sheet th, .mini-sheet td {
    border: 1px solid var(--line-soft); padding: 3px 9px; white-space: nowrap;
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-variant-numeric: tabular-nums;
  }
  /* header blue DIMMED off the button's accent (Abby's walk, 2026-08-14: clickables must be
     obviously the clickables — the sheet header had the same fill as the download button, so
     the page's strongest blue was worn by something inert). Mixed toward mute: desaturates in
     both themes, measured 7.75 light / 4.54 dark against accent-ink (floor held). */
  .mini-sheet th {
    background: color-mix(in srgb, var(--accent) 70%, var(--mute)); color: var(--accent-ink);
    font-weight: 600; font-size: 10.5px; text-align: left; letter-spacing: 0.02em;
  }
  .mini-sheet td { color: var(--ink-2); }
  .mini-sheet td.na { color: var(--ink-3); font-style: italic; }
  /* attribute columns: gold headers, dark fixed ink (same pair both themes — gold-line is stable) */
  .mini-sheet .attcol { background: var(--gold-line); color: #171207; }
  .mini-sheet td.legend-code { background: var(--accent-soft); color: var(--ink); font-weight: 700; }
  .tab-strip {
    display: flex; align-items: stretch; flex-wrap: wrap;
    background: var(--surface-2); border-top: 1px solid var(--line);
    padding: 0 8px;
  }
  .tab-strip .xtab {
    border: 1px solid var(--line); border-top: none; margin-right: -1px;
    border-radius: 0 0 7px 7px;
    background: var(--surface-2); color: var(--ink-2);
    font-size: 11.5px; padding: 3px 13px 4px; cursor: pointer; font-family: inherit;
    white-space: nowrap;
  }
  .tab-strip .xtab:hover { color: var(--ink); background: var(--accent-soft); }
  .tab-strip .xtab.on {
    background: var(--surface); color: var(--ink); font-weight: 600;
    border-top: 2px solid var(--surface); margin-top: -1px; position: relative; z-index: 1;
  }
  /* parked sheets lean italic — the not-really-built-yet whisper */
  .tab-strip .xtab.parked { font-style: italic; }
  .preview-caption { font-size: 12px; color: var(--ink-3); margin: 6px 0 0; }
  .preview-caption b { color: var(--ink-2); }
  /* ---- the teach block: the standing 2D-or-3D answer, living beside the 3D-Sum control ---- */
  .teach {
    font-size: 12.5px; color: var(--ink-2); max-width: 78ch;
    background: var(--surface-2); border: 1px solid var(--line-soft);
    border-radius: 8px; padding: 10px 14px; margin-top: 12px;
  }
  .teach b { color: var(--ink); }
  .teach .mono { font-size: 12px; }
  .xlsx-card .filters-row { padding: 14px 0 0; }
  .xlsx-card .filters-row select {
    border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink);
    padding: 6px 9px; font-size: 13px; font-family: inherit; cursor: pointer; max-width: 100%;
  }
  .xlsx-card .hint.warn { color: var(--warn); font-size: 12.5px; margin-top: 10px; }
  /* ---- scope rows: every download wears its blast radius (the DXF for-each kinship) ---- */
  .scope-table { margin-top: 14px; }
  .scope-table td { padding: 7px 10px; }
  .scope-table tbody tr:last-child td { border-bottom: none; }
  .scope-table .scope-name { font-weight: 600; color: var(--ink); }
  /* the whole-project row's name wears gold — the landmark register */
  .scope-table tr.every-row .scope-name { color: var(--gold); }
  /* a scope with zero points dims rather than lying (the storefront facet grammar) */
  .scope-table tr.zero { opacity: 0.45; }
  .scope-table .verb-col { text-align: right; width: 1%; white-space: nowrap; }
  /* the download verbs wear the PRIMARY dress (Abby's walk, 2026-08-14, superseding the
     ghost outline of the same day: clickables must be obviously the clickables — the
     per-feature downloads now match the Tabbed-by-Line button's accent fill, so filled
     blue on this page means exactly one thing: press to download) */
  .scope-table .row-verb {
    text-decoration: none; display: inline-block;
    background: var(--accent); border: 1px solid var(--accent);
    border-radius: 8px; padding: 5px 13px; box-shadow: var(--btn-shadow);
    color: var(--accent-ink); font-weight: 500;
  }
  .scope-table .row-verb:hover { filter: brightness(1.08); background: var(--accent); color: var(--accent-ink); }
  .scope-table .row-verb:disabled {
    box-shadow: none; background: none; border-color: var(--line);
    color: var(--ink-2); filter: none;
  }

  /* ---------- Map Bookmarks — the bbox_manager rotation (2026-08-14+1; design of record
     mockups/bbox-manager-rail.md, walked + ruled same session, REVISED on Mark's live walk the
     same evening). Satellite room off Project Home's maps card — no rail door. The locator is
     an INSTRUMENT (deliberate departure from .ph-map's locked conduct — bookmarks are tiny
     framed spots, so this map zooms/pans/flies): squarish frame, table beside it on desktop. */
  .bm-grid { display: grid; grid-template-columns: minmax(340px, 5fr) 6fr; gap: 22px; align-items: start; }
  @media (max-width: 1180px) { .bm-grid { grid-template-columns: 1fr; } }
  .bm-map .card-body { padding: 10px 12px 12px; }
  .bm-map .map-frame {
    border-radius: 7px; overflow: hidden; border: 1px solid var(--line-soft);
    aspect-ratio: 1 / 0.9; min-height: 320px; background: var(--surface-2);
    position: relative;
  }
  .bm-map #bmMap { position: absolute; inset: 0; }
  .bm-map .map-legend { padding: 9px 6px 0; font-size: 12.5px; color: var(--ink-2); }
  /* must out-specify leaflet.css's `.leaflet-bar a` (display:block + line-height) or the flex
     centering silently loses and the svg rides the text baseline (the specificity-phantom lesson) */
  .leaflet-bar a.bm-extent-btn { display: flex; align-items: center; justify-content: center; }
  /* the census: title stays an INPUT (classic's rename-in-place gesture), quiet until touched;
     the row itself is a fly-to-the-bookmark verb (clicks on controls stay control clicks) */
  .bm-census .qc-table { margin-top: 12px; }
  .bm-census tbody tr, .bm-shelf tbody tr { cursor: pointer; }
  .bm-title-col { width: 58%; }
  /* Map Bookmarks: the hidden-layers chip row under a title (2026-09-07) */
  .bm-hidden { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 4px; }
  .bm-hidden-label { color: var(--ink-3); font-size: 12px; margin-right: 2px; }
  .bm-chip { font-size: 12px; line-height: 1.3; padding: 1px 7px; border-radius: 4px; border: 1px solid var(--line); background: var(--bg-2); color: var(--ink-2); white-space: nowrap; }
  .bm-title-input {
    width: 100%; min-width: 180px;
    border: 1px solid transparent; border-radius: 6px;
    background: transparent; color: var(--ink);
    font: inherit; padding: 4px 8px; margin-left: -9px;
    cursor: text;
  }
  .bm-title-input:hover { border-color: var(--line); }
  .bm-title-input:focus { border-color: var(--accent); background: var(--surface); outline: none; }
  .bm-census input[type="checkbox"], .bm-shelf input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; }
  .bm-census .card-foot { padding: 0 20px 14px; margin-top: 10px; }
  /* hover sync: the locator lights the row exactly as the row lights the rectangle */
  tr.bm-hot td { background: var(--warn-soft); }
  .bm-shelf .bm-owner { color: var(--ink-3); font-size: 13px; white-space: nowrap; }

  /* ---------- Background Sketches — the sketches rotation (2026-08-14+2; design of record
     mockups/sketches-rail.md). The hub re-sources the house wholesale (xref-zone, row-menu,
     qc-table, verdict-bar, del-dlg, dh-filter); the mints below are the room's own furniture:
     the preview well, the drag column the dissolved dragger room left behind, and the
     Style Editor child's form/preview grid. */
  .sk-title-col { width: 30%; }
  /* naked identity names (Mark's Mountain Valley ruling, 2026-08-14+2): long CAD-layer titles
     (MASTER_DXF layer stems) overflowed the card edge in the button-dressed summary — an
     unwrappable button can only overflow. The name is identity-as-door, so it sheds the button
     and wears the link register as wrapping text; the caret and menu stay. The style PICKER
     followed same session (Mark's restful-eye pass — the first cut kept it button-dressed as
     "a control, not an identity", superseded): the census now sheds button dress entirely, and
     the footer's Primary verbs carry the room's button weight. Full-prefix selectors per the
     specificity-phantom lesson (out-rank details.row-menu > summary). */
  .sk-census details.row-menu > summary.sk-name,
  .sk-census details.row-menu > summary.sk-style-pick {
    background: none; border: none; box-shadow: none; padding: 0;
    display: inline; white-space: normal; overflow-wrap: anywhere;
    color: var(--link); font-size: 14px;
  }
  .sk-census details.row-menu > summary.sk-name:hover,
  .sk-census details.row-menu > summary.sk-style-pick:hover { text-decoration: underline; }
  .sk-check-col { width: 1%; white-space: nowrap; }
  .sk-census .sk-fact, .sk-styles .sk-fact { color: var(--ink-2); white-space: nowrap; font-size: 13px; }
  .sk-census input[type="checkbox"], .sk-styles input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; }
  .sk-prev { display: inline-flex; align-items: center; gap: 8px; }
  /* the preview ground: a CONSTANT dark checker in BOTH themes (Mark's convergence ruling,
     2026-08-14+2, after three tuning rounds — lset-checker verbatim, then theme-mixed tones,
     then per-theme pairs, each still too light for his eye): the ground serves the SWATCH, not
     the theme — the same reasoning that darkened the style-switcher pop, applied to its sibling.
     WHY a checker and not a solid well (Mark, same session): the TEXTURE is the opacity
     instrument — a semi-transparent style shows the squares through its own body, so the eye
     reads "70% opaque" directly off the preview; a solid ground can only show color. Never
     "simplify" this to a flat well.
     Line Settings' .lset-preview keeps its own light checker (chain colors are user-picked for
     dark maps but rarely white; these previews carry classic's white Default routinely).
     THE EYE-TUNING KNOB is the two numbers below: base darker ⇢ light lines pop harder;
     square alpha higher ⇢ pattern reads stronger. Bump on Mark's word. */
  .sk-prev svg {
    display: block; border-radius: 4px;
    --sk-check: rgba(255, 255, 255, 0.12);
    --sk-check-base: #232b38;
    background:
      linear-gradient(45deg, var(--sk-check) 25%, transparent 25%, transparent 75%, var(--sk-check) 75%),
      linear-gradient(45deg, var(--sk-check) 25%, transparent 25%, transparent 75%, var(--sk-check) 75%);
    background-color: var(--sk-check-base);
    background-size: 12px 12px; background-position: 0 0, 6px 6px;
  }
  .sk-filter { padding: 0 20px 10px; max-width: 360px; }
  /* the style-switcher pop: options paint themselves in their style's OWN color, so the pop needs
     a CONSTANT dark ground in both themes — white/very-light styles vanished on Light's surface
     pop (Mark's walk catch, 2026-08-14+2). Same reasoning family as the preview checker: the
     ground serves the swatch, not the theme. Inline style colors out-rank the hover rule, so
     colored options keep their color on hover; the overrides below carry the un-colored ones.
     Selectors carry the FULL details.row-menu prefix on purpose — the specificity phantom's
     third bite in this file: bare .menu-pop.sk-style-pop (0,2,0) silently LOST to the house
     details.row-menu .menu-pop (0,2,1) and the pop stayed white through an Apache kick. */
  details.row-menu .menu-pop.sk-style-pop { background: #2b3140; border-color: #1c2430; }
  details.row-menu .menu-pop.sk-style-pop .mi { color: #e8ecf2; }
  details.row-menu .menu-pop.sk-style-pop .mi:hover { background: rgba(255, 255, 255, 0.12); color: #e8ecf2; }
  .sk-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  /* the dirty-woken foot verbs ANNOUNCE their waking (Mark's pass): enabled = outlined in the
     verb's own register color; disabled stays quiet. NOTE the house .row-verb is border: NONE
     (the flat in-table register) — the first cut set border-color on a border that didn't exist
     and nothing rendered (the v138 miss; a mockup-local bordered row-verb had slipped past the
     census). The foot verbs therefore own a real border box: transparent at rest so the wake
     outline arrives without a layout shift, footer-scaled padding to sit beside the Primaries. */
  .sk-foot .row-verb { border: 1px solid transparent; padding: 5px 13px; border-radius: 7px; }
  .sk-foot .row-verb:not(:disabled) { border-color: var(--accent); }
  .sk-foot .row-verb.danger:not(:disabled) { border-color: var(--bad); }
  .sk-foot .hint { margin-left: auto; }
  .sk-foot form { margin: 0; display: inline-flex; }
  /* the dissolved dragger's handle column (docket 2): grab affordance only — the commit is the
     dirty-woken Save order verb, one POST, never per-drop autosave */
  .sk-drag-col { width: 1%; white-space: nowrap; }
  .drag-me { cursor: grab; color: var(--ink-3); font-size: 15px; padding: 0 4px; user-select: none; }
  tr.sortable-ghost { opacity: 0.4; }
  .sk-order-hint { padding: 4px 20px 8px; font-size: 12px; color: var(--ink-3); }
  .sk-inuse { color: var(--ink-3); font-size: 12px; white-space: nowrap; }
  /* style-name links rest bare, underline on hover — matching the census's naked grammar
     (Mark's pass); the affordance moves to the column head's whisper, which the template gates
     on can_edit so viewers (who get no links) read no false promise */
  .sk-styles td a { text-decoration: none; }
  .sk-styles td a:hover { text-decoration: underline; }
  .sk-th-whisper { font-weight: 400; text-transform: none; letter-spacing: normal; }

  /* the Style Editor child room: form beside the live preview iframe, stacking on narrow */
  .se-grid { display: grid; grid-template-columns: minmax(280px, 2fr) 5fr; gap: 22px; align-items: start; }
  @media (max-width: 1000px) { .se-grid { grid-template-columns: 1fr; } }
  .se-form .card-body, .se-preview .card-body { padding: 14px 20px 18px; }
  /* bare .fld carries no vertical rhythm of its own (contexts set their own) — a tall stacked
     form needs real separation between control groups (Mark's walk catch, 2026-08-14+2) */
  .se-form .fld { margin-bottom: 16px; }
  .se-color { width: 100%; height: 38px; padding: 3px 5px; border: 1px solid var(--check-line); border-radius: 7px; background: var(--surface-2); cursor: pointer; }
  .se-pick { margin-top: 8px; font-size: 12.5px; }
  .se-update { width: 100%; margin-top: 6px; }
  .se-frame { border-radius: 7px; overflow: hidden; border: 1px solid var(--line-soft); background: var(--surface-2); aspect-ratio: 4 / 3; min-height: 420px; position: relative; }
  .se-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: none; }
  .se-frame-note { padding-top: 8px; }
  .se-symbols { display: flex; flex-wrap: wrap; gap: 8px; max-width: 380px; }
  .se-sym {
    width: 44px; height: 40px; font-size: 19px; cursor: pointer;
    background: var(--btn-fill); border: 1px solid var(--line); border-radius: 7px;
    color: var(--ink); box-shadow: var(--btn-shadow);
  }
  .se-sym:hover { border-color: var(--accent); color: var(--accent); }

  /* ============ The exporter STOREFRONT family — CSV Builder (the flagship,
     csv-exporter-reimagined.md, docket closed 2026-08-18) + KMZ Builder + Shapefile Builder
     (exporter-pair-seed.md, walked 2026-08-22). Classic's three-column skeleton in house
     dress: verb card leads col 1, filter cards beside, features right. Reuses dh-card,
     card-head/foot, qc-table, picker-cols/picker-half, count-badge, feat-check, dh-seg
     decide-seg, filters-row/filter-group, dh-select, col-check, primary-btn (the scoped-class
     lesson, honored by reuse); the mints below are the family's furniture. .exp-store and
     .exp-verb-row were born .csv-store/.csv-verb-row and promoted at the rule of two when the
     pair became consumers (2026-08-22); .exp-verb-row stays prefixed because bare .verb-row
     belongs to another room (the mirror-census catch). The Abby-walk register (gold heads,
     surface-2 table bands, gold Online/Offline, the grown select-all) rides .exp-store so all
     three rooms speak it. */
  .exp-store { display: grid; grid-template-columns: minmax(300px, 350px) minmax(260px, 310px) minmax(0, 1fr); gap: 16px; align-items: start; }
  @media (max-width: 1250px) { .exp-store { grid-template-columns: minmax(280px, 1fr) minmax(260px, 1fr); } }
  @media (max-width: 860px) { .exp-store { grid-template-columns: minmax(0, 1fr); } }
  .exp-store > div { min-width: 0; }
  .exp-store .dh-card { margin-bottom: 14px; }
  /* the verb card: the daily user lands on the button, top-left (layout amendment 2) */
  .verb-card .cart-file { display: block; font-size: 12.5px; color: var(--gold); padding: 10px 20px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .verb-card .cart-count { display: block; font-size: 13px; color: var(--ink-2); padding: 4px 20px 0; }
  .verb-card .cart-count b { color: var(--ink); }
  .verb-card .exp-verb-row { padding: 12px 20px 16px; }
  .verb-card .exp-verb-row .primary-btn { width: 100%; }
  /* the settle beat (ruling B): while the count fetch is in flight the facts dim — the verb
     never claims a number the server hasn't confirmed */
  .verb-card.settling .cart-count, .verb-card.settling .primary-btn { opacity: 0.55; transition: opacity 0.15s; }
  /* the columns configurator: dragula's gesture in house dress (ruling G) */
  .col-lists { display: flex; gap: 0; align-items: flex-start; padding: 4px 8px 10px; }
  .col-list { flex: 1 1 0; min-width: 0; padding: 0 10px; }
  .col-list + .col-list { border-left: 1px solid var(--line-soft); }
  .col-list .list-lbl { font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); margin: 8px 0 7px 2px; }
  .col-item {
    display: flex; align-items: center; gap: 7px;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 7px;
    font-size: 12.5px; color: var(--ink); padding: 4px 8px; margin-bottom: 5px;
    cursor: grab; user-select: none;
  }
  .col-item .grip { color: var(--ink-3); font-size: 10px; }
  .col-item.dragging { opacity: 0.4; }
  .col-item.drop-hint { border-top: 2px solid var(--gold-line); }
  .col-item .uncol {
    background: none; border: none; cursor: pointer; color: var(--ink-3);
    font-size: 11px; margin-left: auto; padding: 0 2px; font-family: inherit;
  }
  .col-item .uncol:hover { color: var(--bad); }
  .col-item.avail { color: var(--ink-3); border-style: dashed; background: none; cursor: pointer; }
  .col-item.avail:hover { border-color: var(--accent); color: var(--accent); }
  .col-item.avail .add { margin-left: auto; font-size: 11px; }
  .reset-cols {
    background: none; border: none; cursor: pointer; font-family: inherit;
    font-size: 12px; color: var(--ink-3); text-decoration: underline; padding: 0;
    margin-left: auto; white-space: nowrap;
  }
  .reset-cols:hover { color: var(--accent); }
  /* facet card rows (options / bypass) */
  .facet-row { padding: 8px 20px 0; }
  .facet-row label { font-size: 12px; font-weight: 600; color: var(--ink-2); display: block; margin-bottom: 4px; }
  .facet-row .dh-select, .facet-row input[type="date"] { width: 100%; }
  .facet-row input[type="date"] {
    background: var(--surface-2); color: var(--ink); border: 1px solid var(--line);
    border-radius: 7px; padding: 6px 9px; font-family: inherit; font-size: 13px; color-scheme: inherit;
  }
  .facet-row input[type="date"]:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .date-pair { display: flex; gap: 8px; }
  .date-pair > span { flex: 1 1 0; min-width: 0; }
  .facet-seg { padding: 10px 20px 14px; }
  .facet-seg .lbl { font-size: 12px; font-weight: 600; color: var(--ink-2); display: block; margin-bottom: 5px; }
  .facet-check { padding: 9px 20px 0; }
  .facet-check:last-of-type { padding-bottom: 4px; }
  /* the phases table at facet width */
  .facet-half .qc-table td { padding: 5px 12px; }
  .facet-half .qc-table tbody tr:last-child td { border-bottom: none; }
  .facet-half .qc-table td:last-child, .facet-half .qc-table th:last-child { width: 36px; }
  /* row text aligns with the header (Mark's eye, 2026-08-18): the family's td-padding overrides
     land later in the file than .qc-table td:first-child at EQUAL specificity, so the first
     cell's 20px left seat silently collapsed to 12px while th kept 20px — restored here for this
     room's tables AND the picker-half family (the gpkg/shp rooms carried the same latent skew) */
  .facet-half .qc-table td:first-child, .picker-half .qc-table td:first-child { padding-left: 20px; }
  .facet-half tr.zero { opacity: 0.45; }
  .facet-half tr.zero .count-badge { background: transparent; border: 1px dashed var(--line); }
  /* a facet table that CLOSES its card breathes at the bottom (Mark's walk, 2026-08-22 —
     KMZ's Placemark popups + SHP's Table columns end in the table itself; every other card
     ends in a padded seg or foot) */
  .exp-store .dh-card > .facet-half:last-child { padding-bottom: 12px; }
  /* Abby's walk (2026-08-19), three asks ratified with Mark in the room:
     1 — gold card heads, the ps-board convention's SECOND consumer (case-by-case ruling,
     ui/NEXTGEN): six same-weight cards across three columns wash together without a leading eye.
     2 — the Online and Offline halves read as one grey mass: the list heads brighten to full
     ink on a surface-2 band (the Phases table wears the same dress — one room, one register).
     3 — the select-all is Abby's daily lever (she unchecks it FIRST, then picks): it grows past
     the row checks and wears the accent line at rest, so the master reads as the master. */
  .exp-store .card-head { color: var(--gold); }
  .exp-store .picker-half .qc-table th, .exp-store .facet-half .qc-table th {
    color: var(--ink); background: var(--surface-2);
    padding-top: 8px; padding-bottom: 8px;
  }
  /* the ONLINE / OFFLINE words themselves go gold (Mark, same walk): the axis every export
     decision starts from, leading the eye the same way the card heads do. (The GeoPackage room
     joined 2026-08-22+1 via a .gpkg-pick scope that lived one hour — the same evening's board
     restructure brought the room onto .exp-store proper and the scope retired.) */
  .exp-store .picker-half .qc-table th:first-child { color: var(--gold); }
  .exp-store .qc-table thead .feat-check { width: 18px; height: 18px; border-color: var(--accent); }
  /* Header row (same walk): the one option that reshapes the FILE, not just the filter — it
     steps up to full ink and the facet-label weight so it stops reading as fine print */
  .exp-store .col-check.col-lead { color: var(--ink); font-weight: 600; }
  /* the bypass override: dimmed, not hidden — the operator sees what is set aside */
  .overridden { opacity: 0.38; pointer-events: none; filter: saturate(0.4); }
  .bypass-note { display: none; margin: 8px 20px 0; font-size: 12px; color: var(--gold); }
  .bypass-live .bypass-note { display: block; }
  .bypass-card textarea {
    width: calc(100% - 40px); margin: 8px 20px 0; min-height: 64px; resize: vertical;
    background: var(--surface-2); color: var(--ink); border: 1px solid var(--line);
    border-radius: 7px; padding: 7px 9px; font-size: 12.5px;
  }
  .bypass-card textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  /* the bypass card's foot reads as one thought with the textarea — no separator (Mark's eye, 2026-08-18) */
  .bypass-card .card-foot { border-top: none; }
  /* the sleek foot (Mark's eye, post-deploy same day): Columns + Options keep the family's padded
     foot but drop the separator line — the hint reads as the card's last breath, not a footer.
     Re-ruled at the pair's walk (2026-08-22): the separator earns its keep closing a TABLE;
     under form rows or the verb it is noise. */
  .picker-card.foot-sleek .card-foot { border-top: none; }
  /* ---- the pair's mints (KMZ + SHP, exporter-pair-seed.md rulings 2026-08-22) ---- */
  /* the verb-card foot: the must_scale whisper's seat (SHP) — padded, no separator (the
     sleek-foot ruling applied; the foot follows the button, not a table) */
  .verb-card .card-foot { margin-top: 0; padding: 0 20px 14px; border-top: none; }
  /* the bundle's member grammar line (SHP verb card) */
  .verb-card .cart-members { display: block; font-size: 12px; color: var(--ink-3); padding: 3px 20px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .verb-card .cart-members .mono { color: var(--ink-2); }
  /* classic's "(Metric Bundle)" head suffix, house-dressed (renders on must_scale only) */
  .verb-card .metric-chip { display: inline-block; margin-left: 8px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px; vertical-align: 2px; }
  /* the always-on facts line (ruled over dead checkbox rows): KMZ's popup fields, SHP's
     required columns — honest furniture dressed as FACTS */
  .exp-store .always-facts { padding: 10px 20px 0; font-size: 12.5px; color: var(--ink-2); line-height: 1.55; }
  .exp-store .always-facts b { color: var(--ink); font-weight: 500; }
  .exp-store .always-facts .tick { color: var(--good); font-size: 11px; margin-right: 2px; }
  /* The DBF preflight (xhalo #71, warn-and-proceed 2026-09-01): the collision warn re-wears
     the Code Manager's gold panel inside the exporter cards (Shapefile Builder + Attributed
     Joints — unscoped on purpose), and the abbreviation map folds quiet under a disclosure. */
  .dbf-warn { margin: 10px 20px 0; }
  .dbf-warn a { color: inherit; text-decoration: underline; }
  /* Loose End status teach (Mark's ask, 2026-09-01, the drive-by-setup sitting): the two
     linework rooms state the config's consequence — unset wears the quiet hint register
     (deferral is legitimate, the load-then-tune workflow), set-but-not-Online wears the gold
     panel (declared intent the walks silently ignore). */
  .le-warn { margin: 10px 20px 0; }
  .le-warn a { color: inherit; text-decoration: underline; }
  .le-note { padding: 10px 20px 0; font-size: 12px; color: var(--ink-3); line-height: 1.55; }
  .le-note b { color: var(--ink-2); }
  .dbf-map { padding: 10px 20px 2px; }
  .dbf-map summary { cursor: pointer; font-size: 12px; color: var(--ink-3); list-style: none; user-select: none; }
  .dbf-map summary::-webkit-details-marker { display: none; }
  .dbf-map summary::before { content: '\203A'; display: inline-block; margin-right: 6px; transition: transform 0.15s; }
  .dbf-map[open] summary::before { transform: rotate(90deg); }
  @media (prefers-reduced-motion: reduce) { .dbf-map summary::before { transition: none; } }
  .dbf-map-code { margin: 8px 0 0 14px; font-size: 12px; color: var(--ink-2); }
  .dbf-map-code b { color: var(--ink); font-weight: 500; }
  .dbf-map-row { margin-left: 12px; }
  .dbf-map-row .mono { font-size: 12px; }
  .dbf-map-row .arr { color: var(--ink-3); }
  /* the spread teach (KMZ, ruling F): renders ONLY on breaks + multi-line — testimony for the
     one reader who configured spreads and lost the control to multi-line */
  .exp-store .spread-why { padding: 2px 0 0; font-size: 12px; color: var(--ink-3); line-height: 1.5; }
  /* KMZ's column profile (Mark's walk, 2026-08-22): the SKETCHES column earns the width —
     feature rows are short (code + badge + check) while sketch titles are long filenames, so
     col 2 takes the free width and features cap. min-width-scoped so the shared 2-col/1-col
     collapses below 1250px apply untouched (the modifier would out-specify them otherwise). */
  @media (min-width: 1251px) {
    .exp-store.kmz-cols { grid-template-columns: minmax(300px, 350px) minmax(0, 1fr) minmax(260px, 380px); }
  }
  /* the peek (ruled: survives, collapsed) — the file's actual first rows, one click deep */
  .peek-card summary {
    list-style: none; cursor: pointer; padding: 12px 20px;
    font-size: 13px; color: var(--ink-2);
  }
  .peek-card summary::-webkit-details-marker { display: none; }
  .peek-card summary .tri { display: inline-block; margin-right: 8px; transition: transform 0.15s; color: var(--ink-3); }
  .peek-card[open] summary .tri { transform: rotate(90deg); }
  .peek-card summary b { color: var(--ink); }
  .peek-card .prev-scroll { overflow-x: auto; }
  .peek-card .prev-scroll[hidden] { display: none; }
  .peek-card .qc-table { margin-top: 0; }
  .peek-card .qc-table th { white-space: nowrap; }
  .peek-card .qc-table th.att-col { color: var(--ink-3); font-weight: 500; }
  .peek-card .qc-table td { white-space: nowrap; font-size: 12px; }
  .peek-card .peek-empty { padding: 18px 20px; font-size: 13px; color: var(--ink-3); }
  .peek-card .peek-empty b { color: var(--ink); }

  /* ================= Photos room (photos.html; design of record mockups/photos-rail.md,
     nine ratified en bloc 2026-08-18 — the Jason-call sitting). Two states, one URL:
     the pitch + Connect when hosting is off; the mask card + house table when on. ========= */
  .ph-pitch { padding: 18px 24px 22px; max-width: 720px; font-size: 13.5px; color: var(--ink-2); }
  .ph-pitch p { margin: 0 0 10px; }
  .ph-pitch p b { color: var(--ink); }
  .ph-lede { font-size: 15px; color: var(--ink); }
  .ph-how {
    display: flex; gap: 18px; flex-wrap: wrap;
    margin: 16px 0 18px; padding: 14px 16px;
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: 8px;
  }
  .ph-step { flex: 1; min-width: 180px; font-size: 12.5px; color: var(--ink-2); }
  .ph-step .k {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 50%; margin-bottom: 5px;
    background: var(--accent-soft); color: var(--accent); font-size: 11px; font-weight: 700;
  }
  .ph-step b { display: block; color: var(--ink); font-size: 13px; }
  .ph-connect { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
  .ph-fence { font-size: 12.5px; color: var(--ink-3); }
  .accent-btn:disabled { opacity: 0.45; cursor: default; }
  .accent-btn:disabled:hover { filter: none; }

  /* the mask card — the star: gold-edged, the * wears gold, the chain taught in place */
  .ph-mask { margin-bottom: 18px; border-left: 3px solid var(--gold-line); }
  .ph-mask-body { padding: 12px 20px 16px; }
  .ph-mask-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .ph-mask-str {
    flex: 1; min-width: 260px; font-size: 13px; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px;
    padding: 8px 12px; overflow-x: auto; white-space: nowrap;
  }
  .ph-mask-str .star, .star-ink { color: var(--gold); font-weight: 700; }
  .ph-mask-teach { font-size: 12.5px; color: var(--ink-2); margin-top: 9px; }
  .ph-mask-teach b { color: var(--ink); }

  /* upload rides the toolbar; the input wears the CANON file dress (.fld input[type="file"],
     the Abby 2026-07-29 shape — bordered box + integrated accent browse segment) rather than a
     room-local imitation; this wrapper only sizes it for the inline toolbar shape */
  .ph-upload { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .ph-upload .fld.ph-pick { flex: 0 1 340px; min-width: 220px; }
  .ph-upload-btn { padding: 5px 14px; font-size: 12.5px; }
  .ph-upload .hint { margin-top: 0; }

  .ph-empty { padding: 22px 24px 20px; font-size: 13.5px; color: var(--ink-2); max-width: 640px; }
  .ph-empty p { margin: 0 0 10px; }
  .ph-empty b { color: var(--ink); }

  /* quiet-danger — a destructive door that is present but never a temptation (the disconnect
     verb in the Photos card foot; candidate for generalization at its second consumer) */
  .quiet-danger {
    margin-left: auto;
    background: none; border: none; cursor: pointer; font-family: inherit;
    font-size: 12px; color: var(--ink-3); text-decoration: underline;
    text-underline-offset: 2px; padding: 0;
  }
  .quiet-danger:hover { color: var(--bad); }
  .t-foot .hint { font-size: 12px; color: var(--ink-3); }

  /* ---------- the Project Settings room (rotation 2026-08-19; design of record
     mockups/project-settings-rail.md — all nine docket items ratified one at a time). Reuses
     .dh-card, .card-head, the .fld family, .dh-select, .chk, .hint, .accent-btn, .ghost-btn
     (the canon-before-minting grep, honored); mints only the ps- scope. ---------- */
  .ps-board {
    display: grid; gap: 18px;
    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
    /* align-items stays at the grid default (stretch): same-row cards render equal height —
       Mark's build-time ask, RATIFIED at the walk (2026-08-19) */
  }
  @media (max-width: 560px) { .ps-board { grid-template-columns: 1fr; } }
  .ps-board .dh-card { display: flex; flex-direction: column; }
  .ps-body { padding: 12px 20px 16px; flex: 1; }
  /* the gold title specimen — Mark's build-time ask, RATIFIED at the walk (2026-08-19); still
     scoped to this room — generalizing .card-head to other rooms remains its own ruling */
  .ps-board .card-head { color: var(--gold); }
  .ps-lede { font-size: 12.5px; color: var(--ink-3); margin: 2px 0 12px; }
  .ps-body .fld { margin-bottom: 14px; }
  .ps-body .fld:last-child { margin-bottom: 2px; }
  .ps-body .dh-select { width: 100%; }
  .fld label .lbl-right { float: right; font-weight: 400; color: var(--ink-3); font-size: 11.5px; }
  /* readers see the bench disabled (the config fence teaches; it never vanishes) */
  .ps-body input:disabled, .ps-body textarea:disabled, .ps-body select:disabled {
    opacity: 0.55; cursor: not-allowed;
  }
  .ps-fence {
    margin-bottom: 18px; padding: 11px 16px;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
    font-size: 13px; color: var(--ink-2);
  }
  .ps-fence b { color: var(--ink); }
  .ps-zone-warn { color: var(--bad); font-weight: 600; }
  .ps-lock-line {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--ink);
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 7px;
    padding: 8px 11px;
  }
  .ps-lock-line svg { color: var(--ink-3); flex: none; }
  .ps-teach {
    margin-top: 12px; padding: 10px 13px;
    background: var(--accent-soft); border-radius: 8px;
    font-size: 12.5px; color: var(--ink-2);
  }
  .ps-teach b { color: var(--ink); }
  .ps-chk { padding: 11px 13px; border: 1px solid var(--line-soft); border-radius: 8px; margin-bottom: 12px; }
  .ps-chk:last-child { margin-bottom: 2px; }
  .ps-chk .chk { font-size: 13.5px; color: var(--ink); font-weight: 500; }
  .ps-chk .chk input { accent-color: var(--accent); }
  .ps-chk-sub { font-size: 12.5px; color: var(--ink-2); margin: 5px 0 0 22px; }
  .ps-chk-sub b { color: var(--ink); }
  .ps-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; min-height: 22px; }
  .ps-chip {
    display: inline-flex; align-items: center;
    font-size: 12px; font-weight: 500; color: var(--accent);
    background: var(--accent-soft); border-radius: 6px; padding: 2px 9px;
    font-variant-numeric: tabular-nums;
  }
  .ps-chip.too-long { color: var(--bad); background: var(--bad-soft); text-decoration: line-through; }
  .ps-chip-none { font-size: 12px; color: var(--ink-3); font-style: italic; }
  /* the save bar: sticky, quiet until dirty (docket 8) */
  .ps-save {
    position: sticky; bottom: 14px; z-index: 30;
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    margin-top: 22px; padding: 12px 20px;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow);
  }
  .ps-dirty { font-size: 13px; color: var(--ink-3); }
  .ps-dirty.some { color: var(--gold); font-weight: 500; }
  .ps-save-gap { margin-left: auto; }
  .ps-save .accent-btn:disabled { opacity: 0.45; cursor: default; }
  .ps-save .ghost-btn:disabled { opacity: 0.45; cursor: default; }

  /* ---------- Server Console: the server-wide list editors' card (settings docket 4) ---------- */
  .sc-lists { margin-top: 18px; }
  .sc-lists-row { display: flex; gap: 10px; flex-wrap: wrap; padding: 12px 20px 16px; }
  .sc-count {
    margin-left: 6px; font-size: 11px; color: var(--ink-3);
    background: var(--surface-2); border-radius: 4px; padding: 0 5px;
  }
  .sc-grain {
    padding: 9px 12px; background: var(--warn-soft); border-radius: 8px;
    font-size: 12.5px; color: var(--ink-2);
  }
  .sc-grain b { color: var(--warn); }

  /* ---------- Server Console: the Files.com Photos adoption card (the renewal peek, 2026-08-26) ---------- */
  .sc-photo-rows { padding: 4px 20px 14px; }
  .sc-photo-row {
    display: flex; gap: 16px; flex-wrap: wrap; align-items: baseline;
    padding: 8px 0; border-top: 1px solid var(--line); font-size: 13px;
  }
  .sc-photo-row:first-child { border-top: none; }
  .sc-photo-title { font-weight: 500; }
  .sc-photo-arch {
    margin-left: 8px; font-size: 11px; color: var(--ink-3);
    background: var(--surface-2); border-radius: 4px; padding: 0 5px;
  }
  .sc-photo-fact { color: var(--ink-3); font-size: 12.5px; }
  .sc-photo-empty { padding: 4px 20px 16px; font-size: 13px; color: var(--ink-3); }

  /* ---------- Codes & Features — the Code Manager rotation (design of record:
     mockups/codes-features-rail.md, RATIFIED 2026-08-20, 42 tweaks, Abby's blessing).
     Ported from the mockup's build-delta style block (the mandatory census: house classes
     the mockup leaned on — shell/rail chrome, proj-head family, dh-filter (+ the new house
     ×-wrap), details.row-menu/menu-pop/mi/mh, menu-filter, list-head, mono — all confirmed
     present; everything cf-* below is this room's own mint). The dropdown SECTION SEPARATOR
     is scoped to .cf-room on purpose: fleet spread stays PARKED until Mark eyes other rooms'
     dropdowns wearing it (ui/NEXTGEN, the sitting's rulings block). ---------- */

  /* the anchors strip: statements about the dictionary, not verbs — Primary Weld, Loose End,
     Xref state as teach-and-act dropdown consoles, the hedged import whisper at right */
  .cf-anchors { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 12px; }
  /* sized UP from the house 11.5px row-menu summary (Mark, 08-20): these are CRUCIAL settings —
     primary weld and loose end decide what a joint IS — and the chips should read like it */
  details.row-menu > summary.cf-anchor {
    display: inline-flex; align-items: baseline; gap: 9px;
    border: 1px solid var(--line); border-radius: 9px; background: var(--surface);
    padding: 8px 16px; font-size: 14.5px; color: var(--ink-2); box-shadow: var(--shadow);
  }
  details.row-menu[open] > summary.cf-anchor { border-color: var(--accent); }
  /* the unset selector wears the warn register — classic's outline-warning ? button, house-dressed */
  details.row-menu > summary.cf-anchor.unset { border-color: var(--gold-line); background: var(--warn-soft); }
  .cf-anchor .k { font-size: 11.5px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-3); }
  .cf-anchor .v { font-weight: 700; color: var(--good); font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; }
  .cf-anchor.unset .v { color: var(--gold); font-family: inherit; font-weight: 500; font-style: italic; }
  .cf-anchor .v.plain { color: var(--ink-3); font-family: inherit; font-weight: 500; }
  .cf-anchor .v.gold { color: var(--gold); font-family: inherit; font-weight: 500; }
  .cf-whisper { font-size: 12px; color: var(--ink-3); margin-left: auto; }
  .cf-whisper .mono { font-size: 11.5px; }
  /* the selector/xref pops: anchor LEFT (the chips sit page-left; house pops anchor right) */
  details.row-menu .menu-pop.cf-xref-pop { min-width: 320px; max-width: 350px; left: 0; right: auto; }
  .cf-xref-pop .dep { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-size: 12px; color: var(--ink-2); padding: 2px 10px; }
  .cf-xref-pop .mi svg { width: 12px; height: 12px; margin-right: 6px; vertical-align: -1px; color: var(--ink-3); }
  .cf-xref-pop .mi:hover svg { color: var(--accent); }
  /* long code lists scroll inside the pop (loose end offers every code, classic's rule) */
  .cf-pick-list { max-height: 230px; overflow-y: auto; }
  .cf-pick-list .mi .sym { font-weight: 700; margin-right: 5px; }
  .cf-pick-list .mi .sym.cf-mseat {
    display: inline-block; min-width: 21px; text-align: center;
    padding: 0 3px; margin-right: 7px; border-radius: 4px;
  }

  /* the toolbar: filter left, grouped verbs right */
  .cf-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 16px; }
  /* the room's filter proportion (the house ×-wrap grows to 340 by default; this room's board
     wants the mockup's 300 non-growing box beside the verb rack) */
  .cf-toolbar .dh-filter-wrap { flex: 0 1 300px; }
  .cf-toolbar .match-note { font-size: 12px; color: var(--ink-3); }
  .cf-verbs { margin-left: auto; display: flex; gap: 9px; align-items: center; flex-wrap: wrap; }
  /* sized UP from the house 11.5px row-menu summary (Mark, 08-20): arriving classic users
     will be hunting for the new places to click for imports/exports — the five verb menus
     are the room's doors and should be findable at a glance, not toolbar furniture */
  .cf-verbs > details.row-menu > summary { font-size: 13.5px; padding: 7px 15px; border-radius: 8px; }
  .cf-verbs .cf-chip-badge { font-size: 11px; }
  /* the Line IDs chip's news badge + teach-first menu (Line IDs is a DH-only concept —
     users learn the game HERE, so the menu teaches before it offers verbs) */
  .cf-chip-badge {
    display: inline-block; background: var(--warn-soft); color: var(--gold);
    border-radius: 999px; padding: 0 7px; font-size: 10px; font-weight: 700; margin-left: 4px;
  }
  /* scoped to out-specify the house details.row-menu .menu-pop min-width (the specificity-
     phantom rule: a fix in a losing rule reads as done and does nothing) */
  details.row-menu .menu-pop.cf-lineids-pop { min-width: 320px; max-width: 340px; }
  .cf-menu-teach { font-size: 12px; color: var(--ink-2); padding: 6px 10px 4px; line-height: 1.5; }
  .cf-menu-teach .mono { font-size: 11px; }
  .cf-menu-new {
    display: flex; align-items: baseline; gap: 7px;
    font-size: 12px; color: var(--gold); background: var(--warn-soft);
    border-radius: 7px; padding: 5px 10px; margin: 4px 6px 2px;
  }
  .cf-new-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gold-line); flex: none; align-self: center; }
  .cf-menu-foot { font-size: 11.5px; color: var(--ink-3); padding: 5px 10px 3px; border-top: 1px solid var(--line-soft); margin-top: 5px; }

  /* dropdown sections announce by SEPARATOR (RULED 2026-08-20, the A/B's verdict — the
     white-head promotion is dead): heads keep the house muted ink; a hairline opens each
     mid-menu section. No line above a head that starts its menu. --line, not --line-soft —
     the soft hairline read too faint inside the pop. ROOM-SCOPED; fleet spread PARKED. */
  .cf-room details.row-menu .menu-pop .mh:not(:first-child) {
    border-top: 1px solid var(--line); margin-top: 5px; padding-top: 8px;
  }
  /* …which forces the split: in-menu WHISPERS (hints, fences) are not section heads and must
     not be promoted with them — they keep the muted register under a note class */
  .cf-room details.row-menu .menu-pop .cf-menu-note {
    font-size: 11px; color: var(--ink-3); padding: 4px 10px 3px; line-height: 1.4;
  }

  /* the bad-character notice, in place (no flash alert): warn chip that is itself a teach-menu */
  /* the chip went gold→red 2026-09-01 (Mark's coordination pass): unsafe characters are the
     refusal register everywhere else it shows — the bug glyph and the pill outline are red,
     so the toolbar chip speaks the same color. Gold stays the DBF-collision register. */
  details.row-menu > summary.cf-warn-chip {
    display: inline-flex; align-items: center; gap: 6px;
    border: 1px solid color-mix(in srgb, var(--bad) 45%, transparent);
    background: var(--bad-soft); color: var(--bad);
    font-size: 11.5px; font-weight: 600; padding: 3px 11px; border-radius: 999px;
  }
  details.row-menu > summary.cf-warn-chip:hover { border-color: var(--bad); }
  details.row-menu[open] > summary.cf-warn-chip { border-color: var(--bad); color: var(--bad); }
  details.row-menu .menu-pop.cf-bug-pop { min-width: 300px; max-width: 330px; }
  /* menu-verb glyphs (the singleton-near-narrative doctrine): quiet at rest, accent on hover */
  .cf-bug-pop .mi svg { width: 12px; height: 12px; margin-right: 6px; vertical-align: -1px; color: var(--ink-3); }
  .cf-bug-pop .mi:hover svg { color: var(--accent); }

  /* band heads: list-head + the count, used band leads */
  .cf-band { margin-bottom: 22px; }
  .cf-band[hidden] { display: none; }
  .cf-band .list-head b { color: var(--ink-2); }

  .cf-code {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-weight: 700; font-size: 14.5px; color: var(--ink); white-space: nowrap;
  }
  /* the feature-name whisper — populated on ~75% of real rules; rendered only when it differs
     from the code (classic's rule kept) */
  .cf-feature {
    font-size: 12.5px; color: var(--ink-3); min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* symbol + count married (RULED: folks love the marker and the count is useful), wearing
     classic's map-label dress — fill color + the rule-built four-corner halo */
  .cf-count { font-size: 13px; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--ink-2); }
  /* THE MARKER SEAT (doctrine: user marker colors NEVER render unseated — "a marker has to look
     okay when we don't know all the places it will sit"). One token, every consumer: the card
     count label, the selector pick-lists, whatever comes next. NEUTRAL GRAY with the house blue
     lean, THEME-BIFURCATED (RULED 2026-08-20; settled dials — dark #333c4a, light #b1bbc9,
     asymmetric on purpose). Full three-state contract. */
  .cf-mseat { background: #b1bbc9; border-radius: 5px; }
  .cf-count .cf-maplabel { font-weight: 700; display: inline-block; padding: 0 6px; }
  .cf-count.zero { color: var(--ink-3); font-size: 12px; }

  /* verbs VISIBLE-BUT-DIM (RULED 2026-08-20: the inexpensive fix for the header-hover
     head-scratcher, Abby's training complaint) — always rendered, quiet at rest, full ink on hover */
  .cf-rowverbs { display: inline-flex; gap: 4px; justify-content: flex-end; align-items: center; }
  .cf-iverb {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 24px; border-radius: 6px; border: none; background: none;
    color: var(--ink-3); opacity: 0.55; cursor: pointer; font-family: inherit; font-size: 13px;
    text-decoration: none;
  }
  .cf-iverb svg { width: 13px; height: 13px; }
  .cf-card-head:hover .cf-iverb { opacity: 1; }
  .cf-iverb:hover { background: var(--accent-soft); color: var(--accent); opacity: 1; }
  .cf-rowverbs details.row-menu > summary { border: none; background: none; padding: 3px 6px; opacity: 0.55; }
  .cf-card-head:hover .cf-rowverbs details.row-menu > summary,
  .cf-rowverbs details[open].row-menu > summary { opacity: 1; }

  /* the bad-character bug on the head (head-scale: 12px read fine inline but undersized beside
     the 13.5px code name) + the DBF-collision warn triangle (gold — latent, busts only at export) */
  .cf-bug { color: var(--bad); font-size: 12px; }
  .cf-card-head .cf-bug svg { width: 15px; height: 15px; vertical-align: -2px; }
  .cf-warn10 { color: var(--gold); }
  .cf-card-head .cf-warn10 svg { width: 15px; height: 15px; vertical-align: -2px; }

  /* the expanded body: attributes, then the facts foot */
  .cf-att-list { padding: 12px 18px 14px 20px; min-width: 0; }
  .cf-att-list .cf-atts-head {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-3); margin-bottom: 7px;
  }
  .cf-att { display: flex; align-items: baseline; gap: 7px; padding: 2px 0; font-size: 13px; flex-wrap: wrap; }
  /* the number is the FILE — the positional contract worn plainly (codes/NEXTGEN #1) */
  .cf-att .num { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; color: var(--ink-3); font-size: 12px; width: 20px; text-align: right; flex: none; }
  .cf-att .aname { color: var(--ink); font-weight: 500; }
  .cf-att .req { color: var(--gold); font-size: 11px; font-weight: 600; }
  .cf-att .vtype { font-size: 11.5px; font-style: italic; color: var(--gold); }
  .cf-att .adefault { font-size: 12px; color: var(--ink-3); font-style: italic; }
  .cf-att .amask { font-size: 11.5px; color: var(--accent); text-decoration: none; }
  .cf-att .amask:hover { text-decoration: underline; }
  /* the ordinary menu indicator (Abby's catch): the name itself toggles, a plain gold caret
     beside it — classic's idiom kept; the choice count survives in the tooltip */
  .cf-att .menu-toggle {
    background: none; border: none; font-family: inherit; cursor: pointer; padding: 0;
    font-size: inherit; display: inline-flex; align-items: baseline; gap: 4px;
  }
  .cf-att .menu-toggle .mcaret { color: var(--gold); font-size: 10px; }
  .cf-att .menu-toggle:hover .aname { color: var(--accent); }
  .cf-menu-items { width: 100%; margin: 2px 0 4px 27px; padding: 0; list-style: none; font-size: 12.5px; color: var(--ink-2); }
  .cf-menu-items[hidden] { display: none; }
  .cf-menu-items li { padding: 1px 0; }
  .cf-menu-items .mdefault { color: var(--gold); font-size: 11px; font-weight: 600; margin-left: 6px; }
  .cf-att .abug { color: var(--bad); font-size: 11.5px; font-weight: 600; }
  /* the LINE_ID stale whisper — quiet warn register, cursor-help for the how-to-fix tooltip */
  .cf-att .cf-att-stale { font-size: 11.5px; color: var(--gold); cursor: help; }
  /* the filter's why-this-pill highlight: the matching attribute line gets a soft seat */
  .cf-att.hit .aname { background: var(--warn-soft); color: var(--ink); padding: 0 4px; border-radius: 4px; }
  /* the no-attributes render state (was a flash message) */
  .cf-noatts { font-size: 13px; color: var(--ink-3); font-style: italic; padding: 4px 0; }
  .cf-noatts a { color: var(--accent); }

  /* the facts foot: rule facts, teaches, warnings-in-place + the two doors Abby walks daily */
  .cf-facts { padding: 12px 18px 14px; display: flex; flex-direction: column; gap: 8px; }
  .cf-fact { font-size: 12.5px; color: var(--ink-2); display: flex; align-items: baseline; gap: 8px; }
  .cf-fact .fk { font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); width: 58px; flex: none; }
  .cf-doors { display: flex; gap: 8px; flex-wrap: wrap; margin-top: auto; padding-top: 8px; }
  /* the teach-without-the-door: where the edit door would sit, when the user holds no parent seat */
  .cf-doors-note { font-size: 12px; color: var(--ink-3); font-style: italic; align-self: center; }
  .cf-door-btn {
    display: inline-flex; align-items: center; gap: 7px;
    border: 1px solid var(--line); border-radius: 7px; background: var(--surface);
    color: var(--ink-2); font-size: 12.5px; font-family: inherit; padding: 5px 12px;
    cursor: pointer; text-decoration: none;
  }
  .cf-door-btn:hover { border-color: var(--accent); color: var(--accent); }
  .cf-door-btn svg { width: 13px; height: 13px; }
  .cf-panel-warn { font-size: 12.5px; color: var(--gold); background: var(--warn-soft); border-radius: 7px; padding: 6px 10px; }
  /* the offending/safe characters as tiny mono chips — the concise unsafe-set display */
  .cf-panel-warn .bch {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-weight: 700;
    background: var(--surface); border: 1px solid var(--gold-line); border-radius: 4px;
    padding: 0 5px; margin: 0 1px; display: inline-block; line-height: 1.4;
  }
  .cf-panel-warn .mono { font-size: 12px; }
  /* the shot-type teach (the hand-holding posture: staking/cover/crossing are DH concepts worth
     a sentence right where their codes live) — the quiet register */
  .cf-panel-teach { font-size: 11.5px; color: var(--ink-3); line-height: 1.5; max-width: 46ch; }

  /* THE DRESS — PILLS ×3 (RULED 2026-08-20: Abby likes pills and the users have years of
     reflexes on them; rows retired, ×2/×4 ruled out earlier) */
  .cf-grid { display: grid; gap: 10px; align-items: start; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .cf-grid[hidden] { display: none; }
  /* the ×3 head has no room for the shot-type WORD — classic's glyph language returns at
     pill scale (tooltips carry the words; the expanded body's Type fact states it plainly) */
  .cf-type-glyph { color: var(--ink-3); flex: none; display: inline-flex; cursor: help; }
  .cf-type-glyph svg { width: 13px; height: 13px; }
  /* Online went gold→green 2026-09-01 (Mark's vocabulary pass): gold now does heavy lifting on
     this page's warnings (DBF collision panel + warn-gold outlines), and Online is a healthy
     state — --good says so without competing with the warn register. */
  .cf-type-glyph.online { color: var(--good); }
  .cf-card {
    background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
    box-shadow: var(--shadow); overflow: visible; min-width: 0;
  }
  /* Abby's walk catch #2: classic differentiated ONLINE codes by popping the name white; the
     new UI keeps full-ink text for all, so online pills carry the eye-catcher on the OUTLINE —
     stepped up to --ink-3 at Mark's second pass (--check-line read too close to --line) */
  .cf-card.online { border-color: var(--ink-3); }
  /* warn outlines (Mark's ask, 2026-09-01): the pill's outline takes its warn glyph's color so
     a flagged pill reads as flagged from across the room — the outline is the summons, the head
     glyphs stay the itemized inventory. Red outranks gold when both warns are present; the
     template's elif hands a pill at most ONE warn class, so no ordering trick is load-bearing
     here. A warned pill deliberately overrides its Online brightening. */
  .cf-card.warn-gold { border-color: var(--gold); }
  .cf-card.warn-bad { border-color: var(--bad); }
  .cf-card[hidden] { display: none; }
  .cf-card-head { display: flex; align-items: center; gap: 8px; padding: 5px 8px 5px 10px; cursor: pointer; min-width: 0; border-radius: 9px; }
  .cf-card.open .cf-card-head { border-bottom: 1px solid var(--line-soft); border-radius: 9px 9px 0 0; }
  .cf-card-head:hover { background: var(--accent-soft); }
  .cf-card-head .cf-code { font-size: 13.5px; }
  .cf-card-head .cf-count { margin-left: auto; font-size: 12.5px; }
  /* the feature whisper IN-HEAD at ×3 — truncates to the room left after count+verbs */
  .cf-card-head .cf-feature { flex: 1 1 auto; }
  .cf-card-body { padding: 4px 6px 8px; }
  .cf-card-body[hidden] { display: none; }
  .cf-card-body .cf-att-list { padding: 6px 10px 8px; }
  .cf-card-body .cf-facts { border-top: 1px solid var(--line-soft); padding: 8px 10px 8px; margin-top: 6px; }
  @media (max-width: 950px) { .cf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 660px) { .cf-grid { grid-template-columns: minmax(0, 1fr); } }
  /* the seat's dark dial — full three-state contract (system-dark, explicit dark, explicit
     light): never let a color's only definition live inside one theme branch */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .cf-mseat { background: #333c4a; }
  }
  :root[data-theme="dark"] .cf-mseat { background: #333c4a; }
  :root[data-theme="light"] .cf-mseat { background: #b1bbc9; }

  /* ---------- Code Editor — the brain's child room (rotated 2026-08-21; design of record
     mockups/code-editor-rail.md — eleven rulings + Abby's as-mocked ratification). The room
     rides the cf-room suite scope for separators; ce-* is its own family. Registers: ce-teach
     (quiet in-place WHY), ce-nudge (gold live prevention — wakes AS the hazard is typed),
     ce-block (red — the save WILL refuse this, said before the click). ---------- */
  /* (.ce-back GRADUATED to the canon .room-back — see the proj-head block; spread ruled
     2026-08-21, every ic-return child room wears it) */
  .ce-head-code { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; }

  /* the code studio: identity + marker styling + the live preview in one card */
  .ce-studio {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 16px 20px 18px; margin-bottom: 24px;
  }
  .ce-studio-grid { display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 22px; align-items: start; }
  @media (max-width: 1150px) { .ce-studio-grid { grid-template-columns: 1fr 1fr; } }
  @media (max-width: 640px) { .ce-studio-grid { grid-template-columns: 1fr; } }
  .ce-col-head {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-3); margin-bottom: 10px;
  }
  .ce-studio .fld { margin-bottom: 13px; }
  .ce-studio .fld:last-child { margin-bottom: 2px; }
  .ce-teach { font-size: 11.5px; color: var(--ink-3); line-height: 1.45; margin-top: 4px; max-width: 40ch; }
  .ce-teach .mono { font-size: 11px; }
  .ce-nudge { font-size: 11.5px; color: var(--gold); background: var(--warn-soft);
    border-radius: 6px; padding: 4px 9px; line-height: 1.45; margin-top: 5px; max-width: 42ch; }
  .ce-nudge[hidden] { display: none; }
  .ce-block { font-size: 11.5px; color: var(--bad); background: var(--bad-soft);
    border-radius: 6px; padding: 4px 9px; line-height: 1.45; margin-top: 5px; max-width: 42ch; }
  .ce-block[hidden] { display: none; }
  .ce-block .bch, .ce-nudge .bch {
    font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace; font-weight: 700;
    background: var(--surface); border: 1px solid var(--gold-line); border-radius: 4px;
    padding: 0 5px; margin: 0 1px; display: inline-block; line-height: 1.4;
  }

  /* shot-type radios — the .fld label qualifier is REQUIRED: bare .ce-radio loses to
     .fld label's display:block and the flex gap silently dies (the specificity-phantom
     class, measured at the mockup sitting) */
  .fld label.ce-radio { display: flex; align-items: center; gap: 9px; padding: 3px 0;
    font-size: 13px; font-weight: 400; color: var(--ink-2); cursor: pointer; margin-bottom: 2px; }
  .ce-radio input { accent-color: var(--accent); margin: 0 3px 0 0; cursor: pointer; }
  .ce-radio svg { width: 13px; height: 13px; color: var(--ink-3); flex: none; }
  .ce-radio input:checked ~ svg { color: var(--gold); }
  .ce-radio input:checked ~ .rl { color: var(--ink); font-weight: 500; }

  .ce-color { width: 100%; height: 34px; padding: 2px; border: 1px solid var(--check-line);
    border-radius: 7px; background: var(--surface-2); cursor: pointer; }
  .ce-color:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
  .ce-sym-row { display: flex; gap: 8px; align-items: center; }
  .ce-sym-row input[type="text"] { flex: 1; min-width: 0; }
  .ce-shelf-door { font-size: 12px; color: var(--accent); background: none; border: none;
    cursor: pointer; font-family: inherit; padding: 2px 0; white-space: nowrap; }
  .ce-shelf-door:hover { text-decoration: underline; }

  /* the mini-map preview: the banded tile is DOCTRINE (Mark: "a marker has to look okay when
     we don't know all the places it will sit") — never simplify it away */
  .ce-map {
    width: 250px; height: 250px; border-radius: 9px; border: 1px solid var(--line);
    background-size: 250px 250px; position: relative; overflow: hidden;
  }
  .ce-mk {
    position: absolute; transform: translate(-50%, -50%);
    text-align: center; font-family: 'Muli', 'Segoe UI', sans-serif; font-weight: bold;
    line-height: 1.0; white-space: nowrap; pointer-events: none;
  }
  .ce-map-note { font-size: 11px; color: var(--ink-3); margin-top: 6px; max-width: 250px; line-height: 1.45; }
  .ce-map-nudge { font-size: 11.5px; color: var(--gold); background: var(--warn-soft);
    border-radius: 6px; padding: 4px 9px; margin-top: 6px; max-width: 250px; line-height: 1.45; }
  .ce-map-nudge[hidden] { display: none; }

  /* dirty-woken save verbs (the sketches idiom: quiet until dirty, ANNOUNCE the waking) */
  .ce-save { margin-top: 14px; display: flex; align-items: center; gap: 12px; }
  .ce-save .accent-btn:disabled { opacity: 0.45; cursor: default; }
  .ce-save .accent-btn:not(:disabled) { outline: 2px solid var(--accent); outline-offset: 2px; }
  .ce-savenote { font-size: 12px; color: var(--ink-3); }
  .ce-savenote.dirty { color: var(--gold); font-weight: 500; }

  /* the attributes board */
  .ce-atts-headrow { display: flex; align-items: baseline; gap: 12px; margin: 0 0 10px; }
  .ce-atts-headrow .list-head { margin: 0; }
  .ce-contract-whisper { font-size: 11.5px; color: var(--ink-3); }
  .ce-att-card {
    background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
    box-shadow: var(--shadow); margin-bottom: 8px; overflow: visible;
  }
  .ce-att-card.dragging { opacity: 0.45; }
  .ce-att-head {
    display: flex; align-items: center; gap: 9px; padding: 7px 10px 7px 8px;
    cursor: pointer; min-width: 0; border-radius: 9px;
  }
  .ce-att-card.open .ce-att-head { border-bottom: 1px solid var(--line-soft); border-radius: 9px 9px 0 0; }
  .ce-att-head:hover { background: var(--accent-soft); }
  .ce-grip { color: var(--ink-3); opacity: 0.55; cursor: grab; flex: none; padding: 2px 3px; }
  .ce-grip svg { width: 12px; height: 12px; display: block; }
  .ce-att-head:hover .ce-grip { opacity: 1; }
  /* the number is the FILE — the positional contract worn plainly (codes/NEXTGEN #1) */
  .ce-att-num { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    color: var(--ink-3); font-size: 12px; width: 22px; text-align: right; flex: none; }
  .ce-att-name { font-family: 'Ubuntu Mono', 'Cascadia Mono', 'Consolas', monospace;
    font-weight: 700; font-size: 13.5px; color: var(--ink); white-space: nowrap; }
  .ce-att-name.blank { color: var(--ink-3); font-weight: 400; font-style: italic; font-family: inherit; }
  .ce-traits { display: flex; align-items: baseline; gap: 9px; min-width: 0; overflow: hidden; flex-wrap: nowrap; }
  .ce-trait { font-size: 11.5px; font-style: italic; color: var(--gold); white-space: nowrap; }
  .ce-trait.quiet { color: var(--ink-3); }
  .ce-trait.bug { color: var(--bad); font-style: normal; font-weight: 600; }
  .ce-trait svg { width: 11px; height: 11px; vertical-align: -1px; }
  /* (the head's move up/down arrows died at Mark's live walk — the grip drag is the one
     reorder gesture; no .ce-mv family) */
  .ce-att-body { padding: 12px 16px 14px; }
  .ce-att-body[hidden] { display: none; }
  .ce-att-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; align-items: start; }
  @media (max-width: 950px) { .ce-att-grid { grid-template-columns: 1fr 1fr; } }
  @media (max-width: 640px) { .ce-att-grid { grid-template-columns: 1fr; } }
  .ce-att-body .fld { margin-bottom: 12px; }
  .ce-att-body textarea { resize: vertical; }
  .ce-menu-count { font-weight: 400; color: var(--ink-3); font-size: 11.5px; }
  .ce-chk { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-2); cursor: pointer; padding: 2px 0; }
  .ce-chk input { accent-color: var(--accent); margin: 0; cursor: pointer; }
  .ce-chk input:disabled ~ span { color: var(--ink-3); }
  .ce-att-foot { display: flex; align-items: center; gap: 12px; margin-top: 4px; }
  /* .ghost-btn.danger is canon (the house rule) — no room copy needed */
  .ce-rename-note { font-size: 11.5px; color: var(--ink-3); line-height: 1.45; max-width: 52ch; }
  /* the xref-preview evidence tables: the would-change rows wear the warn seat */
  .qc-table tr.warn-row td { background: var(--warn-soft); color: var(--ink); }

  /* the order bar: act-time is THE time (the ratified reorder ruling — inform, don't rewrite) */
  .ce-order-bar {
    position: sticky; bottom: 14px; z-index: 30;
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    margin: 14px 0 0; padding: 12px 18px;
    background: var(--surface); border: 1px solid var(--gold-line); border-radius: var(--radius);
    box-shadow: var(--shadow);
  }
  .ce-order-bar[hidden] { display: none; }
  .ce-order-text { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; max-width: 62ch; }
  .ce-order-text b { color: var(--gold); }
  .ce-order-verbs { margin-left: auto; display: flex; gap: 9px; }

  .ce-foot { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 18px 0 8px; }
  .ce-foot-note { font-size: 11.5px; color: var(--ink-3); }

  /* native dialogs for the grave verbs (house rule) + the glyph shelf's loved furniture */
  dialog.ce-dialog {
    border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
    color: var(--ink); box-shadow: var(--shadow); padding: 18px 20px; max-width: 460px;
  }
  dialog.ce-dialog::backdrop { background: rgba(0,0,0,0.45); }
  .ce-dialog h3 { margin: 0 0 10px; font-size: 15px; }
  .ce-dialog p { font-size: 13px; color: var(--ink-2); line-height: 1.55; margin: 0 0 10px; }
  .ce-dialog p b { color: var(--ink); }
  .ce-dialog .warn { color: var(--gold); background: var(--warn-soft); border-radius: 7px; padding: 7px 11px; }
  .ce-dialog .verbs { display: flex; gap: 9px; justify-content: flex-end; margin-top: 14px; }
  .ce-shelf-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 7px; margin: 6px 0 2px; }
  .ce-shelf-grid button {
    font-size: 20px; line-height: 1.6; border: 1px solid var(--line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink); cursor: pointer; padding: 4px 0;
  }
  .ce-shelf-grid button:hover { border-color: var(--accent); background: var(--accent-soft); }
  .ce-shelf-more { font-size: 11.5px; color: var(--ink-3); margin-top: 8px; }
  .ce-shelf-more a { color: var(--accent); }

  /* ---------- Design Alignments room (the alignments rotation 2026-08-22; design of record
     mockups/alignments-rail.md). al-* scope. The map card hosts the alignment_map iframe; one
     al-card per alignment (facts, equations, breaks, style, verbs); the storm whisper (.al-storm)
     rides every dialog whose verb restations points. ---------- */
  .al-verdict { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
    padding: 2px 2px 14px; font-size: 13.5px; color: var(--ink-2); }
  .al-verdict b { color: var(--ink); }
  .al-verdict .need { color: var(--gold); }

  /* No overflow:hidden on the card — the footer's row-menu pop must escape the card box
     (a clipped box cannot be rescued by z-index; Mark's mockup catch). The well clips itself. */
  .al-map-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); margin-bottom: 22px; }
  .al-map-well { height: 620px; position: relative; overflow: hidden;
    border-radius: var(--radius) var(--radius) 0 0; }
  .al-map-well iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: none; display: block; }
  .al-map-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 12px 16px; border-top: 1px solid var(--line); }
  .al-map-foot .spacer { flex: 1; }

  details.al-card { background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 14px; }
  details.al-card > summary { list-style: none; cursor: pointer; display: flex; align-items: center;
    gap: 12px; flex-wrap: wrap; padding: 13px 18px; }
  details.al-card > summary::-webkit-details-marker { display: none; }
  details.al-card > summary .al-name { font-size: 15.5px; font-weight: 700; color: var(--ink); }
  details.al-card > summary .al-sum-fact { font-size: 12px; color: var(--ink-3); }
  details.al-card > summary .caret { margin-left: auto; color: var(--ink-3); font-size: 11px;
    transition: transform 0.15s; }
  details.al-card[open] > summary .caret { transform: rotate(180deg); }
  details.al-card[open] > summary { border-bottom: 1px solid var(--line); }
  .al-badge { font-size: 10.5px; font-weight: 600; letter-spacing: 0.05em; border-radius: 999px;
    padding: 2px 9px; border: 1px solid var(--line); color: var(--ink-3); }
  .al-badge.aux { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
  .al-badge.fallback { color: var(--gold); border-color: var(--gold-line); background: var(--warn-soft); }
  .al-badge.bounds { color: var(--good); border-color: var(--good); background: var(--good-soft); }

  .al-body { padding: 16px 18px 18px; }
  .al-grid { display: grid; grid-template-columns: 1.1fr 1.3fr 1fr; gap: 26px; align-items: start; }
  @media (max-width: 1100px) { .al-grid { grid-template-columns: 1fr 1fr; } }
  @media (max-width: 680px) { .al-grid { grid-template-columns: 1fr; } }
  .al-col-head { font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-3); margin-bottom: 9px; }

  .al-facts { font-size: 13px; color: var(--ink-2); }
  .al-facts .fr { display: flex; gap: 10px; padding: 3px 0; }
  .al-facts .fl { color: var(--ink-3); min-width: 96px; flex: none; }
  .al-facts .fv { color: var(--ink); overflow-wrap: anywhere; }
  .al-facts a.fv { color: var(--accent); text-decoration: none; cursor: pointer; }
  .al-facts a.fv:hover { text-decoration: underline; }

  /* verbs sit ABOVE their lists (Mark's ruling — equations grow long) */
  .al-row-verbs { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin: 0 0 8px; }
  .al-row-verbs + .al-row-verbs { margin-top: 8px; }
  .al-rows { font-size: 13px; }
  .al-rows .rr { display: flex; align-items: center; gap: 10px; padding: 4px 0;
    border-bottom: 1px dashed var(--line); }
  .al-rows .rr:last-child { border-bottom: none; }
  .al-rows .rn { color: var(--ink-3); font-size: 11.5px; min-width: 18px; flex: none; }
  .al-rows .rv { color: var(--ink); }
  .al-rows .rx { margin-left: auto; background: none; border: none; color: var(--ink-3);
    cursor: pointer; font-size: 13px; padding: 0 4px; }
  .al-rows .rx:hover { color: var(--bad); }
  .al-rx-form { margin-left: auto; }
  .al-rx-form .rx { margin-left: 0; }

  .al-style { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; }
  .al-style .fld { margin-bottom: 0; }
  .al-style .fld label { font-size: 11px; }
  /* the dirty-woken save (the Code Editor pattern): Update sleeps until a control changes; the
     gold whisper beside it names the unsaved state; the preview repaints live as you fiddle.
     Waking is LOUD (asleep = dim ghost, awake = accent — the constructive-verb step, the sketches
     footer precedent), and the whisper's seat is RESERVED (visibility, not display, + nowrap) so
     its arrival never grows the card or shifts the layout (Mark's eye note, 2026-08-22). */
  .al-style-foot { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; }
  .al-style-save:not(:disabled) { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
  .al-style-save:not(:disabled):hover { filter: brightness(1.1); background: var(--accent); }
  .al-dirty { font-size: 11.5px; color: var(--gold); background: var(--warn-soft);
    border-radius: 6px; padding: 4px 9px; line-height: 1.45; white-space: nowrap; }
  .al-dirty[hidden] { display: inline-block; visibility: hidden; }
  .al-color { width: 100%; height: 30px; padding: 2px; border: 1px solid var(--line);
    border-radius: 7px; background: var(--surface-2); cursor: pointer; }
  /* the preview well is a CONSTANT dark ground in both themes — it plays the map's dark ground
     (the sketches checker convergence, same register) */
  .al-prev { grid-column: 1 / -1; height: 34px; border-radius: 7px; border: 1px solid var(--line);
    background: #232b38; position: relative; overflow: hidden; margin-top: 2px; }
  .al-prev svg { position: absolute; inset: 0; width: 100%; height: 100%; }

  .al-storm { font-size: 11.5px; color: var(--gold); background: var(--warn-soft);
    border-radius: 6px; padding: 4px 9px; line-height: 1.45; }
  .dlg-foot .al-storm { margin-right: auto; max-width: 26ch; }
  .al-teach { font-size: 11.5px; color: var(--ink-3); line-height: 1.5; margin-top: 5px; max-width: 46ch; }
  .al-gate { font-size: 12px; color: var(--ink-3); font-style: italic; padding: 0 2px 12px; }
  .al-gold-hint { color: var(--gold); }
  .al-check { display: flex; align-items: center; gap: 8px; cursor: pointer; }
  .al-check input { accent-color: var(--accent); }
  /* a fenced verb reads fenced (Primary's Delete while points exist; equation-locked Edit
     graphically) — a span in button dress, hover title carries the reason */
  .al-disabled { opacity: 0.45; cursor: not-allowed; }

  details.al-loc { margin-top: 14px; border: 1px dashed var(--line); border-radius: 8px; }
  details.al-loc > summary { list-style: none; cursor: pointer; font-size: 12.5px;
    color: var(--accent); padding: 8px 12px; }
  details.al-loc > summary::-webkit-details-marker { display: none; }
  details.al-loc .loc-body { padding: 4px 12px 12px; }
  details.al-loc form { display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap; margin: 0; }
  details.al-loc textarea { flex: 1; min-width: 200px; min-height: 84px; border: 1px solid var(--check-line);
    border-radius: 7px; background: var(--surface-2); color: var(--ink); padding: 8px 10px;
    font-size: 13px; font-family: inherit; }

  .al-empty { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 26px 30px; max-width: 760px; }
  .al-empty h3 { margin: 0 0 6px; font-size: 17px; color: var(--ink); }
  .al-empty .fmt { font-size: 12.5px; color: var(--ink-3); margin-bottom: 14px; }
  .al-empty p { font-size: 13.5px; color: var(--ink-2); margin: 0 0 6px; }
  .al-empty ul { margin: 12px 0 18px; padding-left: 20px; font-size: 13.5px; color: var(--ink-2); line-height: 1.75; }

  /* one stack, one rhythm: the Actions column's controls (Mark's style walk, 2026-08-22; widths
     follow their text — his second pass reversed the full-width draft). Menu summaries, buttons,
     anchors, and form-wrapped buttons share the vertical metrics (padding, font, radius) so the
     boxes are the same HEIGHT with one consistent gap; each is only as wide as its words. */
  .al-actions { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
  .al-actions form { margin: 0; }
  .al-actions details.row-menu { display: block; }
  .al-actions .ghost-btn, .al-actions .danger-btn,
  .al-actions details.row-menu > summary {
    display: inline-block; padding: 7px 14px; font-size: 13px; border-radius: 8px;
  }
  /* the Draw menu sits beside the accent import button — same size, secondary color
     (Mark's style walk: neighbors of equal rank wear equal boxes) */
  .al-map-foot details.row-menu > summary {
    padding: 7px 16px; font-size: 13.5px; border-radius: 8px;
  }

  /* ================= The Drill pair — Build 3D Polyline + Calculate Weld Positions
     (rail rotation 2026-08-23; design of record mockups/hdd-rail.html +
     mockups/weld-pusher-rail.html, rulings index mockups/drill-pair-seed.md).
     THE GHOST STAGE is the sitting's soul (Mark's teaching commission): the map/profile
     frame renders from FIRST PAINT holding a dashed domain drawing of exactly what will
     materialize, teach text situated inside the drawing where each concept lives —
     extending the .import-ready and .ghost-tile register (dashed = the not-yet-born)
     from a logo to a domain drawing. The classic Instructions card died into this.
     THE WAYFINDING SYSTEM: a three-step ladder in the stage head plus the same circled
     numeral repeated at each step's HOME (card heads, the export seat) — one state,
     three dresses: wait = dim, now = gold, done = green. Both rooms, one grammar. */

  /* the stage card: map pane + profile pane, ghost or live, ONE frame */
  .stage-card { margin-bottom: 16px; }
  .stage-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 12px 20px 10px; }
  .stage-head .card-head { padding: 0; }

  .ladder { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; font-size: 12px; }
  .lad { display: inline-flex; align-items: center; gap: 6px; color: var(--ink-3); }
  .lad .n {
    width: 18px; height: 18px; border-radius: 50%; display: inline-flex; align-items: center;
    justify-content: center; font-size: 10.5px; font-weight: 700;
    border: 1px solid var(--check-line); color: var(--ink-3);
  }
  .lad.now { color: var(--gold); font-weight: 600; }
  .lad.now .n { border-color: var(--gold-line); background: var(--warn-soft); color: var(--gold); }
  .lad.done { color: var(--good); }
  .lad.done .n { border-color: var(--good); background: var(--good-soft); color: var(--good); }
  .lad-sep { color: var(--ink-3); opacity: 0.5; }

  .step-num {
    width: 18px; height: 18px; border-radius: 50%; display: inline-flex; align-items: center;
    justify-content: center; font-size: 10.5px; font-weight: 700; flex: none;
    border: 1px solid var(--check-line); color: var(--ink-3);
    margin-right: 8px; vertical-align: -4px;
  }
  .step-num.now { border-color: var(--gold-line); background: var(--warn-soft); color: var(--gold); }
  .step-num.done { border-color: var(--good); background: var(--good-soft); color: var(--good); }
  .card-head .step-num { display: inline-flex; }
  .card-head .step-num + .step-num { margin-left: -3px; }

  /* the ghost stage: the dashed domain drawing with teach text situated inside it */
  .bore-ghost { border-top: 1px solid var(--line-soft); background: var(--surface-2); padding: 6px 10px 10px; }
  .bore-ghost svg { display: block; width: 100%; height: auto; }
  .bore-ghost .cap { font-size: 14px; fill: var(--ink-2); }
  .bore-ghost .strip { font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; fill: var(--ink-3); }
  .bore-ghost .t { font-size: 12.5px; fill: var(--ink-2); }
  .bore-ghost .w { font-size: 11.5px; fill: var(--ink-3); }
  .bore-ghost .scaffold { stroke: var(--ink-3); fill: none; opacity: 0.65; }
  .bore-ghost .faint { stroke: var(--ink-3); fill: none; opacity: 0.4; }
  .bore-ghost .bore { stroke: var(--accent); fill: none; opacity: 0.55; }
  .bore-ghost .anchor { fill: var(--gold-line); }
  .bore-ghost .anchor-o { fill: none; stroke: var(--gold-line); }
  .bore-ghost .pi { fill: var(--accent); opacity: 0.55; }
  .bore-ghost .weld-ghost { fill: none; stroke: var(--gold-line); stroke-dasharray: 3 3; }

  /* the live stage: the classic Leaflet kit rides in .drill-map; CanvasJS in .drill-chart
     (theme-token recipe lifted from progress.html — chrome from tokens, data ink classic) */
  .drill-map { position: relative; height: 500px; border-top: 1px solid var(--line-soft); }
  .drill-chart { position: relative; height: 190px; border-top: 1px solid var(--line-soft); padding: 8px 12px 4px; }
  /* the staged mid-teach: before this pane's own payload exists, the NEXT step is taught
     exactly where its result will land (an overlay; the chart renders beneath) */
  .chart-midghost {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    text-align: center; padding: 0 40px; font-size: 12.5px; color: var(--ink-3);
    pointer-events: none;
  }

  /* the map-area footer: one house band over the imagery — kit facts left, attribution
     right (Leaflet's own control is off; the band carries the same Google credit).
     z-index 900 floats it above panes, under popups; only its links take the pointer. */
  .map-foot {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 900;
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 5px 12px; font-size: 10.5px; line-height: 1.2;
    color: rgba(255,255,255,0.78); background: rgba(6,9,6,0.6);
    border-top: 1px solid rgba(255,255,255,0.08);
    pointer-events: none;
  }
  .map-foot a { color: rgba(255,255,255,0.9); text-decoration: none; pointer-events: auto; }

  /* the stage foot: dh.css's bare .card-foot is only a flex row — the padded and bordered
     dress is minted per card family; this is the stage family's minting. In the pusher the
     foot IS step 1's home: the DXF importer sits attached to the stage its bore fills. */
  .stage-card .card-foot { margin-top: 0; padding: 10px 20px 12px; border-top: 1px solid var(--line-soft); }
  .stage-foot-fact { font-size: 12px; color: var(--ink-3); }
  .stage-foot-fact b { color: var(--ink-2); font-weight: 500; }
  .stage-card .card-foot .foot-lbl { font-size: 12px; color: var(--ink-2); font-weight: 500; }
  .stage-card .card-foot .fld { flex: 0 1 340px; min-width: 220px; }

  /* the workbench: the pair's form cards. NOT .verb-row (that name is the settings verbs
     table) — the bench's verb seat is .bench-verbs. */
  .bench { display: grid; grid-template-columns: minmax(320px, 420px) minmax(0, 1fr); gap: 16px; align-items: start; }
  @media (max-width: 900px) { .bench { grid-template-columns: minmax(0, 1fr); } }
  .bench .dh-card { margin-bottom: 14px; }
  .bench .card-body { padding: 14px 20px 18px; }
  .bench .field { max-width: none; }
  /* dh.css .field is a flex-sizer with NO vertical rhythm — stacked bench fields sat flush
     (Mark's walk: the elevations label touching the hint above it); every seam breathes */
  .bench .field + .field { margin-top: 14px; }
  .bench .field input[type="text"] { width: 100%; }
  .bench textarea {
    width: 100%; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink); padding: 8px 10px;
    font-family: 'Ubuntu Mono', 'Consolas', monospace; font-size: 13px; line-height: 1.5;
    resize: vertical;
  }
  .bench textarea:focus, .bench input:focus { outline: 2px solid var(--gold-line); outline-offset: -1px; }
  .bench textarea[readonly] { cursor: not-allowed; opacity: 0.65; }
  .bench select {
    height: 34px; border: 1px solid var(--check-line); border-radius: 7px;
    background: var(--surface-2); color: var(--ink); font-family: inherit; font-size: 13px;
    padding: 0 8px; width: 100%;
  }
  .f-hint { font-size: 11.5px; color: var(--ink-3); line-height: 1.5; margin-top: 4px; }
  /* the either-or seam wears caps: an important structural fact, not a mumbled conjunction */
  .or-seam { display: flex; align-items: center; gap: 10px; color: var(--ink-3); font-size: 11.5px; margin: 14px 0; text-transform: uppercase; letter-spacing: 0.08em; }
  .or-seam::before, .or-seam::after { content: ""; flex: 1; border-top: 1px solid var(--line-soft); }
  .bench-verbs { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
  .bench-verbs .clear { font-size: 12.5px; color: var(--ink-3); margin-left: auto; }
  .bench-verbs .clear:hover { color: var(--ink); }
  /* the verbs live where the chain BEGINS (Mark's walk, tweak 13): in the pusher, step 1's
     home is the stage foot, so Update + Clear right-align there beside the importer */
  .stage-card .card-foot .foot-verbs { margin-left: auto; display: inline-flex; align-items: center; gap: 14px; }
  .foot-verbs .clear { font-size: 12.5px; color: var(--ink-3); }
  .foot-verbs .clear:hover { color: var(--ink); }

  /* the bench card head flexes so a title never wraps mid-phrase beside its head-note
     (the proposals fact rides the Calculated Welds head as a lowercase note) */
  .bench .card-head { display: flex; align-items: center; flex-wrap: wrap; row-gap: 2px; }
  .card-head .head-note {
    text-transform: none; letter-spacing: normal; font-weight: 400;
    font-size: 11.5px; color: var(--ink-3); margin-left: 10px;
    flex: 1 1 240px; min-width: 200px; line-height: 1.5;
  }
  .card-head .head-note b { color: var(--ink-2); font-weight: 500; }

  /* the welds preview: classic's readonly CSV textarea, dressed as the deliverable it is */
  .csv-pane {
    border: 1px solid var(--check-line); border-radius: 7px; background: var(--surface-2);
    font-family: 'Ubuntu Mono', 'Consolas', monospace; font-size: 12.5px; line-height: 1.6;
    color: var(--ink-2); padding: 10px 12px; min-height: 280px; max-height: 380px;
    overflow: auto; white-space: pre; margin: 0;
  }
  .csv-pane .hd { color: var(--gold); font-weight: 700; }
  .csv-pane.empty { display: flex; align-items: center; justify-content: center; white-space: normal; color: var(--ink-3); font-family: inherit; font-size: 12.5px; text-align: center; padding: 30px; }

  /* the zoom-extents easy-button icon: classic dressed it in Font Awesome, which the rail
     world deliberately does not ship — a data-URI SVG (four expand corners) carries it
     self-contained and font-independent (a unicode glyph rendered tofu in headless fonts) */
  .leaflet-bar .dh-zoom-extents {
    /* 100% of the anchor, not a fixed box — leaflet's bar buttons are 26px on desktop and
       30px on touch, and a fixed size sat the icon off-center (Mark's walk catch) */
    display: block; width: 100%; height: 100%;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23222' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M2 6V2h4M10 2h4v4M14 10v4h-4M6 14H2v-4'/%3E%3C/svg%3E") center/15px 15px no-repeat;
  }
