/* =============================================================================
   HolyGrail shell.css — ONE file (do not split).
   Rollback: web/_bak/shell.css.ROLLBACK.css
           + web/_bak/shell.css.20260730_131359.bak
   =============================================================================
   LAYER MAP (edit in the right section; cascade-critical tails stay late)
   ---------------------------------------------------------------------------
   0. TOC / cascade laws          (this block)
   1. TOKENS                      :root + html.dark vars, pantone --seg-* defs
   2. RESET + BASE                box model, body, type
   3. CHROME                      header, tabs, project forms, theme
   4. SURFACES (light)            tables → bid → breakdown → gantt → docks → docs
   5. DARK OVERRIDES              html.dark twin blob (exceptions not on tokens)
   3b.SCROLLBAR POLICY            after dark; only place for html.dark * + tabs kill
   6. DOCK EXTRAS                 CF balance stroke, gbar edges
   7. SEGMENT PAINT (apply)       wash/accent on rows (after dark bulk)
   8. CREW + RECRUIT
   9. TIER TEST + TIER SECURITY   security hide LAST among chrome policies
  10. PRIMITIVES (late winners)   focus ring, select hairline restyle, status menu
   ---------------------------------------------------------------------------
   CASCADE LAWS
   • View stack (locked): body is a 100vh flex column with overflow:hidden — no
   document scrollbar, ever. Every .view.on flex-fills below the real chrome and
   its own scroll root (bidwrap/it-scroll/cs-scroll/gantt-wrap) fills the rest.
   Scrollbar space is RESERVED on scroll roots (scrollbar-gutter) so contents
   never shift when a scrollbar appears/disappears. Side gaps come ONLY from
   --hg-tracker-side-padding. Sticky table headers lock at top:0 inside their
   scroll root. Doc heads use 79 (header+tabs only). Prefer --hg-* when touching math.
   • Opaque sticky backgrounds — translucent washes alone let rows bleed under
     parked headers. Pattern: linear-gradient(wash), page-base-color.
   • Never re-introduce a second html.dark * { scrollbar-* } outside §3b.
   • Form chrome final look is owned by §10 (select restyle). Do not restyle
     borders on .gfilters/.crew-pick/.proj-strip .proj-select in surfaces.
   • Segment colors: define --seg-accent on [data-seg] in §1; apply geometry in §7.
     A wash is ALWAYS color-mix(accent, var(--hg-<level>-op)). No alpha-hex wash
     variables exist; do not re-introduce them. No html.dark wash twins either —
     opacity vars live once on :root.
   • Tier hide (§9) uses !important; keep after layout so plain display rules
     cannot resurface restricted UI.
   • Cache-bust: bump shell.css?v= AND every js/?v= in index.html to SAME mark.
   ============================================================================= */

/* ===== 1. TOKENS ===== */
:root {
  /* layout chrome (sticky math) */
  --hg-header-h: 48px;
  --hg-tabs-h: 40px;
  --hg-chrome-h: 88px;           /* header + tabs */
  --hg-sticky-under-chrome: 79px; /* docs: header+tabs only */
  --hg-gantt-label-w: 380px;
  --hg-week-w: 56px;
  --hg-day-w: 11.2px;

  /* cashflow theme */
  --cf-spend: #455a7a44;
  --cf-spend-b: #455a7a33;
  --cf-deficit: color-mix(in srgb, var(--hg-danger) 20%, transparent);
  --cf-deficit-b: color-mix(in srgb, var(--hg-danger) 40%, transparent);
  --cf-income: #27ae60;
  --cf-label: #455a7a;
  --cf-deficit-t: #c0392b;
  --cf-deficit-glow: rgba(192, 57, 43, 0.95);
  /* stronger coats for standalone plot bars (overview panels) — --cf-spend's
     15% alpha is tuned for the gantt dock's dense week grid, too faint alone */
  --cf-bar: #455a7a66;
  --cf-bar-b: #455a7a55;
  --cf-bar-deficit: color-mix(in srgb, var(--hg-danger) 32%, transparent);
  --cf-bar-deficit-b: color-mix(in srgb, var(--hg-danger) 50%, transparent);
  /* ── Text contrast system (step 6 — 2026-08-13) ──────────────────
     --hg-contrast is a 0–100 slider for the appearance panel. By default
     it's unset and --hg-text-ink / --hg-text-bright keep their hardcoded
     values (zero visual change). When the panel sets --hg-contrast, it
     also overrides these tokens with color-mix formulas:
       light: color-mix(in srgb, #000, var(--hg-surface-base) calc(100% - var(--hg-contrast)))
       dark:  color-mix(in srgb, #fff, var(--hg-surface-base) calc(100% - var(--hg-contrast)))
     The formula mixes text toward the surface — 0=text=surface, 100=pure
     black (light) / pure white (dark). It works in both modes because it
     always moves toward the surface base. */
  --hg-text-ink: #515255;
  --hg-text-on-accent: #ffffff;  /* white text on dark/colored buttons, toast, grand totals, selected date */

  /* ── Action/accent tokens (step 8 — 2026-08-13) ──────────────────
     Gold accent for primary actions, danger red for destructive actions,
     info blue for secondary labels. These are the brand-decorative colors
     a tenant can override. Status pill colors (st-rev, st-appr, etc.) will
     reference these as their base in step 9. */
  --hg-accent:        #17181c;  /* accent: active tabs, tier buttons, create buttons, toast, grand totals, focus rings, calendar selection, block-btn.on */
  --hg-danger:        #c0392b;  /* danger backgrounds (confirm btn, workload bar, heat-over) */
  --hg-danger-ink:    #b03a2a;  /* danger text on light (delete buttons, crew-pick.un) */
  --hg-danger-hover:  #a93226;  /* danger hover bg (confirm btn hover, st-reopen bg) */
  --hg-info:          #455a7a;  /* info blue text on light (mpath, weekhdr start, cf-caret) */

  /* ── People token (2026-09-11) ──────────────────────────────────
     Crew reads on the gantt label rows (gantt-crew-read). Violet:
     the one hue no status family claims, so a name never reads as
     status (green/gold/blue-grey/red/grey) or as an action (gold
     accent, danger red). Theme-controllable like the accent family. */
  --hg-people: #6d55b0;

  /* ── Text tokens (step 4 — 2026-08-13) ──────────────────────────
     Muted/secondary/label text. Every color: that was a hardcoded
     muted hex now references one of these. Theme-controllable.
     DO NOT use these for background or border — only color. */
  --hg-text-muted:     var(--hg-border-focus);  /* muted text: labels, meta, hints, disabled, placeholders */
  --hg-text-dim:       #8a93a3;  /* dim text: badges, sub-text, secondary info, drawer labels */
  --hg-text-secondary: #6a7180;  /* secondary text: form labels, plan columns, footnotes */
  --hg-text-label:     #7d8494;  /* header labels: table th, doc th, drawer keys, section heads */

  /* ── Surface tokens (step 1 — 2026-08-13) ──────────────────────────
     Five surface tiers + header/tab chrome. Every background that was a
     hardcoded hex now references one of these. A theme preset overrides
     these values in an injected <style> block; shell.css never changes.
     DO NOT use these tokens for border-color or color — only background. */
  --hg-surface-base:    #f8f5ef;  /* body, subtabs, table headers, filter bar, popovers, modals, form panels */
  --hg-surface-header:  #f0e9dd;  /* header strip */
  --hg-surface-tabs:    #e8dccb;  /* tab row, flat buttons, filter selects, project select */
  --hg-surface-input:   #ffffff;  /* input backgrounds (light) */
  --hg-surface-raised:  #f4f2ea;  /* subtotal rows, spinner buttons, stage hover, editable hover */
  --hg-surface-elevated: #f3eedd; /* editable cell hover, stage days hover (light) */

  /* ── Border tokens (step 3 — 2026-08-13) ──────────────────────────
     Five border families. Every border that was a hardcoded hex now
     references one of these. A theme preset overrides these values.
     DO NOT use these tokens for background or color — only border/outline. */
  --hg-border-chrome:   #e3ded6;  /* header, tabs, table header borders — warm chrome hairlines */
  --hg-border-control:  #e0e0e0;  /* form/button/input borders — neutral control hairlines */
  --hg-border-row:      #e8e8e8;  /* table row borders, panel separators, sum-card borders */
  --hg-border-cell:     #eef0f4;  /* cell bottom border (lightest tier) */
  --hg-border-warm:     #d3cec2;  /* warm-tinted borders: crew/license panels, meta inputs, currency toggles */
  --hg-border-hover:    #c8c8c8;  /* hover border on buttons/selects (light) */
  --hg-border-focus:    #9a9aa2;  /* focus ring on inputs/controls (light) */
  --hg-border-na:       #c5cad4;  /* new-asset gantt + cashflow dock borders (light) */
  --hg-border-menu-chk: #b8bcc6;  /* menu checkbox borders (light) */
  --gantt-head-h: 42px;            /* sticky gantt header band height — label rows park against this */

  /* ── Status tokens (step 9 — 2026-08-13) ────────────────────────
     Pipeline-semantic status colors. NOT editor-controllable — these
     encode shot/task status meaning (in-progress, complete, approved,
     re-open, waiting). Each status has a bg + ink pair. */
  --st-rev-bg:    #f6e8d3;  --st-rev-ink:    #96660f;  /* in-progress: warm gold */
  --st-ip-bg:     #d8efe2;  --st-ip-ink:     #1e6e44;  /* in-pipeline: green */
  --st-cmpt-bg:   #dde5f0;  --st-cmpt-ink:   #344c70;  /* complete: blue-grey */
  --st-appr-bg:   #dde5f0;  /* approved: same bg as complete in light */
  --st-reopen-bg: #f6dcd7;  --st-reopen-ink: #a93226;  /* re-open: red */
  --st-wtg-bg:    #e4e8ee;  --st-wtg-ink:    #5c657a;  /* waiting: neutral grey */

  /* ── Gantt bar tokens (step 10 — 2026-08-13) ────────────────────
     Pipeline-semantic gantt bar colors. NOT editor-controllable.
     Map to status families but use distinct bar-appropriate shades. */
  --gbar-ip-bg:    #287d50;  /* in-pipeline bar (sea green; white text >= 4.5:1) */
  --gbar-wtg-bg:   #667185;  /* waiting bar (slate grey; white text >= 4.5:1) */
  --gbar-rev-bg:   #c28a31;  /* review/in-progress bar (gold) */
  --gbar-rev-ink:  #241806;  /* dark text on gold bar */
  --gbar-appr-bg:  #4a6f9c;  /* approved bar (blue) */
  --gbar-cmpt-bg:  #507b60;  /* complete bar (muted green) */
  --gbar-draft-stripe: #7f8ca0;  /* draft bar stripe alternate */
  --gbar-ip-border: #2c4038;  /* in-pipeline border (dark — unused in light, defined for symmetry) */
  --gbar-wtg-ink:  #d6d9df;  /* text on waiting bar (dark only) */
  --hg-danger-bright: #e74c3c;  /* bright danger red for spike lines, overdue markers, tags */

  /* ── Shadow tokens (step 12 — 2026-08-13) ───────────────────────
     Five shadow tiers. Theme-controllable — a tenant can tune shadow
     intensity. Each token holds the full box-shadow value. */
  --hg-shadow-sm:    0 1px 3px rgba(15, 23, 42, 0.15);   /* subtle: entity body, master-totals */
  --hg-shadow-pop:   0 4px 16px rgba(0,0,0,.12);         /* popover: dropdown panels */
  --hg-shadow-menu:  0 10px 28px #17181c33;               /* menu: status menu, hg-menu, selects */
  --hg-shadow-modal: 0 16px 40px #00000088;               /* modal: dialogs, large panels */
  --hg-shadow-slide: -6px 0 24px #0002;                    /* slide: drawer edge shadow */
}

html.dark {
  --cf-spend: #8a94a626;
  --cf-spend-b: #8a94a61a;
  --cf-deficit: #a05a5a2e;
  --cf-deficit-b: #a05a5a55;
  --cf-income: #3fae6e;
  --cf-label: #6f7076;
  --cf-deficit-t: #c08a8a;
  --cf-deficit-glow: rgba(224, 96, 96, 0.95);
  --cf-bar: #8a94a64d;
  --cf-bar-b: #8a94a655;
  --cf-bar-deficit: #a05a5a4d;
  --cf-bar-deficit-b: #a05a5a66;
  /* Dark-mode bright text — hardcoded default (zero change). The contrast
     formula in :root docs explains how the panel overrides this. */
  --hg-text-bright: rgba(255, 255, 255, 0.6);
  --hg-text-on-accent: #ffffff;

  /* ── Action/accent tokens (dark mode — step 8, 2026-08-13) ──────
     Dark values for accent/danger/info. Gold brightens to #d9a441,
     danger stays #c0392b, danger-ink is #e0655f (lighter red for dark bg),
     danger-hover stays #a93226, info brightens to #7d9cba. */
  --hg-accent:        #d9a441;  /* gold on dark (active tabs, sum-card total, delete hover, block-btn.on) */
  --hg-danger:        #c0392b;  /* same red in both modes */
  --hg-danger-ink:    #e0655f;  /* lighter red text on dark (delete hover, seg-delete hover) */
  --hg-danger-hover:  #a93226;  /* same hover red in both modes */
  --hg-info:          #7d9cba;  /* blue on dark (linked, seg-meta, t-cost, task-add, drawer links) */
  --hg-people:        #9c86d4;  /* people violet brightens on dark (gantt-crew-read) */

  /* ── Text tokens (dark mode — step 4, 2026-08-13) ───────────────
     Same four families, dark values.
     #6f7076 = muted (headers, labels, meta, placeholders, disabled)
     #8a93a3 = dim (badges, sub-text, secondary info — same as light)
     Dark has no separate secondary/label — those light-only tiers
     are overridden here to #6f7076 so any stray light-mode ref stays muted. */
  --hg-text-muted:     #6f7076;
  --hg-text-dim:       #8a93a3;
  --hg-text-secondary: #6f7076;
  --hg-text-label:     #6f7076;

  /* ── Status tokens (dark mode — step 9, 2026-08-13) ────────────
     Same status families, dark values. NOT editor-controllable. */
  --st-rev-bg:    #33291a;  --st-rev-ink:    #c9a468;  /* in-progress: dark gold */
  --st-ip-bg:     #1e2e26;  --st-ip-ink:     #7db892;  /* in-pipeline: dark green */
  --st-cmpt-bg:   #2b2d20;  --st-cmpt-ink:   #a8ad7d;  /* complete: dark olive */
  --st-appr-bg:   #1f2a36;  /* approved: dark blue (distinct from complete) */
  --st-reopen-bg: #342225;  --st-reopen-ink: #c08a92;  /* re-open: dark red */
  --st-wtg-bg:    #24262b;  --st-wtg-ink:    #8b8c92;  /* waiting: dark grey */

  /* ── Gantt bar tokens (dark mode — step 10, 2026-08-13) ────────
     Dark values for gantt bars. IP and CMPT share a lighter green. */
  --gbar-ip-bg:    #6f9c7f;  /* in-pipeline: lighter green for dark */
  --gbar-cmpt-bg:  #87906a;  /* complete: olive, distinct from in-progress */
  --gbar-wtg-bg:   #4a4e58;  /* waiting: dark grey */
  --gbar-draft-stripe: #3e424b;  /* draft: dark stripe alternate */
  --gbar-rev-ink:  #1a1508;  /* dark text on gold buttons/bars */
  --gbar-wtg-ink:  #d6d9df;  /* text on dark waiting bar */
  --gbar-ip-border: #2c4038;  /* in-pipeline border */

  /* ── Shadow tokens (dark mode — step 12, 2026-08-13) ────────────
     Same five tiers, dark values. Deeper shadows for dark surfaces. */
  --hg-shadow-sm:    0 1px 3px rgba(0,0,0,0.45);
  --hg-shadow-pop:   0 8px 24px #00000055;
  --hg-shadow-menu:  0 10px 28px #00000099;
  --hg-shadow-modal: 0 16px 40px #00000088;
  --hg-shadow-slide: -6px 0 24px #00000066;

  /* Tracker cell input dark overrides — one place for all tracker tables.
     --hg-input-border stays transparent (inline-edit = borderless);
     visible/hover/focus borders track --hg-border-control so the whole
     input family follows the active tenant theme (warm ivory, etc.). */
  --hg-input-border: 1px solid transparent;
  --hg-input-border-visible: 1px solid var(--hg-border-control);
  /* dark field fill = halfway between raised and base (the table ground):
     boxes stay visible but stop reading as holes punched in the table */
  --hg-input-bg: color-mix(in srgb, var(--hg-surface-raised) 50%, var(--hg-surface-base));
  --hg-input-ink: var(--hg-text-bright);  /* appearance-editor 'Field text colour' drives this */
  --hg-input-color: var(--hg-input-ink);
  --hg-input-border-hover: var(--hg-border-control);
  --hg-input-border-focus: var(--hg-border-control);

  /* ── Surface tokens (dark mode — step 1, 2026-08-13) ───────────────
     NEUTRAL-TEMPERATURE FALLBACK: the active tenant preset (see
     theme_presets.py) overlays its own surface family on top of these;
     these defaults exist only for surfaces the preset does not set.
     #141517 = base (body/header/tabs/drawer/gantt-labels)
     #17181b = elevated (modals, shot groups, bid subtotals, week headers)
     #1a1b1f = raised (form panels, dropdowns, inputs, tag pills, option lists)
     #1e1f23 = card (hover states, drawer threads, tier buttons)
     #24262b = hover (toast, status pills, tier badges, recruit status) */
  --hg-surface-base:     #141517;
  --hg-surface-header:   #141517;
  --hg-surface-tabs:     #141517;
  --hg-surface-input:    #141517;
  --hg-surface-raised:   #1a1b1f;
  --hg-surface-elevated: #17181b;
  --hg-surface-card:     #1e1f23;
  --hg-surface-hover:    #24262b;

  /* ── Border tokens (dark mode — step 3, 2026-08-13) ───────────────
     Mirrors the light :root set. Same families, dark values.
     #26272b = chrome + row borders (dark)
     #3a3b40 = control borders + input borders (dark)
     #1e1f23 = cell/row bottom borders (dark)
     #2c251d = warm borders (dark — crew/license)
     #55565c = hover/focus borders (dark)
     #e4e4e7 = focus border + outline (dark — brightest tier) */
  --hg-border-chrome:   #26272b;
  --hg-border-control:  #3a3b40;
  --hg-border-row:      #26272b;
  --hg-border-cell:     #1e1f23;
  --hg-border-warm:     #2c251d;
  --hg-border-hover:    #55565c;
  --hg-border-na:       #3a3b40;
  --hg-border-menu-chk: #55565c;
  --hg-border-focus:    #e4e4e7;
}

/* Pantone segment tokens. One mechanism only: --seg-accent drives color-mix()
   washes via the hierarchy opacity vars below. There are deliberately NO
   alpha-hex wash variables — a wash is always color-mix(accent, <level>op). */
:root {
  /* Hierarchy wash opacity: LANE > ENTITY > STAGE. Hover = base × 1.3.
     One definition for both modes; no html.dark overrides for row washes. */
  --hg-lane-op: 30%;
  --hg-lane-op-h: 39%;
  --hg-entity-op: 20%;
  --hg-entity-op-h: 26%;
  --hg-stage-op: 10%;
  --hg-stage-op-h: 13%;
  /* feather length of the shared segment accent edge (--seg-edge, defined on [data-seg]) */
  --seg-feather: 3px;
}
[data-seg="preprod"]      { --seg-accent:#c98f4a; }
[data-seg="characters"]   { --seg-accent:#b85c8a; }
[data-seg="environments"] { --seg-accent:#4f9e6a; }
[data-seg="props"]        { --seg-accent:#7a68c4; }
[data-seg="mocap"]        { --seg-accent:#3aa5ad; }
[data-seg="shots"]        { --seg-accent:#c45c4a; }
[data-seg="support"]      { --seg-accent:#6b7c93; }
[data-seg="gold"]         { --seg-accent:#c2a24a; }
[data-seg="lime"]         { --seg-accent:#8fae3f; }
[data-seg="azure"]        { --seg-accent:#4a8fc2; }
[data-seg="umber"]        { --seg-accent:#a0785a; }
[data-seg="magenta"]      { --seg-accent:#c24ab8; }
[data-seg="other"]        { --seg-accent:var(--hg-border-focus); }
/* Shared feathered accent edge. MUST be computed on [data-seg], not :root:
   a var() inside a custom property resolves against the declaring element's
   own set (:root has no --seg-accent → guaranteed-invalid → every background
   using the token silently drops to transparent). Here it recomputes per
   element with that element's slug accent (light + dark) and inherits into
   children like .hg-entity-body. */
[data-seg] { --seg-edge: linear-gradient(90deg, var(--seg-accent) 0, transparent var(--seg-feather)); }
html.dark [data-seg="preprod"]      { --seg-accent:#f2aa56; }
html.dark [data-seg="characters"]   { --seg-accent:#e671aa; }
html.dark [data-seg="environments"] { --seg-accent:#5bbe7d; }
html.dark [data-seg="props"]        { --seg-accent:#927af2; }
html.dark [data-seg="mocap"]        { --seg-accent:#43c7d1; }
html.dark [data-seg="shots"]        { --seg-accent:#f26b55; }
html.dark [data-seg="support"]      { --seg-accent:#8298b9; }
html.dark [data-seg="gold"]         { --seg-accent:#ffd764; }
html.dark [data-seg="lime"]         { --seg-accent:#c6f05e; }
html.dark [data-seg="azure"]        { --seg-accent:#6cc4ff; }
html.dark [data-seg="umber"]        { --seg-accent:#d9a878; }
html.dark [data-seg="magenta"]      { --seg-accent:#f272e8; }
html.dark [data-seg="other"]        { --seg-accent:#a0a1aa; }

/* ===== 2. RESET + BASE ===== */
  * { box-sizing: border-box; margin: 0; padding: 0; }
  /* Page-level scrollbars must NEVER exist: the app is a locked flex column
     (body height:100vh, overflow:hidden). Views scroll inside their own
     full-width scroll roots (bidwrap/cs-scroll/it-scroll/gantt-wrap), so a
     document scrollbar can never appear and never eat a side gap. Scroll
     roots carry NO scrollbar-gutter reservation — the side gap is owned
     purely by --hg-tracker-side-padding, so it is identical on every view
     and never browser-dependent. */
  :root {
    --hg-tracker-side-padding: 20px;
    /* Central font definitions — the whole app inherits these. */
    --hg-font-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
    --hg-font-mono: ui-monospace, Consolas, "SF Mono", monospace;
    /* Type scale — the only sizes the UI should use. Weights match the
       Google Fonts faces loaded (400/500/600/700).
       --hg-type-scale multiplies every size (default 1.0). The appearance
       panel sets this to retune all type globally (0.85 compact → 1.5 large). */
    --hg-type-scale: 1.0;
    --hg-type-tiny:    calc(8px    * var(--hg-type-scale));  /* tier badge numerals */
    --hg-type-micro:   calc(9.5px  * var(--hg-type-scale));  /* badges, pills, status chips */
    --hg-type-9:       calc(9px    * var(--hg-type-scale));  /* gantt owner labels, collapse btn */
    --hg-type-small:   calc(10.5px * var(--hg-type-scale));  /* table headers, dense meta */
    --hg-type-10:      calc(10px   * var(--hg-type-scale));  /* sum-card labels, entity types, doc gen */
    --hg-type-11:      calc(11px   * var(--hg-type-scale));  /* the most common size — inputs, buttons, meta */
    --hg-type-11h:     calc(11.5px * var(--hg-type-scale));  /* entity names, mrow stg, mid-dense */
    --hg-type-base:    calc(12px   * var(--hg-type-scale));  /* default body (matches body font-size) */
    --hg-type-12h:     calc(12.5px * var(--hg-type-scale));  /* entity names (bold), rate inputs */
    --hg-type-medium:  calc(13px   * var(--hg-type-scale));  /* emphasised body, primary actions */
    --hg-type-14:      calc(14px   * var(--hg-type-scale));  /* form btns, acct toolbar */
    --hg-type-large:   calc(16px   * var(--hg-type-scale));  /* subheads, panel titles */
    --hg-type-18:      calc(18px   * var(--hg-type-scale));  /* doc h1 */
    --hg-type-display: calc(26px   * var(--hg-type-scale));  /* sum-card values, page-level titles */
    --hg-weight-normal: 400;
    --hg-weight-medium: 500;
    --hg-weight-semibold: 600;
    --hg-weight-bold: 700;
    /* Soft text shadow — applied once on body, inherited everywhere.
       Black works in both modes (light ink / bright white text). */
    --hg-text-shadow: 0 1px 3px rgba(0, 0, 0, 0.20);
    /* Tracker cell input styling — one place for all tracker tables
       (Crew, IT, Expenses, future subtabs).  UNIFIED FIELD FILL: every
       input wears --hg-input-bg permanently — idle and selected are the
       SAME colour (selection signals via border/caret only).  The
       breakdown editor's seg/entity/task label fields are the one
       exception family (dedicated coloured rules).  Dark-mode overrides
       are in the html.dark block at the top of the file. */
    --hg-input-border: 1px solid transparent;
    --hg-input-border-visible: 1px solid #d3cec2;
    --hg-input-radius: 4px;
    --hg-input-padding: 2px 5px;
    --hg-input-font-size: var(--hg-type-base);
    --hg-input-bg: var(--hg-surface-input);   /* ONE field fill — idle = selected */
    --hg-input-ink: var(--hg-text-ink);      /* appearance-editor 'Field text colour' drives this */
    --hg-input-color: var(--hg-input-ink);
    --hg-input-border-hover: #d3cec2;
    --hg-input-border-focus: #d3cec2;
  }

  /* ── Tracker cell input classes ──────────────────────────────
     Two classes own every inline-editable cell input across all
     tracker tables (Crew, IT, Expenses, future subtabs).  JS uses
     these class names instead of copy-pasted inline styles; the
     dark-mode block at the bottom of the file overrides the tokens. */
  .hg-cell-input,
  .hg-cell-input-new {
    border: var(--hg-input-border);
    border-radius: var(--hg-input-radius);
    padding: var(--hg-input-padding);
    font-size: var(--hg-input-font-size);
    font-family: var(--hg-font-ui);
    background: var(--hg-input-bg);
    color: var(--hg-input-color);
    outline: none;
  }
  .hg-cell-input-new { border: var(--hg-input-border-visible); }
  /* Crew inputs — borderless text fields (name/role/email) + visible-border
     rate field.  All share color/font from the centralized --hg-input-* tokens.
     The rate override comes AFTER so its visible border wins the cascade. */
  #crewTable td input.cs-name,
  #crewTable td input.cs-role,
  #crewTable td input.cs-email,
  #crewTable td input.rate-input {
    border: 1px solid transparent;
    background: var(--hg-input-bg);
    color: var(--hg-input-color);
    font-size: var(--hg-input-font-size);
    font-family: var(--hg-font-ui);
    outline: none;
  }
  #crewTable td input.rate-input { border: var(--hg-input-border-visible); border-radius: 5px; padding: 3px 7px; }
  .hg-cell-input:hover,
  .hg-cell-input-new:hover,
  #crewTable td input.cs-name:hover,
  #crewTable td input.cs-role:hover,
  #crewTable td input.cs-email:hover,
  #crewTable td input.rate-input:hover { border-color: var(--hg-input-border-hover); }
  .hg-cell-input:focus,
  .hg-cell-input-new:focus,
  #crewTable td input.cs-name:focus,
  #crewTable td input.cs-role:focus,
  #crewTable td input.cs-email:focus,
  #crewTable td input.rate-input:focus {
    border-color: var(--hg-input-border-focus);
    /* fill intentionally NOT restated: --hg-input-bg is idle = selected */
  }

  /* Scrollbar space is RESERVED on the scroll roots (scrollbar-gutter) so the
     contents never shift when a scrollbar appears/disappears — founder-required.
     The SIDE GAP itself is owned by --hg-tracker-side-padding on each root.
     The document itself never scrolls (body overflow:hidden), so there is no
     page-level scrollbar to eat a margin (the old gantt right-edge bug). */
  .bidwrap, .gantt-wrap { scrollbar-gutter: stable; }
  .cs-scroll, .it-scroll, .exp-scroll, .ast-scroll, .cli-inv-scroll, .cti-inv-scroll, .prl-scroll, .rc-scroll, .cf-forecast-scroll, .rec-scroll { scrollbar-gutter: stable both-edges; }
  .cf-forecast-scroll { scrollbar-gutter: auto; }
  .view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
  #v-ib .bidwrap { flex: 1 1 auto; min-height: 0; overflow: auto; }
  #v-cli .bidwrap { flex: 1 1 auto; min-height: 0; overflow: auto; }
  /* Gantt view shell: chart scrolls on its own; cashflow is a sibling dock
     at the bottom of the VIEW (window), never nested in the chart scroll.
     Filters sit ABOVE the scroll root as a plain flex band — not sticky —
     so week headers cannot park under the tabs strip past the filter row. */
  #v-tr.view.on {
    display: flex; flex-direction: column;
    flex: 1 1 auto; /* fills below the real chrome — no hardcoded 88px accounting */
    min-height: 0; overflow: hidden;
  }
  body {
    font-family: var(--hg-font-ui);
    font-size: var(--hg-type-base);
    color: var(--hg-text-ink); background: var(--hg-surface-base); line-height: 1.4;
    text-shadow: var(--hg-text-shadow);
      transition: background .15s, color .15s;
    -webkit-font-smoothing: antialiased;
    /* Edge geometry: the app fills the viewport as a locked column; the active
       view flex-fills what remains below the chrome. No document scrollbar,
       ever — views scroll inside their own roots. */
    display: flex; flex-direction: column; height: 100vh; overflow: hidden;
  }
  /* Form controls must use the same central UI font — the UA default (Arial)
     otherwise leaks into inputs/buttons/selects. Inputs do NOT inherit
     text-shadow from body; the token is restated here so every text field,
     select and button matches its surrounding label text. */
  input, button, select, textarea {
    font-family: var(--hg-font-ui);
    text-shadow: var(--hg-text-shadow);
  }
  /* Single Hydra scales strip — cover-fitted to the window (zooms to fill,
     crops overflow on whichever axis doesn't match the image aspect). */
  body::before {
    content: ""; position: fixed; inset: 0; z-index: -1;
    background: url("assets/HydraScalesBG.jpg") center / cover no-repeat;
    filter: invert(1) grayscale(.4) brightness(1.02); opacity: .13;
    pointer-events: none;
  }
/* ===== 3. CHROME — header, tabs, project chrome ===== */
  header {
    display: flex; align-items: center; gap: 14px;
    padding: 0 20px; height: 48px; background: var(--hg-surface-header); border-bottom: 1px solid var(--hg-border-chrome);
    position: sticky; top: 0; z-index: 40; flex-shrink: 0;
  }
  header .logo { height: 22px; width: auto; flex-shrink: 0; content: url("assets/black_on_white_icon_only.png"); }
  html.dark header .logo { content: url("assets/white_on_black_icon_only.png"); }
  header .proj { font-size: var(--hg-type-medium); font-weight: 600; letter-spacing: -.01em; }
  .hg-serif { font-family: inherit; }
  .hg-mono { font-family: inherit; font-feature-settings: "tnum"; }
  .proj-strip .proj-wrap {
    display: flex; align-items: center; gap: 6px; flex-shrink: 0;
    position: relative; z-index: 2; justify-self: start;
  }
  .proj-strip .proj-select {
    font-size: var(--hg-type-medium); font-weight: 600; letter-spacing: -.01em;
    padding: 3px 8px; border: 1px solid transparent; border-radius: 4px;
    background-color: transparent; color: var(--hg-text-ink); cursor: pointer; min-width: 120px;
  }
  .proj-strip .proj-select:hover { background-color: #f0f0f0; }
  .proj-strip .proj-new-btn {
    font-size: var(--hg-type-11); font-weight: 500;
    padding: 4px 10px; border: 1px solid var(--hg-border-control); border-radius: 4px;
      background: var(--hg-surface-tabs); color: var(--hg-text-ink); cursor: pointer; white-space: nowrap;
  }
  .proj-strip .proj-new-btn:hover { border-color: var(--hg-border-hover); color: var(--hg-text-ink); }
  .proj-strip .proj-edit-btn {
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--hg-type-medium); padding: 3px 7px; border: 1px solid transparent;
    border-radius: 4px; background: transparent; color: var(--hg-text-muted);
    cursor: pointer; line-height: 1;
  }
  .proj-strip .proj-edit-btn:hover { background: #f0f0f0; color: var(--hg-text-ink); }
  /* New project inline form */
  .proj-new-form {
    display: none; position: absolute; top: 88px; left: 16px; z-index: 50;
    background: var(--hg-surface-base); border: 1px solid var(--hg-border-control); border-radius: 3px; padding: 14px;
    box-shadow: var(--hg-shadow-pop); gap: 8px; flex-direction: column; min-width: 280px;
  }
  .proj-new-form.on { display: flex; }
  .proj-new-form label { font-size: var(--hg-type-11); color: var(--hg-text-secondary); font-weight: 600; }
  .proj-new-form input {
    font-size: var(--hg-type-medium); padding: 5px 8px; border: 1px solid var(--hg-border-control); border-radius: 4px; width: 100%;
  }
  .proj-new-form .form-btns { display: flex; gap: 8px; margin-top: 4px; }
  .proj-new-form .form-btns button {
    font-size: var(--hg-type-base); font-weight: 600; padding: 5px 14px; border-radius: 4px; border: 1px solid var(--hg-border-control); cursor: pointer;
  }
  .proj-new-form .form-btns .create { background: var(--hg-accent); color: var(--hg-text-on-accent); border-color: var(--hg-accent); }
  .proj-new-form .form-btns .cancel { background: var(--hg-surface-tabs); color: var(--hg-text-secondary); }
  /* Project settings panel */
  .proj-settings-form {
    display: none; position: absolute; top: 88px; left: 60px; z-index: 50;
    background: var(--hg-surface-base); border: 1px solid var(--hg-border-control); border-radius: 3px; padding: 14px;
    box-shadow: var(--hg-shadow-pop); gap: 8px; flex-direction: column; min-width: 280px;
  }
  .proj-settings-form.on { display: flex; }
  .proj-settings-form label { font-size: var(--hg-type-11); color: var(--hg-text-secondary); font-weight: 600; }
  .proj-settings-form input {
    font-size: var(--hg-type-medium); padding: 5px 8px; border: 1px solid var(--hg-border-control); border-radius: 4px; width: 100%;
  }
  .proj-settings-form .form-btns { display: flex; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
    .proj-settings-form .form-btns button {
      font-size: var(--hg-type-base); font-weight: 600; padding: 5px 14px; border-radius: 4px; border: 1px solid var(--hg-border-control); cursor: pointer;
    }
    .proj-settings-form .form-btns .create { background: var(--hg-accent); color: var(--hg-text-on-accent); border-color: var(--hg-accent); }
    .proj-settings-form .form-btns .dup { background: var(--hg-surface-tabs); color: var(--hg-text-ink); border-color: var(--hg-border-hover); }
    .proj-settings-form .form-btns .dup:hover { border-color: var(--hg-accent); color: var(--hg-text-ink); }
    .proj-settings-form .form-btns .dup:disabled { opacity: .55; cursor: wait; }
    .proj-settings-form .form-btns .cancel { background: var(--hg-surface-tabs); color: var(--hg-text-secondary); }
  /* Duplicate mode popover */
  .dup-mode-pop {
    display: none; position: absolute; top: 42px; left: 60px; z-index: 51;
    background: var(--hg-surface-base); border: 1px solid var(--hg-border-control); border-radius: 3px; padding: 6px;
    box-shadow: var(--hg-shadow-pop); flex-direction: column; min-width: 280px; gap: 2px;
  }
  .dup-mode-pop.on { display: flex; }
  .dup-mode-btn {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    padding: 8px 12px; border: none; background: transparent; cursor: pointer;
    border-radius: 3px; text-align: left;
  }
  .dup-mode-btn:hover { background: #f4f4f5; }
  .dup-mode-label { font-size: var(--hg-type-base); font-weight: 600; color: var(--hg-text-ink); }
  .dup-mode-desc { font-size: var(--hg-type-10); color: var(--hg-text-muted); line-height: 1.3; }
  header .meta { color: var(--hg-text-muted); font-size: var(--hg-type-11); font-variant-numeric: tabular-nums; }
  .agent-strip-head { margin-left: auto; font-size: var(--hg-type-11); color: var(--hg-text-muted); display: flex; gap: 8px; align-items: center; cursor: pointer; }
  /* ===== Footer meta line (segments · plan days · mutation · build) ===== */
  .hg-footer {
    position: fixed; left: 0; right: 0; bottom: 0;
    display: flex; align-items: center; justify-content: center; gap: 14px;
    padding: 6px 20px; background: transparent; border: none;
    font-size: var(--hg-type-11); color: var(--hg-text-muted); opacity: 0.75; font-variant-numeric: tabular-nums;
    pointer-events: none; z-index: 40;
  }
  .hg-footer .meta { color: var(--hg-text-muted); font-size: var(--hg-type-11); font-variant-numeric: tabular-nums; }
  html.dark .hg-footer { background: transparent; color: var(--hg-text-muted); opacity: 0.75; }
  html.dark .hg-footer .meta { color: var(--hg-text-muted); }
  .dot { width: 6px; height: 6px; border-radius: 50%; background: #2e9e5b; display: inline-block; }
  .agent-strip-head.reconnecting { color: #d64545; }
  .agent-strip-head.reconnecting #livetxt { animation: hg-pulse 1.2s ease-in-out infinite; }
  .agent-strip-head.reconnecting .dot { background: #d64545 !important; animation: hg-pulse 1.2s ease-in-out infinite; }
  @keyframes hg-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
  html.dark .agent-strip-head.reconnecting { color: #e0655f; }
  html.dark .agent-strip-head.reconnecting .dot { background: #e0655f !important; }
  .theme-btn {
    border: 1px solid var(--hg-border-control); background: var(--hg-surface-tabs); color: var(--hg-text-ink);
      border-radius: 4px; padding: 4px 10px; font-size: var(--hg-type-11); cursor: pointer; font-weight: 500;
      flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px; margin-left: 8px;
  }
  .theme-btn:hover { border-color: var(--hg-border-hover); color: var(--hg-text-ink); }
  .theme-btn .ico { font-size: var(--hg-type-medium); line-height: 1; }
  /* ===== 3a. SCOPE TABS (Company | Projects) — inline in header ===== */
  .scope-tabs {
    display: flex; align-items: stretch; gap: 14px; flex-shrink: 0;
    align-self: stretch;
  }
  .scope-tab {
    display: inline-flex; align-items: center;
    font-size: var(--hg-type-medium); font-weight: 600; color: var(--hg-text-label); cursor: pointer;
    border: none; border-bottom: 2px solid transparent; border-radius: 0;
    white-space: nowrap; background: transparent;
    transition: color .12s, border-color .12s;
  }
  .scope-tab:hover { color: var(--hg-text-ink); }
  .scope-tab.on { color: var(--hg-text-ink); border-bottom-color: var(--hg-accent); }

  /* ===== 3b. PROJECT STRIP (proj selector + content tabs) ===== */
  .proj-strip {
    display: grid; grid-template-columns: 1fr; align-items: stretch;
    padding: 0 20px; background: var(--hg-surface-tabs); border-bottom: 1px solid var(--hg-border-chrome);
    flex-shrink: 0; position: relative; height: 40px;
  }
  .proj-strip .tabs {
    border: none; background: transparent; padding: 0; gap: 18px;
    height: 100%; position: absolute; left: 0; right: 0; top: 0; bottom: 0;
    justify-content: center; z-index: 1;
  }
  .proj-strip .tab {
    font-size: var(--hg-type-base);
  }
  /* Hide tabs not in the active scope */
  body[data-scope="co"] .tab.scope-proj { display: none !important; }
  body[data-scope="proj"] .tab.scope-co { display: none !important; }
  body[data-scope="co"] .proj-strip .proj-wrap { display: none; }
  .tabs {
    display: flex; align-items: stretch; gap: 22px; background: var(--hg-surface-tabs); padding: 0 20px;
    border-bottom: 1px solid var(--hg-border-chrome); position: sticky; top: 48px; z-index: 39;
    /* 40px border-box = 39 content + 1 bottom border — full integer px, no subpixel overflow */
    height: 40px; overflow-x: auto; overflow-y: hidden;
    flex-shrink: 0;
  }
  .tab {
    display: inline-flex; align-items: center;
    padding: 0; font-size: var(--hg-type-base); color: var(--hg-text-label); cursor: pointer;
    border: none; border-bottom: 2px solid transparent; border-radius: 0;
    white-space: nowrap; background: transparent;
    /* sit on the strip border — no negative margin (that was the +1px overflow source) */
    margin-bottom: 0;
    transition: color .12s, border-color .12s;
  }
  .tab:hover { color: var(--hg-text-ink); background: transparent; }
  .tab.on { color: var(--hg-text-ink); border-bottom-color: var(--hg-accent); background: transparent; font-weight: 500; }
  .view { display: none; }
  /* .view.on keeps its flex-column layout from the §2 rule (line ~442).
     The old '.view.on { display: block }' here silently overrode it (same
     specificity, later in file) — views laid out as block, scroll roots grew
     to content height and never overflowed: no scrollbars on any tab but
     Gantt (whose ID rule out-ranked this). Deleted 2026-09-13. */

  /* ===== 3b. SUB-TABS (inside Company tab) ===== */
  .subtabs {
    display: flex; align-items: stretch; gap: 18px; padding: 0 20px;
    border-bottom: 1px solid var(--hg-border-chrome); background: var(--hg-surface-base);
    height: 32px; overflow-x: auto; overflow-y: hidden; flex-shrink: 0;
  }
  .subtab {
    display: inline-flex; align-items: center;
    padding: 0; font-size: var(--hg-type-11); color: var(--hg-text-label); cursor: pointer;
    border: none; border-bottom: 2px solid transparent; border-radius: 0;
    white-space: nowrap; background: transparent;
    transition: color .12s, border-color .12s;
  }
  .subtab:hover { color: var(--hg-text-ink); }
  .subtab.on { color: var(--hg-text-ink); border-bottom-color: var(--hg-accent); font-weight: 500; }
  .subview { display: none; }
  .subview.on { display: block; }

  /* Centralized glass tokens. Use these, don't sprinkle literals. */
  :root {
    --hg-frost-ink: #17181c;  /* frost tint base — the ink that color-mix diffuses. Change here to retune all frost. */
    --hg-frost-bg: color-mix(in srgb, var(--hg-frost-ink) 4%, transparent);
    --hg-frost-head: color-mix(in srgb, var(--hg-surface-tabs) 6%, transparent);   /* ONE control: all table + panel headers — opacity tint of the tabs shade */
    --hg-frost-blur: 16px;
    --hg-frost-blur-soft: 8px;
    --hg-frost-head-shadow: 0 1px 3px rgba(15, 23, 42, 0.15);
    --hg-frost-hover: color-mix(in srgb, var(--hg-frost-head) 50%, transparent);   /* row highlight: same color as header, half opacity */
  }
  html.dark {
    --hg-frost-ink: #e4e4e7;  /* frost tint base (dark) — the light ink that color-mix diffuses over dark surfaces. */
    --hg-frost-bg: color-mix(in srgb, var(--hg-frost-ink) 4%, transparent);
    --hg-frost-head: color-mix(in srgb, var(--hg-surface-tabs) 6%, transparent);   /* ONE control: all table + panel headers — opacity tint of the tabs shade */
    --hg-frost-head-shadow: 0 1px 3px rgba(0,0,0,0.45);
    /* text shadow twin — black at 0.20 is imperceptible on dark surfaces;
       same geometry, matched to the dark frost-head shadow strength */
    --hg-text-shadow: 0 1px 3px rgba(0,0,0,0.30);
    --hg-frost-hover: color-mix(in srgb, var(--hg-frost-head) 50%, transparent);   /* row highlight: same color as header, half opacity */
  }

  /* ===== 4. SURFACES — shared table (track + crew bones) ===== */
  table.track { width: 100%; border-collapse: separate; border-spacing: 0; background: transparent; }
  table.track th, #crewTable th {
    text-align: left; font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .07em;
    color: var(--hg-text-label); padding: 7px 10px; border-bottom: 1px solid var(--hg-border-chrome); background: var(--hg-frost-head);
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
    position: sticky; top: 0; z-index: 34;
  }
  /* Tracker headers: ONE token. Base rule above paints every th. No thead background. */
  #v-cs #crewTable thead, #v-it table.track thead, #v-ex table.track thead, #v-ast table.track thead, #v-cliInv table.track thead, #v-ctiInv table.track thead, #v-prl table.track thead, #v-rc table.track thead, .ov-scroll .cf-forecast-scroll table.track thead, table.track thead , .ov-scroll .cf-forecast-scroll table.track thead, #v-rec table.track thead {
    position: static; z-index: 34;
  }
  #v-cs #crewTable th, #v-it table.track th, #v-ex table.track th, #v-ast table.track th, #v-cliInv table.track th, #v-ctiInv table.track th, #v-prl table.track th, #v-rc table.track th, .ov-scroll .cf-forecast-scroll table.track th , .ov-scroll .cf-forecast-scroll table.track th, #v-rec table.track th {
    position: static;
  }
  /* Keep the header outside the scrolling row surface. The tbody is the
     viewport, so rows are clipped at the header's lower edge rather than
     being painted underneath its transparent frost. */
  #v-cs #crewTable, #v-it table.track, #v-ex table.track, #v-rc table.track, #v-cliInv table.track, #v-ctiInv table.track, #v-prl table.track, .ov-scroll .cf-forecast-scroll table.track, table.track , .ov-scroll .cf-forecast-scroll table.track, #v-rec table.track {
    display: table; width: max-content; min-width: 100%; table-layout: auto;
  }
  #v-cs #crewTable thead, #v-it table.track thead, #v-ex table.track thead, #v-rc table.track thead, #v-cliInv table.track thead, #v-ctiInv table.track thead, #v-prl table.track thead, .ov-scroll .cf-forecast-scroll table.track thead, table.track thead , .ov-scroll .cf-forecast-scroll table.track thead, #v-rec table.track thead { display: table-header-group; }
  #v-cs #crewTable tbody, #v-it table.track tbody, #v-ex table.track tbody, #v-rc table.track tbody, #v-cliInv table.track tbody, #v-ctiInv table.track tbody, #v-prl table.track tbody, .ov-scroll .cf-forecast-scroll table.track tbody, table.track tbody , .ov-scroll .cf-forecast-scroll table.track tbody, #v-rec table.track tbody { display: table-row-group; }
  #v-cs #crewTable tbody tr, #v-it table.track tbody tr, #v-ex table.track tbody tr, #v-rc table.track tbody tr, #v-cliInv table.track tbody tr, #v-ctiInv table.track tbody tr, #v-prl table.track tbody tr, .ov-scroll .cf-forecast-scroll table.track tbody tr, table.track tbody tr , .ov-scroll .cf-forecast-scroll table.track tbody tr, #v-rec table.track tbody tr { display: table-row; }
  /* The table IS the frosted panel: translucent background + blur only inside
     the table bounds. The scroll root stays transparent with no blur so empty
     gutters and space below the sheet stay clear. */
  #v-cs .cs-scroll, #v-it .it-scroll, #v-ex .exp-scroll, #v-ast .ast-scroll, #v-cliInv .cli-inv-scroll, #v-ctiInv .cti-inv-scroll, #v-prl .prl-scroll, #v-rc .rc-scroll, .ov-scroll .cf-forecast-scroll, .ov-scroll .cf-forecast-scroll, #v-rec .rec-scroll { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
  #v-cs #crewTable, #v-it table.track, #v-ex table.track, #v-ast table.track, #v-cliInv table.track, #v-ctiInv table.track, #v-prl table.track, #v-rc table.track, .ov-scroll .cf-forecast-scroll table.track, table.track , .ov-scroll .cf-forecast-scroll table.track, #v-rec table.track { background: transparent; }
  #v-cs #crewTable tbody, #v-it table.track tbody, #v-ex table.track tbody, #v-ast table.track tbody, #v-cliInv table.track tbody, #v-ctiInv table.track tbody, #v-prl table.track tbody, #v-rc table.track tbody, .ov-scroll .cf-forecast-scroll table.track tbody, table.track tbody , .ov-scroll .cf-forecast-scroll table.track tbody, #v-rec table.track tbody {
    background: var(--hg-frost-bg); background-clip: padding-box;
    backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  }
  /* Sheet corners: border-radius is INERT on tbody in Chromium — the old
     `border-radius: 0 0 4px 4px` above never rendered (pixel-probed
     2026-09-07). The radius must sit on the corner CELLS to clip the wash.
     Top corners are the header row's th — in a real thead (static tables)
     or as the first tbody tr (factory + Crew render the header inside the
     tbody). Bottom corners are the last row's outermost cells. Geometry is
     theme-independent: one rule set serves light + dark. */
  table.track > thead th:first-child, #crewTable > thead th:first-child,
  table.track > tbody > tr:first-child > th:first-child, #crewTable > tbody > tr:first-child > th:first-child { border-top-left-radius: 4px; }
  table.track > thead th:last-child, #crewTable > thead th:last-child,
  table.track > tbody > tr:first-child > th:last-child, #crewTable > tbody > tr:first-child > th:last-child { border-top-right-radius: 4px; }
  table.track > tbody > tr:last-child > td:first-child, #crewTable > tbody > tr:last-child > td:first-child { border-bottom-left-radius: 4px; }
  table.track > tbody > tr:last-child > td:last-child, #crewTable > tbody > tr:last-child > td:last-child { border-bottom-right-radius: 4px; }
  table.track td, #crewTable td { padding: 5px 10px; border-bottom: 1px solid var(--hg-border-cell); }
  /* Row highlight: same ONE token as the header (--hg-frost-head). */
  #v-cs #crewTable tbody tr:hover td,
  #v-it table.track tbody tr:hover td,
  #v-ex table.track tbody tr:hover td,
  #v-rc table.track tbody tr:hover td,
  #v-cliInv table.track tbody tr:hover td,
  #v-ctiInv table.track tbody tr:hover td, #v-prl table.track tbody tr:hover td,
  .ov-scroll .cf-forecast-scroll table.track tbody tr:hover td, table.track tbody tr:hover td , .ov-scroll .cf-forecast-scroll table.track tbody tr:hover td, #v-rec table.track tbody tr:hover td {
    background: var(--hg-frost-hover);
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  }
  .st { font-size: var(--hg-type-micro); padding: 1px 8px; border-radius: 3px; white-space: nowrap; }
  .st-ip { background: var(--st-ip-bg); color: var(--st-ip-ink); }
  .st-wtg { background: var(--st-wtg-bg); color: var(--st-wtg-ink); }
  .st-rev { background: var(--st-rev-bg); color: var(--st-rev-ink); }
  .st-cmpt, .st-appr { background: var(--st-cmpt-bg); color: var(--hg-text-ink); }
  .st-reopen { background: var(--st-reopen-bg); color: var(--hg-danger-hover); }
  /* clickable status-select: looks like a pill but opens a dropdown */
  select.st-select {
    font-size: var(--hg-type-micro); padding: 1px 16px 1px 8px; border-radius: 3px; white-space: nowrap;
    border: 1px solid transparent; cursor: pointer; outline: none;
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpath fill='currentColor' opacity='0.5' d='M0 0l4 5 4-5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 4px center;
    transition: border-color 0.15s;
  }
  select.st-select:hover { border-color: #00000022; }
  select.st-select:focus { border-color: var(--hg-accent); }
  select.st-select.st-ip { background-color: var(--st-ip-bg); color: var(--st-ip-ink); }
  select.st-select.st-wtg { background-color: var(--st-wtg-bg); color: var(--st-wtg-ink); }
  select.st-select.st-rev { background-color: var(--st-rev-bg); color: var(--st-rev-ink); }
  select.st-select.st-cmpt, select.st-select.st-appr { background-color: var(--st-cmpt-bg); color: var(--hg-text-ink); }
  select.st-select.st-reopen { background-color: var(--st-reopen-bg); color: var(--hg-danger-hover); }
  .linked { color: var(--hg-text-ink); font-weight: 600; cursor: pointer; }
  .linked:hover { text-decoration: underline; }
  .badge-seed { font-size: var(--hg-type-9); color: var(--hg-text-dim); }
  .shot-grp td { background: #f4f4f4; font-weight: 600; font-size: var(--hg-type-small); letter-spacing: .02em; color: #6a6a72; padding: 6px 10px; }
  .mine { outline: 2px solid #2e9e5b44; outline-offset: -2px; background: #f4faf6 !important; }

  /* ===== 4a. tracker table segment edge (vars from §1) ===== */
  /* data-seg rows get the lightest tint as a subtle left-edge + background wash */
  table.track tr[data-seg] td { background: color-mix(in srgb, var(--seg-accent) var(--hg-stage-op), transparent); border-left: 3px solid var(--seg-accent); }
  table.track tr[data-seg] td:first-child { border-left: 3px solid var(--seg-accent); }
  table.track tr[data-seg]:hover td { background: color-mix(in srgb, var(--seg-accent) var(--hg-stage-op-h), transparent); }

  /* ===== 4b. bid table ===== */
  /* Full width; 20px breathing room left/right inside every scroll root so
     content never touches the scrollbar gutter or the window edge. The root
     itself fills the view so its scrollbar rides the window's right edge.
     NO top padding: sticky children (hg-lane, table headers) pin at top:0 of
     the scrollport, so a padding-top would leave them parked in an invisible
     gap below the filter bar instead of flush under it. */
  .bidwrap { width: 100%; box-sizing: border-box; padding: 0 20px 60px; }
  .summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin-bottom: 28px; border-top: 1px solid var(--hg-border-row); border-bottom: 1px solid var(--hg-border-row); }
  .sum-card { background: transparent; border: none; border-right: 1px solid var(--hg-border-row); border-radius: 0; padding: 16px 18px 14px; }
  .sum-card:last-child { border-right: none; }
  .sum-card .l { font-size: var(--hg-type-small); color: var(--hg-text-muted); letter-spacing: .02em; margin-bottom: 6px; text-transform: none; }
  .sum-card .v { font-size: var(--hg-type-display); font-weight: 600; letter-spacing: -.02em; margin-top: 0; font-variant-numeric: tabular-nums; }
  .sum-card .s { font-size: var(--hg-type-11); color: var(--hg-text-muted); margin-top: 3px; }
  .sum-card.total { background: transparent; border-color: var(--hg-border-row); }
  .sum-card.total .l, .sum-card.total .s { color: var(--hg-text-muted); }
  .sum-card.total .v { color: var(--hg-accent); }
  table.bid { width: 100%; border-collapse: collapse; background: var(--hg-surface-input); }
  table.bid .dept td { background: #f4f4f4; font-weight: 600; font-size: var(--hg-type-11); letter-spacing: .02em; color: #6a6a72; padding: 7px 10px; border-top: 1px solid var(--hg-border-row); }
  table.bid .dept td .tots { float: right; font-weight: 600; color: var(--hg-text-ink); letter-spacing: 0; }
  table.bid td { padding: 4px 10px; border-bottom: 1px solid #f0f0f0; }
  table.bid tr.line:hover td { background: #f6f6f6; }
  .c-name { width: 40%; } .c-stage { width: 28%; color: var(--hg-text-secondary); }
  .c-days { width: 10%; text-align: right; font-variant-numeric: tabular-nums; }
  .c-plan { width: 12%; text-align: right; font-variant-numeric: tabular-nums; color: var(--hg-text-secondary); }
  .c-src { width: 10%; text-align: right; }
  table.bid .subtotal td { background: var(--hg-surface-raised); font-weight: 600; border-top: 1px solid var(--hg-border-row); font-variant-numeric: tabular-nums; }
  table.bid .grand td { background: var(--hg-accent); color: var(--hg-text-on-accent); font-weight: 700; padding: 8px 10px; }
  .src { font-size: var(--hg-type-10); padding: 1px 7px; border-radius: 3px; }
  .src-agent { background: #e2ecf7; color: #2a5a8a; }
  .src-human { background: #eee9dc; color: #7a6f4d; }
  .src-delta { background: #f6e2d0; color: #b05a1e; }
  .delta td { background: #fdf3ec; } .delta .c-name { color: #b05a1e; }
  td.editable { cursor: text; } td.editable:hover { background: var(--hg-surface-elevated); }
  td.editing { background: #fff8e6; outline: 2px solid #d9b345; outline-offset: -2px; }
  .add-line { width: 100%; text-align: left; border: none; background: none; cursor: pointer; color: var(--hg-text-muted); font-size: var(--hg-type-11); padding: 5px 10px; border-bottom: 1px solid #f0f0f0; }
  .add-line:hover { color: var(--hg-text-ink); background: #faf8f0; }
  .toast { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); background: var(--hg-accent); color: var(--hg-text-on-accent); padding: 8px 18px; border-radius: 3px; font-size: var(--hg-type-base); display: none; z-index: 90; }

  /* ===== 4c. breakdown — hg-entity-block tree + filters + modal ===== */
  .btn-new {
  border: 1px solid color-mix(in srgb, var(--seg-accent) 45%, rgba(255,255,255,.3)); background: color-mix(in srgb, var(--seg-accent) 25%, transparent); color: var(--hg-text-ink);
  border-radius: 4px; padding: 4px 13px; font-size: var(--hg-type-small); font-weight: 500;
  letter-spacing: .03em; text-transform: uppercase; cursor: pointer;
}
.btn-new:hover { background: color-mix(in srgb, var(--seg-accent) 35%, transparent); }
.btn-new:active { box-shadow: inset 0 1px 3px #00000018; transform: translateY(1px); }
.btn-new.hg-confirm-danger { background: var(--hg-danger); border-color: var(--hg-danger); color: var(--hg-text-on-accent); }
.btn-new.hg-confirm-danger:hover { background: var(--hg-danger-hover); }
  .btn-ghost {
  border: 1px solid color-mix(in srgb, var(--seg-accent) 45%, rgba(255,255,255,.3)); background: color-mix(in srgb, var(--seg-accent) 25%, transparent);
  border-radius: 4px; padding: 4px 13px; font-size: var(--hg-type-small); font-weight: 500;
  letter-spacing: .03em; text-transform: uppercase; cursor: pointer; color: var(--hg-text-ink);
}
.btn-ghost:hover { background: color-mix(in srgb, var(--seg-accent) 35%, transparent); border-color: color-mix(in srgb, var(--seg-accent) 55%, rgba(255,255,255,.3)); color: var(--hg-text-ink); }
.btn-ghost:active { box-shadow: inset 0 1px 3px #00000018; transform: translateY(1px); }
  .seg-block { margin-bottom: 14px; }
  /* Sticky within the Breakdown panel's scroll root (.bidwrap): the open
     segment's header parks at the top while its card list scrolls — always
     reachable to roll the segment back up. Same rule as table.track th
     inside their scrollers. Gantt rows are NOT sticky (the base .hg-lane
     above is static); the gantt label pane re-declares its own parking. */
  .hg-lane {
      display: grid; grid-template-columns: 18px auto minmax(160px, 1fr) 118px auto;
      align-items: baseline; column-gap: 12px; padding: 6px 0;
      /* position: static in the GANTT chart pane — the lane-side rows must
         scroll away with the chart (the week header band is the only sticky
         thing there). The Breakdown panel's sticky parking is scoped to
         .seg-block .hg-lane below; the gantt label pane re-scopes its own. */
      position: static; z-index: auto;
      /* Opaque page base first — wash alone is translucent and list rows would bleed */
      background: var(--hg-frost-head); border: none; border-radius: 0; cursor: pointer; user-select: none;
      font-weight: 600; font-size: var(--hg-type-medium); letter-spacing: -.01em; color: var(--hg-text-ink); margin-bottom: 0;
      box-shadow: var(--hg-shadow-sm);
      /* hover-lift: slow decay back to rest on mouseleave (the base transition
         wins when :hover drops). Entry timing is on the :hover rule below. */
      transition: transform .25s cubic-bezier(.22,1,.36,1), filter .25s cubic-bezier(.22,1,.36,1);
    }
    .hg-lane:hover {
      box-shadow: 0 4px 8px rgba(15,23,42,.10),
                  0 -4px 8px color-mix(in srgb, var(--seg-accent) var(--hg-lane-op-h), transparent);
      /* box-shadow, not filter: these rows carry backdrop-filter, and toggling
         `filter` on a backdrop-filtered element forces Chromium to rebuild the
         compositing layer — that rebuild is the flash (founder report). */
      transition: box-shadow .06s ease-out;
    }
    .hg-lane:active {
      transition: box-shadow .06s ease-out;
    }
    .seg-block .hg-lane {
      position: sticky; top: 0; z-index: 33;
  }
  .hg-lane .tw { width: 14px; color: var(--hg-text-muted); font-size: var(--hg-type-11); transition: transform .12s; }
    .seg-block.open > .hg-lane .tw { transform: rotate(90deg); }
    /* inline rename — shrinks to fit text content so only the actual characters
       are clickable; clicks on the surrounding header open the hg-stage. */
    .hg-lane .seg-name-input {
    min-width: 0; max-width: 200px; font: inherit; font-weight: 600; color: inherit; letter-spacing: inherit;
    background: transparent; border: 1px solid transparent; border-radius: 3px; box-sizing: border-box;
    padding: 0; margin: -1px 0 0 -5px; cursor: text;
    }
    .hg-lane .seg-name-input, .hg-lane .seg-name-input:focus, .hg-lane .seg-name-input:hover { background: transparent; }
    .hg-lane .seg-name-input:hover { border-color: #c8ccd5; }
    .hg-lane .seg-name-input:focus { border-color: #c5c9d1; outline: none; }
    /* Action clusters: ONE control (.mv-btn / .danger), ONE wrapper (.row-actions),
       ONE number (--row-actions-gap) for every distance in the cluster. */
    :root { --row-actions-gap: 5px; }
    .row-actions { display: inline-flex; gap: var(--row-actions-gap); padding-right: var(--row-actions-gap); align-self: center; }
  .mv-btn {
    border: none; background: none; cursor: pointer; font-size: var(--hg-type-base); line-height: 1;
    padding: 2px 0; color: var(--hg-text-muted);
  }
  .mv-btn:hover { color: var(--hg-text-ink); }
  html.dark .mv-btn { color: var(--hg-text-muted); }
  html.dark .mv-btn:hover { color: var(--hg-text-bright); }
  .mv-btn.danger:hover { color: var(--hg-danger-ink); }
  html.dark .mv-btn.danger:hover { color: var(--hg-danger-ink); }
  .hg-lane .seg-meta { justify-self: start; font-weight: 600; color: var(--hg-text-ink); font-variant-numeric: tabular-nums; font-size: var(--hg-type-base); letter-spacing: 0; white-space: nowrap; }
  .hg-lane .seg-hint { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 400; color: var(--hg-text-muted); font-size: var(--hg-type-11); letter-spacing: 0; justify-self: end; text-align: right; }
  .seg-body { display: none; padding-left: 16px; }
  /* Bottom "+ New" row inside each hg-stage — keeps empty lanes from being bare
     and puts the add button where new items will append. Uses .btn-new so
     it inherits the same gold-accent style as "+ Add crew" in the Crew tab. */
  .seg-new-row { padding: 8px 0 4px; }
  .seg-new-bottom { font-size: var(--hg-type-10); padding: 3px 11px; }
  /* segment management footer — add button + hidden restore tray */
  .seg-footer { margin-top: 10px; padding-left: 30px; display: flex; flex-direction: column; gap: 6px; }
  .seg-footer-row { display: flex; align-items: baseline; width: 100%; }
  .seg-footer-row .seg-footer-right { margin-left: auto; display: inline-flex; gap: 14px; }
  .seg-tmpl { border: none; background: none; cursor: pointer; color: var(--hg-text-muted); font-size: var(--hg-type-11); padding: 2px 0; }
  .seg-tmpl:hover { color: var(--hg-text-ink); }
  .seg-hidden-toggle { border: none; background: none; cursor: pointer; color: var(--hg-text-muted); font-size: var(--hg-type-11); padding: 2px 0; }
  .seg-hidden-toggle:hover { color: var(--hg-text-ink); }
  .seg-hidden-list { display: flex; flex-direction: column; gap: 2px; padding-left: 8px; }
  .seg-hidden-row { display: flex; align-items: center; gap: 8px; font-size: var(--hg-type-base); color: #6f7076; }
  .seg-hidden-row .sw { font-size: var(--hg-type-9); }
  .seg-hidden-row .seg-restore { border: 1px solid var(--hg-border-control); background: var(--hg-surface-input); border-radius: 4px; font-size: var(--hg-type-11); padding: 1px 8px; cursor: pointer; color: var(--hg-text-ink); }
  .seg-hidden-row .seg-restore:hover { border-color: var(--hg-border-hover); color: var(--hg-text-ink); }
  .seg-hidden-row .seg-delete { border: 1px solid #e0b3ad; background: var(--hg-surface-input); border-radius: 4px; font-size: var(--hg-type-11); padding: 1px 8px; cursor: pointer; color: var(--hg-danger-hover); }
  .seg-hidden-row .seg-delete:hover { border-color: var(--hg-danger); color: var(--hg-danger); }
  .seg-block.open > .seg-body { display: block; }
  .hg-entity-block { background: transparent; border: none; border-bottom: 1px solid #efefef; border-radius: 0; margin-bottom: 0; overflow: visible; }
  .hg-entity { display: flex; align-items: center; gap: 10px; padding: 7px 0; cursor: pointer; user-select: none;
    transition: transform .25s cubic-bezier(.22,1,.36,1), filter .25s cubic-bezier(.22,1,.36,1), background .06s ease-out; }
  .hg-entity:hover { background: color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent);
    box-shadow: 0 3px 6px rgba(15,23,42,.08),
                0 -3px 6px color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent);
    transition: box-shadow .06s ease-out, background .06s ease-out; }
  .hg-entity:active {
    transition: box-shadow .06s ease-out;
  }
  .hg-entity .tw { width: 14px; color: var(--hg-text-muted); font-size: var(--hg-type-11); transition: transform .12s; }
  .hg-entity-block.open .hg-entity .tw { transform: rotate(90deg); }
  .hg-entity .a-name { font-weight: 500; font-size: var(--hg-type-12h); }
  .hg-entity .a-name-input {
    font: inherit; font-weight: 500; font-size: var(--hg-type-12h);
    color: inherit; background: transparent; border: 1px solid transparent;
    border-radius: 4px; padding: 1px 4px; margin: -1px -4px;
    min-width: 60px; width: auto;
  }
  .hg-entity .a-name-input:hover { border-color: var(--hg-border-control); background: var(--hg-surface-input); }
  .hg-entity .a-name-input:focus { border-color: var(--hg-accent); background: var(--hg-surface-input); outline: none; }
  html.dark .hg-entity .a-name-input { color: inherit; background: transparent; border-color: transparent; }
  html.dark .hg-entity .a-name-input:hover { border-color: var(--hg-border-control); background: var(--hg-surface-raised); }
  html.dark .hg-entity .a-name-input:focus { border-color: var(--hg-border-focus); background: var(--hg-surface-raised); }
  .hg-entity .a-type { font-size: var(--hg-type-small); color: var(--hg-text-muted); background: transparent; padding: 0; border-radius: 0; }
  .hg-entity .a-owner { margin-left: auto; margin-right: 15px; display: flex; align-items: center; }
  .hg-entity .a-owner-label { font-size: var(--hg-type-10); color: var(--hg-text-muted); margin-right: 6px; }
  .hg-entity .a-days { font-weight: 600; color: var(--hg-text-ink); font-variant-numeric: tabular-nums; }
  .hg-entity .a-dup { font-size: var(--hg-type-11); font-weight: 700; border-radius: 3px; }
  .hg-entity .a-copy, .hg-entity .a-paste { display: inline-flex; align-items: center; border-radius: 4px; }
  .hg-entity .a-copy svg, .hg-entity .a-paste svg { width: 13px; height: 13px; display: block; }
  .hg-entity .a-paste.empty { color: var(--hg-text-muted); cursor: default; }
  .hg-entity .a-dup:hover { color: var(--hg-text-ink); background: transparent; }
  .hg-entity .a-copy:hover { color: var(--hg-text-ink); background: var(--hg-surface-raised); }
  .hg-entity .a-paste:hover:not(.empty) { color: var(--hg-text-ink); background: var(--hg-surface-raised); }
  .hg-entity-body { display: none; border-top: 1px solid #efefef; padding: 4px 0 8px 8px; margin-left: 16px; background: var(--seg-edge), color-mix(in srgb, var(--seg-accent) var(--hg-stage-op), transparent); }
  .hg-entity-block.open .hg-entity-body {
    display: grid;
    /* THE shared column tracks: every stage row + the totals row align to these. */
    grid-template-columns: 180px 100px minmax(120px,1fr) 120px auto auto auto auto;
    gap: 0 10px;
  }
  .hg-entity-body > * { grid-column: 1 / -1; min-width: 0; }
  /* number input spinner arrows — kill globally (Chrome/Safari/Firefox) */
  input[type=number]::-webkit-outer-spin-button,
  input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
  input[type=number] { -moz-appearance: textfield; appearance: textfield; }

  #assetTree .hg-stage { display: grid; grid-template-columns: subgrid; gap: 10px; align-items: center; padding: 4px 0; border-bottom: 1px solid #f4f4f4; justify-content: start; }
  .crew-pick { border: 1px solid var(--hg-border-control); border-radius: 4px; font-size: var(--hg-type-11); height: 22px; box-sizing: border-box; padding: 2px 6px; background-color: var(--hg-surface-input); color: var(--hg-text-ink); width: 120px; }
  .crew-pick.un { color: var(--hg-danger-ink); border-color: #e3b8ae; background: #fdf3ec; }
  .crew-pick.inherited { color: var(--hg-text-dim); font-style: italic; border-color: var(--hg-border-control); background: #fafafb; }
  .owner-pick { border: 1px solid var(--hg-border-control); border-radius: 4px; font-size: var(--hg-type-11); height: 22px; box-sizing: border-box; padding: 2px 6px; background-color: var(--hg-surface-input); color: var(--hg-text-ink); width: 120px; }
  .owner-pick.un { color: var(--hg-text-muted); border-color: #e8e8ec; background: #fafafb; }
  #assetTree .hg-stage .cost-model-pick { font-size: var(--hg-type-11); height: 22px; box-sizing: border-box; max-width: 96px; min-width: 0; padding: 2px 16px 2px 6px; }
  #assetTree .hg-stage .t-model { display: flex; align-items: center; gap: 6px; min-width: 0; }
  #assetTree .hg-stage .t-crew { display: flex; align-items: center; gap: 4px; min-width: 0; }
  #assetTree .hg-stage .t-model-inputs { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
  #assetTree .hg-stage .t-note { min-width: 0; align-self: start; padding-top: 1px; }
  #assetTree .hg-stage .t-note-input { box-sizing: border-box; width: 100%; min-height: 22px; font-size: var(--hg-type-11); line-height: 1.4; border: 1px solid transparent; border-radius: 4px; padding: 2px 6px; background: var(--hg-input-bg); color: var(--hg-text-secondary); resize: none; overflow: hidden; font-family: inherit; }
  #assetTree .hg-stage .t-note-input::placeholder { color: #c4c4cc; }
  #assetTree .hg-stage .t-note-input:hover { border-color: var(--hg-border-control); }
  #assetTree .hg-stage .t-note-input:focus { outline: none; border-color: var(--hg-border-focus); color: var(--hg-text-ink); }
  #assetTree .hg-stage .t-model-inputs input { box-sizing: border-box; width: 60px; min-width: 0; height: 22px; text-align: right; font-size: var(--hg-type-11); font-weight: 500; font-variant-numeric: tabular-nums; border: 1px solid var(--hg-border-control); border-radius: 4px; padding: 2px 6px; background: var(--hg-surface-input); color: var(--hg-text-ink); -webkit-appearance: none; -moz-appearance: textfield; appearance: none; }
  #assetTree .hg-stage .t-model-inputs input:focus { outline: none; border-color: var(--hg-border-focus); }
  #assetTree .hg-stage .t-model-inputs input.t-cost-fixed { width: 90px; }
  /* formula model: pen (edit) icon on the dropdown row + inline input cells */
  .f-edit-pen { border: none; background: transparent; cursor: pointer; font-size: var(--hg-type-11);
    color: var(--hg-text-secondary); padding: 2px 4px; line-height: 1; border-radius: 3px; }
  .f-edit-pen:hover { background: var(--hg-surface-raised); color: var(--hg-text-ink); }
  /* formula popup editor (2-row strip) */
  .fx-strip { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 4px; margin: 10px 0 4px; }
  .fx-cell { display: inline-flex; flex-direction: column; gap: 2px; }
  /* ONE shared input-control definition (border/bg/type/focus/hover-state) — every per-surface variant below only restates box shape (width/height/padding). Add `.hg-ctl` to the markup. */
  .hg-ctl { box-sizing: border-box; font-size: var(--hg-type-11); border: 1px solid var(--hg-border-control); border-radius: 4px; background-color: var(--hg-input-bg); color: var(--hg-input-ink); }
  input[type="time"].hg-ctl { width: 82px; min-height: 22px; padding: 1px 6px; font: inherit; }
  .hg-ctl:focus { outline: none; border-color: var(--hg-border-focus); }
  .hg-ctl.hollow { border-color: transparent; border-radius: 3px; background: transparent; color: var(--hg-text-muted); }
  .hg-ctl.hollow:hover { border-color: var(--hg-border-control); background: var(--hg-surface-input); }
  .hg-ctl.hollow:focus { outline: none; border-color: var(--hg-border-focus); background: var(--hg-surface-input); color: var(--hg-text-ink); }
  .fx-cell input.fx-val { width: 74px; height: 24px; text-align: right;
    font-variant-numeric: tabular-nums; font-weight: 500;
    padding: 2px 6px; }
  .fx-cell input.fx-lab { width: 74px; height: 18px; font-size: var(--hg-type-tiny);
    padding: 1px 5px; }
  .fx-typerow { display: inline-flex; align-items: center; gap: 2px; }
  .fx-type { font-size: var(--hg-type-tiny); height: 16px; box-sizing: border-box; padding: 0 14px 0 5px;
    color: var(--hg-text-muted); }
  .fx-type:hover { border-color: var(--hg-border-control); background: var(--hg-surface-input); }
  .fx-cell.fx-bind .fx-type { width: 120px; }
  .fx-cell.fx-bind .fx-val { width: 120px; text-align: left; color: var(--hg-info); }
  .fx-cell.fx-bind .fx-val.un { color: var(--hg-danger-ink); }
  .fx-cell.fx-bind input.fx-lab { width: 120px; }
  .fx-op { border: 1px solid var(--hg-border-control); background: var(--hg-surface-raised); border-radius: 4px;
    height: 24px; width: 24px; box-sizing: border-box; font-size: var(--hg-type-12h); color: var(--hg-text-secondary);
    cursor: pointer; user-select: none; }
  .fx-op:hover { color: var(--hg-text-ink); background: var(--hg-surface-raised); }
  .fx-del { border: none; background: transparent; cursor: pointer; color: var(--hg-text-dim);
    font-size: var(--hg-type-11); padding: 0 2px; height: 24px; }
  .fx-del:hover { color: var(--hg-danger-ink); }
  .fx-add { border: 1px dashed var(--hg-border-control); background: transparent; border-radius: 4px;
    height: 24px; min-width: 24px; box-sizing: border-box; color: var(--hg-text-secondary); cursor: pointer;
    font-size: var(--hg-type-12h); }
  .fx-add:hover { color: var(--hg-text-ink); background: var(--hg-surface-raised); }
  .fx-result { margin-left: auto; display: inline-flex; align-items: baseline; gap: 5px;
    font-variant-numeric: tabular-nums; font-weight: 600; font-size: var(--hg-type-12h); color: var(--hg-text-bright); }
  .fx-result .fx-cur { color: var(--hg-text-dim); font-weight: 400; }
  .fx-result.fx-invalid { color: var(--hg-danger-ink); font-weight: 500; }
  .fx-bind-pattern { margin-top: 2px; }
  .fx-bind-pattern input { width: 120px; height: 18px; font-size: var(--hg-type-tiny);
    padding: 1px 5px; }
  .t-spinner { display: flex; align-items: center; gap: 0; }
  .t-spinner .sp { border: 1px solid var(--hg-border-control); background: var(--hg-surface-raised); width: 26px; height: 22px; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: var(--hg-type-base); color: var(--hg-text-secondary); user-select: none; }
  .t-spinner .sp:hover { background: var(--hg-surface-raised); }
  .t-spinner .sp:first-child { border-radius: 4px 0 0 4px; border-right: none; }
  .t-spinner .sp:last-child { border-radius: 0 4px 4px 0; border-left: none; }
  .t-spinner .t-days { border-top: 1px solid var(--hg-border-control); border-bottom: 1px solid var(--hg-border-control); width: 30px; height: 22px; box-sizing: border-box; text-align: center; font-size: var(--hg-type-11); line-height: 20px; padding: 0; font-variant-numeric: tabular-nums; cursor: text; }
  .t-spinner .t-days.last-bar { width: 52px; }
  .t-cost { text-align: right; font-variant-numeric: tabular-nums; color: var(--hg-text-ink); font-weight: 600; font-size: var(--hg-type-11); }
  .t-cost.t1-badge { position: relative; }
  .t-cost.t1-badge::after { content: 'T1'; position: absolute; top: -6px; right: -4px; font-size: var(--hg-type-tiny); color: var(--st-rev-ink); font-weight: 400; }
  #assetTree .hg-stage .t-cost { display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; white-space: nowrap; min-width: 0; }
  #assetTree .hg-stage .t-cost .t-cur { color: var(--hg-text-dim); font-weight: 400; font-size: var(--hg-type-11); }
  #assetTree .hg-stage .t-cost input { box-sizing: border-box; width: 68px; min-width: 0; height: 22px; text-align: right; font-size: var(--hg-type-11); font-weight: 500; font-variant-numeric: tabular-nums; border: 1px solid var(--hg-border-control); border-radius: 4px; padding: 2px 6px; background: var(--hg-surface-input); color: var(--hg-text-ink); -webkit-appearance: none; -moz-appearance: textfield; appearance: none; }
  #assetTree .hg-stage .t-cost input.t-cost-fixed { width: 90px; }
  #assetTree .hg-stage .t-cost input:focus { outline: none; border-color: var(--hg-border-focus); }
  #assetTree .hg-stage .t-cost .t-cost-x { color: var(--hg-text-dim); font-weight: 400; }
  .card-actions-row { display: grid; grid-template-columns: subgrid; gap: 10px; align-items: center; padding-top: 6px; border-top: 1px solid var(--hg-border-row); }
  .card-actions-row > button { justify-self: start; }
  /* Totals row flattened into the shared tracks: Total=col5, days=col6, cost=col7.
     The row emits ONLY the three visible cells (acr-lab/acr-days/t-cost) —
     no placeholder spans hidden by ordinal. */
  .asset-cost-row { display: contents; font-weight: 600; font-size: var(--hg-type-11); }
  .asset-cost-row > .acr-lab { grid-column: 5; text-align: right; color: var(--hg-text-secondary); }
  .asset-cost-row > .acr-days { grid-column: 6; text-align: center; font-variant-numeric: tabular-nums; }
  .asset-cost-row > span.t-cost { grid-column: 7; }

  /* Narrow viewport: split each stage row into two lines — stage+note on top,
     controls wrap below right-aligned under the note. The asset-cost-row is
     display:contents and has no box of its own, so it is not flexed here;
     its three cells inherit the subgrid which stacks naturally at this width. */
  @media (max-width: 960px) {
    #assetTree .hg-stage {
      display: flex; flex-wrap: wrap; align-items: center;
      justify-content: flex-start; gap: 6px 10px;
    }
    #assetTree .hg-stage > .t-stage { order: -2; }
    #assetTree .hg-stage > .t-tags { order: -2; }
    #assetTree .hg-stage > .t-note {
      order: -1; flex: 1 1 100%; min-width: 120px;
    }
    /* Totals row was contents+subgrid tracks (too wide here) — collapse to a
       single right-aligned flex line at narrow widths. */
    #assetTree .asset-cost-row { display: flex; justify-content: flex-end; gap: 10px; }
    #assetTree .asset-cost-row > .acr-lab { grid-column: auto; text-align: left; }
    #assetTree .asset-cost-row > .acr-days, #assetTree .asset-cost-row > span.t-cost { grid-column: auto; }
    #assetTree .hg-stage > .t-note-input { width: 100%; }
    .hg-stage > .t-crew { order: 0; margin-left: auto; }
    .hg-stage > .t-model { order: 0; }
    .hg-stage > .t-spinner { order: 0; }
    #assetTree .hg-stage > .t-cost, #assetTree .asset-cost-row > .t-cost { order: 0; }
    .hg-stage > .row-actions { order: 1; }
  }
  .master-totals { margin-top: 14px; background: transparent; border: 1px solid var(--hg-border-row); border-radius: 4px; padding: 12px 14px; }
  .master-totals h3 { font-size: var(--hg-type-base); text-transform: uppercase; letter-spacing: .06em; color: var(--hg-text-label); margin: 0 0 12px; }
  /* collapsible wire panels used in Breakdown tab */
  .wire-panel {
    transition: padding .15s ease; margin-bottom: 8px; position: relative; isolation: isolate;
  }
  .wire-panel::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background: var(--hg-frost-bg); border-radius: inherit;
    backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  }
  .wire-title {
    cursor: pointer; user-select: none;
    display: flex; justify-content: space-between; align-items: center;
    padding: 8px 12px; margin: -12px -14px 12px;
    background: var(--hg-surface-tabs); border-bottom: none; border-radius: 0;
    font-weight: 600; font-size: var(--hg-type-medium); letter-spacing: -.01em; color: var(--hg-text-ink);
    box-shadow: var(--hg-shadow-sm);
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  }
  .wire-title:hover { filter: none; color: var(--hg-text-ink); }
  /* Internal budget + Crew cost panels — frosted glass + hover-lift on title bar */
  #masterTotals .wire-title,
  #crewCost .wire-title,
  #v-cli .wire-title {
    background: var(--hg-surface-tabs);
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
    color: var(--hg-text-ink);
    transition: transform .25s cubic-bezier(.22,1,.36,1), filter .25s cubic-bezier(.22,1,.36,1);
  }
  #masterTotals .wire-title:hover,
  #crewCost .wire-title:hover,
  #v-cli .wire-title:hover {
    transform: translateY(-2px);
    filter: drop-shadow(0 4px 8px rgba(15,23,42,.10))
            drop-shadow(0 -4px 8px rgba(23,24,28,.08));
    transition: transform .06s ease-out, filter .06s ease-out;
  }
  #masterTotals .wire-title:active,
  #crewCost .wire-title:active,
  #v-cli .wire-title:active {
    transform: translateY(0); filter: none;
    transition: transform .06s ease-out, filter .06s ease-out;
  }
  #masterTotals .cs-del:hover,
  #v-cli .cs-del:hover { color: var(--hg-text-ink); }
  #masterTotals,
  #crewCost,
  #v-cli .master-totals {
    background: var(--hg-frost-bg);
  }
  .wire-body {
    backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  }
  .wire-caret { display: inline-block; transition: transform .15s ease; font-size: var(--hg-type-11); color: var(--hg-text-muted); margin-left: 8px; }
  .wire-panel.collapsed { padding: 0 14px; margin-bottom: 4px; }
  .wire-panel.collapsed .wire-title { margin: 0 -14px; padding: 8px 12px; border-bottom: none; }
  .wire-panel.collapsed .wire-caret { transform: rotate(-90deg); }
  .wire-panel.collapsed .wire-body { display: none; }
  /* project metadata form inside wire panels */
  .meta-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 24px; }
  .meta-section { display: flex; flex-direction: column; gap: 18px; }
  .meta-row { display: flex; align-items: center; gap: 10px; font-size: var(--hg-type-base); min-height: 26px; }
  .meta-label { flex: 0 0 240px; color: var(--hg-text-ink); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: var(--hg-type-10); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* box shape only — the styling vocabulary (border/bg/color/focus) is
     .hg-ctl's; add .hg-ctl to the markup. */
  .meta-input { flex: 1 1 auto; min-width: 0; padding: 4px 8px; }
  /* editable heading inside wire-title — BANNER exception to the unified
     fill: like the breakdown seg/entity/task rows, it's a title-bar element.
     Idle: invisible (transparent, follows the .wire-title bar it sits in).
     Selected: takes the unified field fill (--hg-input-bg). */
  .wire-heading-input {
    flex: 1 1 auto; border: 1px solid transparent; background: transparent;
    font-weight: 600; font-size: var(--hg-type-base); text-transform: uppercase; letter-spacing: .06em; color: inherit;
    padding: 2px 4px; border-radius: 4px; min-width: 0;
  }
  .wire-heading-input:hover { border-color: var(--hg-border-warm); }
  .wire-heading-input:focus {
    outline: none; border-color: var(--hg-border-hover);
    background: var(--hg-input-bg); /* selected = the unified field colour */
  }
  .wire-title-suffix { flex: 0 0 auto; font-weight: 600; font-size: var(--hg-type-medium); }
  /* textarea auto-growing field */
  .meta-textarea {
    resize: none; overflow: hidden; min-height: 22px; line-height: 1.4;
    font-family: inherit;
    margin-bottom: 12px;
  }
  /* add/remove field buttons */
  .meta-add-row {
    margin-top: 8px; font-size: var(--hg-type-11); padding: 4px 10px; opacity: .7;
  }
  .meta-add-row:hover { opacity: 1; }
  .meta-del { flex: 0 0 auto; margin-left: 4px; }
  .meta-panel-del { flex: 0 0 auto; margin-left: 2px; font-size: var(--hg-type-base); opacity: .5; }
  .meta-panel-del:hover { opacity: 1; }
  .meta-panel-reorder { flex: 0 0 auto; margin-left: 2px; font-size: var(--hg-type-base); opacity: .5; }
  .meta-panel-reorder:hover { opacity: 1; }
  .meta-panel-tpl { flex: 0 0 auto; margin-left: 2px; font-size: var(--hg-type-base); opacity: .5; }
  .meta-panel-tpl:hover { opacity: 1; }
  .meta-add-panel { margin-top: 12px; font-size: var(--hg-type-11); padding: 6px 12px; opacity: .7; }
  .meta-add-panel:hover { opacity: 1; }
  /* finance panel nested inside master-totals */
  .fp-cur-toggles { display: inline-flex; gap: 0; margin-left: 4px; }
  .cur-toggle { font-size: var(--hg-type-11); font-weight: 600; padding: 2px 7px; border: 1px solid var(--hg-border-warm); border-right: none; background: var(--hg-surface-input); color: var(--hg-text-ink); cursor: pointer; line-height: 1.3; }
  .cur-toggle:first-child { border-radius: 4px 0 0 4px; }
  .cur-toggle:last-child { border-radius: 0 4px 4px 0; border-right: 1px solid var(--hg-border-warm); }
  .cur-toggle.inactive { background: #f0eee9; color: #b8b4ab; }
  .cur-toggle:hover { background: #f5f3ef; }
  .hide-gbp .cur-gbp, .hide-usd .cur-usd, .hide-eur .cur-eur { display: none !important; }
  .fp-th-cur { font-size: var(--hg-type-base); margin-right: 4px; }
  .fp-th-rate { width: 60px; margin-top: 3px; }
  .fp-th-rate::-webkit-outer-spin-button,
  .fp-th-rate::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
  #msTable { border-collapse: separate; border-spacing: 4px 5px; width: 100%; }
  #msTable td { padding: 0; }
  #msTable th { padding: 0 0 4px 0; }
  #msTable td:first-child,
  #msTable th:first-child { padding-left: 0; }
  #msTable td:nth-child(6),
  #msTable th:nth-child(6) { width: 100%; }
  .fp-ms-amt { width: 80px; text-align: right; }
  .fp-ms-amt::-webkit-outer-spin-button,
  .fp-ms-amt::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
  .fp-ms-note { width: 100%; box-sizing: border-box; }
  #msTable td.num { text-align: right; }
  .fp-table { width: 100%; border-collapse: collapse; font-size: var(--hg-type-base); }
  .fp-table th { text-align: left; font-weight: 600; color: var(--hg-text-label); padding: 4px 6px; border-bottom: 1px solid var(--hg-border-row); }
  .fp-table th.num { text-align: right; }
  .fp-table td { padding: 5px 6px; border-bottom: 1px solid #f0f0f0; }
  .fp-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
  .fp-table tr.doc-total td { font-weight: 600; border-top: 1px solid var(--hg-border-row); border-bottom: none; }
  .fp-table tr.doc-total td.num { color: var(--hg-text-ink); }
  /* client budget grid: line name → note textarea → £/$/€ right-hugged
     Grid with fixed tracks so every row's columns line up exactly —
     same approach as meta-panel rows. */
  .fp-cb-grid { font-size: var(--hg-type-base); }
  .fp-cb-hdr, .fp-cb-row { display: grid; grid-template-columns: 140px 1fr 88px 88px 88px; align-items: center; gap: 10px; min-height: 26px; padding: 4px 0; border-bottom: 1px solid #f0f0f0; }
  .fp-cb-hdr { font-weight: 600; color: var(--hg-text-ink); font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .04em; border-bottom: 1px solid var(--hg-border-row); padding-bottom: 4px; }
  .fp-cb-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: var(--hg-type-10); }
  .fp-cb-note-spacer { }
  .fp-cb-note { resize: none; overflow: hidden; min-height: 22px; line-height: 1.4; font-family: inherit; box-sizing: border-box; width: 100%; }
  .fp-cb-amt { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 6px; }
  /* vertical hairlines between amount columns */
  .fp-cb-amt.cur-gbp, .fp-cb-amt.cur-usd { border-right: 1px solid var(--hg-border-row); }
  .fp-cb-hdr .fp-cb-amt.cur-gbp, .fp-cb-hdr .fp-cb-amt.cur-usd { border-right: 1px solid var(--hg-border-row); }
  .fp-cb-row.fp-cb-total { font-weight: 600; border-top: 1px solid var(--hg-border-row); border-bottom: none; padding-top: 5px; }
  .fp-cb-row.fp-cb-total .fp-cb-amt { color: var(--hg-text-ink); }
  /* currency toggle: collapse grid tracks when a currency is hidden */
  .hide-gbp .fp-cb-hdr, .hide-gbp .fp-cb-row { grid-template-columns: 140px 1fr 88px 88px; }
  .hide-usd .fp-cb-hdr, .hide-usd .fp-cb-row { grid-template-columns: 140px 1fr 88px 88px; }
  .hide-eur .fp-cb-hdr, .hide-eur .fp-cb-row { grid-template-columns: 140px 1fr 88px 88px; }
  .hide-gbp.hide-usd .fp-cb-hdr, .hide-gbp.hide-usd .fp-cb-row { grid-template-columns: 140px 1fr 88px; }
  .hide-gbp.hide-eur .fp-cb-hdr, .hide-gbp.hide-eur .fp-cb-row { grid-template-columns: 140px 1fr 88px; }
  .hide-usd.hide-eur .fp-cb-hdr, .hide-usd.hide-eur .fp-cb-row { grid-template-columns: 140px 1fr 88px; }
  .hide-gbp.hide-usd.hide-eur .fp-cb-hdr, .hide-gbp.hide-usd.hide-eur .fp-cb-row { grid-template-columns: 140px 1fr; }
  /* Internal budget = segment table; Crew cost is its own wire-panel beneath */
  .mt-seg { margin: 0 0 18px; }
  .mt-kpi b { color: var(--hg-text-ink); }
  .mt-table { width: 100%; border-collapse: collapse; font-size: var(--hg-type-base); }
  .mt-table th { text-align: left; font-weight: 600; font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .05em; color: var(--hg-text-dim); padding: 3px 0 4px; border-bottom: 1px solid var(--hg-border-row); }
  .mt-table th.num, .mt-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
  .mt-table td { padding: 3px 0; border-bottom: 1px solid #f0f0f0; color: var(--hg-text-secondary); }
  .mt-table tbody tr:last-child td { border-bottom: none; }
  .mt-table td.num { font-weight: 600; color: var(--hg-text-ink); }
  .mt-table tr.mt-total td { border-top: 1px solid var(--hg-border-row); border-bottom: none; font-weight: 700; color: var(--hg-text-ink); }
  /* extra breathing room above the totals wire: 8px = 3px base td padding + 5px (margins don't apply to td) */
  .mt-table tr:has(+ tr.mt-total) td { padding-bottom: 8px; }
  /* Unassigned crew row: integrated into the worker table — muted, slightly separated. */
  .mt-table tr.mt-ua td { color: var(--hg-text-secondary); border-top: 1px dashed var(--hg-border-control); }
  .mt-rate-row {
    display: flex; justify-content: space-between; align-items: center;
    gap: 10px; padding: 8px 0 2px; margin-top: 4px;
    font-size: var(--hg-type-11); color: var(--hg-text-secondary); font-weight: 500;
  }
  .mt-rate-row label { color: var(--hg-text-secondary); font-weight: 500; cursor: text; }
  .mt-rate-input {
    display: inline-flex; align-items: center; gap: 2px;
    font-variant-numeric: tabular-nums; font-weight: 600; color: var(--hg-text-ink);
  }
  /* shared input style: master markup + per-seg MARKUP column follow ONE rule
     (.hg-inp — underline control). These variants only restate box shape. */
  .mt-rate-input input,
  .mt-table input.mt-seg-markup { text-align: right; }
  .mt-rate-input input { width: 64px; }
  .mt-table input.mt-seg-markup { width: 52px; }
  /* Bid-vs-actual delta cells in master totals (red over / green under) */
  .mt-table td.mt-delta.over { color: var(--hg-danger-ink); }
  .mt-table td.mt-delta.under { color: var(--st-ip-ink); }
  /* Segment expander column: +/− button, then indented per-entity rows */
  .mt-table td.mt-exp { width: 20px; padding-right: 4px; white-space: nowrap; }
  .mt-seg-toggle {
    border: none; background: transparent; cursor: pointer;
    padding: 0 2px; font-size: 12px; line-height: 1;
    color: var(--hg-text-dim); font-variant-numeric: tabular-nums;
  }
  .mt-seg-toggle:hover { color: var(--hg-text-ink); }
  .mt-table tr.mt-ent td { color: var(--hg-text-muted); font-weight: 400; padding-left: 4px; }
  .mt-table tr.mt-ent td.num { font-weight: 500; color: var(--hg-text-secondary); }
  /* Performance strip — divider + margin metrics below the two tables */
  .mt-perf { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--hg-border-row); }
  .mt-perf-title { font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .05em; color: var(--hg-text-dim); margin-bottom: 8px; }
  .mt-perf-strip { display: flex; gap: 28px; flex-wrap: wrap; }
  .mt-perf-item { display: flex; flex-direction: column; gap: 2px; }
  .mt-perf-label { font-size: var(--hg-type-11); color: var(--hg-text-secondary); }
  .mt-perf-val { font-size: var(--hg-type-medium); font-weight: 700; color: var(--hg-text-ink); font-variant-numeric: tabular-nums; }
  .mt-perf-val.neg { color: var(--hg-danger-ink); }
  .mt-perf-val.pos { color: var(--st-ip-ink); }
  #assetTree .hg-stage:last-child { border: none; }

  #assetTree .hg-stage .t-stage { font-size: var(--hg-type-base); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  #assetTree .hg-stage .t-tags { display: flex; align-items: center; gap: 3px; min-width: 0; overflow: hidden; }
  #assetTree .hg-stage .t-stage-input { box-sizing: border-box; width: 100%; height: 22px; font-size: var(--hg-type-base); border: 1px solid transparent; border-radius: 4px; padding: 2px 6px; background: var(--hg-input-bg); color: var(--hg-text-ink); }
  .hg-stage .t-stage-input:hover { border-color: var(--hg-border-control); }
  .hg-stage .t-stage-input:focus { outline: none; border-color: var(--hg-border-focus); }
  .hg-stage .t-days { text-align: right; font-variant-numeric: tabular-nums; cursor: text; border-radius: 4px; padding: 1px 5px; }
  .hg-stage .t-days:hover { background: var(--hg-surface-elevated); }

  .task-add { border: none; background: none; color: var(--hg-text-muted); font-size: var(--hg-type-11); cursor: pointer; padding: 5px 0 2px; }
  .task-add:hover { color: var(--hg-text-ink); }
  /* Card-level action buttons (+ add stage / load preset / save preset / schedule):
     same dark-pill style as .btn-new / .seg-new-bottom, but ~25% smaller
     to fit inside hg-entity-block cards. */
  .card-task-btn { font-size: var(--hg-type-tiny); padding: 2px 8px; margin-left: 0; background: color-mix(in srgb, var(--seg-accent) 25%, transparent); border: 1px solid color-mix(in srgb, var(--seg-accent) 45%, rgba(255,255,255,.3)); color: var(--hg-text-ink); }
  .card-task-btn:hover { background: color-mix(in srgb, var(--seg-accent) 35%, transparent); }
  /* New-task schedule macro: reuse the real Gantt classes, only constrain height. */
  .na-gantt-wrap { display:flex; margin-top:12px; border:1px solid var(--hg-border-na); overflow:auto; position:relative; }
  .na-gantt-wrap::before {
    content:""; position:absolute; inset:0; z-index:0;
    background:url("assets/HydraSkin4.jpg") center / cover no-repeat;
    filter: invert(1) grayscale(.4) brightness(1.02); opacity:.13;
    pointer-events:none;
  }
  #naModal .modal { background:rgba(255,255,255,.92); position:relative; overflow:hidden; }
  #naModal .modal::before {
    content:""; position:absolute; inset:0; z-index:0;
    background:url("assets/HydraSkin4.jpg") center / cover no-repeat;
    filter: invert(1) grayscale(.4) brightness(1.02); opacity:.13;
    pointer-events:none; border-radius:8px;
  }
  #naModal .modal > * { position:relative; z-index:1; }
  /* ONE shared scroller for both columns, same contract as the main Gantt:
     the wrap itself scrolls — both labels and timeline move together. The
     week header and labels-head stick to the top. */
  .na-gantt-wrap .gantt-labels { width:340px; flex-shrink:0; position:sticky; left:0; z-index:5; box-shadow:none; background:rgba(251,251,253,.82); }
  .na-gantt-wrap .gantt-timeline { flex:1; min-width:0; background:transparent; }
  .na-gantt-wrap .na-lane-body { position:relative; min-width:max-content; background:transparent; }
  .na-gantt-wrap .lane { display:flex; position:relative; height:30px; border-bottom:1px solid var(--hg-border-na); box-sizing:border-box; background:rgba(255,255,255,.55); overflow:hidden; }
  .na-gantt-wrap .lane .cells { display:flex; flex:0 0 auto; height:100%; }
  .na-gantt-wrap .lane .cell { height:100%; }
  .na-gantt-wrap .na-row { height:30px; background:rgba(255,255,255,.55); }
  .na-gantt-wrap .labels-head { height: var(--gantt-head-h); position:sticky; top:0; z-index:6; }
  .na-gantt-wrap .gantt-labels > .task-add { display:block; width:100%; text-align:left; padding:8px 16px; border:none; border-top:1px solid var(--hg-border-na); background:rgba(247,248,250,.82); color:var(--hg-text-muted); font-size: var(--hg-type-11); cursor:pointer; }
  .na-gantt-wrap .gantt-labels > .task-add:hover { color: var(--hg-text-ink); }
  /* Editable inputs inside hg-stage for the macro: stage name, days, offset.
     UNIFIED FILL: idle = selected = --hg-input-bg (border is the affordance). */
  .na-gantt-wrap .na-row input.na-stage { flex:1; min-width:0; border:1px solid transparent; border-radius:3px; padding:2px 4px; font-size: var(--hg-type-11h); font-weight:500; color:#343942; background:var(--hg-input-bg); }
  .na-gantt-wrap .na-row input.na-stage:hover, .na-gantt-wrap .na-row input.na-stage:focus { border-color:var(--hg-border-na); outline:none; }
  .na-gantt-wrap .na-row input.na-num { width:42px; border:1px solid transparent; border-radius:3px; padding:2px 3px; font-size: var(--hg-type-11); font-weight:500; color:#343942; background:var(--hg-input-bg); text-align:center; }
  .na-gantt-wrap .na-row input.na-num:hover, .na-gantt-wrap .na-row input.na-num:focus { border-color:var(--hg-border-na); outline:none; }
  .na-gantt-wrap .na-row .na-rm { border:none; background:none; color:#c8c8ce; cursor:pointer; font-size: var(--hg-type-14); padding:2px 4px; flex-shrink:0; }
  .na-gantt-wrap .na-row .na-rm:hover { color:var(--hg-danger-ink); }
  .footnote { margin-top: 18px; font-size: var(--hg-type-base); color: var(--hg-text-secondary); line-height: 1.6; }
  .footnote b { color: var(--hg-text-ink); }
  .rec-dialog { width: min(780px, 94vw); max-height: 86vh; display: flex; flex-direction: column; box-sizing: border-box; }
  #recDialogBody { overflow: auto; min-height: 0; }
  #recDialogTitle { overflow-wrap: anywhere; }
  .rec-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); gap: 12px; margin-bottom: 14px; }
  .rec-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
  .rec-field .hg-ctl { width: 100%; min-height: 30px; padding: 5px 8px; }
  .rec-field button { white-space: normal; overflow-wrap: anywhere; }
  .rec-cycle-options { max-height: 32vh; overflow: auto; margin: 12px 0; }
  .rec-cycle-option { display: grid; grid-template-columns: 20px minmax(0, 1fr) minmax(0, 1fr); gap: 8px; align-items: start; padding: 5px 0; }
  .rec-fields[hidden] { display: none; }
  #recDialogError:empty, #recError:empty { display: none; }
  #recurringDialogBg { z-index: 86; }
  #hgConfirmBg { z-index: 87; }

  .modal-bg { position: fixed; inset: 0; background: transparent; z-index: 85; display: none; align-items: center; justify-content: center; }
  .modal-bg.open { display: flex; }
  .modal { position: relative; background: var(--hg-frost-bg); border-radius: 8px; padding: 22px 24px; width: 460px;
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
    box-shadow: var(--hg-shadow-modal); }
  .modal h3 { margin-bottom: 14px; cursor: move; user-select: none; }
  /* Popups shrink-wrap to content, capped at the viewport — the script never sets px. */
  .modal.fit { width: max-content; max-width: 94vw; min-width: 420px; }
  .mrow { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
  .mlab { width: 76px; font-size: var(--hg-type-11); color: var(--hg-text-secondary); text-transform: uppercase; letter-spacing: .05em; }
  .mrow input, .mrow select { border: 1px solid var(--hg-border-control); border-radius: 4px; padding: 5px 9px; font-size: var(--hg-type-12h); flex: 1; }
  .mrow .stg { display: inline-flex; align-items: center; gap: 4px; font-size: var(--hg-type-11h); background: var(--hg-surface-raised); border-radius: 4px; padding: 3px 8px; margin: 2px 3px 2px 0; cursor: pointer; }
  .mrow .stg.off { opacity: .45; }
  .mpath { font-family: var(--hg-font-mono); font-size: var(--hg-type-11); color: var(--hg-info); background: #f0f3f8; border-radius: 4px; padding: 7px 10px; margin: 8px 0; min-height: 16px; }
  .mfoot { display: flex; gap: 10px; margin-top: 12px; }
  /* Legacy .na-item card styles removed — schedule macro now uses real Gantt .hg-stage */

  /* ===== 4d. gantt shell + bars ===== */
  .gbar {
    position: absolute; top: 6px; height: 18px; border-radius: 3px; cursor: grab;
    user-select: none; -webkit-user-select: none;
    display: flex; align-items: center; padding: 0 6px; font-size: var(--hg-type-10); font-weight: 600;
    color: var(--hg-text-on-accent); white-space: nowrap; overflow: visible; max-width: 100%;
    box-sizing: border-box; z-index: 1;
    /* Raised bar: soft light top, soft shade bottom, visible drop shadow. */
    box-shadow: inset 0 2px 5px rgba(255,255,255,.15),
                inset 0 -3px 7px rgba(0,0,0,.09),
                0 2px 7px rgba(15,23,42,.38);
    /* 70% opaque — NO backdrop blur: Chromium's backdrop-filter blurs the
       grid lines underneath the bar, smearing the day/week seams the chart
       depends on. Opacity alone reads as frost without touching the grid. */
    opacity: 0.7;
  }
  /* Assignment text and status fills must retain their tested contrast. Parent
     envelopes keep the softer shared-bar opacity above. */
  .gbar[data-assignment] { opacity: 1; }
  /* Ghosted weekend stretch inside a bar: the bar's own translucent hole
     across the open Sat/Sun columns — one assignment with a gap, never two
     bars. Same shape as the bar, translucent fill, no new chrome. */
  .gbar .gbar-ghost {
    position: absolute; top: 0; bottom: 0; z-index: 0;
    background: rgba(255, 255, 255, 0.28);
    border-radius: 0;
    pointer-events: none;
  }
  /* Counted weekend whose columns are closed: the bar paints shorter than
     the days it counts, so the collapse point carries a broken-axis mark —
     two thin slanted strokes through the bar (the chart convention for
     compressed time). Graphics, never glyphs: text here collided with the
     bar's own duration label and read as part of the number. The strokes
     ride the bar's own ink, so every status fill keeps contrast in both
     modes — no colour override needed. */
  .gbar .gbar-seam {
    position: absolute; top: -3px; bottom: -3px; width: 12px;
    margin-left: -6px; z-index: 2; pointer-events: none;
    opacity: 0.5;
  }
  .gbar .gbar-seam::before,
  .gbar .gbar-seam::after {
    content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: 1.5px;
    background: currentColor; transform-origin: 50% 50%;
  }
  .gbar .gbar-seam::before { transform: translateX(-3.5px) skewX(-14deg); }
  .gbar .gbar-seam::after { transform: translateX(3.5px) skewX(-14deg); }
  .gbar .gbar-txt {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    min-width: 0; flex: 0 1 auto;
    position: relative; z-index: 1;
  }
  /* Milestone + today vertical spikes must layer above every track and bar. */
  #ganttBody .ms-spike, #ganttBody #spikeLine { z-index: 50 !important; }
  #ganttBody .ms-spike { opacity: 0.5; }
  /* Cashflow dock milestone markers share the Gantt spike colour + transparency. */
  #cfTrack .cf-ms-marker {
    position: absolute; top: 0; bottom: 0; width: 2px;
    background: #26415e88; z-index: 10; pointer-events: none;
  }
  .gbar.ip { background: var(--gbar-ip-bg); } .gbar.wtg { background: var(--gbar-wtg-bg); }
  .gbar.rev { background: var(--gbar-rev-bg); color: var(--gbar-rev-ink); } .gbar.appr { background: var(--gbar-appr-bg); } .gbar.cmpt { background: var(--gbar-cmpt-bg); } .gbar.reopen { background: var(--hg-danger); }
  .gbar:focus-visible { outline: 2px solid var(--hg-border-focus); outline-offset: 2px; }
  .gbar.draft { background: repeating-linear-gradient(45deg,var(--gbar-wtg-bg),var(--gbar-wtg-bg) 5px,var(--gbar-draft-stripe) 5px,var(--gbar-draft-stripe) 10px); }
  .gbar.grp { height: 22px; top: 3px; font-size: var(--hg-type-11); border-radius: 4px; }
  .gbar.grp.gbar-dragging { transform: translateY(2px); }
  /* Expanded parent bars stay visible as ghost tools — translucent fill +
     dashed outline so they read as containers, not tasks. Edges stay
     hit-testable (same .gedge). Collapsed parents keep the solid rollup. */
  .gbar.parent-open {
    background: color-mix(in srgb, var(--gbar-wtg-bg) 16%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gbar-appr-bg) 45%, transparent),
                inset 0 2px 5px rgba(255,255,255,.10),
                0 1px 4px rgba(15,23,42,.18);
    color: #3a4150;
  }
  /* Bid-vs-actual: overdue against bid — red right edge pulse.
     Keeps the base bevel + drop shadow (box-shadow is a single property —
     an override must restate them or the bevel vanishes). */
  .gbar.overdue-bid {
    box-shadow: inset 0 2px 5px rgba(255,255,255,.15),
                inset 0 -3px 7px rgba(0,0,0,.09),
                inset -4px 0 0 0 var(--hg-danger-bright),
                0 2px 7px rgba(15,23,42,.38);
  }
  /* Unstaffed bar: compact (!) mark after the text — a flag prompting
     inspection (crew truth on the bar popup / RMB menu), not a status. */
  .gbar.gbar-openmark .gbar-txt::after {
    content: " (!)";
    color: var(--hg-danger-bright);
    font-weight: 700;
  }
  /* View filter bar. Every view scrolls inside its own root (overflow:auto on
     .bidwrap / .it-scroll / .cs-scroll / .gantt-wrap), so the bar sits static
     above that root — never sticky against the page chrome. */
  .gfilters { display: flex; gap: 10px; align-items: center; justify-content: center; padding: 5px 16px 8px; border-bottom: none; font-size: var(--hg-type-11); color: var(--hg-text-secondary); flex-wrap: wrap; position: static; flex-shrink: 0; z-index: 10; background: transparent;
    /* Own compositing layer: the button row sits above the gantt's
       backdrop-filter surface with no isolation boundary between them, so
       every .block-btn:hover border/color change expanded damage into the
       frost's blur pass and could re-bake stale row pixels (the banding /
       glowy-box ghosts). A promoted layer paints the bar in isolation and
       its damage stops at its own bounds. Menus/tooltips escape via
       document.body attach, so no contain: paint is set here. */
    contain: layout style;
    will-change: transform; }
  .gfilters select, .gfilters input { border: none; border-radius: 4px; padding: 2px 7px; font-size: var(--hg-type-11); background-color: var(--hg-surface-tabs); }
  .gfilters input { width: 90px; }
  /* Project cog settings popup: owns its geometry over the shared .hg-menu
     rule (same specificity, later in the file — its max-width would clip the
     two-column rows). Compound selector wins without touching shared popup
     or .hg-ctl styling. Preferred ~360px, capped at the viewport minus
     gutter; narrow viewports stack label and control. Geometry only. */
  .hg-menu.gantt-settings-menu {
    min-width: 0;
    width: 360px;
    max-width: calc(100vw - 24px);
    max-height: min(70vh, 520px);
    overflow-y: auto;
    padding-bottom: 6px;
  }
  .gantt-setting-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, auto); align-items: center; gap: 12px; padding: 4px 10px; }
  .gantt-setting-row > span { color: var(--hg-text-secondary); font-size: var(--hg-type-11); }
  .gantt-setting-row .hg-ctl { min-width: 0; width: 100%; box-sizing: border-box; }
  @media (max-width: 420px) {
    .gantt-setting-row { grid-template-columns: 1fr; }
  }

  /* Receipt drop zone — frosted glass band above the expenses table.
     Same token language as table headers / wire-panels: translucent
     fill + backdrop blur, no opaque beige block. */
  .receipt-drop-zone {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 16px; margin: var(--hg-tracker-side-padding) calc(var(--hg-tracker-side-padding) + 10px);
    border: 1px dashed color-mix(in srgb, var(--hg-text-ink) 35%, transparent);
    border-radius: 6px;
    background: var(--hg-frost-bg); background-clip: padding-box;
    backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
    cursor: pointer; flex-shrink: 0;
    transition: background 0.15s, border-color 0.15s, transform 0.15s;
    font-size: var(--hg-type-base); color: var(--hg-text-ink);
    box-shadow: var(--hg-frost-head-shadow);
  }
  .receipt-drop-zone:hover {
    background: var(--hg-frost-head);
    border-color: color-mix(in srgb, var(--hg-text-ink) 55%, transparent);
  }
  .receipt-drop-zone.drag-over {
    background: color-mix(in srgb, #5a8fcf 15%, transparent);
    border-color: #5a8fcf;
    transform: translateY(-1px);
  }
  .receipt-drop-zone.uploading { opacity: 0.65; pointer-events: none; }
  .receipt-drop-zone.has-pending {
    border-style: solid;
    border-color: color-mix(in srgb, #5a8fcf 60%, transparent);
    background: color-mix(in srgb, #5a8fcf 8%, transparent);
  }
  .receipt-drop-clear {
    margin-left: auto; flex-shrink: 0; cursor: pointer;
    border: none; background: transparent;
    font-size: var(--hg-type-base); color: var(--hg-text-ink); opacity: 0.6; padding: 2px 6px;
  }
  .receipt-drop-clear:hover { opacity: 1; }
  .receipt-drop-icon { font-size: var(--hg-type-18); flex-shrink: 0; }
  .receipt-drop-text { color: var(--hg-text-ink); line-height: 1.35; }
  .receipt-drop-hint { font-size: var(--hg-type-10); color: var(--hg-text-ink); opacity: 0.65; margin-left: auto; white-space: nowrap; }
  .receipt-drop-spinner {
    display: inline-block; width: 14px; height: 14px; flex-shrink: 0;
    border: 2px solid var(--hg-text-ink); border-top-color: transparent;
    border-radius: 50%; animation: spin 0.8s linear infinite;
  }
  @keyframes spin { to { transform: rotate(360deg); } }
  .receipt-link { cursor: pointer; font-size: var(--hg-type-14); text-decoration: none; color: inherit; }
  .receipt-link:hover { opacity: 0.7; }
  /* Pending-receipt flash on the add-row: draws the eye to the pre-filled
     row after a scan. Animation removes itself (no lingering highlight). */
  .cv-add-row-flash {
    animation: cv-add-row-flash 2.2s ease-out;
  }
  @keyframes cv-add-row-flash {
    0% { background: color-mix(in srgb, #5a8fcf 22%, transparent); }
    60% { background: color-mix(in srgb, #5a8fcf 22%, transparent); }
    100% { background: transparent; }
  }
  /* Receipt review modal — batch scan results, editable per row */
  .receipt-review-modal .rr-row {
    border: 1px solid var(--hg-border-chrome); border-radius: 6px;
    padding: 10px 12px; margin-bottom: 10px;
  }
  .rr-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin-bottom: 8px; font-size: var(--hg-type-base);
  }
  .rr-file { font-weight: 600; color: var(--hg-text-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
  .rr-status { font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .05em; padding: 1px 6px; border-radius: 3px; }
  .rr-status.ok { background: rgba(39,174,96,.12); color: #27ae60; }
  .rr-status.warn { background: rgba(230,126,34,.12); color: #e67e22; }
  .rr-status.dup { background: rgba(190,144,212,.14); color: #8a5ab5; }
  .rr-row.rr-dup { border-color: rgba(190,144,212,.45); }
  .rr-row.rr-dup .rr-file { color: #8a5ab5; }
  .rr-inc { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; font-size: var(--hg-type-11); color: var(--hg-text-ink); cursor: pointer; }
  .rr-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 130px), 1fr));
    gap: 8px 12px;
  }
  .rr-fields { display: grid; gap: 12px; }
  .rr-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .rr-grid .hg-cell-input { width: 100%; min-width: 0; }
  .rr-grid input[type="number"], .rr-grid input[data-total] { text-align: right; }
  .rr-grid .hg-select { min-height: 24px; }
  html.dark .receipt-review-modal .rr-row { border-color: var(--hg-border-chrome); }
  /* View stacking rules live in §2 (body flex column): .view.on flex-fills below
     the chrome, whatever its real height; scroll roots size by flex, not by
     hardcoded 100vh subtractions that drifted when the chrome changed. */
  /* Gantt filter band is the reference look — an opaque static band above the
     scroll root. Light-side band colour is the shared .gfilters base; the only
     gantt-specific rule is that it must NOT scroll with the chart (flex-shrink:0). */
  #v-tr .gantt-shell {
    flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden;
    /* The whole gantt stack — chart AND docks — floats 20px off the window
       edges. The gutter lives OUTSIDE the scrollports (margin, not padding)
       so scrollable overflow can never eat it: at narrow widths the tracks
       stay inset even with the horizontal scrollbar showing. The docks
       inherit the same inset by being children of this shell. */
    margin: 0 var(--hg-tracker-side-padding);
  }
  /* 48 header + 40 tabs + gfilters — remaining height is gantt-wrap */
  /* Sibling panes: labels | chart. The labels column is a normal flex child
     whose box simply ends at the divisor; the chart scroller starts there.
     Nothing overlaps, so nothing is clipped — the frost in both panes samples
     the page normally. */
  .gantt-body {
    display: flex; flex: 1 1 auto; min-height: 0; min-width: 0;
    align-items: stretch;
  }
  .gantt-wrap {
    display: flex; overflow: auto; position: relative; flex: 1 1 auto; min-height: 0;
    align-items: flex-start;
    /* Prevent browser touch gestures (page pinch-zoom, touch panning) from
       hijacking our custom touch handlers. We handle 1-finger scroll, 2-finger
       pinch-zoom and 2-finger pan ourselves in wireGanttTouch(). */
    touch-action: none;
    /* Gutter comes from #v-tr .gantt-shell's 20px margin — no padding here.
       Padding inside a scrollport gets eaten by scrollable overflow when the
       horizontal scrollbar appears, which is exactly the bug this avoids. */
  }
  .gantt-labels {
    width: var(--hg-gantt-label-w, 380px); flex-shrink: 0; position: relative; z-index: 2;
    border-right: 1px solid var(--hg-border-na);
    display: flex; flex-direction: column; min-height: 0;
    box-shadow: 4px 0 10px #00000014;
    /* z-index 2: the divisor grab strip (::after, right: -4px) straddles the
       panes' shared edge and must stay clickable over the chart pane; the
       shadow keeps the old divisor affordance. */
  }
  /* Label/header column: translucent + own blur on the whole column — it
     frosts anything that would otherwise slide under it, but as SIBLING panes
     nothing actually crosses the divisor: this frost exists for the rows
     inside the column and to keep the glass look identical to the old
     sticky-column design. */
  #labelsPanel {
    background: var(--hg-frost-bg);
    backdrop-filter: blur(var(--hg-frost-blur));
    -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  }
  /* All scrollable label rows: their own scrollport below the 42px head.
     #gscroll (the chart pane) owns the shared scroll state; this port mirrors
     its scrollTop on every scroll (ganttSyncLabelScroll), so the label rows
     stay locked to the chart rows while each pane's box truly ends at its
     own edge. */
  #labelsPanel .labels-rows {
    overflow: hidden;
    flex: 1 1 auto;
    min-height: 0;
  }
  /* Segment label parking (breakdown model): each segment's rows live in a
     .labels-block; its .hg-lane label sticks at the band's bottom edge (42px)
     while its own rows scroll beneath it — always reachable to collapse.
     Only UNROLLED segments park (aria-expanded="true") — collapsed ones have
     no rows to scroll and stay in flow. The next segment's label pushes the
     parked one away. Translucent + blur, never opaque. */
  #labelsPanel .labels-block {
    position: relative;
  }
  #labelsPanel .labels-block > .hg-lane[aria-expanded="true"] {
    position: sticky; top: 0; z-index: 3;
    backdrop-filter: blur(var(--hg-frost-blur));
    -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  }
  /* Draggable divisor between the labels column and the tracks.
     Attached to the labels column's own right edge via ::after — the labels
     column is sticky and full-height, so the grab strip spans the whole
     boundary (a standalone element inside the scroll wrap would be clipped to
     the wrap's short viewport). It takes no flow space (no gap). The 2px line
     sits centered in an 8px grab strip; hover/active darkens it. */
  .gantt-labels::after {
    content: ''; position: absolute; top: 0; bottom: 0; right: -4px; width: 8px;
    cursor: col-resize; user-select: none; z-index: 8;
    background: linear-gradient(to right,
      transparent 3px, #c5cad4 3px, #c5cad4 5px, transparent 5px);
    transition: background .12s ease;
  }
  .gantt-labels:hover::after { background: linear-gradient(to right,
      transparent 3px, #7a8494 3px, #7a8494 5px, transparent 5px); }
  html.dark .gantt-labels::after { background: linear-gradient(to right,
      transparent 3px, #3a3b40 3px, #3a3b40 5px, transparent 5px); }
  html.dark .gantt-labels:hover::after { background: linear-gradient(to right,
      transparent 3px, #8a8b92 3px, #8a8b92 5px, transparent 5px); }
  .gantt-labels .labels-head { height: var(--gantt-head-h); background: transparent; border-bottom: 1px solid var(--hg-border-na); position: relative; top: 0; z-index: 7; flex-shrink: 0;
    box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
                inset 0 -2px 5px rgba(15,23,42,.02);
    /* Translucent, frosted by the column's own blur (same as the rows) —
       the head never needs to hide anything: it sits in its own sibling
       pane above the rows' scrollport, and nothing scrolls behind it. */
  }
  .hg-gantt-plan-head { height: 100%; display: flex; align-items: center; gap: 10px; padding: 2px 10px; box-sizing: border-box; overflow: hidden; }
  .hg-gantt-plan-field, .hg-gantt-plan-tail { display: flex; flex-direction: column; min-width: 0; color: var(--hg-text-muted); font-size: var(--hg-type-9); line-height: 1.15; white-space: nowrap; }
  .hg-gantt-plan-field { flex: 0 0 104px; }
  .hg-gantt-plan-tail { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }
  .hg-gantt-plan-label { color: var(--hg-text-muted); text-transform: uppercase; letter-spacing: .04em; }
  .hg-gantt-plan-val { display: flex; align-items: center; height: 22px; font-size: var(--hg-type-10); }
  .hg-gantt-plan-field .hg-date { width: 104px; height: 22px; padding: 1px 5px; font-size: var(--hg-type-10); }
  /* Gantt label column = the Breakdown tree's type treatment at 80% size
     (the column is space-constrained) and the SAME ink tokens — never
     bespoke hexes or sizes here. */
  .gantt-labels .hg-entity {
    display: flex; align-items: center; gap: 6px; background: transparent; padding: 0 8px 0 8px; margin-left: 8px;
    font-weight: 500; font-size: calc(var(--hg-type-12h) * 0.8); letter-spacing: 0; color: var(--hg-text-ink);
    border-bottom: 1px solid var(--hg-border-na); height: 30px; box-sizing: border-box; overflow: hidden;
  }
  .gantt-labels .hg-entity .g-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .gantt-labels .hg-entity .gantt-owner-host { display: flex; align-items: center; flex-shrink: 0; margin-right: 10px; }
  .gantt-labels .hg-entity .gantt-owner-host .a-owner-label { font-size: var(--hg-type-9); color: var(--hg-text-muted); margin-right: 4px; }
  .gantt-labels .hg-entity .gantt-owner-host .owner-pick { font-size: var(--hg-type-10); width: 76px; height: 20px; }
  .gantt-labels .hg-entity .days { margin-left: auto; flex-shrink: 0; font-weight: 600; color: var(--hg-text-ink); letter-spacing: 0; font-variant-numeric: tabular-nums; font-size: var(--hg-type-10); }
  .gantt-labels .hg-stage {
    display: flex; align-items: center; gap: 6px; padding: 0 8px 0 16px; margin-left: 16px; border-bottom: 1px solid var(--hg-border-na);
    height: 30px; box-sizing: border-box; background: transparent; overflow: hidden;
  }
  .gantt-labels .hg-stage .g-stage {
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--hg-text-ink); font-size: calc(var(--hg-type-base) * 0.8); font-weight: 400;
  }
  .gantt-labels .hg-stage .who { flex-shrink: 0; color: var(--hg-text-secondary); font-size: var(--hg-type-10); max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* The crew read is people data — the whole slot paints with --hg-people
     (violet: the one hue no status or action family claims). Names and the
     (!) are row-editing triggers (RMB swap / RMB bulk-assign): context-menu
     cursor + a subtle underline on the names marks the affordance without
     reading as a status change. */
  .gantt-labels .hg-stage .who.gantt-crew-read { color: var(--hg-people); cursor: context-menu; }
  .gantt-labels .hg-stage .who.gantt-crew-read .gantt-crew-name:hover,
  .gantt-labels .hg-stage .who.gantt-crew-read .gantt-crew-more:hover { text-decoration: underline; text-underline-offset: 2px; }
  /* "+N" — the way to crew beyond the three shown in the slot. Reads as a
     link: pointer cursor + hover underline, LMB activates (list menu). */
  .gantt-labels .hg-stage .who.gantt-crew-read .gantt-crew-more { margin-left: 4px; font-weight: 600; cursor: pointer; }
  /* The row (!) sits OUTSIDE the ellipsized names slot as its own flex
     child of .hg-stage, so clipping can never hide it (or its click target).
     It is a link-shaped control: danger red (the unstaffed family), pointer
     cursor, underline on hover — LMB opens the bulk-assign picker. */
  .gantt-labels .hg-stage > .gantt-openmark { flex-shrink: 0; margin-left: 4px; color: var(--hg-danger-bright); font-weight: 700; cursor: pointer; }
  .gantt-labels .hg-stage > .gantt-openmark:hover { text-decoration: underline; text-underline-offset: 2px; }
  /* Menu headings ("Re-assign Sergio to:") use the shared .hg-menu-head
     structure (title + subtitle) — same as the multi-select menu. */
  /* Row-level unstaffed flag: the same (!) the bars carry — the label area
     shows the staffing gap too (after the names when only some bars are
     unstaffed, alone when all of them are). Styled above: it is a link-
     shaped control (danger red, pointer, hover underline, LMB). */
  /* Same law for the entity owner: an assigned owner is a person's name.
     Unassigned (.un) stays muted — it's a placeholder, not a person. */
  .gantt-labels .hg-entity .owner-pick:not(.un) { color: var(--hg-people); }
  .gantt-timeline { flex: 1; min-width: 0; position: relative; z-index: 1; overflow: visible; }
  /* z 70 — above every chart overlay (ms/today spikes z 2, #linkLayer z 55,
     #ganttSplitLine z 60). The old clip used to cut all of #ganttBody at the
     band edge; with sibling panes there is no clip, so paint order alone
     keeps the band off-limits: no full-height overlay may cross it. */
  .gantt-timeline .weekhdr { position: sticky; top: 0; z-index: 70; }
  #ganttBody { position: relative; }
  /* Faint scroll hint — absolutely positioned just above the crew dock
     so it overlays the chart's bottom-right corner. The dock is outside
     #gscroll so the hint can never scroll out of view; it moves naturally
     when docks expand/collapse. pointer-events:none so it never blocks. */
  .gantt-scroll-hint {
    position: absolute;
    top: -32px;
    right: 8px;
    z-index: 10;
    pointer-events: none;
    user-select: none;
    font-size: var(--hg-type-10);
    font-weight: 400;
    letter-spacing: .02em;
    color: #8a93a380;
    background: rgba(255,255,255,.5);
    padding: 2px 8px;
    border-radius: 4px;
    backdrop-filter: blur(var(--hg-frost-blur-soft));
    -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
    white-space: nowrap;
  }
  /* Touch devices show different instructions (pinch/2-finger instead of Alt/MMB).
     We show/hide via (pointer: coarse) media query so the right hint appears
     automatically on touch displays without JS detection. */
  .gantt-scroll-hint .hint-mouse { display: inline; }
  .gantt-scroll-hint .hint-touch { display: none; }
  @media (pointer: coarse) {
    .gantt-scroll-hint .hint-mouse { display: none; }
    .gantt-scroll-hint .hint-touch { display: inline; }
  }
  /* ===== 4e. workload dock (sibling above cashflow; worker × week day grid) =====
       Share week X-scale with Gantt. Horizontal scroll synced in js/workload.js.
       ONE scroller: each worker is name+cells on the SAME row (sticky name).
       Body height = min(all rows, half window − title) via --wl-body-h. */
    .workload-dock {
      flex-shrink: 0; box-sizing: border-box;
      display: flex; flex-direction: column;
      height: calc(28px + var(--wl-body-h, 156px)); /* title + body */
      border-top: 2px solid var(--hg-accent);
      background: var(--hg-frost-bg);
      backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
      position: relative; z-index: 9;
      /* overflow visible so .gantt-scroll-hint (top:-22px) can render above
         the dock. The wl-body has its own overflow:hidden to clip its content. */
      overflow: visible;
      transition: height .22s ease;
      /* Gutter inherited from #v-tr .gantt-shell's margin — the dock bar
         sits flush inside the shell so its scroll viewport width matches
         the chart's exactly and week cells stay X-aligned. */
    }
    .workload-dock.is-collapsed {
      height: 28px;
    }
    .workload-dock .wl-titlebar {
      flex-shrink: 0; height: 28px; box-sizing: border-box;
      display: flex; align-items: center; gap: 8px;
      padding: 0 12px;
      background: var(--hg-frost-head);
      backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
      border-bottom: 1px solid var(--hg-border-warm);
      cursor: pointer; user-select: none;
      color: #5a3d2e; font-size: var(--hg-type-11); font-weight: 600;
      letter-spacing: .03em;
    }
    .workload-dock .wl-titlebar:hover {
      background: color-mix(in srgb, var(--hg-accent) 10%, transparent);
    }
    .workload-dock .wl-titlebar:focus-visible {
      outline: 2px solid #b07050; outline-offset: -2px;
    }
    .workload-dock .wl-caret {
      display: inline-block; width: 12px; text-align: center;
      font-size: var(--hg-type-10); line-height: 1; color: #7a5a48;
      transition: transform .22s ease;
    }
    .workload-dock.is-collapsed .wl-caret {
      transform: rotate(-90deg);
    }
    .workload-dock .wl-titlebar-label { font-weight: 700; }
    .workload-dock .wl-titlebar-sub {
      font-weight: 500; color: #8a7364; letter-spacing: 0;
    }
    .workload-dock .wl-titlebar-meta {
      margin-left: auto; font-weight: 600; color: #6a5548;
      font-variant-numeric: tabular-nums; letter-spacing: 0;
    }
    .workload-dock .wl-titlebar-meta.is-warn {
      color: var(--hg-danger);
    }
    .workload-dock .wl-body {
      flex: 0 0 auto;
      height: var(--wl-body-h, 156px); box-sizing: border-box;
      display: flex; min-height: 0;
      overflow: hidden;
      transition: height .22s ease;
      /* Gutter comes from .workload-dock's 20px margin — no body padding,
         so the dock scroll viewport width matches .gantt-wrap's exactly
         and week cells stay X-aligned at every scrollLeft. */
    }
    .workload-dock.is-collapsed .wl-body {
      height: 0;
    }
    /* Single scroller: X mirrored from Gantt, Y for long crew lists. */
    .workload-dock .wl-scroll {
      flex: 1; min-width: 0;
      overflow: auto;
      position: relative;
      scrollbar-width: thin;
    }
    #workloadPanel {
      position: relative; min-width: 100%;
      height: var(--wl-track-h, 156px);
      background: transparent;
    }
    #wlTrack {
      position: relative; width: 100%; height: 100%;
      display: flex; flex-direction: column;
    }
    /* Each worker: sticky name column + week cells locked together. */
    .workload-dock .wl-worker-row {
      display: flex; flex-direction: row; align-items: stretch;
      height: 26px; flex-shrink: 0; box-sizing: border-box;
      border-bottom: 1px solid #e6ddd6;
      cursor: pointer; user-select: none;
    }
    .workload-dock .wl-worker-row:hover .wl-name,
    .workload-dock .wl-worker-row:hover .wl-cells {
      background: #e8dfd8;
    }
    .workload-dock .wl-worker-row:focus-visible {
      outline: 2px solid #b07050; outline-offset: -2px;
    }
    .workload-dock .wl-worker-row.is-active .wl-name {
      background: #d9e4f2;
      color: #26415e;
      font-weight: 700;
      box-shadow: inset 3px 0 0 #4a7ab5;
    }
    .workload-dock .wl-worker-row.is-active .wl-cells {
      background: #d9e4f22e;
    }
    .workload-dock .wl-worker-row.is-active .wl-cell:not(.is-overload):not(.is-underutilized) {
      background: #c5d6ee55;
    }
    .workload-dock .wl-name {
      position: sticky; left: 0; z-index: 2;
      width: var(--hg-gantt-label-w, 380px); flex-shrink: 0; box-sizing: border-box;
      display: flex; align-items: center;
      padding: 0 12px 0 16px;
      border-right: 1px solid var(--hg-border-warm);
      /* Transparent so the dock body's frost shows through, matching the
         sheet/cell area exactly. */
      background: transparent;
      font-size: var(--hg-type-11h); font-weight: 500; color: #3c322c;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .workload-dock .wl-name-empty {
      color: #8a7364; font-weight: 500; font-style: italic;
      cursor: default;
    }
    .workload-dock .wl-name-text {
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .workload-dock .wl-cells {
      position: relative; flex: 0 0 auto;
      height: 26px; box-sizing: border-box;
      background: transparent;
    }
    .workload-dock .wl-cell {
      position: absolute; top: 0; bottom: 0;
      box-sizing: border-box;
      border-left: 1px solid #e8e0d9;
      display: flex; align-items: center; justify-content: center;
      font-size: var(--hg-type-small); font-weight: 600;
      font-variant-numeric: tabular-nums;
      color: #5a5048;
      background: transparent;
    }
    .workload-dock .wl-cell.has-load {
      background: #d9e4f244;
      color: #2f3b4d;
    }
    /* Over capacity (>5 workdays in the week column) */
    .workload-dock .wl-cell.is-overload {
      background: color-mix(in srgb, var(--hg-danger) 20%, transparent);
      color: #a02820;
      border-left-color: color-mix(in srgb, var(--hg-danger) 40%, transparent);
      font-weight: 700;
      animation: wl-overload-pulse 1.6s ease-in-out infinite;
      will-change: box-shadow, filter;
      z-index: 1;
    }
    @keyframes wl-overload-pulse {
      0%, 100% {
        box-shadow:
          inset 0 0 0 1px rgba(192, 57, 43, 0.35),
          0 0 4px rgba(192, 57, 43, 0.35),
          0 0 10px rgba(192, 57, 43, 0.2);
        filter: brightness(1);
      }
      50% {
        box-shadow:
          inset 0 0 0 1px rgba(192, 57, 43, 0.85),
          0 0 8px rgba(192, 57, 43, 0.85),
          0 0 18px rgba(192, 57, 43, 0.55),
          0 0 28px rgba(224, 80, 70, 0.35);
        filter: brightness(1.15);
      }
    }
    @media (prefers-reduced-motion: reduce) {
      .workload-dock .wl-cell.is-overload {
        animation: none;
        box-shadow:
          inset 0 0 0 1px rgba(192, 57, 43, 0.7),
          0 0 8px rgba(192, 57, 43, 0.55);
      }
    }

    /* Underutilized — idle capacity between tasks (gap weeks) */
    .workload-dock .wl-cell.is-underutilized {
      background: color-mix(in srgb, #e67e22 12%, transparent);
      color: #b3620a;
      border-left-color: color-mix(in srgb, #e67e22 30%, transparent);
      font-weight: 500;
      animation: wl-underutil-pulse 2s ease-in-out infinite;
      will-change: box-shadow, filter;
      z-index: 1;
    }
    @keyframes wl-underutil-pulse {
      0%, 100% {
        box-shadow:
          inset 0 0 0 1px rgba(230, 126, 34, 0.2),
          0 0 3px rgba(230, 126, 34, 0.15);
        filter: brightness(1);
      }
      50% {
        box-shadow:
          inset 0 0 0 1px rgba(230, 126, 34, 0.55),
          0 0 6px rgba(230, 126, 34, 0.5),
          0 0 14px rgba(230, 126, 34, 0.3);
        filter: brightness(1.08);
      }
    }
    @media (prefers-reduced-motion: reduce) {
      .workload-dock .wl-cell.is-underutilized {
        animation: none;
        box-shadow:
          inset 0 0 0 1px rgba(230, 126, 34, 0.45),
          0 0 6px rgba(230, 126, 34, 0.35);
      }
    }

    /* ── crew-dock mode toggle — underline style matching .tab ── */
    .workload-dock .wl-mode-pill {
      display: inline-flex; align-items: stretch; gap: 14px;
      margin-left: 14px; height: 100%;
    }
    .workload-dock .wl-mode-btn {
      appearance: none; border: 0; background: transparent; cursor: pointer;
      padding: 0; font-size: var(--hg-type-11); font-weight: 500; color: #8a7364;
      letter-spacing: .02em; font-family: inherit;
      border-bottom: 2px solid transparent;
      height: 100%; box-sizing: border-box;
    }
    .workload-dock .wl-mode-btn:hover { color: #5a3d2e; }
    .workload-dock .wl-mode-btn.is-active {
      color: #5a3d2e; border-bottom-color: #5a3d2e; font-weight: 600;
    }
    .workload-dock .wl-mode-btn:focus-visible {
      outline: 2px solid #b07050; outline-offset: -2px;
    }
    html.dark .workload-dock .wl-mode-btn { color: #7a6558; }
    html.dark .workload-dock .wl-mode-btn:hover { color: #d2c4b8; }
    html.dark .workload-dock .wl-mode-btn.is-active {
      color: #d2c4b8; border-bottom-color: #d2c4b8;
    }

    /* ── continuous license bars (Licenses mode) ───────────────────────── */
    .workload-dock .wl-lic-cells { overflow: hidden; }
    .workload-dock .wl-lic-bar {
      position: absolute; height: 8px; box-sizing: border-box;
      border-radius: 3px;
      background: var(--lic-hue, #4a7ab5);
      color: var(--hg-text-on-accent); font-size: var(--hg-type-9); font-weight: 600; line-height: 8px;
      padding: 0 5px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
      pointer-events: auto; cursor: default;
      z-index: 1;
    }
    .workload-dock .wl-lic-bar.is-contended {
      background: var(--hg-danger);
      animation: wl-overload-pulse 1.6s ease-in-out infinite;
      z-index: 2;
    }
    html.dark .workload-dock .wl-lic-bar { color: var(--hg-text-bright); }
    .workload-dock .wl-name-lic-sub {
      font-size: var(--hg-type-10); color: #8a7364; font-weight: 400;
      margin-left: 8px; letter-spacing: 0;
      overflow: hidden; text-overflow: ellipsis;
    }
    html.dark .workload-dock .wl-name-lic-sub { color: #7a6558; }
    @media (prefers-reduced-motion: reduce) {
      .workload-dock .wl-lic-bar.is-contended { animation: none; }
    }

    /* ── crew-sheet: seats panel + window dates ────────────────────────── */
    .cs-win-cell {
      white-space: nowrap; font-size: var(--hg-type-11);
    }
    .cs-win-cell input[type="date"] {
      border: 1px solid transparent; border-radius: 4px;
      padding: 2px 5px; font-size: var(--hg-type-11); width: 118px;
      background: var(--hg-input-bg); color: inherit; font-family: inherit;
    }
    .cs-win-cell input[type="date"]:focus {
      border-color: var(--hg-border-warm); outline: none;
      /* fill NOT restated — unified: idle = selected */
    }
    html.dark .cs-win-cell input[type="date"]:focus {
      border-color: var(--hg-border-control); color: var(--hg-text-bright);
      /* fill NOT restated — unified: idle = selected */
    }
    .cs-win-arrow { color: var(--hg-text-dim); margin: 0 2px; }
    .cs-lic-cell .cs-lic-toggle { font-size: var(--hg-type-11); padding: 2px 6px; }
    .cs-lic-cell .cs-lic-toggle.is-empty { color: var(--hg-text-dim); }

    .cs-lic-row {
      display: flex; align-items: center; gap: 10px;
      font-size: var(--hg-type-11); padding: 3px 0; border-bottom: 1px dotted #e3d9d1;
    }
    .cs-lic-row:last-child { border-bottom: 0; }
    .cs-lic-name { font-weight: 600; color: inherit; min-width: 110px; }
    .cs-lic-span { color: var(--hg-text-secondary); font-variant-numeric: tabular-nums; }
    .cs-lic-state {
      font-size: var(--hg-type-10); font-weight: 700; text-transform: uppercase;
      padding: 1px 6px; border-radius: 3px; letter-spacing: .04em;
    }
    .cs-lic-state-owned { background: var(--st-ip-bg); color: var(--st-ip-ink); }
    .cs-lic-state-planned { background: var(--st-rev-bg); color: var(--st-rev-ink); }
    .cs-lic-state-expired { background: var(--st-reopen-bg); color: var(--hg-danger-hover); }
    .cs-lic-edit, .cs-lic-del, .cs-lic-close {
      border: none; background: none; color: #b9b2a0; cursor: pointer;
      font-size: var(--hg-type-base); padding: 0 4px; line-height: 1;
    }
    .cs-lic-edit:hover, .cs-lic-close:hover { color: #4a7ab5; }
    .cs-lic-del:hover { color: #a02820; }
    tr.cs-lic-panel > td {
      background: #f7f8fa; border-top: 1px dashed var(--hg-border-control);
      padding: 8px 12px;
    }
    .cs-lic-panel-head {
      display: flex; align-items: center; justify-content: space-between;
      gap: 10px; margin-bottom: 6px;
    }
    .cs-lic-panel-head h5 {
      margin: 0; font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .05em;
      color: var(--hg-text-label); font-weight: 700;
    }
    .cs-lic-empty { color: var(--hg-text-dim); font-size: var(--hg-type-11); padding: 4px 0; }
    .cs-lic-input {
      font-size: var(--hg-type-11); padding: 3px 6px;
      border: 1px solid var(--hg-border-control); border-radius: 4px;
      background: var(--hg-input-bg); color: var(--hg-text-ink); font-family: inherit;
    }
    .cs-lic-input:focus { outline: none; border-color: var(--hg-accent); }
    .cs-lic-row input[type="date"],
    .cs-lic-row select,
    .cs-lic-row input[type="text"] {
      font-size: var(--hg-type-11); color: var(--hg-text-ink);
    }
    .cs-lic-row input[type="date"]:focus,
    .cs-lic-row select:focus,
    .cs-lic-row input[type="text"]:focus {
      outline: none; border-color: var(--hg-accent);
      /* fill NOT restated — unified: idle = selected */
    }

    /* Force CrewSheet centered in the window.
    .view.on is a flex column; the .doc child centers via its own auto margins. */
    /* Crew is a standalone top-level view (between Client and Breakdown).
       The shared .view.on rule already gives it the flex-column locked stack;
       only the scroll root + actions below it need view-level sizing. */
    #v-cs .cs-scroll {
      flex: 1 1 auto; max-height: none; min-height: 0;
      overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box;
    }
    #v-cs #crewTable {
      width: max-content;
      table-layout: auto;
      border-collapse: separate; border-spacing: 0;
      margin: 0 auto;
    }
    /* Natural state: intrinsic auto columns, centered. The shared controller
       switches all trackers to .hg-tracker-compressed only below this width. */
    #v-cs #crewTable, #v-it table.track, #v-ex table.track, #v-ast table.track, #v-cliInv table.track, #v-ctiInv table.track , #v-prl table.track, #v-rc table.track, #v-rec table.track { display: table; width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-cs #crewTable.hg-tracker-compressed, #v-it .it-scroll table.track.hg-tracker-compressed, #v-ex .exp-scroll table.track.hg-tracker-compressed, #v-ast .ast-scroll table.track.hg-tracker-compressed, #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed, #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed , #v-prl .prl-scroll table.track.hg-tracker-compressed, #v-rc .rc-scroll table.track.hg-tracker-compressed, .ov-scroll .cf-forecast-scroll table.track.hg-tracker-compressed, #v-rec .rec-scroll table.track.hg-tracker-compressed { width: 100%; table-layout: fixed; }
    #v-cs #crewTable.hg-tracker-compressed td, #v-cs #crewTable.hg-tracker-compressed th,
    #v-it table.track.hg-tracker-compressed td, #v-it table.track.hg-tracker-compressed th,
    #v-ex table.track.hg-tracker-compressed td, #v-ex table.track.hg-tracker-compressed th,
    #v-ast .ast-scroll table.track.hg-tracker-compressed td, #v-ast .ast-scroll table.track.hg-tracker-compressed th,
    #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed td, #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed th,
    #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed td, #v-prl .prl-scroll table.track.hg-tracker-compressed td, #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed th, #v-rec table.track.hg-tracker-compressed td, #v-rec table.track.hg-tracker-compressed th, .ov-scroll .cf-forecast-scroll table.track.hg-tracker-compressed td{ overflow: hidden; }
    #v-cs #crewTable.hg-tracker-compressed input, #v-cs #crewTable.hg-tracker-compressed button,
    #v-it table.track.hg-tracker-compressed input, #v-it table.track.hg-tracker-compressed button,
    #v-ex table.track.hg-tracker-compressed input, #v-ex table.track.hg-tracker-compressed button,
    #v-ast .ast-scroll table.track.hg-tracker-compressed input, #v-ast .ast-scroll table.track.hg-tracker-compressed button,
    #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed input, #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed button,
    #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed input, #v-prl .prl-scroll table.track.hg-tracker-compressed input, #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed button, #v-rec table.track.hg-tracker-compressed input, #v-rec table.track.hg-tracker-compressed button, .ov-scroll .cf-forecast-scroll table.track.hg-tracker-compressed input{ min-width: 0; max-width: none; }
    /* Expenses + IT only: factory inline style="width:NNpx" must yield to the
       colgroup under table-layout:fixed. Checkboxes/radios are EXCLUDED so
       Pick never stretches. Delete (cv-del) is a bare button with no fixed
       width — width:100% is fine (centred glyph in a 34px cell). */
    #v-ex .exp-scroll table.track.hg-tracker-compressed input:not([type="checkbox"]):not([type="radio"]),
    #v-ex .exp-scroll table.track.hg-tracker-compressed button,
    #v-it .it-scroll table.track.hg-tracker-compressed input:not([type="checkbox"]):not([type="radio"]),
    #v-it .it-scroll table.track.hg-tracker-compressed button, #v-rec .rec-scroll table.track.hg-tracker-compressed input:not([type="checkbox"]):not([type="radio"]), #v-rec .rec-scroll table.track.hg-tracker-compressed button { width: 100% !important; box-sizing: border-box; }
    #v-ex .exp-scroll table.track.hg-tracker-compressed td > span,
    #v-it .it-scroll table.track.hg-tracker-compressed td > span,
    #v-ast .ast-scroll table.track.hg-tracker-compressed td > span,
    #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed td > span,
    #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed td > span,
    #v-prl .prl-scroll table.track.hg-tracker-compressed td > span,
    #v-rc .rc-scroll table.track.hg-tracker-compressed td > span, #v-rec .rec-scroll table.track.hg-tracker-compressed td > span {
      display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    /* Assets / Client Inv / Contractor Inv / Payroll: same inline-width
       override as Expenses/IT. These four have NO checkbox columns — only
       text inputs, selects/date buttons, and the delete ✕ / + add button. */
    #v-ast .ast-scroll table.track.hg-tracker-compressed input,
    #v-ast .ast-scroll table.track.hg-tracker-compressed button,
    #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed input,
    #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed button,
    #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed input,
    #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed button,
    #v-prl .prl-scroll table.track.hg-tracker-compressed input,
    #v-prl .prl-scroll table.track.hg-tracker-compressed button,
    #v-rc .rc-scroll table.track.hg-tracker-compressed input,
    #v-rc .rc-scroll table.track.hg-tracker-compressed button { width: 100% !important; box-sizing: border-box; }
    /* Delete / add glyphs stay intrinsic in their narrow chrome cell. */
    #v-ex .exp-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-it .it-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-ast .ast-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-prl .prl-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-rc .rc-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-ex .exp-scroll table.track.hg-tracker-compressed button.cv-add-btn,
    #v-ast .ast-scroll table.track.hg-tracker-compressed button.cv-add-btn,
    #v-cliInv .cli-inv-scroll table.track.hg-tracker-compressed button.cv-add-btn,
    #v-ctiInv .cti-inv-scroll table.track.hg-tracker-compressed button.cv-add-btn,
    #v-prl .prl-scroll table.track.hg-tracker-compressed button.cv-add-btn,
    #v-rc .rc-scroll table.track.hg-tracker-compressed button.cv-add-btn, #v-rec .rec-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-rec .rec-scroll table.track.hg-tracker-compressed button.cv-add-btn {
      width: auto !important;
      min-width: 0 !important;
      display: inline-block;
    }
    /* Recruitment skill tag pills are buttons — keep them intrinsic so the
       width:100% rule above doesn't stretch each pill across the cell. */
    #v-rc .rc-scroll table.track.hg-tracker-compressed button.a-tag,
    #v-rc .rc-scroll table.track.hg-tracker-compressed button.rc-skill-pill {
      width: auto !important;
      min-width: 0 !important;
      max-width: none !important;
      display: inline-block;
    }
    /* Chrome columns: checkbox stays the global 12×12 control (never
       width:auto — that overrode the 12px rule and collapsed it under
       min-width:0). Delete glyph stays intrinsic too. */
    #v-it .it-scroll table.track.hg-tracker-compressed input.it-pick,
    #v-it .it-scroll table.track.hg-tracker-compressed input[type="checkbox"] {
      width: 12px !important;
      height: 12px !important;
      min-width: 12px !important;
      max-width: 12px !important;
      display: block;
      margin: 0 auto;
    }
    #v-ex .exp-scroll table.track.hg-tracker-compressed button.cv-del,
    #v-it .it-scroll table.track.hg-tracker-compressed button.cv-del, #v-rec .rec-scroll table.track.hg-tracker-compressed button.cv-del {
      width: auto !important;
      min-width: 0 !important;
      display: inline-block;
    }
    #v-cs #crewTable th { position: static; z-index: auto; }
    /* Crew uses the same scroll root and symmetric gutter as IT Tracker. */
    #v-cs #crewTable thead { position: static; }
    #v-cs #crewTable th { position: static !important; top: auto; z-index: auto; }
    /* IT Tracker header is outside the tbody scroll viewport. */
    #v-it.view.on, #v-rec.view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
    #v-it .it-scroll, #v-rec .rec-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box; }
    /* IT uses the same natural and compressed geometry as Crew above. */
    #v-it .it-scroll table.track, #v-rec .rec-scroll table.track { width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-it .it-scroll table.track th, #v-rec .rec-scroll table.track th { position: static; z-index: auto; }
    #v-it .it-scroll table.track th, #v-rec .rec-scroll table.track th { position: static !important; top: auto; z-index: auto; }
    /* Expenses — same geometry as IT Tracker (see docs/company-subtab-pattern.md). */
    #v-ex.view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
    #v-ex .exp-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box; }
    #v-ex .exp-scroll table.track { width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-ex .exp-scroll table.track th { position: static; z-index: auto; }
    #v-ex .exp-scroll table.track th { position: static !important; top: auto; z-index: auto; }
    /* Assets — same geometry as IT Tracker. */
    #v-ast.view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
    #v-ast .ast-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box; }
    #v-ast .ast-scroll table.track { width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-ast .ast-scroll table.track th { position: static; z-index: auto; }
    #v-ast .ast-scroll table.track th { position: static !important; top: auto; z-index: auto; }
    /* Client Invoices — same geometry as IT Tracker. */
    #v-cliInv.view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
    #v-cliInv .cli-inv-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box; }
    #v-cliInv .cli-inv-scroll table.track { width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-cliInv .cli-inv-scroll table.track th { position: static; z-index: auto; }
    #v-cliInv .cli-inv-scroll table.track th { position: static !important; top: auto; z-index: auto; }
    /* Contractor Invoices — same geometry as IT Tracker. */
    #v-ctiInv.view.on , #v-prl.view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
    #v-ctiInv .cti-inv-scroll , #v-prl .prl-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box; }
    #v-ctiInv .cti-inv-scroll table.track , #v-prl .prl-scroll table.track { width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-ctiInv .cti-inv-scroll table.track th , #v-prl .prl-scroll table.track th { position: static; z-index: auto; }
    #v-ctiInv .cti-inv-scroll table.track th , #v-prl .prl-scroll table.track th { position: static !important; top: auto; z-index: auto; }
    /* Payroll dedicated rules */
    #v-prl.view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
    #v-prl .prl-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box; }
    #v-prl .prl-scroll table.track { width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-prl .prl-scroll table.track.hg-tracker-compressed { width: 100%; table-layout: fixed; }
    #v-prl .prl-scroll table.track.hg-tracker-compressed td, #v-prl .prl-scroll table.track.hg-tracker-compressed th { overflow: hidden; }
    #v-prl .prl-scroll table.track.hg-tracker-compressed input, #v-prl .prl-scroll table.track.hg-tracker-compressed button { min-width: 0; max-width: none; }
    /* Recruitment — same geometry as other Company trackers. */
    #v-rc.view.on { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
    #v-rc .rc-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 var(--hg-tracker-side-padding); box-sizing: border-box; }
    #v-rc .rc-scroll table.track { width: max-content; min-width: 0; table-layout: auto; margin: 0 auto; }
    #v-rc .rc-scroll table.track th { position: static; z-index: auto; }
    #v-rc .rc-scroll table.track th { position: static !important; top: auto; z-index: auto; }
    /* Tag pill cells in the recruitment table */
    .rc-tag-cell { display: flex; flex-wrap: wrap; gap: 3px; align-items: center; }
    .rc-tag-cell .a-tag { font-size: var(--hg-type-10); padding: 1px 6px; }
    /* Actions bar sits under the table outside the scroll root — left edge
       aligned with the scroll root's 20px padding so it reads as part of the
       table's left margin, not the window edge. */
    #v-cs .cs-actions { flex-shrink: 0; margin: 0 0 16px; padding: 0 var(--hg-tracker-side-padding); }

    html.dark .cs-lic-span { color: var(--hg-text-dim); }
    html.dark .cs-lic-row { border-bottom-color: var(--hg-border-warm); }
    html.dark tr.cs-lic-panel > td {
      background: var(--hg-surface-raised); border-top-color: var(--hg-border-chrome);
    }
    html.dark .cs-lic-panel-head h5 { color: var(--hg-text-muted); }
    html.dark .cs-lic-empty { color: var(--hg-text-muted); }
    html.dark .cs-lic-input {
      background: var(--hg-surface-base); border-color: var(--hg-border-control); color: var(--hg-text-bright);
    }
    html.dark .cs-lic-input:focus { border-color: var(--hg-border-focus); }
    html.dark .cs-lic-row input[type="date"],
    html.dark .cs-lic-row select,
    html.dark .cs-lic-row input[type="text"] { color: var(--hg-text-bright); }
    html.dark .cs-lic-row input[type="date"]:focus,
    html.dark .cs-lic-row select:focus,
    html.dark .cs-lic-row input[type="text"]:focus {
      border-color: var(--hg-border-focus);
      /* fill NOT restated — unified: idle = selected */
    }
    /* Crew + IT inline-edit inputs — color is now centralized via
       .hg-cell-input + --hg-input-* tokens. These ID selectors only
       remain for the .cs-win-cell date inputs that don't have the class. */

    html.dark .cs-lic-cell .cs-lic-toggle.is-empty { color: var(--hg-text-muted); }
    html.dark .cs-win-cell input[type="date"] { color: var(--hg-text-bright); }

    /* IT Tracker — dark-mode non-input bits only (inputs are centralized) */
    html.dark #itTable .it-add-row { border-top-color: var(--hg-border-chrome); }
    html.dark #itTable .it-del { color: var(--hg-text-muted); }
    html.dark #itTable .it-del:hover { color: #c08a8a; }
    html.dark #itTable .it-summary { border-top-color: var(--hg-border-chrome); }
    /* Expenses — dark-mode non-input bits only (inputs are centralized) */
    html.dark #expTable .cv-add-row { border-top-color: var(--hg-border-chrome); }
    html.dark #expTable .cv-del { color: var(--hg-text-muted); }
    html.dark #expTable .cv-del:hover { color: #c08a8a; }
    html.dark #licenseModal .modal,
    html.dark #crewModal .modal { background: var(--hg-surface-elevated); color: var(--hg-text-bright); }
    html.dark #licenseList {
      border-color: var(--hg-border-chrome) !important; background: var(--hg-surface-base);
    }
    html.dark #licenseModal .cs-lic-input {
      background: var(--hg-surface-base); border-color: var(--hg-border-control); color: var(--hg-text-bright);
    }
    html.dark #licenseModal .mlab { color: var(--hg-text-muted); }
    html.dark #licenseModal .docsub { color: var(--hg-text-muted); }

  /* ===== 4f. cashflow dock (sibling of chart; pins to bottom of #v-tr) =====
     Share only the week X-scale with the Gantt. Horizontal scroll is synced
     in js/cashflow.js so milestone markers + weekly bars line up.
     Geometry (matches js/cashflow.js): BAR_AREA_H 92 + LABEL_STRIP_H 96 = 188 body.
          Title bar (28) sits above body; click toggles .is-collapsed → body slides away. */
       .cashflow-dock {
       flex-shrink: 0; box-sizing: border-box;
       display: flex; flex-direction: column;
       height: 216px; /* 28 title + 188 body */
       border-top: 2px solid var(--hg-accent);
       background: var(--hg-frost-bg);
       backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
       position: relative; z-index: 8;
       overflow: hidden;
       transition: height .22s ease;
       /* Gutter inherited from #v-tr .gantt-shell's margin — the dock bar
          sits flush inside the shell so its scroll viewport width matches
          the chart's exactly and week cells stay X-aligned. */
        }
  .cashflow-dock.is-collapsed {
    height: 28px; /* title bar only */
  }
  .cashflow-dock .cf-titlebar {
    flex-shrink: 0; height: 28px; box-sizing: border-box;
    display: flex; align-items: center; gap: 8px;
    padding: 0 12px;
    background: var(--hg-frost-head);
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
    border-bottom: 1px solid var(--hg-border-na);
    cursor: pointer; user-select: none;
    color: #26415e; font-size: var(--hg-type-11); font-weight: 600;
    letter-spacing: .03em;
  }
  .cashflow-dock .cf-titlebar:hover {
    background: color-mix(in srgb, var(--hg-accent) 10%, transparent);
  }
  .cashflow-dock .cf-titlebar:focus-visible {
    outline: 2px solid #4a7ab5; outline-offset: -2px;
  }
  .cashflow-dock .cf-caret {
    display: inline-block; width: 12px; text-align: center;
    font-size: var(--hg-type-10); line-height: 1; color: #5a6578;
    transition: transform .22s ease;
  }
  .cashflow-dock.is-collapsed .cf-caret {
    transform: rotate(-90deg); /* points right when body is tucked away */
  }
  .cashflow-dock .cf-titlebar-label { font-weight: 700; }
    .cashflow-dock .cf-titlebar-sub {
      font-weight: 500; color: var(--hg-text-secondary); letter-spacing: 0;
    }
    /* Title-bar meta — totals inline, right (mirrors .wl-titlebar-meta).
         Only the cashflow-deficit fragment (.cf-meta-bit.is-warn) is red. */
      .cashflow-dock .cf-titlebar-meta {
        margin-left: auto; font-weight: 600; color: var(--hg-info);
        font-variant-numeric: tabular-nums; letter-spacing: 0;
        font-size: var(--hg-type-11); min-width: 0;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
        max-width: min(62vw, 720px);
      }
      .cashflow-dock .cf-titlebar-meta .cf-meta-sep {
        font-weight: 500; color: inherit; opacity: .7;
      }
      .cashflow-dock .cf-titlebar-meta .cf-meta-bit.is-warn {
        color: var(--cf-deficit-t, var(--hg-danger));
        font-weight: 700;
      }
      .cashflow-dock .cf-body {
  flex: 0 0 auto;
  height: 188px; box-sizing: border-box;
  display: flex; min-height: 0;
  overflow: hidden;
  transition: height .22s ease;
  /* Gutter comes from .cashflow-dock's 20px margin — no body padding,
     so the dock scroll viewport width matches .gantt-wrap's exactly
     and week cells stay X-aligned at every scrollLeft. */
    }
  .cashflow-dock.is-collapsed .cf-body {
    height: 0;
  }
  .cashflow-dock .cf-label {
    width: var(--hg-gantt-label-w, 380px); flex-shrink: 0; box-sizing: border-box;
    border-right: 1px solid var(--hg-border-na); background: transparent;
    padding: 0; font-size: var(--hg-type-base); color: var(--hg-text-label);
    display: flex; align-items: stretch;
  }
  .cashflow-dock .cf-label-inner {
      flex: 1; display: flex; flex-direction: column;
      height: 100%; min-height: 0; padding: 0 12px; box-sizing: border-box;
      position: relative;
    }
    /* Top block = plot band (92px) — legend only; totals moved to title meta */
    .cashflow-dock .cf-label-top {
      height: 92px; flex-shrink: 0; box-sizing: border-box;
      display: flex; flex-direction: column; justify-content: center; gap: 6px;
      padding: 0;
    }
  .cashflow-dock .cf-label-title {
    font-size: var(--hg-type-11); color: #26415e; font-weight: 600; letter-spacing: .02em;
  }
  .cashflow-dock .cf-label-leg { font-size: var(--hg-type-11); color: var(--cf-label); }
  /* Bottom strip = four 24px value rows — must match track LABEL_STRIP_H */
  .cashflow-dock .cf-label-strip {
    height: 96px; flex-shrink: 0; box-sizing: border-box;
    display: flex; flex-direction: column; justify-content: flex-start;
    margin: 0; padding: 0; border-top: 0;
  }
  .cashflow-dock .cf-label-strip .cf-label-leg {
    height: 24px; line-height: 24px; box-sizing: border-box;
    font-size: var(--hg-type-11);
  }
  .cashflow-dock .cf-dot.income { color: var(--cf-income); }
  .cashflow-dock .cf-dot.deficit { color: var(--cf-deficit-t); }
  .cashflow-dock .cf-scroll {
    flex: 1; min-width: 0; overflow-x: auto; overflow-y: hidden;
    position: relative;
    scrollbar-width: none;
  }
  .cashflow-dock .cf-scroll::-webkit-scrollbar { display: none; height: 0; }
  #cashflowPanel {
  position: relative; height: 188px; box-sizing: border-box;
  background: transparent; min-width: 100%;
    }
  #cfTrack { position: absolute; inset: 0; overflow: hidden; }
  .weekhdr { display: flex; background: var(--hg-surface-base); border-bottom: 1px solid var(--hg-border-chrome); position: sticky; top: 0; z-index: 5; height: 42px; box-sizing: border-box;
    /* Groove — same recessed band as the tracks: light pools at the top
       edge, shade sits at the bottom. Matches the header rows' bevel. */
    box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
                inset 0 -2px 5px rgba(15,23,42,.02);
    /* Own compositing layer (same reasoning as .gfilters): sweeping the cursor
       across the date cells toggles the week-divisor strip + chevron on every
       seam crossing — raster churn in this band re-runs the timeline's shared
       render pass and could bake stale pixels into the frosted rows below
       (the full-height column ghost). The band is opaque, so promoting it
       changes nothing visually; its damage now stays in its own layer. */
    contain: layout style;
    will-change: transform;
  }
  .weekhdr .w {
          /* Fixed week column — driven by --hg-week-w (set by zoom handler).
             flex grow would stretch columns while bars stay on px math → misalignment. */
          flex: 0 0 var(--hg-week-w);
          width: var(--hg-week-w);
          min-width: var(--hg-week-w);
          max-width: var(--hg-week-w);
          box-sizing: border-box;
          text-align: center;
          font-size: var(--hg-type-9);
          color: var(--hg-text-dim);
          padding: 3px 0;
          border-left: 1px solid rgba(138, 147, 163, 0.5);
          line-height: 1.25;
          /* Text never spills out of a header cell, whatever the zoom tier
             writes into it — labels tier with zoom in gantt.js; this is the
             hard stop if anything ever outgrows its column. */
          white-space: nowrap;
          overflow: hidden;
          display: flex;
          flex-direction: column;
          justify-content: center;
          position: relative; /* anchors the week-divisor ::after strip */
        }
  .weekhdr .w .start { font-weight: 600; color: var(--hg-info); }
  .weekhdr .w .end { color: var(--hg-text-dim); }
  /* Week-divisor affordance: the boundary between two week headers is the
     show/hide target for that week's Sat+Sun columns. The strip is the last
     8px inside the cell's right edge (wireGanttWeekDivisor matches it).
     The highlight fires only while the pointer is actually IN the strip —
     JS toggles .divisor-in-range on mousemove, because the strip is
     narrower than the cell and CSS :hover cannot see the boundary. The
     chevron + accent hairline render inside the cell just left of the seam
     (the cell clips overflow, so a straddling affordance would be cut).
     Closed week: » opens Sat+Sun to the right. Open week: « folds them. */
  .weekhdr .w::after,
  .weekhdr .d.wk-end::after,
  .weekhdr .h.wk-end::after {
    content: ''; position: absolute; top: 0; bottom: 0; right: 0; width: 8px;
    cursor: pointer; user-select: none; z-index: 2;
  }
  .weekhdr .w.divisor-in-range::after,
  .weekhdr .d.wk-end.divisor-in-range::after,
  .weekhdr .h.wk-end.divisor-in-range::after {
    background: linear-gradient(to right,
      transparent 0px, var(--hg-accent) 6px, var(--hg-accent) 8px);
  }
  .weekhdr .w::before,
  .weekhdr .d.wk-end::before,
  .weekhdr .h.wk-end::before {
    content: '»'; position: absolute; top: 50%; right: 9px; z-index: 2;
    transform: translateY(-50%);
    font-size: 10px; line-height: 1; font-weight: 700;
    /* No opacity fade: an animated opacity promotes the pseudo-element and
       paints intermediate frames into the header band mid-sweep — the stale-bake
       window for the column ghost below the band. One atomic toggle instead. */
    color: var(--hg-accent); opacity: 0;
    pointer-events: none;
  }
  .weekhdr .w.divisor-in-range::before,
  .weekhdr .d.wk-end.divisor-in-range::before,
  .weekhdr .h.wk-end.divisor-in-range::before { opacity: 1; }
  /* An OPEN week's seam folds its Sat+Sun away — chevron points left. */
  .weekhdr .w.open-week::before,
  .weekhdr .d.wk-end.open-week::before,
  .weekhdr .h.wk-end.open-week::before { content: '«'; }
  html.dark .weekhdr .w.divisor-in-range::after,
  html.dark .weekhdr .d.wk-end.divisor-in-range::after,
  html.dark .weekhdr .h.wk-end.divisor-in-range::after {
    background: linear-gradient(to right,
      transparent 0px, var(--hg-accent) 6px, var(--hg-accent) 8px);
  }
  /* Day tier (zoom column >= 24px per day): one day-cell per workday column.
     A week holds 5; the day cell is 1/5 of the week width so bars/header
     stay aligned by the same --hg-week-w token. Weekdays name their day
     above the date number. */
  .weekhdr .d {
    flex: 0 0 calc(var(--hg-week-w) / 5);
    width: calc(var(--hg-week-w) / 5);
    min-width: calc(var(--hg-week-w) / 5);
    max-width: calc(var(--hg-week-w) / 5);
    box-sizing: border-box;
    text-align: center;
    font-size: var(--hg-type-9);
    color: var(--hg-text-dim);
    padding: 2px 0;
    border-left: 1px dashed rgba(154, 163, 176, 0.5);
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-weight: 600;
    position: relative; /* anchors the week-divisor ::after strip */
  }
  /* The day tier's week seam (Mon|Sun boundary) — solid, full weight, so
     the weekend boundary always outranks the dashed day lines. */
  .weekhdr .d.wk-start { border-left: 1px solid rgba(138, 147, 163, 0.5); }
  html.dark .weekhdr .d.wk-start { border-left-color: rgba(0, 0, 0, 0.85); }
  html.dark .weekhdr .d { border-left-color: rgba(0, 0, 0, 0.6); }
  .weekhdr .d .d-name {
    font-size: calc(var(--hg-type-9) * 0.82);
    font-weight: 500;
    color: var(--hg-text-muted);
    line-height: 1;
    letter-spacing: 0;
  }
  .weekhdr .d .d-num { line-height: 1.2; }
  /* Weekend day cells (open week): the same shared hairline grammar, tinted
     toward the weekend so the open Sat/Sun columns read as weekend, not
     weekdays. Tokens only — no new chrome. */
  .weekhdr .d.wknd {
    color: var(--hg-text-muted);
  }
  /* Month tier (annual / multi-month): one cell per calendar month over
     the week columns. Inner week seams keep the calendar readable — the
     cell spans several weeks and carries no weekend affordance. */
  .weekhdr .m {
    flex-grow: 0; flex-shrink: 0;
    box-sizing: border-box; text-align: center;
    font-size: var(--hg-type-9); color: var(--hg-text-dim);
    padding: 3px 0; border-left: 1px solid rgba(138, 147, 163, 0.5);
    line-height: 1.25; white-space: nowrap; overflow: hidden;
    display: flex; flex-direction: column; justify-content: center;
    position: relative;
  }
  .weekhdr .m .start { font-weight: 600; color: var(--hg-info); }
  .weekhdr .m .hg-week-seam {
    position: absolute; top: 0; bottom: 0; width: 1px;
    background: rgba(138, 147, 163, 0.35); pointer-events: none;
  }
  /* Hour + minute tiers: one cell per civil hour of every visible day.
     Hour lines are lighter dashes; day boundaries keep the dashed day
     line; week boundaries keep the solid seam — the same hierarchy the
     wider tiers use, one scale down. */
  .weekhdr .h {
    flex-grow: 0; flex-shrink: 0;
    box-sizing: border-box; text-align: center;
    color: var(--hg-text-dim); padding: 2px 0;
    border-left: 1px dashed rgba(154, 163, 176, 0.35);
    line-height: 1.15; white-space: nowrap; overflow: hidden;
    display: flex; flex-direction: column; justify-content: flex-start;
    font-size: var(--hg-type-9); position: relative;
  }
  .weekhdr .h .h-top { display: flex; align-items: center; justify-content: center; gap: 2px; height: 14px; }
  .weekhdr .h .h-num { color: var(--hg-text-muted); font-size: calc(var(--hg-type-9) * 0.85); }
  .weekhdr .h .h-num.h-day-start { font-weight: 600; color: var(--hg-text-dim); }
  .weekhdr .h .hg-daymark { font-size: calc(var(--hg-type-9) * 0.85); font-weight: 600; color: var(--hg-text-dim); }
  .weekhdr .h.wk-start { border-left: 1px solid rgba(138, 147, 163, 0.5); }
  .weekhdr .h.wknd { color: var(--hg-text-muted); }
  .weekhdr .h .hg-subticks { display: flex; width: 100%; height: 10px; align-items: flex-end; }
  .weekhdr .h .hg-subtick { font-size: 7px; line-height: 1; color: var(--hg-text-muted); text-align: center; overflow: hidden; }
  .weekhdr .h.minute-tier .hg-subtick.labelled { font-size: 8px; }
  /* Hour tier: minute subdivisions as three 1px ticks at the 15-minute
     marks — no DOM spans, the strip carries the grid. */
  .weekhdr .h:not(.minute-tier) .hg-subticks {
    background-image:
      linear-gradient(to bottom, rgba(154, 163, 176, 0.4) 50%, transparent 50%),
      linear-gradient(to bottom, rgba(154, 163, 176, 0.4) 50%, transparent 50%),
      linear-gradient(to bottom, rgba(154, 163, 176, 0.4) 50%, transparent 50%);
    background-size: 1px 6px, 1px 6px, 1px 6px;
    background-position: 25% 0, 50% 0, 75% 0;
    background-repeat: repeat-y;
  }
  html.dark .weekhdr .h:not(.minute-tier) .hg-subticks {
    background-image:
      linear-gradient(to bottom, rgba(0, 0, 0, 0.4) 50%, transparent 50%),
      linear-gradient(to bottom, rgba(0, 0, 0, 0.4) 50%, transparent 50%),
      linear-gradient(to bottom, rgba(0, 0, 0, 0.4) 50%, transparent 50%);
  }
  /* Bounded header materialization: hidden offscreen days collapse into one
     placeholder of the exact combined width — the flex total, and therefore
     every bar's alignment, is identical to the full materialization. */
  .weekhdr .hg-header-gap { flex-grow: 0; flex-shrink: 0; box-sizing: border-box; }
  .gscroll { overflow: auto; }
  #lanes .hg-stage { display: flex; border-bottom: 1px solid var(--hg-border-na); height: 30px; box-sizing: border-box; position: relative; background: var(--hg-surface-input); overflow: visible; }
  #lanes .hg-stage .cells,
  #lanes .hg-entity .cells,
  #lanes .hg-lane.lane-side .cells {
    display: flex;
    flex: 0 0 auto; /* grow to sum of fixed 56px week cells — don't stretch columns */
    position: relative;
    overflow: hidden;
    min-width: 0;
  }
  /* Week column = solid left border on .cell (and .weekhdr .w).
       Day ticks = 4 dashed verticals at exact workday edges (W/5 × {1,2,3,4}):
       Mon·Tue · Tue·Wed · Wed·Thu · Thu·Fri. Pixel positions lock to bar scale;
       % of a flex-grown cell would drift from header + bar geometry.
       Opacity 50% — orientation only, not chrome.
       Open-week cells (weekend shown) hide the day ticks — their column is
       7 day-columns wide and the uniform W/5 positions would misplace; the
       weekend tint carries the read until the seam marker task. */
    .cell {
      flex: 0 0 var(--hg-week-w);
      width: var(--hg-week-w);
      min-width: var(--hg-week-w);
      max-width: var(--hg-week-w);
      box-sizing: border-box;
      border-left: 1px solid rgba(138, 147, 163, 0.5);
      background-color: transparent;
      background-image:
        linear-gradient(to bottom, rgba(154, 163, 176, 0.5) 50%, transparent 50%),
        linear-gradient(to bottom, rgba(154, 163, 176, 0.5) 50%, transparent 50%),
        linear-gradient(to bottom, rgba(154, 163, 176, 0.5) 50%, transparent 50%),
        linear-gradient(to bottom, rgba(154, 163, 176, 0.5) 50%, transparent 50%);
      background-size: 1px 6px, 1px 6px, 1px 6px, 1px 6px;
      /* W/5 × {1,2,3,4} — left edge of each 1px tick, scales with --hg-week-w */
      background-position:
        calc(var(--hg-week-w) / 5 * 1) 0,
        calc(var(--hg-week-w) / 5 * 2) 0,
        calc(var(--hg-week-w) / 5 * 3) 0,
        calc(var(--hg-week-w) / 5 * 4) 0;
      background-repeat: repeat-y;
    }
  /* Open-week lane cell (weekend columns visible): 7 day-columns wide — the
     uniform W/5 tick positions no longer mark workday edges, so the open
     cell carries explicit per-day gridline divs (gantt.js wkGrid). Each
     paints the classic 1px dashed tick (the same gradient the closed
     weeks' cells use), anchored INSIDE the cell — the cell must be
     positioned or its absolute children land at the row start.
     Hiding/showing a weekend reads as hiding/showing table columns. */
  .cell.open-week {
    position: relative;
    background-image: none;
  }
  .cell.open-week .wk-grid {
    position: absolute; top: 0; bottom: 0;
    box-sizing: border-box;
    background-color: transparent;
    background-image: linear-gradient(to bottom, rgba(154, 163, 176, 0.5) 50%, transparent 50%);
    background-size: 1px 6px;
    background-repeat: repeat-y;
    background-position: 0 0;
  }
  /* Exposing a weekend is purely additive: the Sat/Sun columns and their
     dashed day lines appear — NO other line may appear, move or change
     weight. The week's own left edge already carries the cell's solid
     border, so the first day's tick is suppressed. Never give an open-week
     grid div a border: it lands one pixel inside the cell's own border and
     paints the seam 2px wide. */
  .cell.open-week .wk-grid:first-child { background-image: none; }
  .cell.open-week .wk-grid.wknd {
    background-color: color-mix(in srgb, var(--hg-accent) 5%, transparent);
  }
  /* Lane-side partners of segment/group headers host the collapsed roll-up bar
     on the SAME 30px row — never a second spacer. position:relative for .gbar. */
  #labelsPanel .hg-entity {
    display: flex; align-items: center; gap: 8px; background: var(--hg-frost-bg);
    padding: 0 8px; font-weight: 500; font-size: calc(var(--hg-type-12h) * 0.8); letter-spacing: 0;
    border-bottom: 1px solid var(--hg-border-na); height: 30px; box-sizing: border-box; overflow: hidden;
    position: relative;
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  }
  #lanes .hg-entity {
    display: flex; align-items: center; gap: 8px; background: #e9ecf1;
    padding: 0 8px; font-weight: 700; font-size: var(--hg-type-11); letter-spacing: .06em;
    border-bottom: 1px solid var(--hg-border-na); height: 30px; box-sizing: border-box; overflow: hidden;
    position: relative;
  }
  /* Labels-side text is set by .gantt-labels .hg-entity (visible).
     Lanes-side band must keep transparent text because it hosts bars, not labels. */
  #lanes .hg-entity { color: transparent; }
  #lanes .hg-entity .days { margin-left: auto; font-weight: 600; color: transparent; }
  #lanes .hg-entity .cells { display: flex; flex: 0 0 auto; position: relative; overflow: hidden; min-width: 0; height: 100%; }
  #labelsPanel .hg-lane {
    display: flex; align-items: center; gap: 6px; background: var(--hg-frost-bg); padding: 0 8px;
    font-weight: 600; font-size: var(--hg-type-medium); letter-spacing: -.01em; color: var(--hg-text-ink);
    border-bottom: 1px solid #c9d0dc; height: 30px; box-sizing: border-box; overflow: hidden;
    /* Inter-lane padding: gap above every segment header except the first
       in each panel, so lanes read as separate bands without altering the
       spacing between stage tracks or between a track and its segment. */
    margin-top: 10px;
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  }
  #lanes .hg-lane {
    display: flex; align-items: center; gap: 6px; background: #dfe4ec; padding: 0 8px;
    font-weight: 600; font-size: var(--hg-type-medium); letter-spacing: -.01em; color: var(--hg-text-ink);
    border-bottom: 1px solid #c9d0dc; height: 30px; box-sizing: border-box; overflow: hidden;
    /* Inter-lane padding: gap above every segment header except the first
       in each panel, so lanes read as separate bands without altering the
       spacing between stage tracks or between a track and its segment. */
    margin-top: 10px;
  }
  /* Zero the gap on the first segment in each panel so there's no void
     between the sticky header strip and the first hg-stage. (Label side:
     rows live inside .labels-rows > .labels-block, so neither the head+lane
     sibling rule nor the wrapper's first-child rule applies — target the
     first lane in the FIRST block instead.) */
  #labelsPanel .labels-head + .hg-lane,
  #labelsPanel .labels-rows > .labels-block:first-child > .hg-lane,
  #lanes > .hg-lane:first-child { margin-top: 0; }
  #labelsPanel .hg-lane > span:first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #labelsPanel .hg-lane .days { margin-left: auto; flex-shrink: 0; font-weight: 600; color: var(--hg-text-ink); font-variant-numeric: tabular-nums; letter-spacing: 0; font-size: var(--hg-type-10); }
  #labelsPanel .hg-lane .days.days-over { color: var(--hg-danger); }
  #labelsPanel .hg-lane .days.days-under { color: #2d7a4f; }
  /* Segment policy chips on the lane row (ganttSegmentPolicyChips):
     calendar/clock SVG icon for the scheduling model, 5d/7d for the weekend
     cadence. Muted ink; the words live in the RMB menu + chip titles.
     The lanes-side twin renders identical markup but stays invisible so
     both columns keep matching row layout. */
  #labelsPanel .hg-lane .seg-policy { display: flex; align-items: center; flex-shrink: 0; gap: 4px; color: var(--hg-text-muted); font-variant-numeric: tabular-nums; }
  #labelsPanel .hg-lane .seg-policy-glyph { display: inline-flex; align-items: center; }
  #labelsPanel .hg-lane .seg-policy-glyph svg { display: block; width: 13px; height: 13px; }
  #labelsPanel .hg-lane .seg-policy-days { font-size: var(--hg-type-10); font-weight: 600; letter-spacing: 0; }
  #lanes .hg-lane .seg-policy { display: none; }
  #lanes .hg-lane.lane-side {
    color: transparent; padding: 0; position: relative; overflow: hidden;
  }
  #lanes .hg-lane.lane-side .days { color: transparent; }
  #lanes .hg-lane.lane-side .cells { display: flex; flex: 0 0 auto; position: relative; overflow: hidden; min-width: 0; height: 100%; }
      .collapse-btn { border: 1px solid #c0c6d2; background: linear-gradient(#ffffff, #f3f4f7); border-radius: 3px; font-size: var(--hg-type-9); padding: 0 6px; cursor: pointer; color: #5b6272; box-shadow: inset 0 1px 0 #ffffff; flex-shrink: 0; }
  .collapse-btn:hover { background: #eef0f4; }
  /* Segment/group headers: whole label row toggles expand (chevron removed). */
  .gantt-labels .gantt-toggle-row { cursor: pointer; user-select: none; }
  /* No `filter` here: these rows carry backdrop-filter, and animating filter
     forces a compositing-layer rebuild — the hover flash. A translucent
     overlay tint reads the same and paints without the rebuild. */
  .gantt-labels .gantt-toggle-row:hover { background-image: linear-gradient(rgba(15,23,42,.015), rgba(15,23,42,.015)); }
  .gantt-labels .gantt-toggle-row:focus-visible { outline: 2px solid var(--gbar-appr-bg); outline-offset: -2px; }
  .block-btn { border: 1px solid var(--hg-border-control); background: var(--hg-surface-tabs); color: var(--hg-text-ink); border-radius: 4px; font-size: var(--hg-type-11); font-weight: 500; padding: 4px 10px; cursor: pointer; }
  .block-btn.on { background: var(--hg-accent); border-color: var(--hg-accent); color: var(--hg-text-on-accent); }
  .block-btn:hover { border-color: var(--hg-border-hover); color: var(--hg-text-ink); }
  /* ===== 4g. money/doc views ===== */
  .doc {
    max-width: 820px; margin: 0 auto; padding: 28px 34px;
    margin-top: 16px; margin-bottom: 40px;
    background: transparent; border: none;
  }
  .doc h1 { font-size: var(--hg-type-18); margin-bottom: 2px; }
  .doc .docsub { color: var(--hg-text-secondary); font-size: var(--hg-type-11); margin-bottom: 18px; }
  .doc table { width: 100%; border-collapse: collapse; background: transparent; }
  .doc td, .doc th { padding: 6px 8px; border-bottom: 1px solid var(--hg-border-cell); font-size: var(--hg-type-base); }
  .doc th { text-align: left; font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .06em; color: var(--hg-text-label); border-bottom: 2px solid var(--hg-border-na); position: sticky; top: 79px; z-index: 34; background: var(--hg-surface-input); padding-bottom: 10px; }
  .doc .num { text-align: right; font-variant-numeric: tabular-nums; }
  .doc .doc-total td { font-weight: 700; border-top: 2px solid var(--hg-accent); }
  .doc .gen { font-size: var(--hg-type-10); color: var(--hg-text-dim); margin-top: 14px; }

  /* ===== 4h. drawer ===== */
  .drawer { position: fixed; right: 0; top: 0; bottom: 0; width: 360px; background: var(--hg-surface-input); border-left: 1px solid #d7dae1; box-shadow: var(--hg-shadow-slide); z-index: 80; padding: 20px; display: none; overflow-y: auto; }
  .drawer.open { display: block; }
  .drawer h2 { font-size: var(--hg-type-large); margin-bottom: 4px; }
  .drawer .kv { display: grid; grid-template-columns: 100px 1fr; gap: 6px 10px; margin-top: 14px; font-size: var(--hg-type-base); }
  .drawer .kv .k { color: var(--hg-text-label); }
  .drawer .x { position: absolute; top: 12px; right: 14px; cursor: pointer; color: var(--hg-text-dim); font-size: var(--hg-type-large); }
  .drawer .thread { margin-top: 14px; padding: 10px; background: #f6f7f9; border-radius: 7px; font-size: var(--hg-type-11h); color: #4a5262; }
  .drawer h4 { margin-top: 16px; font-size: var(--hg-type-11); text-transform: uppercase; letter-spacing: .06em; color: var(--hg-text-dim); }
  .drawer ul { margin: 6px 0 0 16px; font-size: var(--hg-type-base); }
/* ===== 5. DARK OVERRIDES — hairline structure, near-black ===== */
  html.dark body { color: var(--hg-text-bright); background: var(--hg-surface-base); }
  html.dark body::before { filter: none; opacity: .14; }
  html.dark header { background: var(--hg-surface-header); border-bottom-color: var(--hg-border-chrome); }
  html.dark .proj-new-form, html.dark .proj-settings-form { background: var(--hg-surface-raised); border-color: var(--hg-border-control); box-shadow: var(--hg-shadow-pop); }
  html.dark .proj-new-form input, html.dark .proj-settings-form input { background: var(--hg-surface-base); border-color: var(--hg-border-control); color: var(--hg-text-bright); }
  html.dark .proj-new-form input:focus, html.dark .proj-settings-form input:focus { border-color: #8a8c92; outline: none; }
  html.dark .proj-new-form .form-btns .create, html.dark .proj-settings-form .form-btns .create { background: var(--hg-accent); border-color: var(--hg-accent); color: var(--gbar-rev-ink); }
    html.dark .proj-new-form .form-btns .create:hover, html.dark .proj-settings-form .form-btns .create:hover { background: #e2b155; }
    html.dark .proj-settings-form .form-btns .dup { background: transparent; color: #c8c8ce; border-color: var(--hg-border-control); }
    html.dark .proj-settings-form .form-btns .dup:hover { border-color: #8a8c92; color: var(--hg-text-bright); }
    html.dark .proj-new-form .form-btns .cancel, html.dark .proj-settings-form .form-btns .cancel { background: transparent; color: var(--hg-text-muted); border-color: var(--hg-border-control); }
    html.dark .dup-mode-pop { background: var(--hg-surface-raised); border-color: var(--hg-border-control); box-shadow: var(--hg-shadow-pop); }
    html.dark .dup-mode-btn:hover { background: #26272b; }
    html.dark .dup-mode-label { color: var(--hg-text-bright); }
    html.dark .dup-mode-desc { color: var(--hg-text-muted); }
  html.dark header .meta { color: var(--hg-text-muted); }
  html.dark .agent-strip-head { color: var(--hg-text-muted); }
  html.dark .dot { background: #3fae6e; }
  html.dark .theme-btn { background: transparent; border-color: var(--hg-border-control); color: #b8b9be; }
  html.dark .theme-btn:hover { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .scope-tab { color: var(--hg-text-muted); }
  html.dark .scope-tab:hover { color: var(--hg-text-bright); }
  html.dark .scope-tab.on { color: var(--hg-text-bright); border-bottom-color: var(--hg-accent); }
  html.dark .proj-strip { background: var(--hg-surface-tabs); border-bottom-color: var(--hg-border-chrome); }
  html.dark .proj-strip .proj-select { color: var(--hg-text-bright); }
  html.dark .proj-strip .proj-select:hover { background-color: var(--hg-surface-card); }
  html.dark .proj-strip .proj-new-btn { background: transparent; border-color: var(--hg-border-control); color: #b8b9be; }
  html.dark .proj-strip .proj-new-btn:hover { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .proj-strip .proj-edit-btn { color: var(--hg-text-muted); }
  html.dark .proj-strip .proj-edit-btn:hover { background: var(--hg-surface-card); color: #b8b9be; }
  html.dark .tabs { background: var(--hg-surface-tabs); border-bottom-color: var(--hg-border-chrome); }
  html.dark .tab { color: var(--hg-text-muted); }
  html.dark .tab:hover { color: var(--hg-text-bright); background: transparent; }
  html.dark .tab.on { color: var(--hg-text-bright); border-bottom-color: var(--hg-accent); }
  html.dark .subtabs { background: var(--hg-surface-tabs); border-bottom-color: var(--hg-border-chrome); }
  html.dark .subtab { color: var(--hg-text-muted); }
  html.dark .subtab:hover { color: var(--hg-text-bright); }
  html.dark .subtab.on { color: var(--hg-text-bright); border-bottom-color: var(--hg-accent); }
  html.dark table.track { background: transparent; }
  html.dark table.track th, html.dark #crewTable th { border-bottom-color: var(--hg-border-chrome); background: var(--hg-frost-head); color: var(--hg-text-muted); }
  html.dark table.track td, html.dark #crewTable td { border-bottom-color: var(--hg-border-cell); }
  /* Dark row highlight: same ONE token as the header (--hg-frost-head). */
  /* Assets — dark-mode non-input bits only (inputs are centralized) */
  html.dark #astTable .cv-add-row { border-top-color: var(--hg-border-chrome); }
  html.dark #astTable .cv-del { color: var(--hg-text-muted); }
  html.dark #astTable .cv-del:hover { color: #c08a8a; }
  html.dark #v-cs #crewTable tbody tr:hover td,
  html.dark #v-it table.track tbody tr:hover td,
  html.dark #v-ex table.track tbody tr:hover td,
  html.dark #v-rc table.track tbody tr:hover td,
  html.dark #v-ast table.track tbody tr:hover td,
  html.dark #v-cliInv table.track tbody tr:hover td,
  html.dark #v-ctiInv table.track tbody tr:hover td, html.dark #v-prl table.track tbody tr:hover td,
  html.dark .ov-scroll .cf-forecast-scroll table.track tbody tr:hover td, html.dark table.track tbody tr:hover td , html.dark .ov-scroll .cf-forecast-scroll table.track tbody tr:hover td, html.dark #v-rec table.track tbody tr:hover td {
    background: var(--hg-frost-hover);
    backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  }
  /* Dark tracker headers: same ONE token — base rule above paints all th. No scoped override. */
  html.dark #v-cs #crewTable, html.dark #v-it table.track, html.dark #v-ex table.track, html.dark #v-ast table.track, html.dark #v-cliInv table.track, html.dark #v-ctiInv table.track, #v-prl table.track, html.dark #v-rc table.track, html.dark .ov-scroll .cf-forecast-scroll table.track, html.dark table.track , .ov-scroll .cf-forecast-scroll table.track, html.dark #v-rec table.track { background: transparent; }
  html.dark #v-cs #crewTable tbody, html.dark #v-it table.track tbody, html.dark #v-ex table.track tbody, html.dark #v-ast table.track tbody, html.dark #v-cliInv table.track tbody, html.dark #v-ctiInv table.track tbody, html.dark #v-prl table.track tbody, html.dark #v-rc table.track tbody, html.dark .ov-scroll .cf-forecast-scroll table.track tbody, html.dark table.track tbody , .ov-scroll .cf-forecast-scroll table.track tbody, html.dark #v-rec table.track tbody {
    background: var(--hg-frost-bg); background-clip: padding-box;
    backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  }
  /* Dark mode: same corner geometry as light — radius lives on the corner
     cells (tbody radius is inert in Chromium), so only the wash token is
     restated here. The light-section corner rules are theme-independent. */
  html.dark #v-cs .cs-scroll, html.dark #v-it .it-scroll, html.dark #v-ex .exp-scroll, html.dark #v-ast .ast-scroll, html.dark #v-cliInv .cli-inv-scroll, html.dark #v-ctiInv .cti-inv-scroll, #v-prl .prl-scroll, html.dark #v-rc .rc-scroll, html.dark .ov-scroll .cf-forecast-scroll, html.dark , .ov-scroll .cf-forecast-scroll, html.dark #v-rec .rec-scroll { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
  html.dark .st-ip { background: var(--st-ip-bg); color: var(--st-ip-ink); }
  html.dark .st-wtg { background: var(--hg-surface-hover); color: #8b8c92; }
  html.dark .st-rev { background: var(--st-rev-bg); color: var(--st-rev-ink); }
  html.dark .st-cmpt { background: var(--st-cmpt-bg); color: var(--st-cmpt-ink); }
  html.dark .st-appr { background: var(--st-appr-bg); color: var(--hg-info); }
  html.dark .st-reopen { background: var(--st-reopen-bg); color: var(--st-reopen-ink); }
  html.dark select.st-select.st-ip { background-color: var(--st-ip-bg); color: var(--st-ip-ink); }
  html.dark select.st-select.st-wtg { background-color: var(--hg-surface-hover); color: #8b8c92; }
  html.dark select.st-select.st-rev { background-color: var(--st-rev-bg); color: var(--st-rev-ink); }
  html.dark select.st-select.st-cmpt { background-color: var(--st-cmpt-bg); color: var(--st-cmpt-ink); }
  html.dark select.st-select.st-appr { background-color: var(--st-appr-bg); color: var(--hg-info); }
  html.dark select.st-select.st-reopen { background-color: var(--st-reopen-bg); color: var(--st-reopen-ink); }
  html.dark select.st-select option { background-color: var(--hg-surface-raised); color: var(--hg-text-bright); }
  html.dark .linked { color: var(--hg-info); }
  html.dark .shot-grp td { background: var(--hg-surface-elevated); color: var(--hg-text-muted); }
  html.dark .mine { outline-color: #3fae6e44; background: #1a2420 !important; }
  html.dark .summary { border-top-color: var(--hg-border-chrome); border-bottom-color: var(--hg-border-chrome); }
  html.dark .sum-card { border-right-color: var(--hg-border-chrome); }
  html.dark .sum-card .l { color: var(--hg-text-muted); }
  html.dark .sum-card .s { color: var(--hg-text-muted); }
  html.dark .sum-card.total { border-color: var(--hg-border-chrome); }
  html.dark .sum-card.total .l, html.dark .sum-card.total .s { color: var(--hg-text-muted); }
  html.dark .sum-card.total .v { color: var(--hg-accent); }
  html.dark table.bid { background: transparent; }
  html.dark table.bid .dept td { background: var(--hg-surface-elevated); color: var(--hg-text-muted); border-top-color: var(--hg-border-chrome); }
  html.dark table.bid .dept td .tots { color: var(--hg-info); }
  html.dark table.bid td { border-bottom-color: var(--hg-border-cell); }
  html.dark table.bid tr.line:hover td { background: var(--hg-surface-raised); }
  html.dark table.bid .subtotal td { background: transparent; border-top-color: var(--hg-border-chrome); }
  html.dark table.bid .grand td { background: var(--hg-surface-elevated); color: var(--hg-text-bright); }
  html.dark .src-agent { background: var(--st-appr-bg); color: var(--hg-info); }
  html.dark .src-human { background: var(--st-cmpt-bg); color: var(--st-cmpt-ink); }
  html.dark .src-delta { background: var(--st-rev-bg); color: var(--st-rev-ink); }
  html.dark .delta td { background: #231d12; }
  html.dark .delta .c-name { color: var(--st-rev-ink); }
  html.dark td.editable:hover { background: #231d12; }
  html.dark td.editing { background: #2c2414; outline-color: var(--st-rev-ink); }
  html.dark .add-line { color: var(--hg-text-muted); border-bottom-color: var(--hg-border-cell); }
  html.dark .add-line:hover { color: var(--hg-info); background: var(--hg-surface-raised); }
  html.dark .toast { background: var(--hg-surface-hover); box-shadow: var(--hg-shadow-pop); color: var(--hg-text-bright); }
  html.dark .gfilters select, html.dark .gfilters input,
  html.dark .crew-pick,
  html.dark select, html.dark input[type="text"], html.dark input[type="number"] {
    background-color: var(--hg-surface-raised); border-color: var(--hg-border-control); color: var(--hg-text-bright);
  }
  html.dark select:focus, html.dark input[type="text"]:focus, html.dark input[type="number"]:focus { border-color: var(--hg-border-focus); outline: none; }
  /* Centralized tracker cell inputs keep their --hg-input-* token look in dark
     mode. This re-assert must sit AFTER the generic fallback above — the base
     rule ties it on specificity and wins by position. Any new shared
     cell-input class must be added to this selector list too. */
  html.dark input.hg-cell-input,
  html.dark input.hg-cell-input-new {
    background: var(--hg-input-bg); border: var(--hg-input-border); color: var(--hg-input-color);
  }
  html.dark input.hg-cell-input-new { border: var(--hg-input-border-visible); }
  html.dark input.hg-cell-input:hover,
  html.dark input.hg-cell-input-new:hover { border-color: var(--hg-input-border-hover); }
  html.dark input.hg-cell-input:focus,
  html.dark input.hg-cell-input-new:focus {
    border-color: var(--hg-input-border-focus); outline: none;
    /* fill intentionally NOT restated: --hg-input-bg is idle = selected */
  }
  /* .hg-ctl (boxed form control): border/bg/type tokens flip automatically;
     only the text token needs a dark twin (--hg-text-ink does NOT flip).
     Scoped to input/textarea so .hg-ctl.hollow buttons keep their muted ink.
     bg/border re-asserts tie the generic fallback above on specificity and
     win by position; :focus re-assert restores the §10 focus border. */
  html.dark input.hg-ctl, html.dark textarea.hg-ctl {
    background-color: var(--hg-input-bg); border-color: var(--hg-border-control); color: var(--hg-input-ink);
  }
  html.dark input.hg-ctl:focus, html.dark textarea.hg-ctl:focus { border-color: var(--hg-border-focus); outline: none; }
  /* Underline controls (.hg-inp / .tbl-inp): the fallback also paints these
     opaque — pin only the background; border/color nuances stay with the
     html.dark .hg-inp / .tbl-inp rules further down. */
  html.dark input.hg-inp, html.dark input.tbl-inp,
  html.dark textarea.hg-inp, html.dark textarea.tbl-inp { background-color: var(--hg-input-bg); }
  html.dark .btn-new { border: 1px solid color-mix(in srgb, var(--seg-accent) 45%, rgba(255,255,255,.3)); background: color-mix(in srgb, var(--seg-accent) 25%, transparent); color: var(--hg-text-bright); box-shadow: none; }
  html.dark .btn-new:hover { background: color-mix(in srgb, var(--seg-accent) 35%, transparent); }
  html.dark .btn-new.hg-confirm-danger { background: var(--hg-danger); border-color: var(--hg-danger); color: var(--hg-text-bright); }
  html.dark .btn-new.hg-confirm-danger:hover { background: var(--hg-danger-hover); }
  html.dark .btn-ghost { background: transparent; border-color: var(--hg-border-control); color: #b8b9be; box-shadow: none; }
  html.dark .btn-ghost:hover { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .hg-lane {
    border-bottom-color: var(--hg-border-control); color: var(--hg-text-bright);
    background: var(--hg-frost-head);
  }
  html.dark .hg-lane:hover {
    box-shadow: 0 4px 8px rgba(0,0,0,.32),
                0 -4px 12px color-mix(in srgb, var(--seg-accent) var(--hg-lane-op-h), transparent);
  }
  html.dark .hg-lane:active {
    box-shadow: none;
  }
  html.dark .hg-lane .seg-meta { color: var(--hg-info); }
  html.dark .hg-lane .seg-hint { color: var(--hg-text-muted); }
  html.dark .hg-lane .tw { color: var(--hg-text-muted); }
  html.dark .hg-lane .seg-name-input,
  html.dark .hg-lane .seg-name-input:hover,
  html.dark .hg-lane .seg-name-input:focus { background: transparent; color: inherit; border-color: transparent; }
  html.dark .hg-lane .seg-name-input:hover { border-color: var(--hg-border-control); }
  html.dark .hg-lane .seg-name-input:focus { border-color: var(--hg-border-hover); }
  html.dark .seg-hidden-toggle { color: var(--hg-text-muted); }
  html.dark .seg-hidden-toggle:hover { color: var(--hg-text-bright); }
  html.dark .seg-hidden-row { color: var(--hg-border-focus); }
  html.dark .seg-hidden-row .seg-restore { background: transparent; border-color: var(--hg-border-control); color: #b8b9be; }
  html.dark .seg-hidden-row .seg-restore:hover { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .seg-hidden-row .seg-delete { background: transparent; border-color: #5a3330; color: #d08a82; }
  html.dark .seg-hidden-row .seg-delete:hover { border-color: var(--hg-danger); color: #e0655f; }
  html.dark .seg-tmpl { color: var(--hg-text-muted); }
  html.dark .seg-tmpl:hover { color: var(--hg-text-bright); }
  html.dark .hg-entity-block { border-bottom-color: var(--hg-border-cell); }
  html.dark .hg-entity:hover { background: color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent);
    box-shadow: 0 3px 6px rgba(0,0,0,.28),
                0 -3px 10px color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent); }
  html.dark .hg-entity:active {
    box-shadow: none;
  }
  html.dark .hg-entity .tw { color: var(--hg-text-muted); }
  html.dark .hg-entity .a-type { color: var(--hg-text-muted); background: transparent; }
  html.dark .hg-entity .a-days { color: var(--hg-info); }
  html.dark .hg-entity .a-dup { color: var(--hg-text-muted); }
  html.dark .hg-entity .a-dup:hover { color: var(--hg-text-bright); background: transparent; }
  html.dark .hg-entity .a-copy, html.dark .hg-entity .a-paste { color: var(--hg-text-muted); }
  html.dark .hg-entity .a-paste.empty { color: var(--hg-text-muted); }
  html.dark .hg-entity .a-copy:hover { color: var(--hg-text-bright); background: #26272b; }
  html.dark .hg-entity .a-paste:hover:not(.empty) { color: var(--hg-text-bright); background: #26272b; }
  html.dark .hg-entity-body { border-top-color: var(--hg-border-cell); }
  html.dark .card-actions-row { border-top-color: #2a2b2f; }
  html.dark #assetTree .hg-stage { border-bottom-color: #1a1b1f; }
  html.dark .t-spinner .sp { background: transparent; border-color: var(--hg-border-control); color: var(--hg-text-muted); box-shadow: none; }
  html.dark .t-spinner .sp:hover { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .t-spinner .t-days { border-color: var(--hg-border-control); }
  html.dark .t-cost { color: var(--hg-info); }
  html.dark #assetTree .hg-stage .t-cost input { border-color: var(--hg-border-control); background: var(--hg-input-bg); color: var(--hg-text-bright); height: 22px; }
  html.dark #assetTree .hg-stage .t-cost input:focus { border-color: var(--hg-border-hover); }
  html.dark #assetTree .hg-stage .t-cost .t-cur { color: var(--hg-text-muted); }
  html.dark #assetTree .hg-stage .t-model-inputs input { border-color: var(--hg-border-control); background: var(--hg-input-bg); color: var(--hg-text-bright); height: 22px; }
  html.dark #assetTree .hg-stage .t-model-inputs input:focus { border-color: var(--hg-border-hover); }
  html.dark #assetTree .hg-stage .t-note-input { color: #9aa0ab; }
  html.dark #assetTree .hg-stage .t-note-input::placeholder { color: #3f4046; }
  html.dark #assetTree .hg-stage .t-note-input:hover { border-color: var(--hg-border-control); }
  html.dark #assetTree .hg-stage .t-note-input:focus { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .t-spinner .sp { border-color: var(--hg-border-control); background: #232428; color: #9aa0ab; }
  html.dark .t-spinner .sp:hover { background: #2c2d33; }
  html.dark .t-spinner .t-days { border-top-color: var(--hg-border-control); border-bottom-color: var(--hg-border-control); background: var(--hg-surface-raised); color: var(--hg-text-bright); }
  html.dark .t-spinner .t-days:hover { background: #2a2620; }
  html.dark #assetTree .hg-stage .t-cost .t-cost-x { color: var(--hg-text-muted); }
  html.dark .asset-cost-row { border-top-color: var(--hg-border-chrome); }
  html.dark .master-totals { border-color: var(--hg-border-chrome); }
  html.dark .master-totals h3 { color: var(--hg-text-muted); }
  html.dark .fp-table th { color: var(--hg-text-muted); border-bottom-color: var(--hg-border-chrome); }
  html.dark .fp-table td { border-bottom-color: var(--hg-border-cell); }
  html.dark .fp-table tr.doc-total td { border-top-color: var(--hg-border-chrome); }
  html.dark .fp-table tr.doc-total td.num { color: var(--hg-text-bright); }
  html.dark .fp-cb-hdr { color: var(--hg-text-muted); border-bottom-color: var(--hg-border-chrome); }
  html.dark .fp-cb-row { border-bottom-color: var(--hg-border-cell); }
  html.dark .fp-cb-row.fp-cb-total { border-top-color: var(--hg-border-chrome); }
  html.dark .fp-cb-row.fp-cb-total .fp-cb-amt { color: var(--hg-text-bright); }
  html.dark .fp-cb-hdr { color: var(--hg-text-bright); border-bottom-color: var(--hg-border-chrome); }
  html.dark .fp-cb-line { color: var(--hg-text-bright); }
  html.dark .fp-cb-amt.cur-gbp, html.dark .fp-cb-amt.cur-usd { border-right-color: var(--hg-border-chrome); }
  html.dark .fp-cb-hdr .fp-cb-amt.cur-gbp, html.dark .fp-cb-hdr .fp-cb-amt.cur-usd { border-right-color: var(--hg-border-chrome); }
  html.dark .cur-toggle { border-color: var(--hg-border-control); background: var(--hg-surface-raised); color: var(--hg-text-bright); }
  html.dark .cur-toggle.inactive { background: #26272b; color: #4a4b50; }
  html.dark .cur-toggle:hover { background: #2a2b30; }
  html.dark .mt-kpi b { color: var(--hg-info); }
  html.dark .mt-table th { border-bottom-color: var(--hg-border-chrome); color: var(--hg-text-muted); }
  html.dark .mt-table td { border-bottom-color: var(--hg-border-cell); color: var(--hg-text-dim); }
  html.dark .mt-table td.num { color: var(--hg-text-bright); }
  html.dark .mt-table tr.mt-total td { border-top-color: var(--hg-border-chrome); color: var(--hg-text-bright); }
  html.dark .mt-table tr.mt-ua td { border-top-color: var(--hg-border-chrome); color: var(--hg-text-dim); }
  html.dark .mt-table td.mt-delta.over { color: var(--hg-danger-bright); }
  html.dark .mt-table td.mt-delta.under { color: var(--st-ip-ink); }
  html.dark .mt-table tr.mt-ent td { color: var(--hg-text-dim); }
  html.dark .mt-table tr.mt-ent td.num { color: var(--hg-text-dim); }
  html.dark .mt-perf { border-top-color: var(--hg-border-chrome); }
  html.dark .mt-perf-val { color: var(--hg-text-bright); }
  html.dark .mt-perf-label { color: var(--hg-text-dim); }
  html.dark .mt-perf-val.neg { color: var(--hg-danger-bright); }
  html.dark .mt-perf-val.pos { color: var(--st-ip-ink); }
  html.dark .wire-panel { margin-bottom: 8px; }
  html.dark .wire-panel.collapsed { margin-bottom: 4px; }
  html.dark .wire-title { background: var(--hg-surface-tabs); border-bottom-color: transparent; color: var(--hg-text-bright); box-shadow: var(--hg-shadow-sm); backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur)); }
  html.dark .wire-title:hover { color: var(--hg-text-bright); }
  /* Internal budget + Crew cost panels — frosted glass, lighter in dark mode */
  html.dark #masterTotals .wire-title,
  html.dark #crewCost .wire-title,
  html.dark #v-cli .wire-title {
    background: var(--hg-surface-tabs);
    color: var(--hg-text-bright);
  }
  html.dark #masterTotals .wire-title:hover,
  html.dark #crewCost .wire-title:hover,
  html.dark #v-cli .wire-title:hover {
    filter: drop-shadow(0 4px 8px rgba(0,0,0,.28))
            drop-shadow(0 -4px 12px rgba(228,228,231,.06));
  }
  html.dark #masterTotals,
  html.dark #crewCost,
  html.dark #v-cli .master-totals {
    background: var(--hg-frost-bg);
  }
  html.dark .wire-body {
    backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  }
  html.dark .wire-heading-input { color: var(--hg-text-bright); }
  html.dark .wire-heading-input:hover { border-color: var(--hg-border-control); }
  html.dark .wire-heading-input:focus { border-color: var(--hg-border-hover); background: var(--hg-input-bg); }
  html.dark .meta-label { color: var(--hg-text-bright); }
  html.dark .hg-prompt-input { border-color: var(--hg-border-control); background: var(--hg-surface-raised); color: var(--hg-text-bright); }
  html.dark .wire-caret { color: var(--hg-border-focus); }
  html.dark #masterTotals .wire-caret,
  html.dark #v-cli .wire-caret { color: #b0b1b8; }
  html.dark #masterTotals .cs-del,
  html.dark #v-cli .cs-del { color: #8a8b92; }
  html.dark #masterTotals .cs-del:hover,
  html.dark #v-cli .cs-del:hover { color: var(--hg-text-bright); }
  html.dark #masterTotals .meta-panel-reorder,
  html.dark #masterTotals .meta-panel-tpl,
  html.dark #v-cli .meta-panel-reorder,
  html.dark #v-cli .meta-panel-tpl { opacity: .7; }
  html.dark .mt-rate-row { color: var(--hg-text-muted); }
  html.dark .mt-rate-row label { color: var(--hg-text-muted); }
  html.dark .footnote { color: var(--hg-text-muted); }
  html.dark .footnote b { color: var(--hg-text-bright); }
  html.dark #hgConfirmBody { color: #a6a7ad; }
html.dark .modal-bg { background: transparent; }
  html.dark .modal { background: var(--hg-frost-bg); border-color: var(--hg-border-control); color: var(--hg-text-bright); box-shadow: var(--hg-shadow-modal); }
  html.dark .modal h3 { color: var(--hg-text-bright); }
  html.dark #naModal .modal { background:rgba(26,27,31,.92); }
  html.dark #naModal .modal::before { filter:none; opacity:.14; }
  html.dark .na-gantt-wrap { border-color:var(--hg-border-chrome); }
  html.dark .na-gantt-wrap::before { filter:none; opacity:.14; }
  html.dark .na-gantt-wrap .gantt-labels { background:rgba(20,21,23,.82); }
  html.dark .na-gantt-wrap .na-lane-body { background:transparent; }
  html.dark .na-gantt-wrap .na-row { background:rgba(20,21,23,.55); }
  html.dark .na-gantt-wrap .cell { border-left-color: rgba(0, 0, 0, 0.6); }
  html.dark .na-gantt-wrap .na-row input.na-stage, html.dark .na-gantt-wrap .na-row input.na-num { color:#c2c3c8; }
  html.dark .na-gantt-wrap .na-row input.na-stage:hover, html.dark .na-gantt-wrap .na-row input.na-stage:focus,
  html.dark .na-gantt-wrap .na-row input.na-num:hover, html.dark .na-gantt-wrap .na-row input.na-num:focus { border-color:var(--hg-border-control); }
  html.dark .na-gantt-wrap .na-row .na-rm { color:#3f4046; }
  html.dark .na-gantt-wrap .na-row .na-rm:hover { color:var(--st-reopen-ink); }
  html.dark .na-gantt-wrap .gantt-labels > .task-add { background:rgba(23,24,27,.82); border-top-color:var(--hg-border-chrome); color:var(--hg-info); }
  html.dark .na-gantt-wrap .gantt-labels > .task-add:hover { color: var(--hg-text-bright); }
  html.dark .na-gantt-wrap .labels-head { background:rgba(23,24,27,.92); border-bottom-color:var(--hg-border-chrome); }
  html.dark .na-gantt-wrap .weekhdr { background:rgba(23,24,27,.92); border-bottom-color:var(--hg-border-chrome); }
  /* Card-level action buttons now use .btn-new .card-task-btn (dark pill),
     so they inherit html.dark .btn-new. The plain .task-add class is still
     used by the seg-footer "+ add segment" and the new-task modal "+ add stage". */
  html.dark .task-add { color: var(--hg-info); }
  html.dark .task-add:hover { color: var(--hg-text-bright); }
  html.dark #assetTree .hg-stage .t-stage-input { background: var(--hg-input-bg); color: var(--hg-text-bright); border-color: transparent; }
  html.dark #assetTree .hg-stage .t-stage-input:hover { border-color: var(--hg-border-control); }
  html.dark #assetTree .hg-stage .t-stage-input:focus { border-color: var(--hg-border-hover); }
  html.dark .gfilters { background: transparent; border-bottom-color: transparent; color: var(--hg-text-muted); }
  /* Receipt drop zone dark-mode: text/border brighten to the same tokens
     as .wire-title (--hg-text-bright) so the strip is legible on the
     near-black surface. Frost fill + blur stay from the shared rule. */
  html.dark .receipt-drop-zone { color: var(--hg-text-bright); border-color: color-mix(in srgb, #8a93a3 45%, transparent); }
  html.dark .receipt-drop-zone:hover { background: var(--hg-frost-head); border-color: color-mix(in srgb, #8a93a3 70%, transparent); }
  html.dark .receipt-drop-text { color: var(--hg-text-bright); }
  html.dark .receipt-drop-hint { color: var(--hg-text-dim); opacity: 1; }
  html.dark .receipt-drop-spinner { border-color: var(--hg-text-bright); border-top-color: transparent; }
  html.dark .receipt-drop-clear { color: var(--hg-text-bright); }
  html.dark .receipt-drop-zone.drag-over { background: color-mix(in srgb, #5a8fcf 18%, transparent); border-color: #7db3e8; }
  html.dark .receipt-drop-zone.has-pending { border-color: color-mix(in srgb, #7db3e8 70%, transparent); background: color-mix(in srgb, #5a8fcf 12%, transparent); }
  html.dark .gbar.ip { background: var(--gbar-ip-bg); color: #141517; }
  html.dark .gbar.wtg { background: var(--gbar-wtg-bg); color: var(--gbar-wtg-ink); }
  html.dark .gbar.appr { background: #6d87a3; color: #141517; }
  html.dark .gbar.cmpt { background: var(--gbar-cmpt-bg); color: #141517; }
  html.dark .gbar.reopen { background: #a0767d; color: #141517; }
  html.dark .gbar.draft {
    background: repeating-linear-gradient(45deg,var(--gbar-wtg-bg),var(--gbar-wtg-bg) 6px,var(--gbar-draft-stripe) 6px,var(--gbar-draft-stripe) 12px);
    color: var(--gbar-wtg-ink);
  }
  html.dark .gbar.rev { background: #b5986a; color: #141517; }
  html.dark .gbar .gbar-ghost { background: rgba(0, 0, 0, 0.32); }
  html.dark .gbar.parent-open {
    background: color-mix(in srgb, var(--gbar-wtg-bg) 22%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, #6d87a3 50%, transparent),
                inset 0 2px 5px rgba(255,255,255,.06),
                0 1px 4px rgba(0,0,0,.35);
    color: #b9bec7;
  }
  html.dark .gantt-scroll-hint { color: #6f707680; background: rgba(20,21,23,.5); }
  html.dark .gantt-labels { background: var(--hg-surface-base); border-right-color: var(--hg-border-chrome); box-shadow: none; }
  html.dark .gantt-labels .labels-head { background: var(--hg-surface-elevated); border-bottom-color: var(--hg-border-chrome);
    box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
                inset 0 -2px 5px rgba(0,0,0,.09);
  }
  html.dark .gantt-labels .hg-entity { color: var(--hg-text-bright); border-bottom-color: var(--hg-border-chrome); }
  html.dark .gantt-labels .hg-entity .days { color: var(--st-ip-ink); }
  html.dark .gantt-labels .hg-stage { border-bottom-color: var(--hg-border-cell); }
  html.dark .gantt-labels .hg-stage .g-stage { color: var(--hg-text-bright); }
  html.dark .gantt-labels .hg-stage .who { color: var(--hg-text-muted); }
  html.dark .gantt-labels .hg-stage .who.gantt-crew-read { color: var(--hg-people); cursor: context-menu; }
  html.dark .gantt-labels .hg-stage .who.gantt-crew-read .gantt-crew-name:hover,
  html.dark .gantt-labels .hg-stage .who.gantt-crew-read .gantt-crew-more:hover { text-decoration: underline; text-underline-offset: 2px; }
  html.dark .gantt-labels .hg-stage .who.gantt-crew-read .gantt-crew-more { margin-left: 4px; font-weight: 600; cursor: pointer; }
  html.dark .gantt-labels .hg-stage > .gantt-openmark { flex-shrink: 0; margin-left: 4px; color: var(--hg-danger-bright); font-weight: 700; cursor: pointer; }
  html.dark .gantt-labels .hg-stage > .gantt-openmark:hover { text-decoration: underline; text-underline-offset: 2px; }
  html.dark .gantt-labels .hg-entity .owner-pick:not(.un) { color: var(--hg-people); }
  /* Placeholder sup shows no field box — the raised fill reads as an empty
     input punched into the row. Unassigned = bare muted text, same chrome
     as assigned minus the person colour. */
  html.dark .gantt-labels .hg-entity .owner-pick.un { background: transparent; }
  html.dark .workload-dock {
    background: var(--hg-frost-bg);
    border-top-color: #3a2e2a;
  }
    html.dark .workload-dock .wl-titlebar {
      background: var(--hg-frost-head);
      border-bottom-color: #3a2e2a; color: #c4a090;
    }
    html.dark .workload-dock .wl-titlebar:hover {
      background: color-mix(in srgb, #e4e4e7 10%, transparent);
    }
    html.dark .workload-dock .wl-caret { color: #9a7a68; }
    html.dark .workload-dock .wl-titlebar-sub { color: #7a6558; }
    html.dark .workload-dock .wl-titlebar-meta { color: #a89080; }
    html.dark .workload-dock .wl-titlebar-meta.is-warn { color: #c08a8a; }
    html.dark #workloadPanel { background: transparent; }
    html.dark .workload-dock .wl-worker-row { border-bottom-color: #2e2622; }
    html.dark .workload-dock .wl-worker-row:hover .wl-name,
    html.dark .workload-dock .wl-worker-row:hover .wl-cells { background: #2a221e; }
    html.dark .workload-dock .wl-name {
      background: transparent; border-right-color: #3a2e2a; color: #d2c4b8;
    }
    html.dark .workload-dock .wl-worker-row.is-active .wl-name {
      background: #1e2a38; color: #9bb8d4;
      box-shadow: inset 3px 0 0 #4a7ab5;
    }
    html.dark .workload-dock .wl-worker-row.is-active .wl-cells { background: #1e2a382e; }
    html.dark .workload-dock .wl-worker-row.is-active .wl-cell:not(.is-overload):not(.is-underutilized) {
      background: #3a4a6033;
    }
    html.dark .workload-dock .wl-name-empty { color: #7a6558; }
    html.dark .workload-dock .wl-cells { background: transparent; }
    html.dark .workload-dock .wl-cell { border-left-color: #2e2622; color: #8a7a6e; }
    html.dark .workload-dock .wl-cell.has-load { background: #3a455a33; color: #c2c8d4; }
    html.dark .workload-dock .wl-cell.is-overload {
      background: #a05a5a2e; color: #c08a8a; border-left-color: #a05a5a55;
    }
    html.dark .workload-dock .wl-cell.is-underutilized {
      background: #8a5a202e; color: #c8a878; border-left-color: #8a5a2055;
    }
  html.dark .cashflow-dock {
    background: var(--hg-frost-bg);
    border-top-color: var(--gbar-ip-border);
  }
  html.dark .cashflow-dock .cf-titlebar {
    background: var(--hg-frost-head);
    border-bottom-color: var(--gbar-ip-border); color: var(--st-ip-ink);
  }
  html.dark .cashflow-dock .cf-titlebar:hover {
    background: color-mix(in srgb, #e4e4e7 10%, transparent);
  }
  html.dark .cashflow-dock .cf-caret { color: #6f987e; }
  html.dark .cashflow-dock .cf-titlebar-sub { color: #6a7a70; }
    html.dark .cashflow-dock .cf-titlebar-meta { color: var(--st-ip-ink); }
      html.dark .cashflow-dock .cf-titlebar-meta .cf-meta-bit.is-warn {
        color: var(--cf-deficit-t, #c08a8a);
      }
    html.dark .cashflow-dock .cf-label { background: transparent; border-right-color: var(--gbar-ip-border); color: var(--st-ip-ink); }
    html.dark .cashflow-dock .cf-label-title { color: var(--st-ip-ink); }
    html.dark #cashflowPanel { background: transparent; }
  html.dark .weekhdr { background: var(--hg-surface-elevated); border-bottom-color: var(--hg-border-chrome);
    box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
                inset 0 -2px 5px rgba(0,0,0,.09);
  }
  html.dark .weekhdr .w, html.dark .weekhdr .m { border-left-color: rgba(0, 0, 0, 0.6); color: var(--hg-text-muted); }
    html.dark .weekhdr .w .start, html.dark .weekhdr .m .start { color: #8b8c92; }
    html.dark .weekhdr .w .end { color: var(--hg-text-muted); }
    html.dark .weekhdr .m .hg-week-seam { background: rgba(0, 0, 0, 0.35); }
    html.dark .weekhdr .h { border-left-color: rgba(0, 0, 0, 0.4); color: var(--hg-text-muted); }
    html.dark .weekhdr .h.wk-start { border-left-color: rgba(0, 0, 0, 0.85); }
    html.dark .weekhdr .h .h-num.h-day-start, html.dark .weekhdr .h .hg-daymark { color: var(--hg-text-muted); }
    html.dark #lanes .hg-stage { border-bottom-color: #1a1c20; }
    html.dark .cell {
        border-left-color: rgba(0, 0, 0, 0.6);
        background-image:
          linear-gradient(to bottom, rgba(0, 0, 0, 0.6) 50%, transparent 50%),
          linear-gradient(to bottom, rgba(0, 0, 0, 0.6) 50%, transparent 50%),
          linear-gradient(to bottom, rgba(0, 0, 0, 0.6) 50%, transparent 50%),
          linear-gradient(to bottom, rgba(0, 0, 0, 0.6) 50%, transparent 50%);
        background-size: 1px 6px, 1px 6px, 1px 6px, 1px 6px;
        background-position:
          calc(var(--hg-week-w) / 5 * 1) 0,
          calc(var(--hg-week-w) / 5 * 2) 0,
          calc(var(--hg-week-w) / 5 * 3) 0,
          calc(var(--hg-week-w) / 5 * 4) 0;
        background-repeat: repeat-y;
      }
    /* Open-week cell, dark twin: same per-day tick pattern, darker hairline
       colour (the tick gradient rides the same .wk-grid rule; only the
       gradient colour needs the dark override). */
    html.dark .cell.open-week {
        background-image: none;
      }
    html.dark .cell.open-week .wk-grid {
        background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.6) 50%, transparent 50%);
      }
    /* Dark twin of the light first-child suppress: the dark generic
       gradient above out-specifies the light rule, and without this the
       first day re-paints its tick one pixel inside the cell's own border
       — a seam 2px wide. Exposing must add only the weekend day lines. */
    html.dark .cell.open-week .wk-grid:first-child { background-image: none; }
    html.dark .cell.open-week .wk-grid.wknd {
        background-color: color-mix(in srgb, var(--hg-accent) 7%, transparent);
      }
  html.dark #labelsPanel .hg-entity, html.dark #lanes .hg-entity { border-bottom-color: var(--hg-border-chrome); }
  html.dark #labelsPanel .hg-lane, html.dark #lanes .hg-lane { color: var(--hg-text-bright); border-bottom-color: var(--hg-border-chrome); }
  html.dark #labelsPanel .hg-lane .days { color: var(--st-ip-ink); }
  html.dark #labelsPanel .hg-lane .days.days-over { color: var(--hg-danger-bright); }
  html.dark #labelsPanel .hg-lane .days.days-under { color: var(--st-ip-ink); }
  html.dark .collapse-btn { background: transparent; border-color: var(--hg-border-control); color: var(--hg-text-muted); box-shadow: none; }
  html.dark .collapse-btn:hover { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .gantt-labels .gantt-toggle-row:hover { background-image: linear-gradient(rgba(255,255,255,.05), rgba(255,255,255,.05)); }
  html.dark .block-btn { background: transparent; border-color: var(--hg-border-control); color: #b8b9be; }
  html.dark .block-btn.on { background: var(--hg-accent); border-color: var(--hg-accent); color: var(--gbar-rev-ink); }
  html.dark .block-btn:hover { border-color: var(--hg-border-hover); color: var(--hg-text-bright); }
  html.dark .block-btn.on:hover { background: #e2b155; color: var(--gbar-rev-ink); }
  html.dark .doc { background: transparent; border-color: var(--hg-border-chrome); }
  html.dark .doc .docsub { color: var(--hg-text-muted); }
  html.dark .doc td, html.dark .doc th { border-bottom-color: var(--hg-border-cell); }
  html.dark .doc th { color: var(--hg-text-muted); border-bottom-color: var(--hg-border-chrome); position: sticky; top: 79px; z-index: 34; background: var(--hg-surface-base); }
  html.dark table.track th, html.dark #crewTable th { background: var(--hg-frost-head); }
  html.dark .doc .doc-total td { border-top-color: var(--hg-border-control); }
  html.dark .doc .gen { color: var(--hg-text-muted); }
  html.dark .drawer { background: var(--hg-surface-base); border-left-color: var(--hg-border-chrome); box-shadow: var(--hg-shadow-slide); }
  html.dark .drawer .kv .k { color: var(--hg-text-muted); }
  html.dark .drawer .x { color: var(--hg-text-muted); }
  html.dark .drawer .thread { background: var(--hg-surface-card); color: #a8a9ae; }
  html.dark .drawer h4 { color: var(--hg-text-muted); }
  html.dark .drawer .evi, html.dark .drawer a { color: var(--hg-info); }
    html.dark #spikeLine { background: #a05a5a !important; box-shadow: 0 0 0 1px #17181b !important; }
  html.dark .crew-pick.un { color: var(--st-reopen-ink); border-color: var(--st-reopen-bg); background: #241a1c; }
  html.dark .crew-pick.inherited { color: var(--hg-text-muted); border-color: #2a2b30; background: var(--hg-surface-raised); }
  html.dark .owner-pick { border-color: var(--hg-border-control); background-color: transparent; color: var(--hg-text-bright); }
  html.dark .owner-pick.un { color: var(--hg-text-muted); border-color: #2a2b30; background: var(--hg-surface-raised); }
  html.dark #viewHint { color: var(--hg-text-muted) !important; }

/* ===== 3b. SCROLLBAR POLICY (chrome) =====
   Order is mandatory:
   1) hide scrollbars on .tabs (light + dark)
   2) optionally enable thin scrollbars on html.dark *
   3) re-hide .tabs with !important so step 2 cannot win
   Do NOT add another html.dark * scrollbar rule elsewhere. */
.tabs,
html.dark .tabs { scrollbar-width: none; }
.tabs::-webkit-scrollbar,
html.dark .tabs::-webkit-scrollbar { display: none; width: 0; height: 0; }

/* Light-mode scrollbar track: transparent background in both WebKit and Firefox. */
* { scrollbar-color: #c1c1c1 transparent; }
::-webkit-scrollbar-track { background: transparent; }

html.dark * { scrollbar-width: thin; scrollbar-color: #3a3b40 transparent; }
html.dark ::-webkit-scrollbar { width: 10px; height: 10px; }
html.dark ::-webkit-scrollbar-track { background: transparent; }
html.dark ::-webkit-scrollbar-thumb { background: #3a3b40; border-radius: 4px; border: 2px solid transparent; }
html.dark ::-webkit-scrollbar-thumb:hover { background: #4a4c52; }

html.dark .tabs { scrollbar-width: none !important; }
html.dark .tabs::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }

/* ===== 6. DOCK EXTRAS — CF balance stroke + gbar resize edges ===== */
/* Continuous SVG cash-balance stroke (replaces day-tile staircase) */
#cfTrack .cf-bal-svg { display: block; }
#cfTrack .cf-bal-path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
#cfTrack .cf-bal-path.cf-bal-surplus {
  stroke: var(--cf-income);
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--cf-income) 70%, transparent));
}
#cfTrack .cf-bal-path.cf-bal-deficit {
  stroke: var(--cf-deficit-t);
  animation: cf-deficit-pulse 1.6s ease-in-out infinite;
  will-change: filter;
}
/* Red (underwater) stroke: pulsating red glow via SVG-friendly drop-shadow */
@keyframes cf-deficit-pulse {
  0%, 100% {
    filter:
      drop-shadow(0 0 2px var(--cf-deficit-glow))
      drop-shadow(0 0 6px color-mix(in srgb, var(--cf-deficit-glow) 55%, transparent))
      brightness(1);
  }
  50% {
    filter:
      drop-shadow(0 0 4px var(--cf-deficit-glow))
      drop-shadow(0 0 12px var(--cf-deficit-glow))
      drop-shadow(0 0 22px color-mix(in srgb, var(--cf-deficit-glow) 75%, transparent))
      brightness(1.2);
  }
}
@media (prefers-reduced-motion: reduce) {
  #cfTrack .cf-bal-path.cf-bal-deficit {
    animation: none;
    filter:
      drop-shadow(0 0 4px var(--cf-deficit-glow))
      drop-shadow(0 0 12px color-mix(in srgb, var(--cf-deficit-glow) 60%, transparent));
  }
}
.gbar { position: absolute; } /* ensure edges position relative to bar */
.gbar .gedge {
  position: absolute; top: 0; bottom: 0; width: 10px; cursor: ew-resize; z-index: 3;
  background: transparent;
}
.gbar .gedge[data-edge="l"] { left: 0; border-radius: 3px 0 0 3px; }
.gbar .gedge[data-edge="r"] { right: 0; border-radius: 0 3px 3px 0; }
.gbar .gedge:hover { background: #ffffff55; }
.gbar[data-seg], .gbar[data-task], .gbar[data-grp] { cursor: grab; }
.gbar-dragging { transform: translateY(1px); transition: transform .06s ease-out; }

/* ── Dependency link plugs ─────────────────────────────── */
/* Plugs are semicircles that stick OUT past the bar ends so they don't
   clash with the .gedge resize handles (which sit inside the bar at
   left:0 / right:0). The plug is a 10px circle centered on the bar edge,
   so half sticks out. The .hg-stage row has overflow:visible to allow
   this (the .cells grid inside still has its own overflow:hidden). */
.gbar .gplug {
  position: absolute; top: 50%; width: 10px; height: 10px;
  border-radius: 50%; z-index: 60;
  background: var(--hg-surface-raised);
  border: 1.5px solid var(--hg-accent);
  opacity: 0; transition: opacity .1s ease, transform .1s ease;
  transform: translateY(-50%); cursor: crosshair; pointer-events: auto;
}
.gbar .gplug-start { left: -10px; }
.gbar .gplug-end { right: -10px; }
.gbar .gplug:hover {
  border-color: var(--hg-accent);
  box-shadow: 0 0 4px var(--hg-accent);
}
.gbar .gplug.drop-target {
  border-color: var(--hg-accent);
  box-shadow: 0 0 6px var(--hg-accent);
  transform: translateY(-50%) scale(1.4);
}
.gbar .gplug.drop-reject {
  border-color: var(--hg-danger);
}

/* (assignment + copy icon removed 2026-09-09 — Copy bar lives in the RMB menu) */

/* ── Dependency link SVG overlay ───────────────────────── */
#linkLayer { pointer-events: none; }
#linkLayer path { pointer-events: stroke; }

/* ── Dependency overlap hatching ───────────────────────── */
/* Same 45deg hatching pattern as the draft/review bar, but as a semi-transparent
   overlay so the bar's own status colour shows through. Indicates where a
   predecessor and successor overlap in time — dependencies are flexible, this
   just signals where it's happening. */
.gbar-dep-overlap {
  background: repeating-linear-gradient(45deg,
    transparent, transparent 4px,
    color-mix(in srgb, var(--hg-accent) 35%, transparent) 4px,
    color-mix(in srgb, var(--hg-accent) 35%, transparent) 8px);
}

/* ── Cascade toggle button ─────────────────────────────── */
 .gf-btn.gfCascade.on { background: var(--hg-accent); color: var(--hg-text-on-accent); }
/* ── Gantt home button: icon-only, vertically centered ─── */
 .gf-home { display: inline-flex; align-items: center; justify-content: center; padding: 4px 6px; vertical-align: middle; }
 .gf-home svg { display: block; }
/* ===== 7. SEGMENT PAINT (apply) — geometry after dark bulk ===== */
/* Hierarchy semantics: LANE (.hg-lane) > ENTITY (.hg-entity) > STAGE (.hg-stage).
   Same (bevel × shadow × accent-width) contract as the pre-refactor rules; the
   only deltas are (a) hardcoded 17/8% become the shared --hg-<level>-op vars in
   :root (lane 30, entity 20, stage 10), (b) alpha-hex --seg-wash* are gone —
   the same paint is expressed as color-mix(accent, level-op). Dark twins exist
   ONLY where the pre-refactor CSS had them: bevels are mode-dependent
   (white .14/.02 light vs .01/.09 dark), so they must not be unified away.
   Lane-side partners (.lane-side in #lanes) share their labels-row partner's
   level; they MUST NOT get a real border-left (shifts .cells 3px and desyncs
   the week grid) — the accent edge is inset box-shadow there. */
/* Breakdown lane header — sticky, wash layered ON the opaque page base so
   rows cannot bleed under the parked header. */
.hg-lane[data-seg] {
  border-bottom-color: transparent;
  box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
              inset 0 -2px 5px rgba(15,23,42,.02),
              0 1px 3px color-mix(in srgb, var(--seg-accent) 25%, rgba(15,23,42,.15));
  padding-left: 10px;
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), transparent);
  backdrop-filter: blur(var(--hg-frost-blur));
  -webkit-backdrop-filter: blur(var(--hg-frost-blur));
}
.seg-block.open > .hg-lane[data-seg] {
  border-bottom-color: transparent;
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.14),
              inset 0 2px 5px rgba(15,23,42,.02),
              0 1px 3px color-mix(in srgb, var(--seg-accent) 25%, rgba(15,23,42,.15));
  padding-left: 10px;
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), transparent);
  backdrop-filter: blur(var(--hg-frost-blur));
  -webkit-backdrop-filter: blur(var(--hg-frost-blur));
}
.hg-entity-block[data-seg] { backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft)); }
.hg-entity-block[data-seg] .hg-entity {
  padding-left: 8px;
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-entity-op), transparent);
}
html .hg-stage[data-seg] { background: transparent; }
/* Gantt lanes panel: label rows carry border-left accents; lane-side partners
   share the same wash level but use inset shadows only. Gantt tracks read as
   GROOVES — wide soft inner shadow on every track band (bump when collapsed,
   pressed when expanded via [aria-expanded] below). */
#labelsPanel .hg-lane[data-seg] {
                        border-left: 3px solid transparent;
                        background: var(--seg-edge),
                                    color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), var(--hg-frost-bg));
                        /* gradient must anchor at the true edge: default padding-box
                           origin starts the fade inside the 3px transparent border */
                        background-origin: border-box;
                        backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
                        box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
                                    inset 0 -2px 5px rgba(15,23,42,.02);
                        /* No `filter` in the transition list: these rows carry
                           backdrop-filter, and an animated filter rebuilds the
                           compositing layer (f606b10). */
                        transition: transform .25s cubic-bezier(.22,1,.36,1); }
  /* Hover glow toggles instantly (no .06s fade): an animated box-shadow writes
     intermediate glow states into the frost blur's sampled input across frames —
     the stale-bake window behind the banding ghost. One atomic paint instead. */
  #labelsPanel .hg-lane[data-seg]:hover,
  #labelsPanel .hg-lane[data-seg].hover-pair {
                        box-shadow: 0 3px 6px rgba(15,23,42,.08),
                                    0 -3px 6px color-mix(in srgb, var(--seg-accent) var(--hg-lane-op-h), transparent);
                        transition: none; }
  #labelsPanel .hg-lane[data-seg]:active {
                        transition: none; }
#lanes .hg-lane.lane-side[data-seg] {
  border-left: none;
  padding-left: 0;
  box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
              inset 0 -2px 5px rgba(15,23,42,.02);
  background: color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), transparent);
  backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  /* No `filter` transition: backdrop-filtered rows (f606b10). */
}
  #lanes .hg-lane.lane-side[data-seg]:hover,
  #lanes .hg-lane.lane-side[data-seg].hover-pair {
    box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
                inset 0 -2px 5px rgba(15,23,42,.02),
                0 3px 6px rgba(15,23,42,.08),
                0 -3px 6px color-mix(in srgb, var(--seg-accent) var(--hg-lane-op-h), transparent);
    /* Instant glow toggle — animated box-shadow on frosted rows is the stale-bake window. */
    transition: none;
  }
  #lanes .hg-lane.lane-side[data-seg]:active {
    transition: none;
  }
#labelsPanel .hg-entity[data-seg] {
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-entity-op), var(--hg-frost-bg));
  backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  /* No `filter` transition: backdrop-filtered rows (f606b10). */
}
  #labelsPanel .hg-entity[data-seg]:hover,
  #labelsPanel .hg-entity[data-seg].hover-pair {
    box-shadow: 0 3px 6px rgba(15,23,42,.08),
                0 -3px 6px color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent);
    /* Instant glow toggle — animated box-shadow on frosted rows is the stale-bake window. */
    transition: none;
  }
  #labelsPanel .hg-entity[data-seg]:active {
    transition: none;
  }
#lanes .hg-entity.lane-side[data-seg] {
  padding-left: 0;
  box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
              inset 0 -2px 5px rgba(15,23,42,.02);
  background: color-mix(in srgb, var(--seg-accent) var(--hg-entity-op), transparent);
  backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  /* No `filter` transition: backdrop-filtered rows (f606b10). */
}
  #lanes .hg-entity.lane-side[data-seg]:hover,
  #lanes .hg-entity.lane-side[data-seg].hover-pair {
    box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
                inset 0 -2px 5px rgba(15,23,42,.02),
                0 3px 6px rgba(15,23,42,.08),
                0 -3px 6px color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent);
    /* Instant glow toggle — animated box-shadow on frosted rows is the stale-bake window. */
    transition: none;
  }
  #lanes .hg-entity.lane-side[data-seg]:active {
    transition: none;
  }
#labelsPanel .hg-stage[data-seg] {
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-stage-op), var(--hg-frost-bg));
  backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
}

#lanes .hg-stage.lane-side[data-seg] {
  padding-left: 0;
  box-shadow: inset 0 2px 4px rgba(255,255,255,.14),
              inset 0 -2px 5px rgba(15,23,42,.02);
  background: color-mix(in srgb, var(--seg-accent) var(--hg-stage-op), transparent);
  backdrop-filter: blur(var(--hg-frost-blur-soft)); -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
}

/* Dark twins: same paint, darker groove (bevels are mode-dependent). */
html.dark #lanes .hg-lane.lane-side[data-seg] {
  background: color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), transparent);
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09);
}
html.dark #labelsPanel .hg-lane[data-seg] {
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), var(--hg-frost-bg));
  background-origin: border-box; /* shorthand above resets origin — re-assert */
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09);
}
html.dark #labelsPanel .hg-entity[data-seg] {
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-entity-op), var(--hg-frost-bg));
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09);
}
html.dark #lanes .hg-entity.lane-side[data-seg] {
  background: color-mix(in srgb, var(--seg-accent) var(--hg-entity-op), transparent);
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09);
}
html.dark #labelsPanel .hg-stage[data-seg] {
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-stage-op), var(--hg-frost-bg));
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09);
}
html.dark #lanes .hg-stage.lane-side[data-seg] {
  background: color-mix(in srgb, var(--seg-accent) var(--hg-stage-op), transparent);
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09);
}
/* Dark hover glow for gantt tracks. box-shadow (not filter): these rows carry
   backdrop-filter, and animating `filter` on them rebuilds the compositing
   layer every toggle — the flash. Dark inset bevels are restated because
   box-shadow is a single property. */
html.dark #labelsPanel .hg-lane[data-seg]:hover,
html.dark #labelsPanel .hg-lane[data-seg].hover-pair {
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09),
              0 3px 6px rgba(0,0,0,.28),
              0 -3px 10px color-mix(in srgb, var(--seg-accent) var(--hg-lane-op-h), transparent);
}
html.dark #lanes .hg-lane.lane-side[data-seg]:hover,
html.dark #lanes .hg-lane.lane-side[data-seg].hover-pair {
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09),
              0 3px 6px rgba(0,0,0,.28),
              0 -3px 10px color-mix(in srgb, var(--seg-accent) var(--hg-lane-op-h), transparent);
}
html.dark #labelsPanel .hg-entity[data-seg]:hover,
html.dark #labelsPanel .hg-entity[data-seg].hover-pair {
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09),
              0 3px 6px rgba(0,0,0,.28),
              0 -3px 10px color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent);
}
html.dark #lanes .hg-entity.lane-side[data-seg]:hover,
html.dark #lanes .hg-entity.lane-side[data-seg].hover-pair {
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09),
              0 3px 6px rgba(0,0,0,.28),
              0 -3px 10px color-mix(in srgb, var(--seg-accent) var(--hg-entity-op-h), transparent);
}

/* DEPRESSED (expanded) toggle rows — bevel REVERSED to a groove. */
#labelsPanel .hg-lane[data-seg][aria-expanded="true"],
#lanes .hg-lane.lane-side[data-seg][aria-expanded="true"] {
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.14),
              inset 0 2px 5px rgba(15,23,42,.02);
}
#labelsPanel .hg-entity[data-seg][aria-expanded="true"] {
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.14),
              inset 0 2px 5px rgba(15,23,42,.02);
}
#lanes .hg-entity.lane-side[data-seg][aria-expanded="true"] {
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.14),
              inset 0 2px 5px rgba(15,23,42,.02);
}
html.dark #labelsPanel .hg-lane[data-seg][aria-expanded="true"],
html.dark #lanes .hg-lane.lane-side[data-seg][aria-expanded="true"] {
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.01),
              inset 0 2px 5px rgba(0,0,0,.09);
}
html.dark #labelsPanel .hg-entity[data-seg][aria-expanded="true"] {
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.01),
              inset 0 2px 5px rgba(0,0,0,.09);
}
html.dark #lanes .hg-entity.lane-side[data-seg][aria-expanded="true"] {
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.01),
              inset 0 2px 5px rgba(0,0,0,.09);
}

html.dark .hg-lane[data-seg] {
  border-bottom-color: var(--hg-border-control);
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), transparent);
  box-shadow: inset 0 2px 4px rgba(255,255,255,.01),
              inset 0 -2px 5px rgba(0,0,0,.09);
}
html.dark .seg-block.open > .hg-lane[data-seg] {
  border-bottom-color: var(--hg-border-control);
  background: var(--seg-edge),
              color-mix(in srgb, var(--seg-accent) var(--hg-lane-op), transparent);
  box-shadow: inset 0 -2px 4px rgba(255,255,255,.01),
              inset 0 2px 5px rgba(0,0,0,.09);
}
.flag { margin-bottom: 10px; }
/* ===== 8. CREW + RECRUIT ===== */
.cs-actions { display: flex; gap: 10px; margin-top: 12px; }
.cs-login-lab { display:inline-flex; align-items:center; gap:6px; font-size: var(--hg-type-11); color:var(--hg-text-secondary); cursor:pointer; user-select:none; }
.cs-login-lab input { margin:0; }
.cs-login-txt { min-width:22px; }

.tier-badge {
  font-size: var(--hg-type-micro); padding: 1px 8px; border-radius: 3px; white-space: nowrap;
  font-weight: 600; letter-spacing: .03em;
}
.tier-badge.tier-1 { background: #e2ecf7; color: #2a5a8a; }
.tier-badge.tier-2 { background: var(--st-ip-bg); color: var(--st-ip-ink); }
.tier-badge.tier-3 { background: var(--st-rev-bg); color: var(--st-rev-ink); }
.tier-badge.tier-4 { background: var(--st-wtg-bg); color: var(--st-wtg-ink); }
.cs-empty { color: var(--hg-text-dim); font-size: var(--hg-type-11); }
.heat-row { display: flex; gap: 2px; }
.heat-cell {
  width: 22px; height: 18px; border-radius: 3px; background: var(--hg-accent);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--hg-type-tiny); color: var(--hg-text-on-accent); font-weight: 600;
}
.heat-cell.heat-over {
  background: var(--hg-danger); color: var(--hg-text-on-accent);
  animation: heat-pulse 1.4s ease-in-out infinite;
}
@keyframes heat-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(192,57,43,0.7); }
  50% { box-shadow: 0 0 8px 3px rgba(192,57,43,0.55); }
}
.cs-del {
  border: none; background: none; cursor: pointer;
  font-size: var(--hg-type-medium); padding: 2px 6px;
}
.cs-del:hover { color: var(--hg-danger-ink); }

/* recruitment picker */
.recruit-card {
  border: 1px solid var(--hg-border-row); border-radius: 4px; padding: 10px 12px; margin-bottom: 8px;
  display: flex; flex-direction: column; gap: 4px;
}
.recruit-card .rc-head { display: flex; align-items: center; gap: 8px; font-size: var(--hg-type-medium); }
.recruit-card .rc-skills { font-size: var(--hg-type-11); color: var(--hg-text-secondary); }
.recruit-card .rc-meta { font-size: var(--hg-type-11); color: var(--hg-text-dim); display: flex; gap: 6px; align-items: center; }
.recruit-card .rc-pick { align-self: flex-start; margin-top: 4px; }
.recruit-rating {
  font-size: var(--hg-type-micro); padding: 1px 6px; border-radius: 3px;
  background: var(--st-rev-bg); color: var(--st-rev-ink); font-weight: 600;
}
.recruit-nda {
  font-size: var(--hg-type-micro); padding: 1px 6px; border-radius: 3px;
  background: var(--st-ip-bg); color: var(--st-ip-ink); font-weight: 600;
}
.recruit-status {
  font-size: var(--hg-type-micro); padding: 1px 6px; border-radius: 3px;
  background: var(--st-wtg-bg); color: var(--st-wtg-ink); font-weight: 600;
}

/* recruitment picker — same glass recipe as the Internal Budget panel:
   no overlay dim, panel = app frost tokens, table crisp on top. */
#recruitModal.modal-bg { background: transparent; }
html.dark #recruitModal.modal-bg { background: transparent; }
#recruitModal .modal {
  --hg-frost-blur: 32px;
  --hg-frost-blur-soft: 16px;
  background: var(--hg-frost-bg);
  backdrop-filter: blur(var(--hg-frost-blur)); -webkit-backdrop-filter: blur(var(--hg-frost-blur));
  box-shadow: var(--hg-shadow-modal);
}
html.dark #recruitModal .modal {
  background: var(--hg-frost-bg);
  box-shadow: var(--hg-shadow-modal);
}
#recruitList table.track {
  display: table; width: max-content; min-width: 100%; table-layout: auto;
  background: transparent;
}
#recruitList table.track thead { display: table-header-group; }
#recruitList table.track th {
  text-align: left; font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .07em;
  color: var(--hg-text-label); padding: 7px 10px; border-bottom: 1px solid var(--hg-border-chrome);
  background: var(--hg-frost-head);
  position: static;
}
#recruitList table.track tbody {
  display: table-row-group;
  background: transparent;
}
#recruitList table.track td { padding: 5px 10px; border-bottom: 1px solid var(--hg-border-cell); }
#recruitList table.track tbody tr:hover td {
  background: var(--hg-frost-hover);
}
/* row selection — accent-driven so the appearance panel controls it */
.rc-pick-row { cursor: default; }
.rc-pick-sel td {
  background: color-mix(in srgb, var(--hg-accent) 12%, transparent) !important;
}
/* dark mode — identical to standard table dark overrides */
html.dark #recruitList table.track th { border-bottom-color: var(--hg-border-chrome); color: var(--hg-text-muted); }
html.dark #recruitList table.track td { border-bottom-color: var(--hg-border-cell); }
html.dark .rc-pick-sel td {
  background: color-mix(in srgb, var(--hg-accent) 15%, transparent) !important;
}

/* dark mode for crew additions */
html.dark .tier-badge.tier-1 { background: var(--st-appr-bg); color: var(--hg-info); }
html.dark .tier-badge.tier-2 { background: var(--st-ip-bg); color: var(--st-ip-ink); }
html.dark .tier-badge.tier-3 { background: var(--st-rev-bg); color: var(--st-rev-ink); }
html.dark .tier-badge.tier-4 { background: var(--hg-surface-hover); color: #8b8c92; }
html.dark .heat-cell { background: #2a3542; color: var(--hg-text-bright); }
html.dark .heat-cell.heat-over { background: var(--hg-danger); color: var(--hg-text-bright); }
html.dark .cs-del { color: #3f4046; }
html.dark .cs-del:hover { color: var(--st-reopen-ink); }
html.dark .recruit-card { background: var(--hg-surface-elevated); border-color: var(--hg-border-chrome); }
html.dark .recruit-card .rc-skills { color: var(--hg-text-muted); }
html.dark .recruit-card .rc-meta { color: var(--hg-text-muted); }
html.dark .recruit-rating { background: var(--st-rev-bg); color: var(--st-rev-ink); }
html.dark .recruit-nda { background: var(--st-ip-bg); color: var(--st-ip-ink); }
html.dark .recruit-status { background: var(--hg-surface-hover); color: #8b8c92; }
/* crew/IT inline-edit dark states now owned in §4e (crew/IT dark block) */
#crewTable .cs-invite { font-size: var(--hg-type-11); padding: 2px 8px; white-space: nowrap; }
#crewTable .cs-invite:disabled { opacity: 0.45; cursor: not-allowed; }

/* ===== APPEARANCE PANEL ===== */
/*  Follows the same modal convention as the crew/recruitment modals:
    .modal-bg overlay + .modal frost panel are inherited from the global
    rules. Only appearance-specific controls (sections, sliders, color
    pickers, preset swatches, textarea) are styled here. All colors use
    the existing token system so light/dark both work automatically. */
/* Per Sergio: panel bg opacity +50% (frost-ink 4% → 6%) and the large
   blur (16px → 32px) — token overrides only; the global .modal rule
   picks them up. */
#appearanceModal {
  --hg-frost-bg: color-mix(in srgb, var(--hg-frost-ink) 6%, transparent);
  --hg-frost-blur: 32px;
  --hg-frost-blur-soft: 16px;
}
/* Close (✕) button — top-right of the panel, distinct from Save */
.ap-close {
  position: absolute; top: 10px; right: 12px;
  border: none; background: transparent; cursor: pointer;
  font-size: var(--hg-type-medium); line-height: 1;
  color: var(--hg-text-muted); padding: 4px 6px; border-radius: 4px;
}
.ap-close:hover { color: var(--hg-text-ink); background: var(--hg-frost-hover); }
html.dark .ap-close { color: var(--hg-text-muted); }
html.dark .ap-close:hover { color: var(--hg-text-bright); background: var(--hg-frost-hover); }
.ap-section { margin-bottom: 16px; }
.ap-label {
  display: block; font-size: var(--hg-type-11); font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--hg-text-ink); margin-bottom: 8px;
}
html.dark .ap-label { color: var(--hg-text-bright); }
.ap-hint {
  display: block; font-size: var(--hg-type-10); color: var(--hg-text-muted);
  margin-top: 4px; line-height: 1.4;
}

/* Preset swatches row */
.ap-preset-row { display: flex; gap: 8px; flex-wrap: wrap; }
.ap-preset-btn {
  border: none; border-radius: 6px;
  padding: 8px 14px; cursor: pointer; background: transparent;
  font-size: var(--hg-type-11); font-weight: 500; color: var(--hg-text-ink);
  transition: color .15s;
}
.ap-preset-btn:hover { color: var(--hg-text-ink); }
html.dark .ap-preset-btn { color: var(--hg-text-bright); }
html.dark .ap-preset-btn:hover { color: var(--hg-text-bright); }
.ap-preset-btn.on {
  color: var(--hg-accent); font-weight: 600;
}
html.dark .ap-preset-btn.on { color: var(--hg-accent); }
/* Small surface preview swatch inside the button */
.ap-preset-swatch {
  display: inline-block; width: 14px; height: 14px; border-radius: 3px;
  margin-right: 6px; vertical-align: middle;
}

/* Accent colour pickers */
.ap-accent-row { display: flex; align-items: center; gap: 8px; }
.ap-color-pick {
  width: 32px; height: 32px; border: 1px solid var(--hg-border-control);
  border-radius: 4px; cursor: pointer; padding: 2px; background: transparent;
}
.ap-color-pick::-webkit-color-swatch { border: none; border-radius: 2px; }
.ap-color-pick::-moz-color-swatch { border: none; border-radius: 2px; }
.ap-color-lab {
  font-size: var(--hg-type-11); color: var(--hg-text-secondary);
}
html.dark .ap-color-lab { color: var(--hg-text-muted); }
.ap-reset-btn {
  border: 1px solid var(--hg-border-control); border-radius: 4px;
  padding: 4px 10px; font-size: var(--hg-type-10); cursor: pointer;
  background: transparent; color: var(--hg-text-secondary); margin-left: auto;
}
.ap-reset-btn:hover { color: var(--hg-text-ink); border-color: var(--hg-border-hover); }
html.dark .ap-reset-btn { color: var(--hg-text-muted); }
html.dark .ap-reset-btn:hover { color: var(--hg-text-bright); }

/* Sliders — styled range inputs using accent token */
.ap-slider {
  width: 100%; height: 4px; -webkit-appearance: none; appearance: none;
  background: var(--hg-text-secondary); border-radius: 2px; outline: none;
  margin: 6px 0;
}
html.dark .ap-slider { background: var(--hg-text-dim); }
.ap-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 16px; height: 16px;
  border-radius: 50%; background: var(--hg-accent); cursor: pointer;
  border: 2px solid var(--hg-surface-base);
}
.ap-slider::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%; background: var(--hg-accent);
  cursor: pointer; border: 2px solid var(--hg-surface-base);
}
html.dark .ap-slider::-webkit-slider-thumb { border-color: var(--hg-surface-base); }
html.dark .ap-slider::-moz-range-thumb { border-color: var(--hg-surface-base); }
.ap-slider-val {
  font-size: var(--hg-type-10); font-weight: 600; color: var(--hg-text-ink);
}
html.dark .ap-slider-val { color: var(--hg-text-bright); }

/* Background image row */
.ap-bg-row { display: flex; align-items: center; gap: 8px; }
.ap-bg-url { font-size: var(--hg-type-11); }

.cf-section-head td {
  font-size: var(--hg-type-10); font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: var(--hg-text-dim); padding: 8px 6px 4px;
  border-bottom: 1px solid var(--hg-border-row);
}
.cf-section-total td {
  font-weight: 600; border-top: 1px solid var(--hg-border-row); color: var(--hg-text-ink);
}
.cf-grand-total td {
  font-weight: 700; border-top: 2px solid var(--hg-border-warm); border-bottom: none;
  color: var(--hg-text-ink); font-size: var(--hg-type-medium);
}
.cf-row-balance td {
  font-weight: 600; padding: 6px 6px; border-top: 1px solid var(--hg-border-row);
}
.cf-balance { font-variant-numeric: tabular-nums; }
.cf-balance-neg { color: var(--hg-danger); }
.cf-balance-empty { border: none !important; background: transparent !important; }
.cf-label { white-space: nowrap; font-size: var(--hg-type-11); }
.cf-line-label { white-space: nowrap; font-size: var(--hg-type-base); }
.cf-row-total { font-variant-numeric: tabular-nums; font-weight: 600; }
.cf-del-cell { text-align: center; padding: 2px 4px; }

/* dark mode */
html.dark .acct-cf-wrap { border-top-color: var(--hg-border-chrome); }
html.dark .acct-cf-title { color: var(--hg-text-bright); }
html.dark .acct-cf-sub { color: var(--hg-text-muted); }
html.dark .cf-section-head td { color: var(--hg-text-muted); border-bottom-color: var(--hg-border-chrome); }
html.dark .cf-section-total td { border-top-color: var(--hg-border-chrome); color: var(--hg-text-bright); }
html.dark .cf-grand-total td { border-top-color: var(--hg-border-control); color: var(--hg-text-bright); }
html.dark .cf-row-balance td { border-top-color: var(--hg-border-chrome); }
html.dark .cf-balance-neg { color: var(--hg-danger-bright); }
html.dark .cf-forecast-scroll { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }

/* scenario selector + derived/scenario row styling */
/* Head bar for Book Overview + Cashflow views: title, subtitle and
   period controls in one aligned strip (centered, app filter-bar idiom). */
.acct-cf-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  justify-content: center;
  padding: 8px 16px 6px;
}
.acct-cf-head .acct-cf-title {
  font-size: var(--hg-type-base); font-weight: 600;
  color: var(--hg-text-secondary);
}
.acct-cf-head .acct-cf-sub {
  font-size: var(--hg-type-11); color: var(--hg-text-dim);
}
.acct-cf-head .acct-cf-spacer { flex: 0 0 22px; }
.acct-cf-head .acct-mode-btn {
  appearance: none; border: none; background: transparent; cursor: pointer;
  padding: 0 6px; font-size: var(--hg-type-base); color: var(--hg-text-muted);
}
.acct-cf-head .acct-mode-btn:hover { color: var(--hg-accent); }
.acct-cf-spacer { flex: 1; }
.acct-cf-scen-lbl { font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .05em; color: var(--hg-text-dim); }
.cf-derived-row td { color: var(--hg-text-secondary); }
.cf-derived-cell { font-variant-numeric: tabular-nums; font-size: var(--hg-type-11); }
.cf-scenario-row td { color: var(--st-rev-ink); background: #fdf6e9; }
html.dark .cf-derived-row td { color: var(--hg-text-muted); }
html.dark .cf-derived-cell { color: var(--hg-text-muted); }
html.dark .cf-scenario-row td { color: var(--st-rev-ink); background: var(--st-rev-bg); }

/* ===== 9. TIER TEST + TIER SECURITY ===== */
.tier-test {
  display: inline-flex; gap: 2px; margin-left: 8px;
  border: 1px solid var(--hg-border-control); border-radius: 4px; padding: 1px;
  background: var(--hg-surface-input);
}
.tier-btn {
  border: none; background: var(--hg-surface-tabs); cursor: pointer;
  font-size: var(--hg-type-10); font-weight: 500; padding: 2px 8px;
  border-radius: 3px; color: var(--hg-text-muted); transition: all .15s;
  font-variant-numeric: tabular-nums;
}
.tier-btn:hover { color: var(--hg-text-ink); background: var(--hg-surface-tabs); }
.tier-btn.on { background: var(--hg-accent); color: var(--hg-text-on-accent); }
.tier-btn.on:hover { background: var(--hg-accent); }

/* tier-test dark */
html.dark .tier-test { background: transparent; border-color: var(--hg-border-control); }
html.dark .tier-btn { color: var(--hg-text-muted); background: var(--hg-surface-card); }
html.dark .tier-btn:hover { color: #b8b9be; background: var(--hg-surface-card); }
html.dark .tier-btn.on { background: var(--hg-accent); color: var(--gbar-rev-ink); }

/* ===== 10. UNDO / REDO STRIP ===== */
.undo-strip {
  display: inline-flex; gap: 2px; margin-left: 8px;
  border: 1px solid var(--hg-border-control); border-radius: 4px; padding: 1px;
  background: var(--hg-surface-input);
}
.undo-btn {
  border: none; background: #eee; cursor: pointer;
  font-size: var(--hg-type-11); font-weight: 500; padding: 2px 8px; line-height: 1.2;
  border-radius: 3px; color: var(--hg-text-ink); transition: all .15s;
  font-variant-numeric: tabular-nums; min-width: 32px;
}
.undo-btn:hover:not(:disabled) { background: #e2e2e2; }
.undo-btn:disabled { color: var(--hg-text-muted); background: transparent; cursor: default; }

html.dark .undo-strip { background: transparent; border-color: var(--hg-border-control); }
html.dark .undo-btn { color: #b8b9be; background: var(--hg-surface-card); }
html.dark .undo-btn:hover:not(:disabled) { background: var(--hg-surface-hover); }
html.dark .undo-btn:disabled { color: var(--hg-text-muted); background: transparent; }
html.dark .tier-btn.on:hover { background: var(--hg-accent); }
/* tier-based visibility (security) — keep late */
/* t1-only: visible only at T1 (Founder). Hidden at T2/T3/T4. */
[data-tier="2"] .t1-only,
[data-tier="3"] .t1-only,
[data-tier="4"] .t1-only { display: none !important; }

/* t2-only: visible at T1 and T2. Hidden at T3/T4. */
[data-tier="3"] .t2-only,
[data-tier="4"] .t2-only { display: none !important; }
/* ===== 10. PRIMITIVES (late winners) — focus, select hairline, status menu =====
   OWNED HERE: select/input/crew-pick/proj-select final chrome. Surfaces must not
   re-assert boxed borders on these. */
/* focus ring — buttons/selects/tabs only. Text inputs use the hairline
   underline focus (see .gfilters input:focus, .hg-inp:focus, etc.); a boxed
   ring on text boxes is not part of the design language. */
button:focus-visible, select:focus-visible, .tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 1px var(--hg-accent), 0 0 0 3px color-mix(in srgb, var(--hg-accent) 20%, transparent);
}
html.dark button:focus-visible, html.dark select:focus-visible, html.dark .tab:focus-visible {
  box-shadow: 0 0 0 1px #8fa9c4, 0 0 0 3px #8fa9c433;
}
/* select restyle — flat hairline, custom chevron, no OS chrome */
select {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6' viewBox='0 0 8 6'%3E%3Cpath d='M1 1.5l3 3 3-3' fill='none' stroke='%239a9aa2' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 8px center;
  border: none; border-bottom: 1px solid var(--hg-border-control); border-radius: 0;
  padding: 3px 20px 3px 2px; font: inherit; font-size: var(--hg-type-11h); color: var(--hg-text-ink);
  cursor: pointer;
}
select:hover { border-bottom-color: var(--hg-border-focus); }
select:focus { outline: none; border-bottom-color: var(--hg-accent); box-shadow: none; }
select option { background-color: var(--hg-surface-input); color: var(--hg-text-ink); }
html.dark select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6' viewBox='0 0 8 6'%3E%3Cpath d='M1 1.5l3 3 3-3' fill='none' stroke='%236f7076' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  border-bottom-color: var(--hg-border-control); color: var(--hg-text-bright);
}
html.dark select:hover { border-bottom-color: #6f7076; }
html.dark select:focus { border-bottom-color: var(--hg-border-focus); }
html.dark select option { background-color: var(--hg-surface-raised); color: var(--hg-text-bright); }

/* filter rows: kill the old boxed style */
.gfilters select { border: none; border-bottom: 1px solid var(--hg-border-control); border-radius: 0; background-color: transparent; padding: 3px 20px 3px 2px; }
html.dark .gfilters select { border-bottom-color: var(--hg-border-control); background-color: transparent; }

/* status pill selects keep their pill color but get the new chevron + no native arrow */
select.st-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6' viewBox='0 0 8 6'%3E%3Cpath d='M1 1.5l3 3 3-3' fill='none' stroke='%239a9aa2' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 5px center;
  border: none; border-bottom: none; border-radius: 3px;
  padding: 1px 18px 1px 8px;
}
html.dark select.st-select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6' viewBox='0 0 8 6'%3E%3Cpath d='M1 1.5l3 3 3-3' fill='none' stroke='%236f7076' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }

/* project picker in proj-strip: transparent, hairline on hover */
.proj-strip .proj-select {
  border: none; border-bottom: 1px solid transparent; border-radius: 0;
  padding: 3px 20px 3px 2px; background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6' viewBox='0 0 8 6'%3E%3Cpath d='M1 1.5l3 3 3-3' fill='none' stroke='%239a9aa2' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 6px center;
}
.proj-strip .proj-select:hover { background-color: transparent; border-bottom-color: var(--hg-border-focus); }
html.dark .proj-strip .proj-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='6' viewBox='0 0 8 6'%3E%3Cpath d='M1 1.5l3 3 3-3' fill='none' stroke='%236f7076' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); border-bottom-color: transparent;
}
html.dark .proj-strip .proj-select:hover { background-color: transparent; border-bottom-color: #6f7076; }

/* crew pick: match the same flat look */
.crew-pick {
  border: none; border-bottom: 1px solid var(--hg-border-control); border-radius: 0;
  background-color: transparent; padding: 1px 16px 1px 2px;
}
html.dark .crew-pick { border-bottom-color: var(--hg-border-control); background-color: transparent; }
html.dark .crew-pick.un { border-bottom-color: var(--st-reopen-bg); }
html.dark .crew-pick.inherited { border-bottom-color: #2a2b30; }

/* owner pick: same flat chrome */
.owner-pick {
  border: none; border-bottom: 1px solid var(--hg-border-control); border-radius: 0;
  background-color: transparent; padding: 1px 16px 1px 2px;
}
html.dark .owner-pick { border-bottom-color: var(--hg-border-control); background-color: transparent; }
html.dark .owner-pick.un { border-bottom-color: #2a2b30; }

/* text inputs: same hairline treatment */
.gfilters input, .mrow input {
  border: none; border-bottom: 1px solid var(--hg-border-control); border-radius: 0;
  background-color: transparent; padding: 3px 2px; font-size: var(--hg-type-11h);
}
.gfilters input:focus, .mrow input:focus { outline: none; border-bottom-color: var(--hg-accent); box-shadow: none; }
html.dark .gfilters input, html.dark .mrow input {
  border-bottom-color: var(--hg-border-control); background-color: transparent; color: var(--hg-text-bright);
}
html.dark .gfilters input:focus, html.dark .mrow input:focus { border-bottom-color: var(--hg-border-focus); }
/* custom status menu — replaces native selects */
button.st-select {
  appearance: none; -webkit-appearance: none;
  display: inline-flex; align-items: center; gap: 5px;
  font: inherit; font-size: var(--hg-type-micro); line-height: 15px; white-space: nowrap;
  padding: 1px 6px 1px 8px; border: 0; border-radius: 3px;
  cursor: pointer; color: inherit; background-image: none;
}
button.st-select:hover { filter: brightness(.97); }
button.st-select:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; box-shadow: none; }
button.st-select:disabled { cursor: wait; opacity: .7; }
.st-chevron { width: 0; height: 0; border-left: 3px solid transparent; border-right: 3px solid transparent; border-top: 4px solid currentColor; opacity: .48; flex: 0 0 auto; }
button.st-select.st-ip { background-color: var(--st-ip-bg); color: var(--st-ip-ink); }
button.st-select.st-wtg { background-color: var(--st-wtg-bg); color: var(--st-wtg-ink); }
button.st-select.st-rev { background-color: var(--st-rev-bg); color: var(--st-rev-ink); }
button.st-select.st-cmpt, button.st-select.st-appr { background-color: var(--st-cmpt-bg); color: var(--hg-text-ink); }
button.st-select.st-reopen { background-color: var(--st-reopen-bg); color: var(--hg-danger-hover); }
.status-menu {
  position: fixed; z-index: 100; width: 132px; padding: 4px;
  background: var(--hg-surface-tabs); border: 1px solid #dcdcdc; border-radius: 4px;
  box-shadow: var(--hg-shadow-menu);
}
.status-menu-item {
  display: flex; width: 100%; border: 0; border-radius: 3px; padding: 5px 8px;
  background: transparent; color: var(--hg-text-ink); text-align: left; font: 500 11px/1.2 "Inter", sans-serif; cursor: pointer;
}
.status-menu-item:hover, .status-menu-item.current { background: #f0f0f0; }
.status-menu-item.current::after { content: ""; width: 4px; height: 4px; margin: auto 0 auto auto; border-radius: 50%; background: currentColor; }
.status-menu-item.st-ip { color: var(--st-ip-ink); }
.status-menu-item.st-wtg { color: var(--st-wtg-ink); }
.status-menu-item.st-rev { color: var(--st-rev-ink); }
.status-menu-item.st-cmpt, .status-menu-item.st-appr { color: var(--st-cmpt-ink); }
.status-menu-item.st-reopen { color: var(--hg-danger-hover); }
html.dark button.st-select.st-ip { background-color: var(--st-ip-bg); color: var(--st-ip-ink); }
html.dark button.st-select.st-wtg { background-color: var(--hg-surface-hover); color: #b4b5bb; }
html.dark button.st-select.st-rev { background-color: var(--st-rev-bg); color: var(--st-rev-ink); }
html.dark button.st-select.st-cmpt { background-color: var(--st-cmpt-bg); color: var(--st-cmpt-ink); }
html.dark button.st-select.st-appr { background-color: var(--st-appr-bg); color: var(--hg-info); }
html.dark button.st-select.st-reopen { background-color: var(--st-reopen-bg); color: var(--st-reopen-ink); }
html.dark .status-menu { background: var(--hg-surface-tabs); border-color: var(--hg-border-control); box-shadow: var(--hg-shadow-menu); }
html.dark .status-menu-item { color: #c2c3c8; }
html.dark .status-menu-item:hover, html.dark .status-menu-item.current { background: #26272b; }
html.dark .status-menu-item.st-ip { color: var(--st-ip-ink); }
html.dark .status-menu-item.st-wtg { color: #b4b5bb; }
html.dark .status-menu-item.st-rev { color: var(--st-rev-ink); }
html.dark .status-menu-item.st-cmpt { color: var(--st-cmpt-ink); }
html.dark .status-menu-item.st-appr { color: var(--hg-info); }
html.dark .status-menu-item.st-reopen { color: var(--st-reopen-ink); }

/* ===== shared popover dropdown (hgSelect / hgSelectMulti) ===== */
.hg-select, .hg-multi-select {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  display: inline-flex; align-items: center; gap: 6px;
  background-color: transparent; background-image: none;
  border: none; border-bottom: 1px solid var(--hg-border-control); border-radius: 0;
  padding: 3px 20px 3px 2px; font: inherit; font-size: var(--hg-type-11h);
  color: var(--hg-text-ink); cursor: pointer; white-space: nowrap;
}
.hg-select:not(.un), .hg-multi-select:not(.un) { font-weight: 500; }
.hg-select:hover, .hg-multi-select:hover { border-bottom-color: var(--hg-border-focus); }
.hg-select:focus-visible, .hg-multi-select:focus-visible {
  outline: none; border-bottom-color: var(--hg-accent);
}
.hg-select.un, .hg-multi-select.un { color: var(--hg-text-muted); }
/* First-column row labels must match IT Tracker / Crew: --hg-text-ink,
   base font size, weight 600 — even when the cell is a select trigger. */
#v-cliInv #cliInvTable td:first-child .hg-select,
#v-ctiInv #conInvTable td:first-child .hg-select {
  font-size: var(--hg-type-base);
  font-weight: 600;
  color: var(--hg-text-ink);
}
#v-cliInv #cliInvTable td:first-child .hg-select.un,
#v-ctiInv #conInvTable td:first-child .hg-select.un {
  color: var(--hg-text-ink);
}
html.dark #v-cliInv #cliInvTable td:first-child .hg-select,
html.dark #v-ctiInv #conInvTable td:first-child .hg-select {
  color: var(--hg-text-bright);
}
html.dark #v-cliInv #cliInvTable td:first-child .hg-select.un,
html.dark #v-ctiInv #conInvTable td:first-child .hg-select.un {
  color: var(--hg-text-bright);
}
/* First-column row labels in the remaining tracker tables must match IT
   Tracker / Crew: weight 600 (color + font already inherit the shared
   .hg-cell-input tokens — ink/bright + Inter 12px). */
#v-ex #expTable td .hg-cell-input[data-field="vendor"],
#v-ast #astTable td:first-child .hg-cell-input,
#v-prl #prlTable td:first-child .hg-cell-input,
#v-rc #rcTable td:first-child .hg-cell-input {
  font-weight: 600;
}
/* per-option color on the trigger (optional, from option.cls) */
.hg-select.st-ip, .hg-multi-select.st-ip { background-color: var(--st-ip-bg); color: var(--st-ip-ink); }
.hg-select.st-wtg, .hg-multi-select.st-wtg { background-color: var(--st-wtg-bg); color: var(--st-wtg-ink); }
.hg-select.st-rev, .hg-multi-select.st-rev { background-color: var(--st-rev-bg); color: var(--st-rev-ink); }
.hg-select.st-cmpt, .hg-multi-select.st-cmpt,
.hg-select.st-appr, .hg-multi-select.st-appr { background-color: var(--st-cmpt-bg); color: var(--hg-text-ink); }
.hg-select.st-reopen, .hg-multi-select.st-reopen { background-color: var(--st-reopen-bg); color: var(--hg-danger-hover); }

.hg-menu {
  position: fixed; z-index: 210; min-width: 140px; max-width: 260px;
  max-height: 260px; overflow-y: auto; padding: 4px;
  background: var(--hg-surface-tabs); border: 1px solid color-mix(in srgb, var(--seg-accent) 35%, var(--hg-border-control)); border-radius: 4px;
  box-shadow: var(--hg-shadow-menu);
}
.hg-menu-item {
  display: flex; width: 100%; align-items: center; gap: 8px;
  border: 0; border-radius: 3px; padding: 5px 8px;
  background: transparent; color: var(--hg-text-ink); text-align: left;
  font: 500 11.5px/1.2 "Inter", sans-serif; cursor: pointer; white-space: nowrap;
}
.hg-menu-item:hover, .hg-menu-item.current { background: color-mix(in srgb, var(--seg-accent) 25%, var(--hg-surface-header)); }
.hg-menu-head {
  position: sticky; top: -4px; z-index: 1; margin: -4px -4px 4px;
  padding: 8px 12px; background: var(--hg-surface-header);
  border-bottom: 1px solid var(--hg-border-row);
}
.hg-menu-title { color: var(--hg-text-ink); font-size: var(--hg-type-base); font-weight: 650; }
.hg-menu-subtitle { margin-top: 2px; color: var(--hg-text-muted); font-size: var(--hg-type-small); font-variant-numeric: tabular-nums; }
.hg-menu-item.current::after {
  content: ""; width: 4px; height: 4px; margin: auto 0 auto auto;
  border-radius: 50%; background: currentColor; flex-shrink: 0;
}
.hg-menu-multi .hg-menu-item::before {
  content: ""; width: 11px; height: 11px; flex-shrink: 0;
  border: 1px solid var(--hg-border-menu-chk); border-radius: 3px; background: var(--hg-surface-input);
}
.hg-menu-multi .hg-menu-item.checked::before {
  background-color: var(--hg-accent); border-color: var(--hg-accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='7' viewBox='0 0 9 7'%3E%3Cpath d='M1 3.5l2.5 2.5L8 1' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 9px 7px;
}
/* per-option color inside the menu (from option.cls) */
.hg-menu-item.st-ip { color: var(--st-ip-ink); }
.hg-menu-item.st-wtg { color: var(--st-wtg-ink); }
.hg-menu-item.st-rev { color: var(--st-rev-ink); }
/* separator + new-project button in picker dropdown */
.hg-menu-sep { height: 1px; margin: 4px 2px; background: #e0e0e0; }
.hg-menu-new { color: var(--hg-text-muted); font-weight: 600; }
.hg-menu-new:hover { color: var(--hg-text-ink); }
/* section heading inside a menu (e.g. Scheduling / Weekends on the segment
   label-row RMB menu) — a plain muted label row, not a menu item */
.hg-menu-label {
  padding: 6px 8px 2px; color: var(--hg-text-muted);
  font: 600 10px/1.3 "Inter", sans-serif; text-transform: uppercase;
  letter-spacing: .04em; user-select: none;
}
.hg-menu-item:disabled,
.hg-menu-item:disabled:hover {
  color: var(--hg-text-muted); opacity: .55; cursor: default;
  background: transparent;
}

/* ── Themed tooltip card (gantt bars + dependency wires) ── */
.hg-tooltip {
  position: fixed; z-index: 200; min-width: 120px; max-width: 340px;
  padding: 8px 10px;
  background: var(--hg-surface-tabs);
  border: 1px solid color-mix(in srgb, var(--seg-accent) 35%, var(--hg-border-control));
  border-radius: 6px;
  box-shadow: var(--hg-shadow-menu);
  font: 500 11.5px/1.4 "Inter", sans-serif;
  color: var(--hg-text-ink);
  pointer-events: none;
  /* Own compositing layer (same reasoning as .gfilters): a fixed z-200 card
     sharing the gantt's surface means every show/move/hide re-runs the
     frost's blur pass over wherever it sits, dragging already-blurred
     pixels with it — the glowy clipped box. Promoted, its damage is its own. */
  contain: layout style;
  will-change: transform;
}
.hg-tip-title { font-weight: 600; color: var(--hg-text-ink); }
.hg-tip-body { margin-top: 4px; color: var(--hg-text-secondary); }
.hg-tip-kicker {
  margin-bottom: 2px; color: var(--hg-text-muted); font-size: var(--hg-type-9);
  font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.hg-tip-context { margin-top: 2px; color: var(--hg-text-secondary); font-size: var(--hg-type-small); }
.hg-tip-grid {
  display: grid; gap: 4px; margin: 8px -10px 0; padding: 8px 10px 0;
  border-top: 1px solid var(--hg-border-row);
}
.hg-tip-row { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 10px; margin: 0; }
.hg-tip-row dt { color: var(--hg-text-muted); font-size: var(--hg-type-small); font-weight: 600; }
.hg-tip-row dd { min-width: 0; margin: 0; color: var(--hg-text-ink); overflow-wrap: anywhere; }
.hg-tip-label { color: var(--hg-text-muted); font-size: var(--hg-type-small); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
.hg-tip-note, .hg-tip-alert { margin: 8px -10px -8px; padding: 8px 10px; border-top: 1px solid var(--hg-border-row); }
.hg-tip-alert { color: var(--hg-danger-hover); font-weight: 600; }
.hg-tip-arrow { color: var(--hg-accent); font-weight: 700; margin: 2px 0; }
/* Tooltip text flips in dark mode (ink does NOT flip) — use bright there */
html.dark .hg-tooltip { color: var(--hg-text-bright); }
html.dark .hg-tip-title { color: var(--hg-text-bright); }
html.dark .hg-tip-body { color: var(--hg-text-bright); }
html.dark .hg-tip-context, html.dark .hg-tip-row dd { color: var(--hg-text-bright); }
/* Pinned card (LMB on a task label): same card, anchored below the row and
   static — it does not follow the cursor until dismissed. */
.hg-tooltip-pinned { min-width: 200px; }
/* Interactive bar card (bar-popup-editing): the pinned assignment card edits
   live data — it stops pointer events, its rows space out for controls, and
   its spawned menus/calendars are dismissed as part of it. */
.hg-tooltip.hg-tip-interactive { pointer-events: auto; max-width: 320px; }
.hg-tip-interactive .hg-tip-field dd {
  display: flex; align-items: center; gap: 5px; min-width: 0;
}
.hg-tip-interactive .barcard-date { width: 96px; height: 22px; padding: 1px 6px; font-size: var(--hg-type-10); justify-content: center; }
.hg-tip-interactive .barcard-days { width: 52px; min-height: 22px; padding: 2px 5px; font: 500 11.5px/1.2 "Inter", sans-serif; text-align: right; font-variant-numeric: tabular-nums; }
.hg-tip-interactive .barcard-unit { color: var(--hg-text-muted); font-size: var(--hg-type-small); }
.hg-tip-interactive .barcard-note { width: 100%; min-height: 40px; padding: 4px 6px; resize: vertical; font: 500 11.5px/1.4 "Inter", sans-serif; }
.hg-tip-interactive .barcard-tap,
.hg-menu-seg-policy .barcard-tap {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--hg-border-control); border-radius: 4px;
  background: var(--hg-input-bg); color: var(--hg-input-ink);
  font: 600 11px/1.2 "Inter", sans-serif; padding: 3px 8px; cursor: pointer;
  max-width: 190px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hg-tip-interactive .barcard-tap:hover,
.hg-menu-seg-policy .barcard-tap:not(:disabled):hover { border-color: var(--hg-border-focus); }
.hg-tip-interactive .barcard-weekends { display: flex; flex-wrap: wrap; gap: 4px; }
.hg-tip-interactive .barcard-weekend { max-width: none; }
.hg-tip-interactive .barcard-weekend.pressed,
.hg-menu-seg-policy .barcard-tap.pressed { background: var(--hg-accent); border-color: var(--hg-accent); color: var(--hg-text-on-accent); }
/* Dark twin, adjacent so the pair can never drift (rule 45): dark accent is
   gold — white text on it fails contrast; pressed controls flip to the dark
   ink, exactly like block-btn.on / tier-btn.on. Covers BOTH surfaces that
   share this vocabulary: the bar card's Sat/Sun buttons and the segment RMB
   toggles. */
html.dark .hg-tip-interactive .barcard-weekend.pressed,
html.dark .hg-menu-seg-policy .barcard-tap.pressed { color: var(--gbar-rev-ink); }
.hg-tip-interactive .barcard-tap.st-ip { background: var(--st-ip-bg); color: var(--st-ip-ink); }
.hg-tip-interactive .barcard-tap.st-wtg { background: var(--st-wtg-bg); color: var(--st-wtg-ink); }
.hg-tip-interactive .barcard-tap.st-rev { background: var(--st-rev-bg); color: var(--st-rev-ink); }
.hg-tip-interactive .barcard-tap.st-cmpt { background: var(--st-cmpt-bg); color: var(--st-cmpt-ink); }
.hg-tip-interactive .barcard-tap.st-appr { background: var(--st-appr-bg); color: var(--st-appr-ink); }
.hg-tip-interactive .barcard-static {
  display: inline-flex; align-items: center;
  font: 600 11px/1.2 "Inter", sans-serif; padding: 3px 8px; border-radius: 4px;
  max-width: 190px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hg-tip-interactive .barcard-static.st-ip { background: var(--st-ip-bg); color: var(--st-ip-ink); }
.hg-tip-interactive .barcard-static.st-wtg { background: var(--st-wtg-bg); color: var(--st-wtg-ink); }
.hg-tip-interactive .barcard-static.st-rev { background: var(--st-rev-bg); color: var(--st-rev-ink); }
.hg-tip-interactive .barcard-static.st-cmpt { background: var(--st-cmpt-bg); color: var(--st-cmpt-ink); }
.hg-tip-interactive .barcard-static.st-appr { background: var(--st-appr-bg); color: var(--st-appr-ink); }
html.dark .hg-tip-interactive .barcard-note,
html.dark .hg-tip-interactive .barcard-days { color: var(--hg-text-bright); }
/* Bar-card sections (bar-popup-editing): the card groups into Schedule /
   People sections with small uppercase labels; the label column widens to
   fit "Weekday span" and rows gain breathing room. Scoped to .barcard-grid
   so the task-label row card keeps its compact rows. */
.hg-tip-interactive .hg-tip-grid.barcard-grid { gap: 7px; padding-top: 10px; }
.hg-tip-interactive .barcard-grid .hg-tip-row { grid-template-columns: 86px minmax(0, 1fr); gap: 12px; }
/* Segment RMB policy toggles (gantt-business-time.js): segmented pairs in
   the popover, one pressed = the segment's current mode. They reuse the
   bar card's toggle vocabulary (barcard-tap / pressed) — the same Sat/Sun
   control, extended to the menu — not a second control family. */
.hg-menu-seg-policy .hg-seg-toggle {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px 6px;
}
.hg-menu-seg-policy .hg-seg-toggle .barcard-tap {
  display: flex; justify-content: center; max-width: none;
}
.hg-menu-seg-policy .hg-seg-toggle .barcard-tap:disabled { opacity: .45; cursor: default; }
.barcard-sec-title {
  margin-top: 5px; padding-bottom: 3px;
  color: var(--hg-text-muted); font-size: var(--hg-type-9);
  font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.barcard-sec-title:first-child { margin-top: 0; }
/* Row card (task label popup): each bar row's dd is [status text]
   [crew names][days]. Names paint people-violet (rule 39) and underline on
   hover when clickable; done bars keep violet names without the pointer.
   Unstaffed is placeholder text, never a control. Days stay read text,
   pushed to the right edge. */
.hg-tip-interactive .hg-tip-field dd .rowcard-status { white-space: nowrap; }
.hg-tip-interactive .hg-tip-field dd .rowcard-crew-name { color: var(--hg-people); }
.hg-tip-interactive .hg-tip-field dd .rowcard-crew-name[data-assignment] { cursor: pointer; }
.hg-tip-interactive .hg-tip-field dd .rowcard-crew-name[data-assignment]:hover { text-decoration: underline; text-underline-offset: 2px; }
.hg-tip-interactive .hg-tip-field dd .rowcard-unstaffed { color: var(--hg-text-muted); cursor: pointer; }
.hg-tip-interactive .hg-tip-field dd .rowcard-unstaffed:hover { text-decoration: underline; text-underline-offset: 2px; }
.hg-tip-interactive .hg-tip-field dd .rowcard-days {
  color: var(--hg-text-muted); font: 500 11px/1.2 "Inter", sans-serif;
  white-space: nowrap; margin-left: auto; flex-shrink: 0;
}
.hg-menu-item.st-cmpt, .hg-menu-item.st-appr { color: var(--st-cmpt-ink); }
.hg-menu-item.st-reopen { color: var(--hg-danger-hover); }

/* Assignment chooser reuses .hg-menu, .hg-ctl and semantic tokens. Per-row
   rules define layout only; controls retain the shared primitive vocabulary. */
.assignment-chooser { min-width: 360px; max-width: min(520px, calc(100vw - 16px)); }
.assignment-choice { padding: 7px 8px; border-bottom: 1px solid var(--hg-border-row); }
.assignment-choice:last-child { border-bottom: 0; }
.assignment-choice-main { display: flex; justify-content: space-between; gap: 12px; color: var(--hg-text-ink); font-size: var(--hg-type-11); font-variant-numeric: tabular-nums; }
.assignment-choice-main span:last-child { color: var(--hg-text-muted); }
.assignment-choice-actions { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 4px; }
.assignment-choice-actions .hg-ctl { min-height: 22px; padding: 2px 5px; cursor: pointer; }
.assignment-choice-readonly { color: var(--hg-text-muted); font: var(--hg-type-meta); padding: 3px 0; }
.assignment-unscheduled { color: var(--hg-text-muted); font-size: var(--hg-type-11); }
html.dark .assignment-choice-main { color: var(--hg-text-bright); }

/* Preset picker menu — rows with name + ✕ delete */
.hg-menu-presets .hg-preset-row {
  display: flex; align-items: center; gap: 2px;
  border-radius: 3px; padding: 0;
}
.hg-menu-presets .hg-preset-name {
  flex: 1; border: 0; background: transparent; text-align: left;
  padding: 5px 8px; color: var(--hg-text-ink);
  font: 500 11.5px/1.2 "Inter", sans-serif; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  border-radius: 3px;
}
.hg-menu-presets .hg-preset-name:hover { background: color-mix(in srgb, var(--seg-accent) 25%, var(--hg-surface-header)); }
.hg-menu-presets .hg-preset-del {
  border: 0; background: transparent; cursor: pointer;
  color: #c8c8ce; font-size: var(--hg-type-base); padding: 2px 6px;
  border-radius: 3px; flex-shrink: 0;
}
.hg-menu-presets .hg-preset-del:hover { color: var(--hg-danger-ink); }
/* "new preset…" separator in save-preset menu */
.hg-menu-presets .hg-preset-newopt {
  border-top: 1px solid var(--hg-border-control); margin-top: 2px; padding-top: 7px;
  color: var(--hg-text-muted);
}
.hg-menu-presets .hg-preset-newopt:hover { color: var(--hg-text-ink); }
html.dark .hg-select, html.dark .hg-multi-select {
  border-bottom-color: var(--hg-border-control); color: var(--hg-text-bright);
}
html.dark .hg-select:hover, html.dark .hg-multi-select:hover { border-bottom-color: #6f7076; }
html.dark .hg-select.un, html.dark .hg-multi-select.un { color: var(--hg-text-muted); }
html.dark .hg-select.st-ip, html.dark .hg-multi-select.st-ip { background-color: var(--st-ip-bg); color: var(--st-ip-ink); }
html.dark .hg-select.st-wtg, html.dark .hg-multi-select.st-wtg { background-color: var(--hg-surface-hover); color: #b4b5bb; }
html.dark .hg-select.st-rev, html.dark .hg-multi-select.st-rev { background-color: var(--st-rev-bg); color: var(--st-rev-ink); }
html.dark .hg-select.st-cmpt, html.dark .hg-multi-select.st-cmpt,
html.dark .hg-select.st-appr, html.dark .hg-multi-select.st-appr { background-color: var(--st-cmpt-bg); color: var(--st-cmpt-ink); }
html.dark .hg-select.st-reopen, html.dark .hg-multi-select.st-reopen { background-color: var(--st-reopen-bg); color: var(--st-reopen-ink); }
html.dark .hg-menu { background: var(--hg-surface-tabs); border-color: var(--hg-border-control); box-shadow: var(--hg-shadow-menu); }
html.dark .hg-menu-head { background: var(--hg-surface-header); border-bottom-color: var(--hg-border-row); }
html.dark .hg-menu-title { color: var(--hg-text-bright); }
html.dark .hg-menu-item { color: #c2c3c8; }
html.dark .hg-menu-item:hover, html.dark .hg-menu-item.current { background: #26272b; }
html.dark .hg-menu-sep { background: #3a3b40; }
html.dark .hg-menu-new { color: var(--hg-text-muted); }
html.dark .hg-menu-new:hover { color: var(--hg-text-bright); }
html.dark .hg-menu-multi .hg-menu-item::before {
  border-color: var(--hg-border-hover); background: var(--hg-surface-raised);
}
html.dark .hg-menu-multi .hg-menu-item.checked::before {
  background-color: var(--hg-accent); border-color: var(--hg-accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='7' viewBox='0 0 9 7'%3E%3Cpath d='M1 3.5l2.5 2.5L8 1' fill='none' stroke='%23515255' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 9px 7px;
}
html.dark .hg-menu-item.st-ip { color: var(--st-ip-ink); }
html.dark .hg-menu-item.st-wtg { color: #b4b5bb; }
html.dark .hg-menu-item.st-rev { color: var(--st-rev-ink); }
html.dark .hg-menu-item.st-cmpt { color: var(--st-cmpt-ink); }
html.dark .hg-menu-item.st-appr { color: var(--hg-info); }
html.dark .hg-menu-item.st-reopen { color: var(--st-reopen-ink); }

/* dark: preset picker rows */
html.dark .hg-menu-presets .hg-preset-name { color: #c2c3c8; }
html.dark .hg-menu-presets .hg-preset-name:hover { background: #26272b; }
html.dark .hg-menu-presets .hg-preset-del { color: #3f4046; }

/* Tag multiselect menu on hg-entity-block cards — reuses .hg-menu-presets row chrome */
.hg-tag-toggle::before { content: ""; display: inline-block; width: 10px; color: var(--hg-text-muted); }
.hg-tag-toggle.on::before { content: "✓"; color: var(--hg-text-ink); }
/* Tag-row action icons: ✎ rename (neutral, blue on hover) + 🗑 delete (red on hover) */
.hg-tag-row .hg-tag-ren { color: var(--hg-text-muted); }
.hg-tag-row .hg-tag-ren:hover { color: #2a6db0; }
.hg-tag-row .hg-tag-del { color: #b8b8be; }
.hg-tag-row .hg-tag-del:hover { color: #d92b2b; }
.hg-tag-empty { padding: 7px 10px; font-size: var(--hg-type-11); color: var(--hg-text-muted); }
.tag-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
.hg-tag-addrow { border-top: 1px solid color-mix(in srgb, var(--seg-accent) 30%, rgba(255,255,255,.3)); padding: 5px 6px; display: flex; align-items: center; gap: 6px; }
.hg-tag-addrow .hg-tag-newlabel { font-size: var(--hg-type-11h); color: var(--hg-text-muted, #8a93a3); flex-shrink: 0; user-select: none; }
.hg-tag-addrow .hg-tag-new { flex: 1; min-width: 0; box-sizing: border-box; font-size: var(--hg-type-11h); }
.hg-tag-cliprow { border-top: 1px solid color-mix(in srgb, var(--seg-accent) 30%, rgba(255,255,255,.3)); padding: 5px 6px; display: flex; gap: 6px; }
.hg-tag-cliprow .hg-tag-copy, .hg-tag-cliprow .hg-tag-paste {
  flex: 1; font-size: var(--hg-type-11); border: 1px solid color-mix(in srgb, var(--seg-accent) 45%, rgba(255,255,255,.3)); border-radius: 4px;
  padding: 3px 6px; text-align: center; cursor: pointer; color: var(--hg-text-ink); background: color-mix(in srgb, var(--seg-accent) 25%, transparent);
}
.hg-tag-cliprow .hg-tag-copy:hover, .hg-tag-cliprow .hg-tag-paste:hover { border-color: color-mix(in srgb, var(--seg-accent) 65%, rgba(255,255,255,.3)); background: color-mix(in srgb, var(--seg-accent) 35%, transparent); }
.hg-tag-cliprow .hg-tag-paste.un { color: var(--hg-text-muted); cursor: default; }
.hg-tag-cliprow .hg-tag-paste.un:hover { border-color: color-mix(in srgb, var(--seg-accent) 30%, rgba(255,255,255,.3)); background: color-mix(in srgb, var(--seg-accent) 10%, transparent); }
.a-tag, .tag-pill, .t-tag { font-size: var(--hg-type-small); border: 1px solid color-mix(in srgb, var(--seg-accent) 45%, rgba(255,255,255,.3)); border-radius: 4px; padding: 1px 4px; background: color-mix(in srgb, var(--seg-accent) 20%, transparent); color: var(--hg-text-ink); cursor: pointer; outline: none; white-space: nowrap; }
.a-tag:hover, .tag-pill:hover, .t-tag:hover { border-color: color-mix(in srgb, var(--seg-accent) 65%, rgba(255,255,255,.3)); background: color-mix(in srgb, var(--seg-accent) 30%, transparent); }
.a-tag.un, .tag-pill.un, .t-tag.un { color: var(--hg-text-muted); background: color-mix(in srgb, var(--seg-accent) 10%, transparent); }
html.dark .a-tag, html.dark .tag-pill, html.dark .t-tag { background: var(--hg-surface-raised); border-color: var(--hg-border-control); color: #8a8b90; }
html.dark .a-tag:hover, html.dark .tag-pill:hover, html.dark .t-tag:hover { border-color: var(--hg-border-hover); }
html.dark .a-tag.un, html.dark .tag-pill.un, html.dark .t-tag.un { color: #55565c; background: color-mix(in srgb, var(--seg-accent) 10%, transparent); }
/* Tag colour palette — one class per slot, saturated so tags stand out from
   the washed hg-stage tints. Sorted position within the hg-stage vocabulary picks the
   slot (tagSlot in dom.js, mod 8). Dark mode gets its own deep set. */
.a-tag.tag-0, .tag-pill.tag-0, .t-tag.tag-0 { background:#f2b233; border-color:#c98f1f; color:#3a2b05; }
.a-tag.tag-1, .tag-pill.tag-1, .t-tag.tag-1 { background:#e56aa8; border-color:#c44b87; color:#3d0e29; }
.a-tag.tag-2, .tag-pill.tag-2, .t-tag.tag-2 { background:#4caf6d; border-color:#3a8f55; color:#0c2f18; }
.a-tag.tag-3, .tag-pill.tag-3, .t-tag.tag-3 { background:#8f6ce0; border-color:#7350c4; color:#1e0f3d; }
.a-tag.tag-4, .tag-pill.tag-4, .t-tag.tag-4 { background:#2fb4c4; border-color:#2197a5; color:#06282d; }
.a-tag.tag-5, .tag-pill.tag-5, .t-tag.tag-5 { background:#ee7b54; border-color:#cf5f38; color:#3d1203; }
.a-tag.tag-6, .tag-pill.tag-6, .t-tag.tag-6 { background:#5d82b8; border-color:#47689a; color:#0d1c30; }
.a-tag.tag-7, .tag-pill.tag-7, .t-tag.tag-7 { background:#9aa0a8; border-color:#7e848c; color:#1c1e22; }
html.dark .a-tag.tag-0, html.dark .tag-pill.tag-0, html.dark .t-tag.tag-0 { background:#d9a13b; border-color:#a87b27; color:#1c1202; }
html.dark .a-tag.tag-1, html.dark .tag-pill.tag-1, html.dark .t-tag.tag-1 { background:#d15f9e; border-color:#a8477d; color:#220614; }
html.dark .a-tag.tag-2, html.dark .tag-pill.tag-2, html.dark .t-tag.tag-2 { background:#3f9d63; border-color:#2e7c4b; color:#07150c; }
html.dark .a-tag.tag-3, html.dark .tag-pill.tag-3, html.dark .t-tag.tag-3 { background:#7d5fd4; border-color:#6248ad; color:#150b30; }
html.dark .a-tag.tag-4, html.dark .tag-pill.tag-4, html.dark .t-tag.tag-4 { background:#2aa3b3; border-color:#1f828f; color:#031c20; }
html.dark .a-tag.tag-5, html.dark .tag-pill.tag-5, html.dark .t-tag.tag-5 { background:#d96a47; border-color:#b05233; color:#2a0c02; }
html.dark .a-tag.tag-6, html.dark .tag-pill.tag-6, html.dark .t-tag.tag-6 { background:#4d74ad; border-color:#3a5a8a; color:#081426; }
html.dark .a-tag.tag-7, html.dark .tag-pill.tag-7, html.dark .t-tag.tag-7 { background:#70757f; border-color:#565b64; color:#101216; }
/* Menu row dots mirror the pill colours */
.tag-dot-0 { background:#f2b233; } .tag-dot-1 { background:#e56aa8; }
.tag-dot-2 { background:#4caf6d; } .tag-dot-3 { background:#8f6ce0; }
.tag-dot-4 { background:#2fb4c4; } .tag-dot-5 { background:#ee7b54; }
.tag-dot-6 { background:#5d82b8; } .tag-dot-7 { background:#9aa0a8; }
html.dark .tag-dot-0 { background:#d9a13b; } html.dark .tag-dot-1 { background:#d15f9e; }
html.dark .tag-dot-2 { background:#3f9d63; } html.dark .tag-dot-3 { background:#7d5fd4; }
html.dark .tag-dot-4 { background:#2aa3b3; } html.dark .tag-dot-5 { background:#d96a47; }
html.dark .tag-dot-6 { background:#4d74ad; } html.dark .tag-dot-7 { background:#70757f; }
/* Stage-tag palette — a different 8-colour set from entity tags so the two
   never read as the same class of label. Applied after the entity palette so
   the overrides win (same specificity, later order). */
.t-tag.tag-0 { background:var(--hg-danger-bright); border-color:var(--hg-danger); color:#2a0503; }
.t-tag.tag-1 { background:#26a69a; border-color:#1e8f84; color:#04201d; }
.t-tag.tag-2 { background:#8d6e63; border-color:#74584e; color:#1d0f0b; }
.t-tag.tag-3 { background:#42a5f5; border-color:#3387cc; color:#041c33; }
.t-tag.tag-4 { background:#ec407a; border-color:#c72f63; color:#2d0413; }
.t-tag.tag-5 { background:#7cb342; border-color:#64982f; color:#152205; }
.t-tag.tag-6 { background:#ffb300; border-color:#d99a00; color:#2a1f02; }
.t-tag.tag-7 { background:#5c6bc0; border-color:#48529f; color:#0b0f26; }
html.dark .t-tag.tag-0 { background:#d63b2e; border-color:#a92d23; color:#1a0301; }
html.dark .t-tag.tag-1 { background:#1f8f85; border-color:#177269; color:#03120f; }
html.dark .t-tag.tag-2 { background:#7a5f56; border-color:#60483f; color:#140b08; }
html.dark .t-tag.tag-3 { background:#3790dd; border-color:#2b71ad; color:#030f1d; }
html.dark .t-tag.tag-4 { background:#d63870; border-color:#ab2b58; color:#1d020d; }
html.dark .t-tag.tag-5 { background:#6da63a; border-color:#55832c; color:#0e1703; }
html.dark .t-tag.tag-6 { background:#e0a400; border-color:#b38200; color:#201801; }
html.dark .t-tag.tag-7 { background:#4f5eb0; border-color:#3d4a8c; color:#080c1e; }
.st-dot-0 { background:var(--hg-danger-bright); } .st-dot-1 { background:#26a69a; }
.st-dot-2 { background:#8d6e63; } .st-dot-3 { background:#42a5f5; }
.st-dot-4 { background:#ec407a; } .st-dot-5 { background:#7cb342; }
.st-dot-6 { background:#ffb300; } .st-dot-7 { background:#5c6bc0; }
html.dark .st-dot-0 { background:#d63b2e; } html.dark .st-dot-1 { background:#1f8f85; }
html.dark .st-dot-2 { background:#7a5f56; } html.dark .st-dot-3 { background:#3790dd; }
html.dark .st-dot-4 { background:#d63870; } html.dark .st-dot-5 { background:#6da63a; }
html.dark .st-dot-6 { background:#e0a400; } html.dark .st-dot-7 { background:#4f5eb0; }

html.dark .hg-tag-toggle::before { color: #55565c; }
html.dark .hg-tag-toggle.on::before { color: var(--hg-text-bright); }
html.dark .hg-tag-row .hg-tag-ren { color: var(--hg-text-muted); }
html.dark .hg-tag-row .hg-tag-ren:hover { color: #5a9fd8; }
html.dark .hg-tag-row .hg-tag-del { color: var(--hg-text-muted); }
html.dark .hg-tag-row .hg-tag-del:hover { color: #e84545; }
html.dark .hg-tag-addrow { border-top-color: var(--hg-border-chrome); }
html.dark .hg-tag-cliprow { border-top-color: var(--hg-border-chrome); }
html.dark .hg-tag-cliprow .hg-tag-copy, html.dark .hg-tag-cliprow .hg-tag-paste {
  background: var(--hg-surface-raised); border-color: var(--hg-border-control); color: #8a8b90;
}
html.dark .hg-tag-cliprow .hg-tag-copy:hover, html.dark .hg-tag-cliprow .hg-tag-paste:hover {
  border-color: var(--hg-border-hover); background: var(--hg-surface-raised);
}
html.dark .hg-tag-cliprow .hg-tag-paste.un { color: #55565c; }
html.dark .hg-menu-presets .hg-preset-del:hover { color: var(--st-reopen-ink); }
html.dark .hg-menu-presets .hg-preset-newopt {
  border-top-color: var(--hg-border-control); color: #6f7076;
}
html.dark .hg-menu-presets .hg-preset-newopt:hover { color: var(--hg-text-bright); }

/* ===== date picker (hgDate) =====
   Matches the hgSelect popover language: monochromatic, hairline, flat.
   The trigger is a button (`.hg-date`) showing the ISO date or a placeholder;
   the popover is a small calendar grid anchored below it. */
.hg-date {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  display: inline-flex; align-items: center; gap: 6px;
  background-color: transparent; background-image: none;
  border: 1px solid var(--hg-border-control); border-radius: 4px;
  padding: 3px 8px; font: inherit; font-size: var(--hg-type-11h);
  color: var(--hg-text-ink); cursor: pointer; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.hg-date:not(.un) { font-weight: 500; }
.hg-date:hover { border-color: var(--hg-border-focus); }
.hg-date:focus-visible { outline: none; border-color: var(--hg-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--hg-accent) 20%, transparent); }
.hg-date.un { color: var(--hg-text-muted); font-weight: 400; }
/* in table rows / tight cells */
.cs-lic-row .hg-date, .it-edit.hg-date, .cs-win-cell .hg-date, .fp-ms-date.hg-date {
  font-size: var(--hg-type-11); padding: 2px 6px;
}

.hg-cal {
  position: fixed; z-index: 210; width: 202px;
  background: var(--hg-surface-tabs); border: 1px solid #dcdcdc; border-radius: 4px;
  box-shadow: var(--hg-shadow-menu); padding: 6px;
  user-select: none; overflow: hidden;
}
.hg-cal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 4px; margin-bottom: 4px;
}
.hg-cal-title {
  font: 600 11.5px "Inter", sans-serif; color: var(--hg-text-ink); text-align: center; flex: 1;
}
.hg-cal-nav {
  width: 22px; height: 20px; flex-shrink: 0;
  border: 1px solid var(--hg-border-control); border-radius: 3px;
  background: var(--hg-surface-tabs); color: var(--hg-text-ink); font: 500 13px/1 "Inter", sans-serif;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.hg-cal-nav:hover { background: #f0f0f0; border-color: var(--hg-border-focus); }
.hg-cal-dow {
  display: grid; grid-template-columns: repeat(7, 1fr);
  margin-bottom: 2px;
}
.hg-cal-dow span {
  font: 500 9px "Inter", sans-serif; color: var(--hg-text-muted); text-align: center;
  text-transform: uppercase; letter-spacing: .02em; padding: 2px 0;
}
.hg-cal-row { display: grid; grid-template-columns: repeat(7, 1fr); }
.hg-cal-d {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; height: 22px; border: 0; border-radius: 3px;
  background: transparent; color: var(--hg-text-ink);
  font: 500 10.5px/1 "Inter", sans-serif; cursor: pointer; padding: 0;
}
.hg-cal-d:hover { background: #eef0f2; }
.hg-cal-d.today { box-shadow: inset 0 0 0 1px var(--hg-border-focus); }
.hg-cal-d.sel { background: var(--hg-accent); color: var(--hg-text-on-accent); }
.hg-cal-d.sel:hover { background: var(--hg-accent); }
.hg-cal-clear {
  display: block; width: 100%; margin-top: 6px; padding: 4px 0;
  border: 1px solid var(--hg-border-control); border-radius: 3px;
  background: var(--hg-surface-tabs); color: var(--hg-text-secondary); font: 500 11px "Inter", sans-serif;
  cursor: pointer; text-align: center;
}
.hg-cal-clear:hover { background: #f0f0f0; border-color: var(--hg-border-focus); color: var(--hg-text-ink); }
html.dark .hg-date {
  border-color: var(--hg-border-control); color: var(--hg-text-bright);
}
html.dark .hg-date:not(.un) { color: var(--hg-text-bright); }
html.dark .hg-date:hover { border-color: #6f7076; }
html.dark .hg-date:focus-visible { border-color: #8fa9c4; box-shadow: 0 0 0 2px #8fa9c433; }
html.dark .hg-date.un { color: var(--hg-text-muted); }
html.dark .hg-cal {
  background: var(--hg-surface-tabs); border-color: var(--hg-border-control); box-shadow: var(--hg-shadow-menu);
}
html.dark .hg-cal-title { color: #c2c3c8; }
html.dark .hg-cal-nav { border-color: var(--hg-border-control); color: #c2c3c8; background: var(--hg-surface-tabs); }
html.dark .hg-cal-nav:hover { background: #26272b; border-color: #6f7076; }
html.dark .hg-cal-dow span { color: var(--hg-text-muted); }
html.dark .hg-cal-d { color: #c2c3c8; }
html.dark .hg-cal-d:hover { background: #26272b; }
html.dark .hg-cal-clear { border-color: var(--hg-border-control); background: var(--hg-surface-tabs); color: var(--hg-border-focus); }
html.dark .hg-cal-clear:hover { background: #26272b; border-color: #6f7076; color: var(--hg-text-bright); }
html.dark .hg-cal-d.today { box-shadow: inset 0 0 0 1px #6f7076; }
html.dark .hg-cal-d.sel { background: #e4e4e7; color: var(--hg-text-ink); }
html.dark .hg-cal-d.sel:hover { background: #e4e4e7; }

/* ── T1 database rollback modal ─────────────────────────────────── */
.rst-warn {
  background: #fdecea; border: 1px solid #e6b0aa; color: #8c2f23;
  border-radius: 6px; padding: 10px 12px; font-size: var(--hg-type-base); line-height: 1.5;
  margin-bottom: 12px;
}
.rst-list {
  max-height: 240px; overflow-y: auto; border: 1px solid var(--hg-border-control);
  border-radius: 6px; margin-bottom: 12px;
}
.rst-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  font-size: var(--hg-type-base); cursor: pointer; border-bottom: 1px solid #f0f0f0;
}
.rst-row:last-child { border-bottom: 0; }
.rst-row:hover { background: #f7f7f9; }
.rst-age { font-weight: 600; min-width: 110px; }
.rst-when { color: var(--hg-text-label); font-variant-numeric: tabular-nums; }
.rst-empty { padding: 14px; font-size: var(--hg-type-base); color: var(--hg-text-label); text-align: center; }
.rst-auth { display: flex; gap: 10px; align-items: center; }
.rst-auth input {
  font-size: var(--hg-type-18); letter-spacing: 6px; text-align: center; width: 130px;
  padding: 6px 8px; border: 1px solid #d5d5da; border-radius: 4px;
  font-family: var(--hg-font-mono);
}
.rst-err { color: var(--hg-danger); font-size: var(--hg-type-base); min-height: 16px; margin-top: 8px; }
html.dark .rst-warn { background: #3a2320; border-color: #7d4238; color: #f0b4ab; }
html.dark .rst-list { border-color: #34363f; }
html.dark .rst-row { border-bottom-color: #2b2d35; }
html.dark .rst-row:hover { background: var(--hg-surface-hover); }
html.dark .rst-auth input { background: #17181d; color: #e2e3e7; border-color: #3a3d47; }

/* ── Danger zone (project settings footer) ──────────────────────── */
/* Separated from the Save/Duplicate row on purpose: rolling the database back
   is not an edit, it discards other people's work. It should never sit next to
   an everyday button. */
.danger-zone {
  margin-top: 14px; padding-top: 12px; border-top: 1px dashed #e0b4ae;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.dz-lab {
  font-size: var(--hg-type-10); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--hg-danger-ink);
}
.dz-btn {
  background: var(--hg-surface-input); color: var(--hg-danger-ink); border: 1px solid #e0b4ae;
  border-radius: 4px; padding: 5px 10px; font-size: var(--hg-type-base); cursor: pointer;
}
/* ===== 14. UNIFIED FORM PRIMITIVES (text inputs + checkboxes) =====
   One look for every text/numeric field and every native checkbox.
   Text fields use the flat hairline treatment; checkboxes mirror the
   hgSelectMulti menu tick (11px box, SVG tick, same light/dark palette).
   Inline-editable table cells stay transparent via .tbl-inp (transparent
   border until hover/focus), but share the same focus + dark colours. */
.hg-inp, .tbl-inp {
  -webkit-appearance: none; appearance: none;
  border: none; border-bottom: 1px solid var(--hg-border-control); border-radius: 0;
  background-color: transparent; background-image: none;
  padding: 3px 2px; font: inherit; font-size: var(--hg-type-11h);
  color: var(--hg-input-ink); outline: none;
}
.hg-inp[type="number"] { -moz-appearance: textfield; }
.hg-inp::-webkit-outer-spin-button, .hg-inp::-webkit-inner-spin-button,
.tbl-inp::-webkit-outer-spin-button, .tbl-inp::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.tbl-inp { border-bottom-color: transparent; width: 100%; box-sizing: border-box; font-size: var(--hg-type-base); }
.tbl-inp:hover { border-bottom-color: var(--hg-border-control); }
.hg-inp:focus { border-bottom-color: var(--hg-accent); }
.tbl-inp:focus { border-bottom-color: var(--hg-accent); }
.hg-inp::placeholder, .tbl-inp::placeholder, input::placeholder, textarea::placeholder { color: var(--hg-text-muted); opacity: 1; }
.hg-inp:disabled, .tbl-inp:disabled { opacity: .5; cursor: default; }
html.dark .hg-inp, html.dark .tbl-inp { border-bottom-color: var(--hg-border-control); color: var(--hg-input-ink); }
html.dark .tbl-inp { border-bottom-color: transparent; }
html.dark .tbl-inp:hover { border-bottom-color: var(--hg-border-control); }
html.dark .hg-inp:focus { border-bottom-color: var(--hg-border-focus); }
html.dark .tbl-inp:focus { border-bottom-color: var(--hg-border-focus); }
html.dark input::placeholder, html.dark textarea::placeholder { color: var(--hg-text-muted); opacity: 1; }

/* native checkbox restyle — mirrors .hg-menu-multi .hg-menu-item[.checked]::before */
input[type="checkbox"] {
  -webkit-appearance: none; appearance: none;
  width: 12px; height: 12px; flex-shrink: 0; margin: 0; padding: 0;
  border: 1px solid var(--hg-border-menu-chk); border-radius: 3px; background-color: var(--hg-surface-input);
  cursor: pointer; position: relative; vertical-align: -1px;
}
input[type="checkbox"]:hover { border-color: var(--hg-border-focus); }
input[type="checkbox"]:checked {
  background-color: var(--hg-accent); border-color: var(--hg-accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='7' viewBox='0 0 9 7'%3E%3Cpath d='M1 3.5l2.5 2.5L8 1' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 9px 7px;
}
input[type="checkbox"]:focus-visible { outline: 1px solid var(--hg-accent); outline-offset: 1px; }
input[type="checkbox"]:disabled { opacity: .45; cursor: default; }
html.dark input[type="checkbox"] { border-color: var(--hg-border-hover); background-color: var(--hg-surface-raised); }
html.dark input[type="checkbox"]:hover { border-color: var(--hg-text-muted); }
html.dark input[type="checkbox"]:checked {
  background-color: var(--hg-accent); border-color: var(--hg-accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='7' viewBox='0 0 9 7'%3E%3Cpath d='M1 3.5l2.5 2.5L8 1' fill='none' stroke='%23515255' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 9px 7px;
}
html.dark input[type="checkbox"]:focus-visible { outline-color: var(--hg-border-focus); }

/* boxed finance fields get the dark treatment via .hg-ctl's token vocabulary */
.a-name-input::placeholder { color: var(--hg-text-muted); }

.dz-btn:hover { background: #fdecea; border-color: var(--hg-danger); }
.dz-note { font-size: var(--hg-type-11); color: var(--hg-text-label); flex: 1 1 100%; }
html.dark .danger-zone { border-top-color: #6b3b34; }
html.dark .dz-btn { background: #1f2026; color: #e8736a; border-color: #6b3b34; }

/* ===== BOOK OVERVIEW TAB (v-ov) =====
   Realized-money dashboard. Shares the Accounting/Cashflow vocabulary;
   new surfaces only restate box shape. */

.ov-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 10px var(--hg-tracker-side-padding) 24px;
  box-sizing: border-box;
}

/* ── summary cards ── */
.ov-cards { display: flex; flex-wrap: wrap; gap: 12px; margin: 4px 0 12px; }
.ov-card {
  flex: 1 1 170px; min-width: 150px; max-width: 240px; padding: 10px 14px;
  border: 1px solid var(--hg-border-row); border-radius: 6px;
  background: var(--hg-frost-bg);
  backdrop-filter: blur(var(--hg-frost-blur-soft));
  -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
}
.ov-card-title {
  font-size: var(--hg-type-10); text-transform: uppercase; letter-spacing: .07em;
  color: var(--hg-text-dim); margin-bottom: 4px;
}
.ov-card-value { font-size: var(--hg-type-medium); font-weight: 700; font-variant-numeric: tabular-nums; }
.ov-card-neg .ov-card-value { color: var(--hg-danger); }

/* ── record health ── */
.ov-health { margin: 0 0 14px; }
.ov-health-ok {
  font-size: var(--hg-type-11); color: var(--hg-text-muted);
  padding: 4px 0;
}
.ov-health-toggle {
  font-size: var(--hg-type-11); color: var(--hg-warn-ink, #8a6d1a);
  background: none; border: none; padding: 4px 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.ov-issue-list {
  margin: 4px 0 0; padding: 6px 10px; border: 1px solid var(--hg-border-row);
  border-radius: 4px; background: var(--hg-frost-bg);
  backdrop-filter: blur(var(--hg-frost-blur-soft));
  -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
}
.ov-issue { font-size: var(--hg-type-11); color: var(--hg-text-muted); padding: 2px 0; }

/* ── unreconciled spend worklist (Expenses tab) ──
   The wrap is NOT an inset box: side geometry is owned entirely by the
   nested .exp-scroll (same padding + both-edges gutter as the register's
   scroll root directly above), so table edges and scrollbar track line up
   with the register instead of doubling the inset. */
.exp-unrec-wrap { margin: 14px 0 0; }
.exp-unrec-title { font-size: var(--hg-type-11); font-weight: 600; color: var(--hg-warn-ink, #8a6d1a); padding: 0 calc(var(--hg-tracker-side-padding) + 10px) 6px; text-align: center; }
.exp-unrec-wrap .exp-scroll { max-height: 260px; }

/* ── unreconciled spend panel ── */
.ov-unrec {
  border: 1px solid var(--hg-border-row); border-radius: 6px;
  background: var(--hg-frost-bg); padding: 8px 12px 10px;
  margin: 0 0 14px;
  backdrop-filter: blur(var(--hg-frost-blur-soft));
  -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
}
.ov-unrec-count {
  font-size: var(--hg-type-11); font-weight: 600; color: var(--hg-warn-ink, #8a6d1a);
  padding: 2px 0 4px;
}
html.dark .ov-unrec { border-color: var(--hg-border-chrome); }

/* ── breakdown sections ── */
.ov-sections { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 14px; }

/* ── cashflow forecast strip (beneath the realized record) ── */
.ov-forecast-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  justify-content: center;
  margin: 22px 0 10px; padding: 8px 16px 6px;
}
.ov-forecast-title { font-size: var(--hg-type-base); font-weight: 600; color: var(--hg-text-secondary); }
.ov-forecast-sub { font-size: var(--hg-type-11); color: var(--hg-text-dim); }
.ov-forecast-head .acct-cf-spacer { flex: 0 0 22px; }
/* the forecast table scrolls within the strip; never bleed past the right margin */
.ov-scroll .cf-forecast-scroll { margin-top: 0; flex: 1 1 auto; min-height: 0; overflow: auto; box-sizing: border-box; }
.ov-section {
  border: 1px solid var(--hg-border-row); border-radius: 6px;
  background: var(--hg-frost-bg); padding: 8px 12px 10px;
  backdrop-filter: blur(var(--hg-frost-blur-soft));
  -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  min-width: 0;
}
.ov-section-title {
  font-size: var(--hg-type-10); font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: var(--hg-text-dim); padding: 2px 0 6px;
}
.ov-table { width: 100%; border-collapse: collapse; }
.ov-table td { padding: 3px 6px; font-size: var(--hg-type-base); }
.ov-row-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40%; }
.ov-row-bar { width: 45%; }
.ov-bar { height: 6px; border-radius: 3px; background: var(--hg-border-row); overflow: hidden; }
.ov-bar-fill { height: 100%; border-radius: 3px; background: var(--hg-accent, var(--hg-text-dim)); }
.ov-row-val { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ov-empty { font-size: var(--hg-type-11); color: var(--hg-text-muted); padding: 4px 0; }
.ov-total-row td {
  border-top: 1px solid var(--hg-border-row); font-weight: 600; padding-top: 5px;
}

/* dock-style plot panels (js/cashflow-forecast-plot.js, js/overview-history-plot.js)
   Same anatomy as the gantt cashflow dock: title bar with meta, framed plot
   band with a baseline, label strip inside. Tokens flip in dark mode. */
.ov-plot-panel {
  border: 1px solid var(--hg-border-row); border-radius: 6px;
  background: var(--hg-frost-bg);
  backdrop-filter: blur(var(--hg-frost-blur-soft));
  -webkit-backdrop-filter: blur(var(--hg-frost-blur-soft));
  overflow: hidden; box-sizing: border-box; min-width: 0;
}
.ov-plot-titlebar {
  display: flex; align-items: baseline; gap: 10px;
  padding: 6px 12px 5px; box-sizing: border-box;
  background: var(--hg-frost-head);
  border-bottom: 1px solid var(--hg-border-row);
}
.ov-plot-title { font-size: var(--hg-type-11); font-weight: 700; color: var(--hg-text-secondary); }
.ov-plot-sub { font-size: var(--hg-type-10); color: var(--hg-text-dim); }
.ov-plot-meta {
  margin-left: auto; font-size: var(--hg-type-10); font-weight: 600;
  color: var(--hg-info); font-variant-numeric: tabular-nums;
}
.ov-plot-band {
  position: relative; box-sizing: border-box;
  border-bottom: 1px solid var(--hg-border-row);  /* the baseline bars sit on */
  background:
    linear-gradient(to right, var(--hg-border-row) 0, var(--hg-border-row) 1px, transparent 1px) 0 0 / max(1px, var(--hg-plot-grid, 56px)) 100%,
    transparent;
}
.ov-plot-strip { position: relative; box-sizing: border-box; }
/* ── forecast plot: the gantt cashflow dock, ported 1:1 (js/cashflow-forecast-plot.js)
   Geometry matches the dock: titlebar 28 + band 92 + 4×24 label rows = 216. */
.cfp-titlebar {
  flex-shrink: 0; height: 28px; box-sizing: border-box;
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px;
  background: var(--hg-frost-head);
  border-bottom: 1px solid var(--hg-border-na);
  color: #26415e; font-size: var(--hg-type-11); font-weight: 600;
  letter-spacing: .03em;
}
.cfp-caret { display: inline-block; width: 12px; text-align: center; font-size: var(--hg-type-10); color: #5a6578; }
.cfp-titlebar-label { font-weight: 700; }
.cfp-titlebar-sub { font-weight: 500; color: var(--hg-text-secondary); letter-spacing: 0; }
.cfp-titlebar-meta {
  margin-left: auto; font-weight: 600; color: var(--hg-info);
  font-variant-numeric: tabular-nums; letter-spacing: 0;
  font-size: var(--hg-type-11); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: min(62vw, 720px);
}
.cfp-titlebar-meta .cfp-meta-sep { font-weight: 500; color: inherit; opacity: .7; }
.cfp-titlebar-meta .cfp-meta-bit.is-warn {
  color: var(--cf-deficit-t, var(--hg-danger));
  font-weight: 700;
}
.cfp-body {
  display: flex; min-height: 0; height: 188px; box-sizing: border-box; overflow: hidden;
}
.cfp-label {
  width: 150px; flex-shrink: 0; box-sizing: border-box;
  border-right: 1px solid var(--hg-border-na); background: transparent;
  font-size: var(--hg-type-base); color: var(--hg-text-label);
  display: flex; align-items: stretch;
}
.cfp-label-inner {
  flex: 1; display: flex; flex-direction: column;
  height: 100%; min-height: 0; padding: 0 12px; box-sizing: border-box;
}
.cfp-label-top {
  flex-shrink: 0; box-sizing: border-box;
  display: flex; flex-direction: column; justify-content: center; gap: 6px;
}
.cfp-label-leg { font-size: var(--hg-type-11); color: var(--cf-label); }
.cfp-dot.income { color: var(--cf-income); }
.cfp-dot.deficit { color: var(--cf-deficit-t); }
.cfp-label-strip {
  flex-shrink: 0; box-sizing: border-box;
  display: flex; flex-direction: column; justify-content: flex-start;
}
.cfp-strip-leg {
  height: 24px; line-height: 24px; box-sizing: border-box;
  font-size: var(--hg-type-11); color: var(--cf-label);
}
.cfp-scroll {
  flex: 1; min-width: 0; overflow-x: auto; overflow-y: hidden;
  position: relative; scrollbar-width: none;
}
.cfp-scroll::-webkit-scrollbar { display: none; height: 0; }
.cfp-panel { position: relative; box-sizing: border-box; background: transparent; min-width: 100%; }
html.dark .cfp-titlebar {
  background: var(--hg-frost-head);
  border-bottom-color: var(--hg-border-chrome); color: var(--hg-text-secondary);
}
html.dark .cfp-titlebar-sub { color: var(--hg-text-dim); }
html.dark .cfp-titlebar-meta .cfp-meta-bit.is-warn { color: var(--cf-deficit-t, #c08a8a); }
html.dark .cfp-label { border-right-color: var(--hg-border-chrome); color: var(--hg-text-secondary); }
/* plotline strokes (balance paths share the dock's .cf-bal-path vocabulary —
   those rules are scoped to #cfTrack, so this panel restates the strokes) */
.cf-zero-axis {
  position: absolute; left: 0; width: 100%; height: 1px;
  background: var(--cf-label); opacity: .35; z-index: 2; pointer-events: none;
}
.cf-fp-svg { position: absolute; overflow: visible; z-index: 3; pointer-events: none; display: block; }
.cf-fp-svg .cf-spent-path {
  fill: none; stroke: #9aa4b8; stroke-width: 1.5; stroke-dasharray: 4 3;
  stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
html.dark .cf-fp-svg .cf-spent-path { stroke: #6f7888; }
.cf-fp-svg .cf-bal-path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.cf-fp-svg .cf-bal-path.cf-bal-surplus {
  stroke: var(--cf-income); stroke-width: 2.5;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--cf-income) 70%, transparent));
}
.cf-fp-svg .cf-bal-path.cf-bal-deficit {
  stroke: var(--cf-deficit-t); stroke-width: 2.5;
  animation: cf-deficit-pulse 1.6s ease-in-out infinite;
  will-change: filter;
}
@media (prefers-reduced-motion: reduce) {
  .cf-fp-svg .cf-bal-path.cf-bal-deficit {
    animation: none;
    filter: drop-shadow(0 0 4px var(--cf-deficit-glow));
  }
}
/* weekly cost bars under the forecast table — X-measured from the table */
.cf-forecast-plot { margin: 14px 0 12px; border-left: 0; border-right: 0; }
/* The dock panel is a continuation of the table surface: its BODY aligns
   with the table's scrollable content (LINE ITEM gutter + month columns),
   so the plot band spans exactly the table's first-to-last column edges
   and pans in lockstep. Titlebar stays viewport-fixed. */
.cf-forecast-plot .cfp-body { display: flex; align-items: stretch; }
.cf-forecast-plot .cfp-scroll { flex: 1 1 auto; min-width: 0; overflow: visible; }
/* the band width is set in JS (union of month columns); the dock's
   min-width:100% would stretch it past the last month column */
.cf-forecast-plot .cfp-panel { min-width: 0; }
/* weekly realized-cost bars over the selected overview period */
.ov-history-plot { margin: 14px 0 12px; }
html.dark .ov-plot-panel { border-color: var(--hg-border-chrome); }
html.dark .ov-plot-titlebar { border-bottom-color: var(--hg-border-chrome); }
html.dark .ov-plot-band { border-bottom-color: var(--hg-border-chrome); }

/* dark mode */
.ov-card-unrec .ov-card-value { color: var(--hg-warn-ink, #8a6d1a); }
html.dark .ov-card { border-color: var(--hg-border-chrome); }
html.dark .ov-card-neg .ov-card-value { color: var(--hg-danger-bright); }
html.dark .ov-issue-list { border-color: var(--hg-border-chrome); }
html.dark .ov-section { border-color: var(--hg-border-chrome); }
html.dark .ov-bar { background: var(--hg-border-chrome); }
html.dark .dz-btn:hover { background: #3a2320; }
