/*
 * ═══════════════════════════════════════════════════════════
 * DW DESIGN SYSTEM — dw-design.css v2.25.1
 * Dillon's Welding Hub-and-Spoke Platform
 * Shared CSS for all spoke applications
 *
 * v2.25.1 (2026-10-22, Dillon's dead-code marks): about 120 class names (with modifiers) that no page or script used
 *   are deleted (221 lines):
 *   Stat card v2 and its icon colors, the Data card, Crew use, the Schedule strip, the old Cmd+K palette, the
 *   Pipeline bar, .aging-bars, the Attention items and Activity feed (only the retired Production dashboard used
 *   them), the sidebar search and user footer, .btn-secondary/-accent/-destructive, .toast-v2 parts, 3 spinner
 *   sizes, .g6, .bt-p-light, .table-empty, .row-action-btn, .mini-bar, .job-num, .rel-time, .page-subtitle,
 *   .theme-toggle-label, .theme-icons, .three-col, .attention-list, .stats-grid, and their motion rules. Kept:
 *   .pf, .right-now, .toast-wrap and toastIn (still used). Every class was searched in every repo first.
 * v2.25.0 (2026-10-21): "WHAT IS IT?" in the note form (theme-warm only; dw-tabs.js 0.7.0; Dillon's 36x86 report
 *   6a0aed2d). .dwh-lbl (the row's heading, as the form's labels) and .dwh-kinds / .dwh-kind (1 row of 3 equal buttons,
 *   44px tall, the picked one .on in the main blue). ADDITIVE: every rule names .theme-warm and a .dwh class.
 * v2.24.0 (2026-10-21): THE SIDE LIST (theme-warm only; dw-side.js 0.1.0; Dillon's marks of 10-21, hub
 *   Mockups/index-hq-side-list-2026-10-20.html). The list look (.dws, .dws-h headings, .dws-i items with a small second
 *   line, numbered items, the lit item, a right-hand note, a warning) and the page layout: a .dw-sheet whose side host
 *   (.dws-host, where the chip row was) holds a list turns into 2 columns, the list left of the page, inside the 1600px
 *   frame. CSS :has, so a page that empties the host gets 1 column back. Under 861px: 1 column again, and the list folds
 *   into 1 picker button on top. ADDITIVE: every rule names .theme-warm and a .dws class.
 *
 * v2.23.0 (2026-10-05): THE TABS COME FIRST (theme-warm only; dw-tabs.js 0.5.0). Found at a 1284px frame on staging:
 *   HQ's Setup tab sat under "Connected / Rev" and could not be seen or clicked. The tab strip is the only part of the
 *   tab row that can shrink, so a short row hid tabs. dw-tabs.js now measures the row and sets up to 3 classes on it
 *   until every tab shows: .dwt-norev hides the version, .dwt-nometa the sync text and the version, .dwt-icon the
 *   helper's words (its icon stays, as on a phone). No class = the full row. ADDITIVE: 3 rules, each names .theme-warm.
 *
 * v2.22.0 (2026-09-29): "NEED A HAND?" for every app on the one look's tab row (theme-warm only; dw-tabs.js 0.3.0;
 *   Dillon: "make sure the need a hand behavior is the same everywhere (i like that over the flag)"). Office's helper
 *   button (.dwt-help, at the right end of the row where the report flag was), its menu (.dwh-menu), the "Send a note to
 *   Dillon" form (.dwh-scrim, .dwh-sheet) and the "Show me how" pulse (.dwh-spot), on the theme's tokens. Phones: the
 *   icon only. ADDITIVE: every rule names .theme-warm.
 *
 * v2.21.0 (2026-09-29): the one look's FRAME, TWO-LINE TABS and LOGO (theme-warm only; Dillon at 2560px: "the navbar
 *   and the actual content being out of line looks weird", "what happened to the descriptors", "the logo needs to make
 *   a comeback"). --dw-frame (1600px) + --dw-gutter: on screens wider than 1648px the tab row, chips, .ct, .stats-bar,
 *   .filter-bar and the .mn toolbar share one centered frame; narrower screens keep the 24px gutter they had. Tabs show a
 *   second line (.dwt-d); the Dillon's Welding logo (.dwt-logo, dw-tabs.js 0.2.0) opens the tab row. Phones: unchanged
 *   gutters, no second line, no logo. ADDITIVE: every rule names .theme-warm.
 *
 * v2.20.0 (2026-09-28): THE ONE LOOK, body.theme-warm ("Warm and quiet", Dillon's pick; spec MC-DESIGN-LANGUAGE.md
 *   section 9, plan ONE-LOOK-PLAN.md). Office's paper and ink in a flat structure: no side stripes, shadows, grain or
 *   blueprint grid; blue #3F6DB5 for the main button; slate for status "info"; sentence-case labels; 8px / 6px corners;
 *   a warm dark set. Replaces the drafting deck on a page that opts in (the page drops "theme-drafting dw-deck", takes
 *   "theme-warm" and mounts dw-tabs.js). Styles the dw-tabs.js tab row (.dw-tabbar / .dwt-*), the chip row
 *   (.dwt-chips and a page's .dw-substrip) and the dashboard primitives (.pvitals, .mc-three, .mc-na, .mc-feed).
 *   ADDITIVE ONLY: every new rule names .theme-warm; no existing rule changed, so no page moves until it opts in.
 *
 * v2.19.1 (2026-09-23): phone deck tabs (ticket 0e401818) — at ≤480px the deck header clipped
 *   its last tab (Analytics "Histori…" at 443px, hidden at 375px). One mobile-only media rule
 *   after the ≤900px deck block: brand padding 6px 8px 6px 0, logo 20px tall, tab padding 0 8px
 *   + gap 5px + --fs-md, report-flag margin 0 0 0 6px, tab row scrollbar hidden (still swipes
 *   sideways when a spoke has more tabs than fit, e.g. Spark's 7). Nothing changes above 480px.
 *
 * v2.19.0 (2026-07-19): COMFORT MODE (design-critique F1, ticket 54b06237) — body.comfort,
 *   the per-user display preference succeeding the v2.9.0-deleted simple-view WITHOUT its
 *   .power-user hiding or lockout semantics. Token remap (--fs-base 14→16 et al.), 48px
 *   touch floor on .bt/.btn/.fi/.fs/.nb/.bn-btn, wider td/th row padding. Stamped at boot
 *   by the consuming spoke from settings.display_prefs (fail-open). Pilot: Office (Diana,
 *   default ON). Zero effect without the class.
 *
 * v2.18.0 (2026-07-19): .mo-xl opt-in extra-wide modal variant (design-critique F6b, ticket
 *   e26330a2) — `.mo-c.mo-xl{width:1280px;max-width:96vw}`, everything else (max-height,
 *   overflow, radius, padding, mobile full-bleed override) inherited from .mo-c. The 880px
 *   .mo-c default is unchanged (F6 resolved no-change); spokes add the class only on
 *   data-dense modals that need the room. First consumer: Production job-detail + import
 *   review modals.
 *
 * v2.17.0 (2026-07-19): SELF-HOSTED FONTS (design-critique F4, ticket b3d1f8da) — the render-
 *   blocking Google Fonts @import is replaced by six @font-face rules over variable woff2 files
 *   in /fonts/ on this Pages project (DM Sans wght 300-800 + italic 400, JetBrains Mono wght
 *   400-700; latin + latin-ext — Spanish covered for Shop). Relative url() resolves against the
 *   CSS origin so all spokes inherit with zero edits. font-display:swap. _headers added:
 *   /fonts/* immutable 1yr (filenames are stable; a font upgrade = new filenames). Zero
 *   requests to fonts.googleapis.com / fonts.gstatic.com fleet-wide once deployed.
 *
 * v2.16.0 (2026-07-19): design-critique batch (tickets: design-critique-2026-07-19) —
 *   - WCAG AA: light-mode --t3 #999→#767676 (2.7:1→4.5:1 on #f8f7f5) + drafting-light
 *     --t3 #647488→#5d6c80. Meta/timestamp text now passes at 11-12px.
 *   - Touch: @media (hover:none) shows .row-actions at .85 opacity (Shop iPad).
 *   - Tokens: --ls-label/--ls-wide/--ls-brand/--ls-sec; 7 uppercase-label rules
 *     swapped off literal px. Zero visual change.
 *   - FROZEN-LEGACY comment markers on .bt/.bd/legacy .toast/.sh (canonical:
 *     .btn/.badge/.toast-v2/.section-header). Comments only.
 *   - Scrollbars 6px→10px (low-vision visibility).
 *
 * v2.15.0 (2026-07-10): two fixes from the audit-harvest queue —
 *   - .fi/.fs focus ring: rgba(var(--focus),.15) was invalid CSS (--focus holds a hex,
 *     not channel triplets) so the declaration was silently dropped and inputs never
 *     showed a focus ring. Now color-mix(in srgb, var(--focus) 15%, transparent).
 *   - .report-submit ink: hardcoded #000 → var(--acc-ink,#000) so dark accents
 *     (e.g. Sales purple) can opt into readable button text; identical by default.
 *
 * v2.14.0: DARK MODE for the drafting deck — a body.theme-drafting:not(.light) block remaps the
 *   palette to soft dark slate (off-white ink, quiet blueprint grid, gently brightened semantics) plus
 *   two chrome overrides (.dw-sheet + .deck-tb hardcoded light hexes that tokens do not reach). Every
 *   deck spoke already has a Dark Mode toggle that flips body.light, so this ships dark mode platform-
 *   wide at once with zero per-spoke edits; --acc is per-spoke and falls back to the brighter :root
 *   value when .light drops. Additive + scoped to :not(.light) => zero light-mode impact. Tuned gentle
 *   for eye comfort (lifted off pure-black; off-white, not pure-white). Portal .dw-vellum home is NOT
 *   covered (it is .dw-vellum on a div, not body.theme-drafting) — out of scope for now.
 *
 * v2.13.2: Added .dw-vellum — a scopable opt-in for the drafting palette tokens, so a NON-deck
 *   surface (Portal Mission Control home) can derive from the master vellum palette without the
 *   deck chrome/layout. Additive (the token block selector gains `, .dw-vellum`); deck spokes on
 *   body.theme-drafting are untouched. Backlog #4 (Portal reconcile).
 *
 * v2.13.1: Extracted Money's card-header action link to shared (.mc-three .cd h3 .lnk) —
 *   the "A/R ->" / "Invoice ->" / "Pay ->" links. Now any deck spoke with a header action
 *   inherits it (accent-relative via var(--acc)). Convergence backlog #7; Money drops its local copy.
 *
 * v2.13.0: Convergence step 1 (MC design-language audit — see MC-DESIGN-LANGUAGE.md).
 *   Added the ONE shared Tier-2 sub-strip (.dw-substrip + .dw-grp group label) that replaces
 *   the per-spoke .an-substrip / .adm-substrip / .wb-substrip local copies, plus a .dark-acc
 *   body modifier giving dark-accent spokes a white active-tab icon on BOTH the Tier-1 deck
 *   tabs and the Tier-2 sub-strip (retires the per-spoke .nb.on .ic{brightness(0) invert(1)}
 *   overrides). Additive + .dw-deck-gated → INERT until a spoke renames its sub-strip class to
 *   .dw-substrip and adds .dark-acc to its body. DEPLOY THIS BEFORE the spoke swaps. Migrate:
 *   Analytics (.an-substrip→.dw-substrip), Admin (.adm-substrip), Workbench (.wb-substrip);
 *   add .dark-acc to Analytics/Admin/Workbench/Sales (Production folds in with its larger
 *   .dw-deck adoption later).
 *
 * v2.12.1: FIX — scoped the legacy "dark sidebar in light mode" block (body.light .sb/.nb/.sb-sec/...)
 *   to body.light:not(.theme-drafting). The body.light .nb{color:rgba(255,255,255,.5)} rule (specificity
 *   0,2,1) was beating spoke sub-strip .nb rules (0,2,0) and rendering deck page tabs as invisible white —
 *   it bit Analytics (fixed locally v6.46.1) then Admin (v2.0). Now inert for all theme-drafting (deck)
 *   spokes; preserved for any non-drafting light context. Spokes no longer need to defensively re-scope
 *   their sub-strip .nb under .dw-deck (existing scoping is harmless).
 *
 * v2.12.0: Mission Control dashboard primitives. Extracted the vitals strip
 *   (.pvitals/.pvit/.pvl/.pvv/.pvs), the section tag (.pv-tag), the three-up grid
 *   (.mc-three), the needs-attention rows (.mc-na/.ic2), and the activity feed
 *   (.mc-feed/.fdot) — verbatim from the approved Production/Estimating/Sales MC
 *   dashboards (rule of three). All gated behind body.theme-drafting.dw-deck, so
 *   only deck spokes pick them up; Production (no .dw-deck class) keeps its local
 *   copy untouched. Est/Sales local copies are now redundant (shared wins on
 *   specificity, identical content) — delete them in a later cleanup pass. Spoke-
 *   specific pipeline BOARDS and bespoke panels (e.g. Sales field-measures) stay
 *   local. Lets new MC spokes (Operations next) inherit the primitives instead of
 *   each carrying its own copy.
 *
 * v2.11.1: FIX — gate the deck rules behind .dw-deck. v2.11.0 scoped the deck
 *   layout (flex-direction:column, etc.) to plain .theme-drafting, which flipped
 *   the live theme-drafting *sidebar* spokes (Estimating/Sales/Ops/Analytics/
 *   Admin/Money/Workbench) to a broken column layout. Now body-affecting deck
 *   rules require body.theme-drafting.dw-deck; palette-only spokes are untouched.
 *   .cd reverts to the underline for palette-only spokes; deck spokes get the left
 *   spine. A spoke opts into the deck via class="theme-drafting dw-deck".
 *
 * v2.11.0: Command-deck chrome (Mission Control top-deck). Shared styling for the
 *   dw-deck.js header (logo · page tabs · titleblock), the .dw-sheet "drawing sheet",
 *   sharp corners everywhere, the closed quick-stats box, and the single LEFT accent
 *   spine on .cd (replaces the old bottom underline). Extracted verbatim from the
 *   approved Production v3.5.0. Pairs with dw-deck.js v1.0.0. Still scoped to
 *   body.theme-drafting + new .dw-sheet / .deck-* classes → spokes without the deck
 *   are unaffected, and a spoke's local copy (e.g. Production) still overrides.
 *
 * v2.10.1: Drafting theme — crisper card contrast. Strengthened the blue-faint
 *   border token (--brd #cdd9ea→#a9c0e6, --brd2→#8fb0dc) and nudged --shadow-card
 *   so cards/panels read distinctly on the vellum+grid, matching Portal Mission
 *   Control. Scoped to body.theme-drafting; dark (non-drafting) spokes unaffected.
 *
 * v2.10.0: Opt-in "drafting" theme (body.theme-drafting)
 *   - Additive, opt-in light skin. A spoke adds class="theme-drafting" to
 *     <body>; the token remap re-skins every token-driven component (sidebar,
 *     toolbar, cards, tables, kanban, modals) to a light "drafting station"
 *     palette — vellum bg, ink text, blue-faint technical borders, soft
 *     shadows, faint blueprint grid — while preserving each spoke's --acc.
 *   - Spacing / type / radius tokens UNCHANGED → information density identical.
 *   - ZERO blast radius: every rule is scoped under .theme-drafting, so spokes
 *     without the class are byte-for-byte unaffected. Remove the class = revert.
 *   - Pilot: Production. Office excluded (warm island). External-facing
 *     (Website/Customers/Partner) deferred pending review.
 *
 * v2.9.0: Simple View removed (deprecated comfort mode)
 *   - Deleted the body.simple-view block (type/spacing bump, 48px touch targets,
 *     .power-user hiding, tooltip/card/table/modal comfort) + .report-fab overrides.
 *     Comfort mode retired platform-wide; lock-out moved to role-based gating
 *     (sensitive Operations items now gated in code, not CSS).
 *
 * v2.8.0: Toast severity variants + .req required marker
 *   - New: .toast.toast-error (red) and .toast.toast-info (blue) variants —
 *     pairs with dw-core.js v0.6.0 toast({type}). Default .toast stays green.
 *   - New: .req — required-field asterisk marker for .fl labels
 *     (color:var(--red)). Spokes use <span class="req" aria-hidden="true">*</span>.
 *
 * v2.7.0: Modal width — wide default
 *   - .mo-c default width 560 → 880. Every content modal (forms + detail views)
 *     is now wide platform-wide; spokes inherit it — no per-spoke class needed.
 *   - body.simple-view .mo-c no longer pins 580 (inherits 880, so simple-view
 *     isn't smaller than normal). Mobile (<768px) still collapses to full-width.
 *   - Confirms stay compact (~440) via dw-confirm.js's inline cap — unchanged.
 *   - Follow-up commits delete now-redundant per-spoke width overrides
 *     (Production #mo-job 900, Sales .qa-wide 720, Estimating inline 480).
 *
 * v2.6.0: Canonical Status Pills + cyan/install tokens
 *   - New tokens: --cyan/--cyan-d and --install-color/--install-d (light + dark).
 *   - New: canonical production-stage pills (.pill-queued/-fabrication/-paint/
 *     -galvanizing/-ready_to_ship/-install/-complete) with ALIASES for per-spoke
 *     naming (.pill-in_progress=fabrication, .pill-finishing=paint, .pill-ready=ready_to_ship)
 *     so no spoke markup has to change.
 *   - .pill-complete is the only SOLID pill (terminal state) with a leading check;
 *     add .just-done for a one-shot shimmer on the completion transition (spoke opt-in).
 *   - Replaces divergent per-spoke stage colors (fabrication was orange/red/blue;
 *     ready was green/slate). Spokes drop their local stage-pill defs to inherit.
 *
 * v2.5.0: Accent Ink Token (--acc-ink)
 *   - .bt-p primary-button text color is now color:var(--acc-ink,#000)
 *     instead of hardcoded #000, so contrast travels WITH the accent.
 *   - Spokes set --acc-ink:#fff in their :root/body.light accent block for
 *     DARK accents (Sales purple, Analytics blue, Partner/Office red,
 *     Admin slate in light mode). Bright accents omit it (fallback #000).
 *   - Fixes black-on-dark-accent WCAG contrast bug + retires the scattered
 *     per-spoke .bt-p{color:...} overrides and the unused .bt-p-light.
 *
 * v2.4.0: Report-a-Problem Components
 *   - New: .report-fab — floating action button (bottom-right)
 *   - New: .report-overlay, .report-modal — modal shell
 *   - New: .report-modal-close — top-right close button
 *   - New: .report-type-toggle, .report-type-btn — bug/suggestion + severity buttons
 *   - New: .report-type-btn.active-bug, .active-suggestion — type active states
 *   - New: .report-type-btn.active-sev-critical|high|med|low — severity active states
 *   - New: .report-spoke-tag, .report-spoke-dot — auto-detected spoke pill
 *   - New: .report-submit, .report-err — submit button + validation error
 *   - Companion to dw-report.js v1.0.0 shared module
 *
 * v2.3.0: File System Components
 *   - New: .file-grid, .file-card — job file thumbnail grid
 *   - New: .file-thumb, .file-thumb-placeholder — image preview + ext icon
 *   - New: .file-info, .file-name, .file-meta, .file-cat — file metadata
 *   - New: .file-actions — view/category/delete action bar
 *   - New: .file-upload-zone — drag-and-drop upload area
 *   - Responsive: 110px min cards + 80px thumbs on mobile
 *
 * v2.2.0: Accent Scope Restriction (Option C)
 *   - New: .cd.hero — accent-bordered hero card variant
 *   - New: --prog-default, .pf-default — neutral progress bar
 *   - New: .job-num-n — neutral job number (replaces accent job nums)
 *   - ACCENT SCOPE RULE: --acc should only be used in 3 places:
 *     1. Sidebar brand mark (.sb-brand h1)
 *     2. Active nav indicator (.nb.on, mobile tab .active)
 *     3. Primary buttons (.bt-p, .btn-primary-acc)
 *     All other uses (KPI values, progress bars, job numbers,
 *     inline text) should use semantic colors (--grn/--red/--amb)
 *     or neutral (--t1/--t2/--blu). Spokes migrating gradually.
 *
 * v2.0.0 BREAKING: Consumer-grade visual redesign
 *   - Font: Inter → DM Sans
 *   - New shadow, radius, and transition tokens
 *   - New component patterns (stat cards, attention items,
 *     Right Now card, Cmd+K palette, toast v2, activity feed,
 *     page header, crew utilization, schedule strip, etc.)
 *   - Type scale +1px bump on kpi/2xl
 *   - Light mode: warm gray (#f8f7f5) background
 *   - All interactive elements: 180ms ease transitions
 *   - References: Linear, Stripe, Notion, Superhuman
 * ═══════════════════════════════════════════════════════════
 *
 * USAGE: Each spoke includes:
 *   <link rel="stylesheet" href="https://dw-design.pages.dev/dw-design.css">
 *   <style>
 *     :root { --acc:#22C55E; --acc-d:rgba(34,197,94,.12); --acc-hover:#16A34A; --focus:#22C55E; }
 *     body.light { --acc:#16A34A; --acc-d:rgba(22,163,74,.15); --acc-hover:#15803D; --focus:#16A34A; }
 *     [spoke-specific styles only]
 *   </style>
 *
 * ACCENT COLORS:
 *   Operations:  --acc:#06B6D4  (cyan)
 *   Estimating:  --acc:#F59E0B  (gold)
 *   Analytics:   --acc:#3B82F6  (blue)
 *   Sales:       --acc:#A855F7  (purple)
 *   Production:  --acc:#F97316  (orange)
 *   Money:       --acc:#22C55E  (green)
 *   Admin:       --acc:#94A3B8  (slate)
 *   Partner:     --acc:#EF4444  (red)
 *
 * TYPE SCALE (v2.0.0):
 *   --fs-xs   11px  (meta labels, timestamps)
 *   --fs-sm   12px  (sidebar chrome, badges, captions)
 *   --fs-md   13px  (secondary text, table headers)
 *   --fs-base 14px  (body text, buttons, form labels)
 *   --fs-lg   15px  (nav items, card titles)
 *   --fs-xl   16px  (body base, section content)
 *   --fs-2xl  20px  (page titles, modal titles)
 *   --fs-3xl  24px  (dashboard titles)
 *   --fs-kpi  32px  (KPI values, stat cards)
 *
 * SPACING SCALE (v2.0.0 — 4px grid, extended):
 *   --sp-1   4px   --sp-2   8px   --sp-3  12px
 *   --sp-4  16px   --sp-5  20px   --sp-6  24px
 *   --sp-8  32px   --sp-10 40px
 *
 * Z-INDEX SCALE:
 *   --z-sticky 2  --z-sticky-corner 3  --z-nav 80
 *   --z-modal 100  --z-toast 500  --z-tooltip 600
 *   --z-overlay 9000  --z-login 9500  --z-cmdk 1000
 *
 * SIMPLE VIEW: body.simple-view — unchanged from v1
 * THEME: root = dark, body.light = warm light — unchanged toggle logic
 */

/* ── Fonts (v2.17.0: self-hosted variable woff2 — was a render-blocking Google Fonts @import).
   Files live in /fonts/ on this Pages project; relative url() resolves against the CSS origin,
   so every spoke linking dw-design.css inherits them with zero spoke edits. latin + latin-ext
   subsets (latin-ext covers Spanish for the Shop crew). font-display:swap throughout. ── */
@font-face{font-family:'DM Sans';font-style:normal;font-weight:300 800;font-display:swap;src:url(fonts/dmsans-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'DM Sans';font-style:normal;font-weight:300 800;font-display:swap;src:url(fonts/dmsans-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'DM Sans';font-style:italic;font-weight:400;font-display:swap;src:url(fonts/dmsans-italic-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'DM Sans';font-style:italic;font-weight:400;font-display:swap;src:url(fonts/dmsans-italic-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/jetbrainsmono-normal-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400 700;font-display:swap;src:url(fonts/jetbrainsmono-normal-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}

/* ══════════════════════════════════════════════
   ROOT VARIABLES (dark theme — default)
   --acc, --acc-d, --acc-hover, --focus set per spoke
   ══════════════════════════════════════════════ */
:root {
  /* Backgrounds (dark) */
  --bg0:#111113;--bg1:#1a1a1c;--bg2:#222225;--bg3:#2a2a2e;--bg4:#333338;
  /* Borders */
  --brd:#2a2a2e;--brd2:#3a3a40;
  /* Typography */
  --t1:#e8e9ed;--t2:#9fa3b8;--t3:#7a7f94;
  /* Semantic palette */
  --grn:#22C55E;--grn-d:rgba(34,197,94,.1);
  --red:#EF4444;--red-d:rgba(239,68,68,.1);
  --blu:#3B82F6;--blu-d:rgba(59,130,246,.1);
  --org:#F97316;--org-d:rgba(249,115,22,.1);
  --pur:#A855F7;--pur-d:rgba(168,85,247,.1);
  --amb:#F59E0B;--amb-d:rgba(245,158,11,.12);
  --cyan:#06B6D4;--cyan-d:rgba(6,182,212,.12);
  --install-color:#0EA5E9;--install-d:rgba(14,165,233,.12);
  /* Neutral progress default (Option C — not tied to accent) */
  --prog-default:#64748b;--prog-default-end:#94a3b8;
  /* Tokens */
  --r:6px;--r-md:10px;--r-lg:14px;
  --mono:'JetBrains Mono',monospace;
  --sans:'DM Sans',-apple-system,system-ui,sans-serif;
  /* Shadows */
  --shadow-card:0 1px 4px rgba(0,0,0,.15);
  --shadow-hover:0 4px 12px rgba(0,0,0,.25);
  --shadow-modal:0 16px 48px rgba(0,0,0,.4);
  /* Type scale */
  --fs-xs:11px;--fs-sm:12px;--fs-md:13px;--fs-base:14px;--fs-lg:15px;--fs-xl:16px;--fs-2xl:20px;--fs-3xl:24px;--fs-kpi:32px;
  /* Spacing scale */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:20px;--sp-6:24px;--sp-8:32px;--sp-10:40px;
  /* Z-index scale */
  --z-sticky:2;--z-sticky-corner:3;--z-nav:80;--z-modal:100;--z-toast:500;--z-tooltip:600;--z-overlay:9000;--z-login:9500;--z-cmdk:1000;
  /* Transition tokens */
  --ease:cubic-bezier(.4,0,.2,1);--dur:180ms;
  /* Uppercase-label letter-spacing tokens (v2.16.0) */
  --ls-label:.8px;--ls-wide:1px;--ls-brand:1.5px;--ls-sec:2px;
}

/* ── Reset ── */
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden}
body{font-family:var(--sans);background:var(--bg0);color:var(--t1);display:flex;font-size:var(--fs-xl);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}

/* ══════════════════════════════════════════════
   SIDEBAR (preserved: .sb .sb-brand .sb-nav .sb-sec .nb .sb-ft)
   ══════════════════════════════════════════════ */
/* border-right removed (v2.2.0) — dark/light contrast does the work */
.sb{width:220px;min-width:220px;background:var(--bg1);display:flex;flex-direction:column}
.sb-brand{padding:18px 16px 14px}
.sb-brand h1{font-family:var(--mono);font-size:var(--fs-2xl);font-weight:700;color:var(--acc);letter-spacing:var(--ls-brand);text-transform:uppercase}
.sb-brand span{font-size:var(--fs-sm);color:var(--t3);display:block;margin-top:2px;letter-spacing:.3px}
.sb-nav{flex:1;padding:8px 6px;overflow-y:auto}
.sb-sec{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:var(--ls-sec);color:var(--t3);padding:16px 10px 4px;font-weight:600}
.nb{display:flex;align-items:center;gap:var(--sp-2);padding:10px var(--sp-3);border:none;border-radius:var(--r);background:0;color:var(--t2);font-family:var(--sans);font-size:var(--fs-lg);font-weight:500;cursor:pointer;width:100%;text-align:left;transition:all var(--dur) var(--ease)}
.nb:hover{background:rgba(255,255,255,.04);color:var(--t1)}
.nb.on{background:var(--acc-d);color:var(--acc);font-weight:600}
.nb .ic{font-size:16px;width:18px;text-align:center;opacity:.7}
.nb.on .ic{opacity:1}
.sb-ft{padding:10px 16px;font-size:var(--fs-xs);color:var(--t3);font-family:var(--mono);letter-spacing:.5px;border-top:1px solid var(--brd)}

/* ══════════════════════════════════════════════
   MAIN LAYOUT (preserved: .mn .stats-bar .stat .tb .ct)
   ══════════════════════════════════════════════ */
.mn{flex:1;display:flex;flex-direction:column;overflow:hidden}

/* ── Stats bar (persistent KPIs) ── */
.stats-bar{height:40px;min-height:40px;background:var(--bg1);display:flex;align-items:center;padding:0 18px;gap:4px;font-size:var(--fs-base);border-bottom:1px solid var(--brd)}
.stat{display:flex;align-items:center;gap:5px;padding:0 10px;color:var(--t2)}
.stat-label{font-size:var(--fs-base);color:var(--t3);font-weight:500}
.stat-val{font-family:var(--mono);font-weight:600;font-size:var(--fs-base)}
.stat-val.v-grn{color:var(--grn)}.stat-val.v-amb{color:var(--amb)}.stat-val.v-red{color:var(--red)}.stat-val.v-blu{color:var(--blu)}.stat-val.v-pur{color:var(--pur)}.stat-val.v-acc{color:var(--acc)}
.stat-sep{width:1px;height:18px;background:var(--brd);margin:0 4px}

/* ── Page header ── */
.tb{height:48px;min-height:48px;display:flex;align-items:center;justify-content:space-between;padding:0 var(--sp-6)}
.tb h2{font-size:var(--fs-2xl);font-weight:700;letter-spacing:-.2px}
.tb-r{font-size:var(--fs-base);color:var(--t3);font-family:var(--mono)}
.ct{flex:1;overflow-y:auto;padding:var(--sp-5) var(--sp-6);animation:dwFadeIn .35s var(--ease)}

/* ══════════════════════════════════════════════
   WAVE 8 — MOTION & MICRO-INTERACTIONS
   Professional, fast, not decorative
   ══════════════════════════════════════════════ */
@keyframes dwFadeIn{from{opacity:0}to{opacity:1}}
@keyframes dwSlideUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
@keyframes dwBarGrow{from{width:0}to{width:var(--bar-w,100%)}}

/* Content area fade-in on page render */
.ct>*{animation:dwSlideUp .3s var(--ease) both}
.ct>*:nth-child(1){animation-delay:0s}
.ct>*:nth-child(2){animation-delay:.04s}
.ct>*:nth-child(3){animation-delay:.08s}
.ct>*:nth-child(4){animation-delay:.12s}
.ct>*:nth-child(5){animation-delay:.16s}
.ct>*:nth-child(6){animation-delay:.2s}
.ct>*:nth-child(n+7){animation-delay:.24s}

/* Progress bar animate on load */
.pf{animation:dwBarGrow .6s var(--ease) .2s both}

/* Right Now card entrance */
.right-now{animation:dwSlideUp .3s var(--ease) .05s both}

/* Reduce motion for users who prefer it */
@media(prefers-reduced-motion:reduce){
  .ct,.ct>*,.pf,.right-now{animation:none!important}
}

/* ══════════════════════════════════════════════
   GRID SYSTEM (preserved: .g2—.g5; .g6 deleted in v2.25.1, no page used it)
   ══════════════════════════════════════════════ */
.g2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3)}
.g3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:var(--sp-3)}
.g4{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-3)}
.g5{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-3)}

/* ══════════════════════════════════════════════
   CARDS (preserved: .cd .cd-h .mb)
   v2: updated shadow, radius, border
   ══════════════════════════════════════════════ */
.cd{background:var(--bg2);border:1px solid var(--brd);border-radius:var(--r-md);padding:var(--sp-4);box-shadow:var(--shadow-card);transition:box-shadow var(--dur) var(--ease)}
.cd:hover{box-shadow:var(--shadow-hover)}
.cd-h{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}
.cd-h h3{font-size:var(--fs-lg);font-weight:700;letter-spacing:-.1px;color:var(--t1)}
/* Hero card — accent top border for primary KPI / visual anchor (Option C) */
.cd.hero{border-top:2px solid var(--acc)}
.mb{margin-bottom:14px}

/* ══════════════════════════════════════════════
   KPI (preserved: .kpi .kpi-l .kpi-v .kpi-s .k-*)
   v2: larger value, tighter letter-spacing
   ══════════════════════════════════════════════ */
.kpi{padding:var(--sp-3) var(--sp-4)}
.kpi-l{font-size:var(--fs-sm);color:var(--t3);text-transform:uppercase;letter-spacing:var(--ls-wide);margin-bottom:4px;font-weight:600}
.kpi-v{font-family:var(--mono);font-size:var(--fs-kpi);font-weight:700;line-height:1;letter-spacing:-.5px}
.kpi-s{font-size:var(--fs-base);color:var(--t3);margin-top:3px;font-family:var(--mono)}
.k-grn .kpi-v{color:var(--grn)}.k-amb .kpi-v{color:var(--amb)}.k-red .kpi-v{color:var(--red)}.k-blu .kpi-v{color:var(--blu)}.k-pur .kpi-v{color:var(--pur)}.k-acc .kpi-v{color:var(--acc)}

/* ══════════════════════════════════════════════
   FORMS (preserved: .fg .fl .fi .fs .fi-sm .fi-num .error .valid)
   v2: updated radius, transition
   ══════════════════════════════════════════════ */
.fg{margin-bottom:var(--sp-3)}
.fl{display:block;font-size:var(--fs-sm);font-weight:600;text-transform:uppercase;letter-spacing:var(--ls-label);color:var(--t3);margin-bottom:4px}
.fi,.fs{width:100%;padding:10px var(--sp-3);background:var(--bg3);border:1px solid var(--brd);border-radius:var(--r);color:var(--t1);font-family:var(--sans);font-size:var(--fs-lg);transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
.fi:focus,.fs:focus{outline:0;border-color:var(--focus);box-shadow:0 0 0 2px color-mix(in srgb,var(--focus) 15%,transparent)}
.fi::placeholder{color:var(--t3)}
.fi-sm{padding:var(--sp-2) 10px;font-size:var(--fs-base)}
.fi-num{font-family:var(--mono);text-align:right;width:100px}
select.fs{cursor:pointer}
select.fs option{background:var(--bg2);color:var(--t1)}
textarea.fi{resize:vertical;min-height:60px;font-family:var(--sans)}

/* ── Form validation states ── */
.fi.error,.fi[aria-invalid="true"],.fs.error,.fs[aria-invalid="true"]{border-color:var(--red);background:var(--red-d)}
.fi.error:focus,.fi[aria-invalid="true"]:focus,.fs.error:focus,.fs[aria-invalid="true"]:focus{border-color:var(--red);box-shadow:0 0 0 2px var(--red-d)}
.error-msg{font-size:var(--fs-sm);color:var(--red);margin-top:4px;font-weight:500}
.req{color:var(--red);margin-left:2px;font-weight:600}
.fi.valid,.fs.valid{border-color:var(--grn)}

/* ══════════════════════════════════════════════
   BUTTONS (preserved: .bt .bt-p .bt-d .bt-s .bg)
   v2: smoother transitions, updated radius
   ══════════════════════════════════════════════ */
/* FROZEN-LEGACY (v2.16.0): .bt/.bt-p/.bt-d/.bt-s frozen — new code uses .btn variants below */
.bt{display:inline-flex;align-items:center;gap:6px;padding:10px var(--sp-4);border:1px solid var(--brd);border-radius:var(--r);background:var(--bg3);color:var(--t1);font-family:var(--sans);font-size:var(--fs-base);font-weight:600;cursor:pointer;transition:all var(--dur) var(--ease);white-space:nowrap}
.bt:hover{background:var(--bg4);border-color:var(--brd2)}
.bt:active{transform:scale(.97)}
.bt-p{background:var(--acc);border-color:var(--acc);color:var(--acc-ink,#000);font-weight:600}
.bt-p:hover{background:var(--acc-hover);border-color:var(--acc-hover)}
.bt-d{background:var(--red-d);border-color:rgba(239,68,68,.3);color:var(--red)}
.bt-d:hover{background:var(--red);color:#fff}
.bt:disabled,.bt[disabled]{opacity:.45;cursor:not-allowed;pointer-events:none}
.bt:focus-visible,.nb:focus-visible,.fi:focus-visible,.fs:focus-visible,.bn-btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.bt-s{padding:6px 10px;font-size:var(--fs-base)}
.bg{display:flex;gap:5px;flex-wrap:wrap}

/* ── Button v2 variants (NEW — coexist with .bt) ── */
.btn{display:inline-flex;align-items:center;gap:6px;padding:9px 16px;border-radius:var(--r);font-family:var(--sans);font-size:var(--fs-md);font-weight:600;cursor:pointer;transition:all var(--dur) var(--ease);border:1px solid transparent;white-space:nowrap}
.btn:active{transform:scale(.97)}
.btn-primary{background:var(--t1);color:var(--bg0);border-color:var(--t1)}
.btn-primary:hover{opacity:.85}
.btn-ghost{background:transparent;color:var(--t2);border:none;padding:8px 12px}
.btn-ghost:hover{background:var(--bg3);color:var(--t1)}

/* ══════════════════════════════════════════════
   TABLES (preserved: .tw table th td .m .r .tot-row .sortable .sorted)
   v2: hover transition, updated header style
   ══════════════════════════════════════════════ */
.tw{overflow-x:auto;-webkit-overflow-scrolling:touch}
table{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
th{text-align:left;padding:var(--sp-3) var(--sp-4);font-size:var(--fs-xs);font-weight:600;text-transform:uppercase;letter-spacing:var(--ls-label);color:var(--t3);border-bottom:1px solid var(--brd);white-space:nowrap;position:sticky;top:0;background:var(--bg3);z-index:var(--z-sticky)}
td{padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--brd);white-space:nowrap}
tr{transition:background var(--dur) var(--ease)}
tr:hover td{background:var(--bg3)}

/* ── Table: column header tooltip (Wave 5) ── */
th[title]{cursor:help;position:relative}
th[title]:hover::after{content:attr(title);position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);background:var(--bg0);color:var(--t1);font-size:var(--fs-xs);font-weight:500;text-transform:none;letter-spacing:0;padding:6px 10px;border-radius:var(--r);border:1px solid var(--brd2);box-shadow:var(--shadow-hover);white-space:nowrap;z-index:var(--z-tooltip);pointer-events:none;animation:dwFadeIn .15s var(--ease)}

/* ── Table: empty row message ── */
.m{font-family:var(--mono);font-size:var(--fs-base)}
.r{text-align:right}
.tot-row{font-weight:700;border-top:2px solid var(--acc)}
.tot-row td{background:var(--bg1) !important}
th.sortable{cursor:pointer;user-select:none}
th.sortable:hover{color:var(--t1)}
th.sorted{color:var(--acc)}

/* ── Table v2 enhancements (NEW) ── */
.row-actions{opacity:0;transition:opacity var(--dur) var(--ease);display:flex;gap:4px}
tr:hover .row-actions{opacity:1}
@media (hover:none){.row-actions{opacity:.85}}
/* Neutral job number — Option C (data, not identity) */
.job-num-n{font-family:var(--mono);font-weight:600;color:var(--t1);font-size:var(--fs-md)}

/* ══════════════════════════════════════════════
   BADGES & PILLS (preserved: .bd .bd-* .pill)
   ══════════════════════════════════════════════ */
/* FROZEN-LEGACY (v2.16.0): .bd/.bd-* frozen — new code uses .badge */
.bd{display:inline-flex;align-items:center;padding:var(--sp-1) var(--sp-2);border-radius:10px;font-size:var(--fs-sm);font-weight:600;font-family:var(--mono);letter-spacing:.3px;text-transform:uppercase}
.bd-g{background:var(--grn-d);color:var(--grn)}
.bd-a{background:var(--amb-d);color:var(--amb)}
.bd-r{background:var(--red-d);color:var(--red)}
.bd-b{background:var(--blu-d);color:var(--blu)}
.bd-p{background:var(--pur-d);color:var(--pur)}
.bd-acc{background:var(--acc-d);color:var(--acc)}
.pill{display:inline-flex;align-items:center;padding:var(--sp-1) var(--sp-3);border-radius:10px;font-size:var(--fs-sm);font-weight:600;font-family:var(--mono);letter-spacing:.3px}

/* ── Canonical production-stage pills (v2.6.0). Aliases cover per-spoke class names. ── */
.pill-queued{background:var(--blu-d);color:var(--blu)}
.pill-fabrication,.pill-in_progress{background:var(--org-d);color:var(--org)}
.pill-paint,.pill-finishing{background:var(--pur-d);color:var(--pur)}
.pill-galvanizing{background:var(--cyan-d);color:var(--cyan)}
.pill-ready,.pill-ready_to_ship{background:var(--grn-d);color:var(--grn)}
.pill-install{background:var(--install-d);color:var(--install-color)}
/* Complete = the only SOLID pill (terminal state) + leading check */
.pill-complete,.pill-completed{background:var(--grn);color:#06351b;font-weight:700;position:relative;overflow:hidden}
body.light .pill-complete,body.light .pill-completed{background:#16A34A;color:#fff}
.pill-complete::before,.pill-completed::before{content:"\2713\00a0"}
/* One-shot shimmer — spokes add .just-done only on the genuine not-complete->complete transition */
.pill-complete.just-done::after{content:"";position:absolute;inset:0;background:linear-gradient(110deg,transparent 35%,rgba(255,255,255,.6) 50%,transparent 65%);transform:translateX(-160%);animation:pillShimmer .9s ease-out 1}
@keyframes pillShimmer{to{transform:translateX(160%)}}
@media(prefers-reduced-motion:reduce){.pill-complete.just-done::after{display:none;animation:none}}

/* ── Badge v2 (NEW — used alongside .bd) ── */
.badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:20px;font-size:var(--fs-xs);font-weight:600;letter-spacing:.2px}

/* ══════════════════════════════════════════════
   PROGRESS BAR (preserved: .pb .pf .pf-*)
   ══════════════════════════════════════════════ */
.pb{height:5px;background:var(--bg4);border-radius:3px;overflow:hidden}
.pf{height:100%;border-radius:3px;transition:width .3s var(--ease)}
.pf-g{background:var(--grn)}.pf-a{background:var(--amb)}.pf-r{background:var(--red)}.pf-b{background:var(--blu)}.pf-acc{background:var(--acc)}
/* Neutral progress fill — Option C default (not tied to accent) */
.pf-default{background:linear-gradient(90deg,var(--prog-default),var(--prog-default-end))}

/* ══════════════════════════════════════════════
   SECTION HEADER (preserved: .sh .st)
   ══════════════════════════════════════════════ */
/* FROZEN-LEGACY (v2.16.0): .sh/.st frozen — new code uses .section-header/.section-title */
.sh{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}
.st{font-size:var(--fs-lg);font-weight:600;text-transform:uppercase;letter-spacing:var(--ls-wide);color:var(--t2)}

/* ── Section header v2 (NEW) ── */
.section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sp-4)}
.section-title{font-size:var(--fs-xl);font-weight:700;letter-spacing:-.2px;color:var(--t1)}
.section-link{font-size:var(--fs-md);color:var(--t3);text-decoration:none;font-weight:500;cursor:pointer;transition:color var(--dur) var(--ease)}
.section-link:hover{color:var(--acc)}

/* ══════════════════════════════════════════════
   TOOLTIPS (preserved: .tip .tip-t .tip-r .tip-l)
   ══════════════════════════════════════════════ */
.tip{position:relative;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background:var(--acc-d);color:var(--acc);font-size:var(--fs-xs);font-weight:700;cursor:help;margin-left:4px;vertical-align:middle;flex-shrink:0;font-style:normal;font-family:var(--sans);line-height:1;transition:all var(--dur) var(--ease);border:1px solid var(--acc);opacity:.7}
.tip:hover{background:var(--acc-d);color:var(--acc);opacity:1}
.tip .tip-t{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}

/* ══════════════════════════════════════════════
   MODAL (preserved: .mo .mo-c)
   v2: updated shadow, radius, backdrop
   ══════════════════════════════════════════════ */
.mo{position:fixed;inset:0;background:rgba(0,0,0,.55);backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;z-index:var(--z-modal)}
.mo.show{display:flex}
.mo-c{background:var(--bg2);border:1px solid var(--brd);border-radius:var(--r-lg);padding:var(--sp-6);width:880px;max-width:92vw;max-height:85vh;overflow-y:auto;box-shadow:var(--shadow-modal)}
/* v2.18.0: opt-in extra-wide variant for data-dense modals (job dossiers, wide editors) */
.mo-c.mo-xl{width:1280px;max-width:96vw}
.mo-c h3{font-size:var(--fs-2xl);font-weight:700;margin-bottom:14px}

/* ══════════════════════════════════════════════
   TOAST (preserved: .toast .toast.show — backward compat)
   v2 NEW: .toast-wrap for stacked toasts
   ══════════════════════════════════════════════ */
/* Legacy toast (still works for existing spoke code) */
/* FROZEN-LEGACY (v2.16.0): legacy .toast frozen — new code uses .toast-v2/.toast-wrap */
.toast{position:fixed;bottom:var(--sp-4);right:var(--sp-4);background:var(--grn);color:#000;padding:10px var(--sp-5);border-radius:var(--r);font-size:var(--fs-base);font-weight:600;transform:translateY(80px);opacity:0;transition:.25s var(--ease);z-index:var(--z-toast)}
.toast.show{transform:translateY(0);opacity:1}
.toast.toast-error{background:var(--red);color:#fff}
.toast.toast-info{background:var(--blu);color:#fff}

/* Toast v2 — stacked, dismissable, card-style */
.toast-wrap{position:fixed;bottom:var(--sp-5);left:var(--sp-5);z-index:var(--z-toast);display:flex;flex-direction:column;gap:var(--sp-2)}
@keyframes toastIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}

/* ══════════════════════════════════════════════
   EXPORT BOX (preserved: .ebox)
   ══════════════════════════════════════════════ */
.ebox{background:var(--bg3);border:1px solid var(--brd);border-radius:var(--r);padding:var(--sp-3);font-family:var(--mono);font-size:var(--fs-base);color:var(--t2);max-height:200px;overflow:auto;white-space:pre;line-height:1.5}

/* ══════════════════════════════════════════════
   LOADING SPINNER (preserved: .spinner)
   ══════════════════════════════════════════════ */
@keyframes dw-spin{to{transform:rotate(360deg)}}
.spinner{display:inline-block;width:18px;height:18px;border:2px solid var(--brd2);border-top-color:var(--t2);border-radius:50%;animation:dw-spin .6s linear infinite;vertical-align:middle}

/* ══════════════════════════════════════════════
   SCROLLBAR
   ══════════════════════════════════════════════ */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:0}
::-webkit-scrollbar-thumb{background:var(--brd2);border-radius:3px}
::-webkit-scrollbar-thumb:hover{background:var(--t3)}

/* ══════════════════════════════════════════════
   LIGHT MODE — warm gray theme
   body.light toggle logic unchanged from v1
   ══════════════════════════════════════════════ */
body.light{
  --bg0:#f8f7f5;--bg1:#ffffff;--bg2:#f3f2ef;--bg3:#eae9e5;--bg4:#dddcd8;
  --brd:#e5e4e0;--brd2:#d4d3cf;
  --t1:#1a1a1a;--t2:#555;--t3:#767676;
  /* Semantic palette (light variants) */
  --grn:#16A34A;--grn-d:rgba(22,163,74,.08);
  --red:#DC2626;--red-d:rgba(220,38,38,.08);
  --blu:#2563EB;--blu-d:rgba(37,99,235,.08);
  --org:#EA580C;--org-d:rgba(234,88,12,.08);
  --pur:#7C3AED;--pur-d:rgba(124,58,237,.08);
  --amb:#D97706;--amb-d:rgba(217,119,6,.08);
  --cyan:#0891B2;--cyan-d:rgba(8,145,178,.10);
  --install-color:#0284C7;--install-d:rgba(2,132,199,.10);
  /* Neutral progress default (light) */
  --prog-default:#94a3b8;--prog-default-end:#cbd5e1;
  /* Light shadows */
  --shadow-card:0 1px 4px rgba(0,0,0,.04);
  --shadow-hover:0 4px 12px rgba(0,0,0,.08);
  --shadow-modal:0 16px 48px rgba(0,0,0,.12);
}
/* ── Dark chrome: sidebar + stats bar stay dark in light mode ── */
/* v2.12.1: legacy "dark sidebar in light mode" block — scoped to :not(.theme-drafting) so it no longer
   leaks into deck spokes. The `body.light .nb{color:rgba(255,255,255,.5)}` rule (specificity 0,2,1) was
   beating spoke sub-strip `.nb` rules (0,2,0) and rendering the page tabs as invisible white (bit Analytics
   v6.46 + Admin v2.0). Every spoke is theme-drafting now, so this block is inert for them (token-driven light
   styles apply); kept as a safety net for any non-drafting light context. */
body.light:not(.theme-drafting) .sb{background:#1a1a1a}
body.light:not(.theme-drafting) .sb-brand h1{color:var(--acc)}
body.light:not(.theme-drafting) .sb-brand span{color:#7a7f94}
body.light:not(.theme-drafting) .sb-sec{color:rgba(255,255,255,.25)}
body.light:not(.theme-drafting) .nb{color:rgba(255,255,255,.5)}
body.light:not(.theme-drafting) .nb:hover{background:rgba(255,255,255,.06);color:rgba(255,255,255,.85)}
body.light:not(.theme-drafting) .nb.on{background:var(--acc-d);color:var(--acc)}
body.light:not(.theme-drafting) .sb-ft{color:rgba(255,255,255,.35);border-top-color:#2a2a2e}
body.light:not(.theme-drafting) .theme-toggle{border-top-color:#2a2a2e}
body.light .stats-bar{background:#1a1a1a;border-bottom-color:#2a2a2e}
body.light .stats-bar .stat{color:rgba(255,255,255,.55)}
body.light .stats-bar .stat-label{color:rgba(255,255,255,.35)}
body.light .stats-bar .stat-val{color:rgba(255,255,255,.7)}
body.light .stats-bar .stat-sep{background:#2a2a2e}
body.light tr:hover td{background:var(--bg3)}
body.light .tot-row td{background:var(--bg1)!important}
body.light .mo{background:rgba(0,0,0,.35)}
body.light ::-webkit-scrollbar-thumb{background:#ddd}
body.light ::-webkit-scrollbar-thumb:hover{background:#ccc}

/* ══════════════════════════════════════════════
   THEME TOGGLE (preserved)
   ══════════════════════════════════════════════ */
.theme-toggle{display:flex;align-items:center;justify-content:space-between;padding:8px 16px 12px;border-top:1px solid var(--brd);margin-top:4px;gap:8px}
.theme-sw{position:relative;width:48px;height:28px;cursor:pointer;flex-shrink:0}
.theme-sw input{opacity:0;width:0;height:0;position:absolute}
.theme-sw-track{position:absolute;inset:0;background:var(--bg3);border:1px solid var(--brd2);border-radius:14px;transition:.2s var(--ease)}
.theme-sw input:checked+.theme-sw-track{background:var(--acc);border-color:var(--acc)}
.theme-sw-thumb{position:absolute;width:20px;height:20px;background:#fff;border-radius:50%;top:3px;left:3px;transition:.2s var(--ease);box-shadow:0 1px 3px rgba(0,0,0,.3);pointer-events:none}
.theme-sw input:checked~.theme-sw-thumb{left:24px}

/* ══════════════════════════════════════════════════
   ═══════  NEW v2 COMPONENTS  ═══════
   ══════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════
   PAGE HEADER (NEW: .page-header .page-greeting .page-title .page-subtitle)
   Contextual greeting + title + subtitle pattern
   ══════════════════════════════════════════════ */
.page-header{margin-bottom:var(--sp-6)}
.page-greeting{font-size:var(--fs-base);color:var(--t3);margin-bottom:2px;font-weight:400}
.page-title{font-size:var(--fs-3xl);font-weight:700;letter-spacing:-.3px;color:var(--t1)}

/* ══════════════════════════════════════════════
   RIGHT NOW CARD (NEW)
   Single most important action — Superhuman-inspired
   ══════════════════════════════════════════════ */
.right-now{background:var(--bg2);border:1px solid var(--brd);border-radius:var(--r-md);padding:var(--sp-5) var(--sp-6);box-shadow:var(--shadow-card);margin-bottom:var(--sp-6);display:flex;align-items:center;gap:var(--sp-5);border-left:3px solid var(--acc);transition:box-shadow var(--dur) var(--ease)}
.right-now:hover{box-shadow:var(--shadow-hover)}
.right-now-icon{font-size:20px;flex-shrink:0;width:40px;height:40px;border-radius:var(--r);display:flex;align-items:center;justify-content:center}
.right-now-body{flex:1;min-width:0}
.right-now-label{font-size:var(--fs-xs);font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--t3);margin-bottom:3px}
.right-now-text{font-size:var(--fs-base);font-weight:500;color:var(--t1);line-height:1.5}
.right-now-text strong{font-weight:700}
.right-now-action{flex-shrink:0}

/* ══════════════════════════════════════════════
   EMPTY STATE (NEW)
   Friendly language + icon instead of "No data"
   ══════════════════════════════════════════════ */
.empty{text-align:center;padding:var(--sp-10) var(--sp-6)}
.empty-icon{font-size:36px;margin-bottom:var(--sp-3);opacity:.35}
.empty-title{font-size:var(--fs-lg);font-weight:600;color:var(--t1);margin-bottom:var(--sp-2)}
.empty-desc{font-size:var(--fs-base);color:var(--t3);max-width:340px;margin:0 auto;line-height:1.6}

/* ══════════════════════════════════════════════
   AR AGING BARS (NEW — Money)
   ══════════════════════════════════════════════ */
.aging-col{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px}
.aging-bar{width:100%;border-radius:4px 4px 0 0;min-height:4px;transition:height .4s var(--ease)}
.aging-label{font-size:var(--fs-xs);color:var(--t3);text-align:center}
.aging-val{font-family:var(--mono);font-size:var(--fs-md);font-weight:700;text-align:center}

/* ══════════════════════════════════════════════
   LAYOUT HELPERS (NEW)
   ══════════════════════════════════════════════ */
.two-col{display:grid;grid-template-columns:1fr 360px;gap:var(--sp-6);margin-bottom:var(--sp-6)}

/* ══════════════════════════════════════════════
   MOBILE RESPONSIVE
   Shared breakpoints — preserved from v1
   ══════════════════════════════════════════════ */

/* Bottom nav (mobile) — opt-in per spoke */
.bottom-nav{display:none;position:fixed;bottom:0;left:0;right:0;height:60px;background:var(--bg1);border-top:1px solid var(--brd);z-index:var(--z-nav);padding:0 8px}
.bottom-nav-inner{display:flex;align-items:center;justify-content:space-around;height:100%;max-width:480px;margin:0 auto}
.bn-btn{display:flex;flex-direction:column;align-items:center;gap:2px;padding:6px 12px;border:none;background:0;color:var(--t3);font-size:var(--fs-xs);font-weight:600;letter-spacing:.3px;cursor:pointer;border-radius:var(--r);transition:all var(--dur) var(--ease);min-width:54px;font-family:var(--sans)}
.bn-btn .bn-ic{font-size:20px}
.bn-btn.on{color:var(--acc)}
.bn-btn:active{background:var(--acc-d)}

@media(max-width:768px){
  .sb{display:none}
  .bottom-nav{display:block}
  .mn{width:100%}
  .stats-bar{overflow-x:auto;-webkit-overflow-scrolling:touch;height:auto;min-height:36px;padding:0 12px}
  .tb{padding:0 16px;height:44px;min-height:44px}
  .tb h2{font-size:16px}
  .ct{padding:14px 16px 80px}
  .g2,.g3,.g4,.g5,.g6{grid-template-columns:1fr}
  .two-col{grid-template-columns:1fr}
  .mo-c,.mo-c.mo-xl{width:100%;max-width:100%;border-radius:0;max-height:100vh;padding:16px}
  .cmd-box{width:calc(100vw - 32px);margin:0 16px}
  table{font-size:var(--fs-md)}
  td,th{padding:6px 8px}
  .fi,.fs,textarea.fi{font-size:16px}
  .kpi-v{font-size:24px}
  .stat-card-value{font-size:24px}
  .right-now{flex-direction:column;align-items:flex-start;gap:var(--sp-3)}
  .right-now-action{align-self:flex-end}
  .att{flex-direction:column;align-items:flex-start;gap:var(--sp-2)}
  .att-action{align-self:flex-end}
  .row-actions{opacity:1}
}
@media(max-width:480px){
  .bn-btn{min-width:0;padding:6px 4px;font-size:10px;letter-spacing:0;gap:1px}
  .bn-btn .bn-ic{font-size:18px}
  .ct{padding:12px 12px 72px}
  .tb{padding:0 12px}
  .tb h2{font-size:15px}
  .bt,.fi,.fs{min-height:44px}
  .cd{padding:var(--sp-3)}
  .kpi-v{font-size:20px}
  .stat-card-value{font-size:20px}
  .stats-bar .stat-label{display:none}
  .stats-grid{grid-template-columns:1fr 1fr}
  .sched-strip{gap:var(--sp-2)}
}
@media(min-width:769px){
  .bottom-nav{display:none!important}
}

/* Simple View (body.simple-view) removed v2.9.0 — comfort mode deprecated platform-wide; lock-out moved to role-based gating */

/* ══════════════════════════════════════════════
   COMFORT MODE (body.comfort) — v2.19.0, design-critique F1 (ticket 54b06237)
   Per-user DISPLAY preference (settings.display_prefs blob; the consuming spoke
   reads it at boot and stamps the class). Ergonomics ONLY — the successor to the
   deleted simple-view WITHOUT its .power-user hiding: no features hidden, no
   permissions semantics (lockout stays role-based). Pilot consumer: Office.
   ══════════════════════════════════════════════ */
/* Type: base 14→16 effective via token remap — no per-element edits */
body.comfort{
  --fs-xs:12.5px;--fs-sm:14px;--fs-md:15px;--fs-base:16px;--fs-lg:17px;
  --fs-xl:18px;--fs-2xl:22px;--fs-3xl:26px;--fs-kpi:34px;
}
/* 48px touch floor on interactive chrome (buttons, inputs, selects, nav) */
body.comfort .bt,body.comfort .btn,body.comfort .fi,body.comfort .fs{min-height:48px}
body.comfort .nb{min-height:48px;padding-top:12px;padding-bottom:12px}
body.comfort .bn-btn{min-height:48px}
body.comfort .pill-btn,body.comfort .tab-btn{min-height:44px}
/* Wider row/cell padding — taller, easier-to-hit table rows */
body.comfort td,body.comfort th{padding-top:14px;padding-bottom:14px}
body.comfort .mo-c{line-height:1.55}
/* Modal/toast copy breathes a little more */
body.comfort .toast,body.comfort .toast-v2{font-size:var(--fs-lg)}

/* ── File System (job_files) ── */
.file-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px;padding:8px 0}
.file-card{background:var(--bg1);border:1px solid var(--brd);border-radius:var(--r);overflow:hidden;transition:box-shadow .15s}
.file-card:hover{box-shadow:0 2px 8px rgba(0,0,0,.2)}
.file-thumb{width:100%;height:100px;object-fit:cover;display:block;background:var(--bg3)}
.file-thumb-placeholder{width:100%;height:100px;display:flex;align-items:center;justify-content:center;background:var(--bg3);font-size:28px}
.file-info{padding:6px 8px}
.file-name{font-size:var(--fs-xs);font-weight:600;color:var(--t1);word-break:break-word;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.file-meta{font-size:var(--fs-xs);color:var(--t3);margin-top:2px}
.file-cat{display:inline-block;padding:1px 6px;border-radius:8px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.3px;background:var(--bg4);color:var(--t2);margin-top:3px}
.file-actions{display:flex;border-top:1px solid var(--brd)}
.file-actions button{flex:1;padding:6px 0;border:0;background:none;font-size:var(--fs-xs);font-weight:600;cursor:pointer;font-family:inherit;color:var(--t2);transition:.15s}
.file-actions button:hover{background:var(--bg3)}
.file-actions button:not(:last-child){border-right:1px solid var(--brd)}
.file-actions button.file-del{color:var(--red)}
.file-upload-zone{border:2px dashed var(--brd);border-radius:var(--r);padding:20px;text-align:center;cursor:pointer;transition:.15s;background:var(--bg1)}
.file-upload-zone:hover,.file-upload-zone.dragover{border-color:var(--acc);background:var(--acc-d)}
.file-upload-zone input[type="file"]{display:none}
@media(max-width:768px){.file-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr))}.file-thumb,.file-thumb-placeholder{height:80px}}

/* ── Report a Problem (dw-report.js companion) ── */
.report-fab{position:fixed;bottom:28px;right:28px;width:52px;height:52px;border-radius:14px;background:var(--bg2);border:1px solid var(--brd);color:var(--t3);font-size:20px;cursor:pointer;z-index:89;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 24px rgba(0,0,0,.4);transition:all .25s cubic-bezier(.16,1,.3,1)}
.report-fab:hover{background:var(--bg3);border-color:var(--brd2);color:var(--t1);transform:translateY(-2px);box-shadow:0 8px 32px rgba(0,0,0,.5)}
.report-fab .report-tip{position:absolute;right:62px;top:50%;transform:translateY(-50%);background:var(--bg3);border:1px solid var(--brd);border-radius:8px;padding:8px 14px;font-size:var(--fs-sm);font-weight:500;color:var(--t2);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .2s}
.report-fab:hover .report-tip{opacity:1}
@media(max-width:768px){.report-fab{bottom:76px;right:16px;width:48px;height:48px;font-size:18px}}
.report-overlay{position:fixed;inset:0;z-index:var(--z-overlay);background:rgba(0,0,0,.6);backdrop-filter:blur(4px);display:none;align-items:center;justify-content:center}
.report-overlay.show{display:flex}
.report-modal{background:var(--bg2);border:1px solid var(--brd);border-radius:16px;width:420px;max-width:calc(100vw - 32px);padding:28px;position:relative;box-shadow:0 24px 80px rgba(0,0,0,.5);max-height:calc(100vh - 32px);overflow-y:auto}
.report-modal-close{position:absolute;top:16px;right:16px;width:32px;height:32px;border-radius:8px;background:0;border:1px solid transparent;color:var(--t3);cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;transition:all .15s}
.report-modal-close:hover{background:var(--bg3);border-color:var(--brd);color:var(--t1)}
.report-type-toggle{display:flex;gap:8px;margin-bottom:20px}
.report-type-btn{flex:1;padding:12px;border-radius:10px;border:1px solid var(--brd);background:var(--bg1);color:var(--t3);font-size:var(--fs-base);font-weight:600;cursor:pointer;text-align:center;font-family:inherit;transition:all .15s}
.report-type-btn:hover{border-color:var(--brd2);color:var(--t2)}
.report-type-btn.active-bug{border-color:#EF4444;background:#EF444411;color:#EF4444}
.report-type-btn.active-suggestion{border-color:#3B82F6;background:#3B82F611;color:#3B82F6}
.report-type-btn.active-sev-critical{border-color:#EF4444;background:#EF444411;color:#EF4444}
.report-type-btn.active-sev-high{border-color:#F97316;background:#F9731611;color:#F97316}
.report-type-btn.active-sev-med{border-color:#EAB308;background:#EAB30811;color:#EAB308}
.report-type-btn.active-sev-low{border-color:#22C55E;background:#22C55E11;color:#22C55E}
.report-spoke-tag{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:6px;background:var(--bg3);border:1px solid var(--brd);font-size:var(--fs-sm);font-weight:600;color:var(--t2);margin-bottom:20px}
.report-spoke-dot{width:6px;height:6px;border-radius:50%;background:var(--t2)}
.report-submit{width:100%;padding:14px;border-radius:10px;border:none;background:var(--acc);color:var(--acc-ink,#000);font-size:var(--fs-lg);font-weight:700;cursor:pointer;font-family:inherit;transition:all .15s}
.report-submit:hover{filter:brightness(1.15)}
.report-submit:disabled{opacity:.5;cursor:not-allowed}
.report-err{font-size:var(--fs-sm);color:var(--red);margin-top:6px;display:none}

/* ── Print base ── */
@media print {
  body{background:#fff;color:#000;display:block;font-size:var(--fs-base)}
  .sb,.stats-bar,.tb,.toast,.toast-wrap,.mo,.bottom-nav,.cmd-overlay,.no-print,.right-now-action{display:none!important}
  .mn{overflow:visible}
  .ct{padding:0;overflow:visible}
  .cd,.stat-card,.att,.act-card,.data-card{border:1px solid #ccc;background:#fff;break-inside:avoid;box-shadow:none}
  .kpi-v,.stat-card-value{color:#000}
}

/* ════════════════════════════════════════════════════════════
   v2.10.0 — OPT-IN DRAFTING THEME  (body.theme-drafting)
   Light "drafting station" skin: pure token remap + faint blueprint grid
   + softened shadows + an accent underline on cards. Re-skins every
   token-driven component. Per-spoke --acc preserved. Spacing/type/radius
   tokens untouched (density identical). Spokes WITHOUT .theme-drafting are
   completely unaffected — every rule below is scoped under the class.
   ════════════════════════════════════════════════════════════ */
body.theme-drafting, .dw-vellum{
  /* v2.13.2 (#4): .dw-vellum lets a NON-deck surface (Portal Mission Control home) opt into
     the shared drafting palette without the deck chrome — so Portal derives from the master.
     The blueprint-grid background below also applies to .dw-vellum, but a surface with its own
     grid (Portal's .mc-home) overrides it by source order. body.theme-drafting deck spokes: unchanged. */
  /* backgrounds → vellum */
  --bg0:#e7edf3;--bg1:#ffffff;--bg2:#f3f7fb;--bg3:#eef3f9;--bg4:#e3ebf5;
  /* borders → blue-faint technical lines (matched to Portal Mission Control for crisp cards on vellum) */
  --brd:#a9c0e6;--brd2:#8fb0dc;
  /* typography → ink */
  --t1:#13243a;--t2:#3a4b61;--t3:#5d6c80;
  /* semantic palette — darkened for contrast on light */
  --grn:#15803d;--red:#dc2626;--blu:#2563EB;--org:#EA580C;--pur:#9333EA;--amb:#c2740a;--cyan:#0891b2;--install-color:#0284C7;
  /* shadows → soft + cool */
  --shadow-card:0 1px 4px rgba(20,40,75,.10);
  --shadow-hover:0 5px 16px rgba(20,40,75,.13);
  --shadow-modal:0 18px 48px rgba(20,40,75,.22);
  /* drafting ink (for optional chrome) */
  --dwd-ink:#2563EB;--dwd-faint:#a9c0e6;
  /* faint blueprint grid */
  background-image:
    linear-gradient(rgba(37,99,235,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(37,99,235,.05) 1px,transparent 1px),
    linear-gradient(rgba(37,99,235,.11) 1px,transparent 1px),
    linear-gradient(90deg,rgba(37,99,235,.11) 1px,transparent 1px);
  background-size:24px 24px,24px 24px,120px 120px,120px 120px;
}
/* signature drafting card: accent underline (palette-only spokes); deck spokes get a LEFT spine via .dw-deck below */
body.theme-drafting .cd{box-shadow:inset 0 -3px 0 var(--acc),var(--shadow-card);}
body.theme-drafting .cd:hover{box-shadow:inset 0 -3px 0 var(--acc),var(--shadow-hover);}

/* ════════════════════════════════════════════════════════════
   v2.11.0 — COMMAND DECK chrome (Mission Control top-deck)
   Shared styling for the dw-deck.js header + the drafting drawing-sheet,
   sharp corners, and closed quick-stats box. Extracted verbatim from the
   approved Production v3.5.0. Pairs with dw-deck.js v1.0.0.
   GATING (v2.11.1): body-affecting deck rules (layout, .mn, .cd, .stats-bar, .tb)
   are scoped to body.theme-drafting.dw-deck so palette-only theme-drafting spokes
   (still on a sidebar) are NOT flipped to column layout. Deck-markup rules
   (.dw-sheet/.deck-head/.deck-tb) match deck markup only → stay unscoped.
   Opt in with class="theme-drafting dw-deck".
   ════════════════════════════════════════════════════════════ */
/* deck layout: top-down (no left rail), vellum gutter, hard edges — deck spokes only */
body.theme-drafting.dw-deck{flex-direction:column;padding:10px;--r:0;--r-md:0;--r-lg:0;}

/* the solid "drawing sheet" wrapper — blueprint grid frames the edges */
.dw-sheet{flex:1;min-height:0;display:flex;flex-direction:column;background:var(--bg1);border:1px solid #c4d0e0;box-shadow:0 1px 0 #fff inset,0 10px 34px rgba(20,40,75,.12);overflow:hidden;position:relative;padding:7px 18px 16px;}
.dw-sheet::before{content:'';position:absolute;inset:6px;border:1px solid var(--brd);pointer-events:none;z-index:0;}

/* command-deck header (rendered by dw-deck.js) */
.deck-head{display:flex;align-items:stretch;background:transparent;border-bottom:1px solid var(--brd);min-height:64px;}
.deck-head .sb-brand{display:flex;align-items:center;padding:6px 18px 6px 0;border-right:1px solid var(--brd);flex-shrink:0;margin:11px 0;}
.deck-head .spoke-logo{width:auto;height:50px;}
.deck-head .sb-nav{display:flex;align-items:stretch;flex:1;padding:0;overflow-x:auto;gap:0;}
.deck-head .sb-nav .nb{width:auto;border-radius:0;padding:0 16px;border-bottom:3px solid transparent;align-items:center;white-space:nowrap;position:relative;color:var(--t2);}
.deck-head .sb-nav .nb:hover{background:var(--bg2);color:var(--t1);}
.deck-head .sb-nav .nb.on{background:var(--acc);color:var(--acc-ink,#000);border-bottom-color:transparent;font-weight:700;}
.deck-head .sb-nav .nb .ic{opacity:.9;filter:none;}
.deck-head .sb-nav .nb.on .ic{opacity:1;filter:brightness(0);}  /* dark-accent spokes (purple/slate): override to brightness(0) invert(1) */
.deck-head .sb-nav .nb .nav-badge{position:static;margin-left:6px;}
/* titleblock (right) */
.deck-tb{display:grid;grid-template-columns:max-content max-content max-content max-content;align-items:stretch;border:1.5px solid var(--brd);flex-shrink:0;margin:11px 0;}
.deck-tb .tbc{padding:8px 14px;border-right:1px solid #dbe3ee;border-bottom:1px solid #dbe3ee;display:flex;flex-direction:column;justify-content:center;}
.deck-tb .tbc.full{grid-column:1/-1;border-right:none;}
.deck-tb .tbc.tb-end{border-right:none;}
.deck-tb .k{font-family:var(--mono);font-size:8px;letter-spacing:1.5px;color:var(--blu);text-transform:uppercase;opacity:.85;}
.deck-tb .v{font-family:var(--mono);font-size:11px;color:var(--t1);margin-top:1px;font-weight:500;white-space:nowrap;display:flex;align-items:center;gap:6px;}
@media(max-width:900px){.deck-tb{display:none;}.deck-head .sb-brand{padding:6px 12px;}.deck-head .spoke-logo{height:26px;}}
/* v2.19.1 (ticket 0e401818): phones (≤480px) clipped the last deck tab ("Histori…" on Analytics at 443px,
   gone entirely at 375px). Tighter brand/tab/flag spacing gives the tab row ~90px back; the row still
   scrolls sideways (no scrollbar) when a spoke has more tabs than fit. Desktop/tablet unchanged. */
@media(max-width:480px){.deck-head .sb-brand{padding:6px 8px 6px 0;}.deck-head .spoke-logo{height:20px;}.deck-head .sb-nav{scrollbar-width:none;-webkit-overflow-scrolling:touch;}.deck-head .sb-nav::-webkit-scrollbar{display:none;}.deck-head .sb-nav .nb{padding:0 8px;gap:5px;font-size:var(--fs-md);}.deck-head #dw-deck-report{margin:0 0 0 6px!important;}}

/* context / quick-stats bar → closed box (deck spokes only) */
body.theme-drafting.dw-deck .stats-bar{background:var(--bg2)!important;border-bottom:1px solid var(--brd);border-left:1px solid var(--brd);border-right:1px solid var(--brd);}
body.theme-drafting.dw-deck .stats-bar .stat{color:var(--t2);}
body.theme-drafting.dw-deck .stats-bar .stat-label{color:var(--t3);}
body.theme-drafting.dw-deck .stats-bar .stat-sep{background:var(--brd);}
body.theme-drafting.dw-deck .stats-bar .stat-val{color:var(--t1);}
body.theme-drafting.dw-deck .stats-bar .stat-val.v-grn{color:var(--grn);}
body.theme-drafting.dw-deck .stats-bar .stat-val.v-amb{color:var(--amb);}
body.theme-drafting.dw-deck .stats-bar .stat-val.v-red{color:var(--red);}
body.theme-drafting.dw-deck .tb{background:transparent;}

/* deck card: single LEFT accent spine (overrides the palette underline) — deck spokes only */
body.theme-drafting.dw-deck .cd{box-shadow:var(--shadow-card);border-left:3px solid var(--acc);}
body.theme-drafting.dw-deck .cd:hover{box-shadow:var(--shadow-hover);}

/* ════════════════════════════════════════════════════════════
   v2.14.0 — DARK MODE for the drafting deck (body.theme-drafting WITHOUT .light)
   "Drafting station at night": soft dark-slate surfaces, off-white ink, a quiet
   blueprint grid, gently brightened semantics. Token remap + 2 chrome overrides
   for the hardcoded light hexes in .dw-sheet / .deck-tb that tokens do not cover.
   Every deck spoke's Dark Mode toggle flips body.light, so this lights up platform-
   wide; --acc is per-spoke and falls back to the brighter :root value when .light
   drops. Tuned gentle for eye comfort (lifted off pure-black; off-white, not white).
   ════════════════════════════════════════════════════════════ */
body.theme-drafting:not(.light){
  /* surfaces -> dark slate (lifted off black for comfort) */
  --bg0:#1a232f;--bg1:#232e3c;--bg2:#2b3746;--bg3:#28333f;--bg4:#313e4f;
  /* technical lines -> muted slate-blue */
  --brd:#3b4b62;--brd2:#48596f;
  /* ink -> off-white (not pure white, avoids glare) */
  --t1:#d8e1ec;--t2:#a4b4c7;--t3:#76879b;
  /* semantic palette -> gently brightened for dark */
  --grn:#48d191;--red:#f0837a;--blu:#74aaf0;--org:#f59e6a;--pur:#bd92e6;--amb:#e7b65c;--cyan:#52c9d6;--install-color:#5aa9e8;
  /* shadows -> deep + soft (no white inset on dark) */
  --shadow-card:0 1px 3px rgba(0,0,0,.35);
  --shadow-hover:0 6px 18px rgba(0,0,0,.45);
  --shadow-modal:0 18px 48px rgba(0,0,0,.60);
  --dwd-ink:#74aaf0;--dwd-faint:#3b4b62;
  /* quiet blueprint grid on the dark gutter */
  background-image:
    linear-gradient(rgba(116,170,240,.035) 1px,transparent 1px),
    linear-gradient(90deg,rgba(116,170,240,.035) 1px,transparent 1px),
    linear-gradient(rgba(116,170,240,.06) 1px,transparent 1px),
    linear-gradient(90deg,rgba(116,170,240,.06) 1px,transparent 1px);
}
/* chrome: the two hardcoded light hexes that tokens do not reach */
body.theme-drafting:not(.light) .dw-sheet{border-color:#33425a;box-shadow:0 10px 30px rgba(0,0,0,.40);}
body.theme-drafting:not(.light) .deck-tb .tbc{border-right-color:#2f3e52;border-bottom-color:#2f3e52;}
/* SHARP corners everywhere (drafting is hard-edged); intentional circles preserved — deck spokes only */
body.theme-drafting.dw-deck .mn *,body.theme-drafting.dw-deck .deck-head *,body.theme-drafting.dw-deck .mo *{border-radius:0!important;}
body.theme-drafting.dw-deck .mat-step-dot,body.theme-drafting.dw-deck .mat-step-next,body.theme-drafting.dw-deck .sb-user-avatar,body.theme-drafting.dw-deck .report-spoke-dot,body.theme-drafting.dw-deck .act-feed-dot,body.theme-drafting.dw-deck .crew-av,body.theme-drafting.dw-deck .tip,body.theme-drafting.dw-deck .spinner,body.theme-drafting.dw-deck .theme-sw-thumb,body.theme-drafting.dw-deck [style*="border-radius:50%"]{border-radius:50%!important;}

/* ═══════════════════════════════════════════════════════════════════════
 * MISSION CONTROL dashboard primitives (v2.12.0) — shared by all deck spokes
 * Extracted verbatim from Production/Estimating/Sales MC dashboards.
 * Spoke-specific pipeline boards (.spb/.sboard/etc.) and bespoke panels
 * (e.g. Sales .mc-meas field-measures) stay LOCAL in each spoke.
 * ═══════════════════════════════════════════════════════════════════════ */
/* section label chip */
body.theme-drafting.dw-deck .pv-tag{display:inline-block;font-family:var(--mono);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:#fff;background:var(--blu);padding:2px 10px;margin:0 0 10px;}
/* vitals strip */
body.theme-drafting.dw-deck .pvitals{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--brd);border-left:3px solid var(--acc);background:var(--bg2);margin-bottom:16px;box-shadow:var(--shadow-card);}
body.theme-drafting.dw-deck .pvit{padding:12px 15px;border-right:1px dashed var(--brd);}
body.theme-drafting.dw-deck .pvit:last-child{border-right:none;}
body.theme-drafting.dw-deck .pvl{font-family:var(--mono);font-size:9px;letter-spacing:1.5px;text-transform:uppercase;color:var(--t3);}
body.theme-drafting.dw-deck .pvv{font-family:var(--mono);font-weight:800;font-size:26px;line-height:1;margin:6px 0 3px;color:var(--t1);}
body.theme-drafting.dw-deck .pvit.warn .pvv{color:var(--amb);}
body.theme-drafting.dw-deck .pvit.crit .pvv{color:var(--red);}
body.theme-drafting.dw-deck .pvit.good .pvv{color:var(--grn);}
body.theme-drafting.dw-deck .pvs{font-family:var(--mono);font-size:10px;color:var(--t2);}
@media(max-width:760px){body.theme-drafting.dw-deck .pvitals{grid-template-columns:repeat(3,1fr);}}
@media(max-width:480px){body.theme-drafting.dw-deck .pvitals{grid-template-columns:repeat(2,1fr);}}
/* three-up bottom grid */
body.theme-drafting.dw-deck .mc-three{display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:14px;margin-bottom:16px;}
@media(max-width:980px){body.theme-drafting.dw-deck .mc-three{grid-template-columns:1fr;}}
body.theme-drafting.dw-deck .mc-three .cd h3{margin:0 0 10px;font-size:13px;}
body.theme-drafting.dw-deck .mc-three .cd h3 .lnk{font-size:10px;color:var(--acc);cursor:pointer;font-weight:700;float:right;letter-spacing:.3px;} /* v2.13.1: card-header action link (A/R -> / Invoice -> / Pay ->), extracted from Money (#7) */
/* needs-attention rows */
body.theme-drafting.dw-deck .mc-na{display:flex;gap:9px;align-items:flex-start;padding:7px 0;border-top:1px solid var(--brd);}
body.theme-drafting.dw-deck .mc-na:first-of-type{border-top:0;}
body.theme-drafting.dw-deck .mc-na .ic2{width:22px;height:22px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:12px;}
body.theme-drafting.dw-deck .mc-na .ic2.red{background:rgba(220,38,38,.12);color:var(--red);}
body.theme-drafting.dw-deck .mc-na .ic2.amb{background:rgba(194,116,10,.14);color:var(--amb);}
body.theme-drafting.dw-deck .mc-na .tx{font-size:12px;color:var(--t2);line-height:1.4;}
body.theme-drafting.dw-deck .mc-na .tx b{color:var(--t1);}
/* activity feed rows */
body.theme-drafting.dw-deck .mc-feed{display:flex;gap:8px;align-items:center;padding:6px 0;font-size:11.5px;color:var(--t2);}
body.theme-drafting.dw-deck .mc-feed b{color:var(--t1);}
body.theme-drafting.dw-deck .mc-feed .fdot{width:8px;height:8px;flex-shrink:0;}

/* ═══════════════════════════════════════════════════════════════════════
 * SHARED TIER-2 SUB-STRIP (v2.13.0) — the ONE .dw-substrip that replaces the
 * per-spoke .an-substrip / .adm-substrip / .wb-substrip local copies. CSS lifted
 * verbatim from those (zero visual change) with the active-icon invert moved out
 * to the .dark-acc modifier below. Users in 2026-10: HQ (books, index, setup, tasks) and Office Takeoff.
 * ═══════════════════════════════════════════════════════════════════════ */
body.theme-drafting.dw-deck .dw-substrip{display:flex;align-items:stretch;gap:0;background:var(--bg2);border:1px solid var(--brd);border-top:0;overflow-x:auto;scrollbar-width:thin;}
body.theme-drafting.dw-deck .dw-substrip .nb{display:flex;align-items:center;gap:6px;padding:0 13px;height:38px;width:auto;flex-shrink:0;border:0;border-right:1px solid var(--brd);border-radius:0;background:0;color:var(--t2);font-size:12px;font-weight:500;white-space:nowrap;cursor:pointer;font-family:inherit;text-align:left;transition:background .12s,color .12s;}
body.theme-drafting.dw-deck .dw-substrip .nb:hover{background:var(--bg1);color:var(--t1);}
body.theme-drafting.dw-deck .dw-substrip .nb.on{background:var(--acc);color:var(--acc-ink);font-weight:700;}
body.theme-drafting.dw-deck .dw-substrip .nb .ic{font-size:13px;filter:none;width:auto;height:auto;}
body.theme-drafting.dw-deck .dw-substrip .nb.on .ic{filter:brightness(0);} /* light-accent default; .dark-acc overrides to white below */
/* sub-strip group label (e.g. "Reports", "Command · admin") */
body.theme-drafting.dw-deck .dw-grp{display:flex;align-items:center;padding:0 12px;font-family:var(--mono);font-size:9px;font-weight:700;letter-spacing:1.5px;text-transform:uppercase;color:var(--t3);border-right:1px solid var(--brd);background:var(--bg3);flex-shrink:0;white-space:nowrap;}
/* dark-accent pages (body.dark-acc: HQ, Office Takeoff, Portal Library, SSI Portal, the Production and Sales fallbacks): white active-tab icon on the accent fill — Tier-1 deck tabs + Tier-2 sub-strip */
body.theme-drafting.dw-deck.dark-acc .deck-head .sb-nav .nb.on .ic,
body.theme-drafting.dw-deck.dark-acc .dw-substrip .nb.on .ic{filter:brightness(0) invert(1);}

/* ═══════════════════════════════════════════════════════════════════════
 * v2.20.0 - THE ONE LOOK: body.theme-warm ("Warm and quiet", Dillon 2026-09-28)
 * Spec: MC-DESIGN-LANGUAGE.md section 9. Plan: ONE-LOOK-PLAN.md (hub). Mockup: Mockups/index-one-look-mockup-2026-09-28.html.
 * Office's paper and ink in a plain, flat structure: no side stripes, no shadows, no grain, no blueprint grid,
 * one blue for the main button (#3F6DB5), slate for status "info", sentence-case labels, 8px cards / 6px controls.
 * REPLACES the drafting deck on a page: the page drops "theme-drafting dw-deck" and takes "theme-warm", and
 * mounts dw-tabs.js (the tab row) instead of dw-deck.js. No drafting rule applies to it any more.
 * ADDITIVE ONLY: every rule below names .theme-warm, so a page without the class renders exactly as before.
 * Specificity: tokens sit on "html body.theme-warm" (0,1,2) so they beat a page's own body.light accent (0,1,1);
 * tab and chip rules sit at (0,3,2)+ so they beat the legacy body.light:not(.theme-drafting) .nb block (0,3,1)+.
 * Prints are separate documents and do not change.
 * ═══════════════════════════════════════════════════════════════════════ */
html body.theme-warm{
  color-scheme:light;
  --bg0:#F6F1E8;--bg1:#FFFDF8;--bg2:#FFFDF8;--bg3:#FBF6EC;--bg4:#EFE7D7;
  --brd:#E8DFCF;--brd2:#DDD0BA;
  --t1:#2B2722;--t2:#5F564C;--t3:#766B5E;
  --grn:#33693F;--grn-d:#E4EFE3;--red:#A8322A;--red-d:#F4E1DD;--amb:#8A5D0F;--amb-d:#F6EBD3;
  --blu:#4F5E72;--blu-d:#E6E9EE;--org:#9A4816;--org-d:#F5E3D4;--pur:#6A4A93;--pur-d:#ECE5F3;
  --cyan:#1F6E80;--cyan-d:#DDEEF1;--install-color:#2B6A8A;--install-d:#E0ECF2;
  --acc:#3F6DB5;--acc-d:#E3EAF5;--acc-hover:#2F5A99;--focus:#3F6DB5;--acc-ink:#FFFFFF;
  --prog-default:#9A8E7E;--prog-default-end:#C9BEAD;
  --r:6px;--r-md:8px;--r-lg:12px;
  --sans:system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --mono:'JetBrains Mono',Consolas,monospace;
  --shadow-card:none;--shadow-hover:0 6px 18px rgba(60,45,30,.12);--shadow-modal:0 18px 48px rgba(40,30,20,.22);
  --dwd-ink:#3F6DB5;--dwd-faint:#DDD0BA;
  --ls-label:0;--ls-wide:0;--ls-sec:.02em;--ls-brand:.06em;
  flex-direction:column;padding:0;background-color:var(--bg0);background-image:none;color:var(--t1);font-family:var(--sans);
}
/* dark: warm espresso; buttons turn light blue with dark text (one blue cannot pass as both a white-text fill and a link on dark) */
html body.theme-warm:not(.light){
  color-scheme:dark;
  --bg0:#1C1916;--bg1:#231F1B;--bg2:#28231F;--bg3:#2E2924;--bg4:#38322B;
  --brd:#3A332C;--brd2:#4A4239;
  --t1:#EDE6DA;--t2:#C4BAAB;--t3:#9E9384;
  --grn:#7CC08E;--grn-d:rgba(124,192,142,.14);--red:#EE8A7E;--red-d:rgba(238,138,126,.14);--amb:#E2B45E;--amb-d:rgba(226,180,94,.14);
  --blu:#A3AFC0;--blu-d:rgba(163,175,192,.14);--org:#EFA36B;--org-d:rgba(239,163,107,.14);--pur:#C1A5E8;--pur-d:rgba(193,165,232,.14);
  --cyan:#6FC6D4;--cyan-d:rgba(111,198,212,.14);--install-color:#82BADD;--install-d:rgba(130,186,221,.14);
  --acc:#7FA3DE;--acc-d:rgba(127,163,222,.16);--acc-hover:#96B4E5;--focus:#96B4E5;--acc-ink:#101418;
  --prog-default:#6E6458;--prog-default-end:#8F8474;
  --shadow-hover:0 6px 18px rgba(0,0,0,.40);--shadow-modal:0 18px 48px rgba(0,0,0,.55);
  --dwd-ink:#7FA3DE;--dwd-faint:#4A4239;
}
/* the drawing sheet a migrated page may still wrap its content in: flat, no frame */
html body.theme-warm .dw-sheet{background:transparent;border:0;box-shadow:none;padding:0}
html body.theme-warm .dw-sheet::before{display:none}

/* the tab row (dw-tabs.js): quiet underline tabs, then the action slot, then one line of small meta text */
html body.theme-warm .dw-tabbar{display:flex;align-items:stretch;gap:8px;flex-shrink:0;min-height:46px;padding:0 24px;background:var(--bg1);border-bottom:1px solid var(--brd)}
html body.theme-warm .dwt-tabs{display:flex;align-items:stretch;gap:2px;flex:1 1 auto;min-width:0;overflow-x:auto;scrollbar-width:none}
html body.theme-warm .dwt-tabs::-webkit-scrollbar{display:none}
html body.theme-warm .dw-tabbar .nb{width:auto;display:inline-flex;align-items:center;gap:6px;margin:0;padding:0 12px;border:0;border-bottom:2px solid transparent;border-radius:0;background:transparent;color:var(--t2);font:600 var(--fs-base)/1.2 var(--sans);white-space:nowrap;cursor:pointer}
html body.theme-warm .dw-tabbar .nb:hover{background:transparent;color:var(--t1)}
html body.theme-warm .dw-tabbar .nb.on{background:transparent;color:var(--t1);font-weight:700;border-bottom-color:var(--t1)}
html body.theme-warm .dw-tabbar .nb .ic{display:none}
html body.theme-warm .dw-tabbar .nav-badge{position:static;display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--amb-d);color:var(--amb);font:700 var(--fs-xs)/1 var(--sans)}
html body.theme-warm .dwt-acts{display:flex;align-items:center;gap:6px;flex-shrink:0}
html body.theme-warm .dwt-acts:empty{display:none}
html body.theme-warm .dwt-meta{display:flex;align-items:center;gap:14px;flex-shrink:0;margin-left:auto;color:var(--t3);font:500 var(--fs-sm)/1.2 var(--sans);white-space:nowrap}
html body.theme-warm .dwt-meta #sb-status{display:inline-flex;align-items:center;gap:5px;cursor:pointer}
html body.theme-warm .dwt-meta #sb-status-dot{color:var(--grn);font-size:9px;line-height:1}
html body.theme-warm .dwt-meta #sb-version{font-family:var(--mono);font-size:var(--fs-xs)}
html body.theme-warm .dwt-report{align-self:center;flex:0 0 auto;width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--brd);border-radius:var(--r);background:transparent;color:var(--t2);font-size:14px;line-height:1;cursor:pointer}
html body.theme-warm .dwt-report:hover{background:var(--bg3);color:var(--t1)}
@media(max-width:640px){html body.theme-warm .dw-tabbar{padding:0 8px}html body.theme-warm .dwt-meta{display:none}}

/* the chip row: the pages inside a tab. dw-tabs.js .dwt-chips, or a page's own .dw-substrip */
html body.theme-warm .dwt-chips,html body.theme-warm .dw-substrip{display:flex;align-items:center;flex-wrap:wrap;gap:4px;flex-shrink:0;padding:10px 24px 2px;background:transparent;border:0;overflow:visible}
html body.theme-warm .dwt-chips .nb,html body.theme-warm .dw-substrip .nb{width:auto;height:auto;min-height:32px;display:inline-flex;align-items:center;gap:6px;margin:0;padding:5px 11px;border:1px solid transparent;border-radius:var(--r);background:transparent;color:var(--t2);font:500 var(--fs-md)/1.2 var(--sans);white-space:nowrap;cursor:pointer}
html body.theme-warm .dwt-chips .nb:hover,html body.theme-warm .dw-substrip .nb:hover{background:var(--bg3);color:var(--t1)}
html body.theme-warm .dwt-chips .nb.on,html body.theme-warm .dw-substrip .nb.on{background:var(--bg1);border-color:var(--brd2);color:var(--t1);font-weight:700}
html body.theme-warm .dwt-chips .nb .ic,html body.theme-warm .dw-substrip .nb .ic{display:none}
html body.theme-warm .dwt-chips .dwt-gap{width:10px}
html body.theme-warm .dwt-chips .nb.adm::after{content:'admin';margin-left:2px;color:var(--t3);font-size:var(--fs-xs);font-weight:600}
html body.theme-warm .dw-grp{display:inline-flex;align-items:center;padding:0 4px 0 10px;background:transparent;border:0;color:var(--t3);font:600 var(--fs-xs)/1 var(--sans);text-transform:none;letter-spacing:0}
@media(max-width:640px){html body.theme-warm .dwt-chips,html body.theme-warm .dw-substrip{padding:8px 8px 2px}}

/* base components, the quiet way */
html body.theme-warm .cd{background:var(--bg2);border:1px solid var(--brd);border-radius:var(--r-md);box-shadow:none}
html body.theme-warm .cd:hover{box-shadow:none}
html body.theme-warm .cd.hero{border-top:1px solid var(--brd)}
html body.theme-warm .fl{text-transform:none;letter-spacing:0;font-size:var(--fs-sm);font-weight:600;color:var(--t2)}
html body.theme-warm th{text-transform:none;letter-spacing:0;font-size:var(--fs-sm);font-weight:600;color:var(--t2);background:var(--bg3)}
html body.theme-warm .kpi-l,html body.theme-warm .st,html body.theme-warm .cmd-sec,html body.theme-warm .right-now-label,html body.theme-warm .sched-day-name,html body.theme-warm .stat-label{text-transform:none;letter-spacing:0}
html body.theme-warm .tot-row{border-top-color:var(--t2)}
html body.theme-warm .bt{background:var(--bg1);border-color:var(--brd2);border-radius:var(--r)}
html body.theme-warm .bt:hover{background:var(--bg3);border-color:var(--t3)}
html body.theme-warm .bt-p,html body.theme-warm .btn-primary,html body.theme-warm .btn-accent{background:var(--acc);border-color:var(--acc);color:var(--acc-ink)}
html body.theme-warm .bt-p:hover,html body.theme-warm .btn-primary:hover,html body.theme-warm .btn-accent:hover{background:var(--acc-hover);border-color:var(--acc-hover);opacity:1;filter:none}
html body.theme-warm .btn-secondary{background:var(--bg1)}
html body.theme-warm .bd,html body.theme-warm .pill,html body.theme-warm .badge{font-family:var(--sans);letter-spacing:0;border-radius:999px}
html body.theme-warm .bd{text-transform:none}
html body.theme-warm .stat-card:hover,html body.theme-warm .att:hover{transform:none;box-shadow:none}
html body.theme-warm .right-now{border-left:1px solid var(--brd)}
html body.theme-warm .right-now:hover,html body.theme-warm .sched-day:hover,html body.theme-warm .act-card:hover{box-shadow:none}
/* attention rows: the colored side stripe becomes a colored dot (no side stripes) */
html body.theme-warm .att{border-left:1px solid var(--brd)}
html body.theme-warm .att::before{content:'';flex:none;width:9px;height:9px;border-radius:50%;background:var(--t3)}
html body.theme-warm .att.urgent::before{background:var(--red)}
html body.theme-warm .att.warning::before{background:var(--amb)}
html body.theme-warm .att.info::before{background:var(--blu)}
html body.theme-warm .att.success::before{background:var(--grn)}
html body.theme-warm .sched-job{border-left:0}
/* the sanctioned readout strips (Money A/R, HQ Historical): the legacy body.light .stats-bar paints them black; warm keeps them light */
html body.theme-warm .stats-bar{background:var(--bg1);border-bottom:1px solid var(--brd);color:var(--t2)}
html body.theme-warm .stats-bar .stat{color:var(--t2)}
html body.theme-warm .stats-bar .stat-label{color:var(--t3)}
html body.theme-warm .stats-bar .stat-sep{background:var(--brd)}
html body.theme-warm .stats-bar .stat-val{color:var(--t1)}
html body.theme-warm .stats-bar .stat-val.v-grn{color:var(--grn)}
html body.theme-warm .stats-bar .stat-val.v-amb{color:var(--amb)}
html body.theme-warm .stats-bar .stat-val.v-red{color:var(--red)}
html body.theme-warm .stats-bar .stat-val.v-blu{color:var(--blu)}
html body.theme-warm .stats-bar .stat-val.v-pur{color:var(--pur)}
html body.theme-warm .stats-bar .stat-val.v-acc{color:var(--acc)}

/* the dashboard primitives (they are gated to the deck elsewhere), restyled: plain numbers, flat cards */
html body.theme-warm .pv-tag{display:inline-block;margin:0 0 8px;padding:0;background:transparent;color:var(--t2);font:600 var(--fs-sm)/1.3 var(--sans);letter-spacing:0;text-transform:none}
html body.theme-warm .pvitals{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:20px;margin-bottom:16px;padding:4px 0;border:0;background:transparent;box-shadow:none}
html body.theme-warm .pvit{min-width:0;padding:0;border:0}
html body.theme-warm .pvl{display:block;color:var(--t2);font:500 var(--fs-md)/1.3 var(--sans);letter-spacing:0;text-transform:none}
html body.theme-warm .pvv{display:block;margin:4px 0 2px;color:var(--t1);font:600 var(--fs-3xl)/1.1 var(--sans);font-variant-numeric:tabular-nums}
html body.theme-warm .pvit.warn .pvv{color:var(--amb)}
html body.theme-warm .pvit.crit .pvv{color:var(--red)}
html body.theme-warm .pvit.good .pvv{color:var(--grn)}
html body.theme-warm .pvs{display:block;color:var(--t3);font:400 var(--fs-sm)/1.3 var(--sans)}
@media(max-width:760px){html body.theme-warm .pvitals{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:480px){html body.theme-warm .pvitals{grid-template-columns:repeat(2,minmax(0,1fr))}}
html body.theme-warm .mc-three{display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:14px;margin-bottom:16px}
@media(max-width:980px){html body.theme-warm .mc-three{grid-template-columns:1fr}}
html body.theme-warm .mc-three .cd h3{margin:0 0 10px;color:var(--t1);font:600 var(--fs-lg)/1.3 var(--sans)}
html body.theme-warm .mc-three .cd h3 .lnk{float:right;color:var(--acc);font:600 var(--fs-sm)/1.3 var(--sans);letter-spacing:0;cursor:pointer}
html body.theme-warm .mc-na{display:flex;gap:10px;align-items:flex-start;padding:8px 0;border-top:1px solid var(--brd)}
html body.theme-warm .mc-na:first-of-type{border-top:0}
html body.theme-warm .mc-na .ic2{width:22px;height:22px;display:flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:50%;font-size:var(--fs-xs)}
html body.theme-warm .mc-na .ic2.red{background:var(--red-d);color:var(--red)}
html body.theme-warm .mc-na .ic2.amb{background:var(--amb-d);color:var(--amb)}
html body.theme-warm .mc-na .tx{color:var(--t2);font-size:var(--fs-md);line-height:1.45}
html body.theme-warm .mc-na .tx b{color:var(--t1)}
html body.theme-warm .mc-feed{display:flex;gap:8px;align-items:center;padding:6px 0;color:var(--t2);font-size:var(--fs-md)}
html body.theme-warm .mc-feed b{color:var(--t1)}
html body.theme-warm .mc-feed .fdot{width:8px;height:8px;flex-shrink:0;border-radius:50%}

/* ── v2.21.0 THE FRAME, TWO-LINE TABS, THE LOGO (Dillon 2026-09-29, on the staging walk at 2560px: the tab row sat 700px
   left of the page; "the descriptors" of the one-look mockup were missing; "the logo needs to make a comeback").
   One centered frame on a wide screen (1600px; hub Mockups/one-look-spacing-options-2026-09-29.html, option B): the
   tab row, the chip row, the page toolbar and strips and .ct share its left and right edges. Below 1648px the gutter
   stays 24px, the same as before. Portal's black bar uses the same width (Portal index.html v1.72.0). Each tab carries
   a second line (.dwt-d, dw-tabs.js 0.2.0 renders a tab's desc). The Dillon's Welding logo (.dwt-logo) opens the tab row.
   Phones keep the old gutters and hide the second line and the logo. Scoped to theme-warm, like the rest. ── */
html body.theme-warm{--dw-frame:1600px;--dw-gutter:max(24px, calc((100% - var(--dw-frame)) / 2))}
@media(min-width:641px){
  html body.theme-warm .dw-tabbar{min-height:58px;padding-left:var(--dw-gutter);padding-right:var(--dw-gutter)}
  html body.theme-warm :is(.dwt-chips,.dw-substrip,.ct,.stats-bar,.mn > .tb){padding-left:var(--dw-gutter);padding-right:var(--dw-gutter)}
  html body.theme-warm .filter-bar{padding-left:max(18px, calc((100% - var(--dw-frame)) / 2));padding-right:max(18px, calc((100% - var(--dw-frame)) / 2))}
}
html body.theme-warm .dw-tabbar .nb{flex-direction:column;align-items:flex-start;justify-content:center;gap:2px;padding:8px 12px 7px;line-height:1.2}
html body.theme-warm .dwt-l{display:block}
html body.theme-warm .dwt-d{display:block;color:var(--t3);font:500 var(--fs-xs)/1.25 var(--sans);white-space:nowrap}
html body.theme-warm .dw-tabbar .nb.on .dwt-d{color:var(--t2)}
html body.theme-warm .dwt-logo{flex:none;align-self:center;display:flex;align-items:center;height:34px;margin:0 8px 0 0;padding:0 18px 0 0;border:0;border-right:1px solid var(--brd);border-radius:0;background:transparent;cursor:pointer}
html body.theme-warm .dwt-logo img{display:block;height:28px;width:auto}
html body.theme-warm:not(.light) .dwt-logo img{filter:brightness(0) invert(.9)}   /* dark: the navy word would vanish, so the mark turns light */
@media(max-width:640px){html body.theme-warm :is(.dwt-d,.dwt-logo){display:none}}

/* ── v2.22.0 "NEED A HAND?" (dw-tabs.js 0.3.0; Dillon 2026-09-29: "make sure the need a hand behavior is the same
   everywhere (i like that over the flag) - flag can stay the same in the portal navbar"). Office's helper, one copy for
   every app on the tab row: a quiet button at the right end of the row (where the report flag was), a small menu under
   it, and the "Send a note to Dillon" form. Office's layout on the theme's tokens (dark mode follows), 8px corners like
   every card. .dwh-spot = the pulse "Show me how" puts around where to start. Scoped to theme-warm, like the rest. ── */
html body.theme-warm .dwt-help{flex:0 0 auto;align-self:center;display:inline-flex;align-items:center;gap:6px;margin:0 0 0 6px;padding:5px 11px;border:1px solid var(--brd2);border-radius:var(--r);background:var(--bg1);color:var(--t1);font:600 var(--fs-md)/1.2 var(--sans);white-space:nowrap;cursor:pointer}
html body.theme-warm .dwt-help:hover,html body.theme-warm .dwt-help[aria-expanded="true"]{background:var(--bg3)}
html body.theme-warm .dwt-help svg{flex:none;width:15px;height:15px}
@media(max-width:640px){html body.theme-warm .dwt-help{margin:0;padding:6px 8px}html body.theme-warm .dwt-help span{display:none}}   /* a phone: the icon only */
html body.theme-warm .dwh-menu{position:fixed;z-index:9000;display:none;box-sizing:border-box;width:288px;max-width:calc(100vw - 16px);padding:14px;background:var(--bg1);border:1px solid var(--brd);border-radius:var(--r-md);box-shadow:var(--shadow-hover);color:var(--t1);font-family:var(--sans);text-align:left}
html body.theme-warm .dwh-menu.show{display:block}
html body.theme-warm .dwh-menu h4{margin:0 0 2px;font:600 var(--fs-lg)/1.3 var(--sans);color:var(--t1)}
html body.theme-warm .dwh-menu p{margin:0 0 12px;font-size:var(--fs-sm);color:var(--t2)}
html body.theme-warm .dwh-opt{display:flex;align-items:center;gap:12px;width:100%;margin:0 0 8px;padding:10px 12px;text-align:left;background:var(--bg3);border:1px solid var(--brd);border-radius:var(--r-md);color:var(--t1);font:700 var(--fs-base)/1.3 var(--sans);cursor:pointer}
html body.theme-warm .dwh-opt:last-child{margin-bottom:0}
html body.theme-warm .dwh-opt:hover{background:var(--bg4);border-color:var(--brd2)}
html body.theme-warm .dwh-opt small{display:block;margin-top:1px;font:500 var(--fs-sm)/1.35 var(--sans);color:var(--t2)}
html body.theme-warm .dwh-oic{flex:none;display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:var(--bg1);border:1px solid var(--brd);border-radius:var(--r);color:var(--t2)}
html body.theme-warm .dwh-scrim{position:fixed;inset:0;z-index:9001;display:none;background:rgba(28,25,22,.42)}
html body.theme-warm .dwh-scrim.show{display:block}
html body.theme-warm .dwh-sheet{position:fixed;z-index:9002;left:50%;top:50%;transform:translate(-50%,-50%);display:none;box-sizing:border-box;width:min(520px,92vw);max-height:88vh;overflow:auto;padding:24px 26px;background:var(--bg1);border:1px solid var(--brd);border-radius:var(--r-md);box-shadow:var(--shadow-modal);color:var(--t1);font-family:var(--sans);text-align:left}
html body.theme-warm .dwh-sheet.show{display:block}
html body.theme-warm .dwh-x{position:absolute;top:14px;right:14px;width:32px;height:32px;padding:0;border:0;border-radius:var(--r);background:var(--bg3);color:var(--t2);font:400 var(--fs-xl)/1 var(--sans);cursor:pointer}
html body.theme-warm .dwh-x:hover{background:var(--bg4);color:var(--t1)}
html body.theme-warm .dwh-sheet h3{margin:0 0 4px;padding-right:40px;font:600 var(--fs-2xl)/1.2 var(--sans);color:var(--t1)}
html body.theme-warm .dwh-sub{margin:0 0 18px;font-size:var(--fs-base);color:var(--t2)}
html body.theme-warm .dwh-sheet label{display:block;margin:0 0 6px;font:700 var(--fs-base)/1.35 var(--sans);color:var(--t1);text-transform:none;letter-spacing:0}
html body.theme-warm .dwh-sheet textarea{display:block;box-sizing:border-box;width:100%;min-height:110px;margin:0;padding:12px 13px;resize:vertical;background:var(--bg1);border:1px solid var(--brd2);border-radius:var(--r-md);color:var(--t1);font:400 var(--fs-base)/1.45 var(--sans)}
html body.theme-warm .dwh-sheet textarea:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px var(--acc-d)}
html body.theme-warm .dwh-err{display:none;margin:8px 0 0;font-size:var(--fs-sm);font-weight:600;color:var(--red)}
html body.theme-warm .dwh-shot{display:flex;align-items:center;gap:12px;margin:14px 0 0;padding:11px 13px;background:var(--bg3);border:1px solid var(--brd);border-radius:var(--r-md);cursor:pointer}
html body.theme-warm .dwh-shot:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
html body.theme-warm .dwh-tog{flex:none;position:relative;width:44px;height:26px;border-radius:999px;background:var(--grn);transition:background .15s}
html body.theme-warm .dwh-tog::after{content:"";position:absolute;top:3px;left:21px;width:20px;height:20px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:left .15s}
html body.theme-warm .dwh-shot.off .dwh-tog{background:var(--brd2)}
html body.theme-warm .dwh-shot.off .dwh-tog::after{left:3px}
html body.theme-warm .dwh-shot b{display:block;font-size:var(--fs-base);color:var(--t1)}
html body.theme-warm .dwh-shot small{display:block;font-size:var(--fs-sm);color:var(--t2)}
html body.theme-warm .dwh-auto{margin:16px 0 20px}
html body.theme-warm .dwh-auto p{margin:0 0 8px;font:700 var(--fs-sm)/1.35 var(--sans);color:var(--t1)}
html body.theme-warm .dwh-chips{display:flex;flex-wrap:wrap;gap:6px}
html body.theme-warm .dwh-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;background:var(--bg3);border:1px solid var(--brd);border-radius:999px;color:var(--t2);font:600 var(--fs-xs)/1.3 var(--sans)}
html body.theme-warm .dwh-chip svg{flex:none;width:12px;height:12px;color:var(--grn)}
html body.theme-warm .dwh-send{display:block;width:100%;padding:13px;border:0;border-radius:var(--r-md);background:var(--acc);color:var(--acc-ink);font:700 var(--fs-lg)/1.2 var(--sans);cursor:pointer}
html body.theme-warm .dwh-send:hover{background:var(--acc-hover)}
html body.theme-warm .dwh-send:disabled{opacity:.6;cursor:default}
/* v2.25.0 (dw-tabs.js 0.7.0): "What is it?" = 1 row of 3 (Suggestion / Annoying / Stops me); the picked one in the main blue */
html body.theme-warm .dwh-lbl{margin:0 0 6px;font:700 var(--fs-base)/1.35 var(--sans);color:var(--t1)}
html body.theme-warm .dwh-kinds{display:flex;gap:8px;margin:0 0 16px}
html body.theme-warm .dwh-kind{flex:1 1 0;min-width:0;min-height:44px;padding:8px 10px;background:var(--bg1);border:1px solid var(--brd2);border-radius:var(--r-md);color:var(--t1);font:700 var(--fs-base)/1.2 var(--sans);cursor:pointer}
html body.theme-warm .dwh-kind:hover{background:var(--bg3)}
html body.theme-warm .dwh-kind.on{background:var(--acc);border-color:var(--acc);color:var(--acc-ink)}
html body.theme-warm .dwh-kind:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
html body.theme-warm .dwh-toast{position:fixed;z-index:9003;left:50%;bottom:24px;transform:translateX(-50%);padding:10px 16px;background:var(--t1);color:var(--bg1);border-radius:var(--r-md);font:600 var(--fs-md)/1.3 var(--sans)}
html body.theme-warm .dwh-spot{animation:dwhSpot 1.1s ease-in-out 3}
@keyframes dwhSpot{0%,100%{box-shadow:0 0 0 0 transparent}50%{box-shadow:0 0 0 4px var(--acc-d),0 0 0 1px var(--acc)}}
@media print{html body.theme-warm :is(.dwt-help,.dwh-menu,.dwh-scrim,.dwh-sheet,.dwh-toast){display:none !important}}

/* ── v2.23.0 THE TABS COME FIRST (dw-tabs.js 0.5.0; found 2026-10-05 at a 1284px frame on staging: HQ's Setup tab sat
   under "Connected / Rev" and could not be seen or clicked). The tab strip (.dwt-tabs) is the only part of the row that
   can shrink, and its scrollbar is hidden, so a short row hid tabs. dw-tabs.js now measures the row and puts up to 3
   classes on it, a step at a time, until every tab shows: the version goes, then the sync text, then the helper's words
   (its icon stays, as on a phone; the sync text and the version come back while they fit). No class = the full row, so
   a wide screen, and a page with an older dw-tabs.js, do not change. Scoped to theme-warm, like the rest. ── */
html body.theme-warm .dw-tabbar.dwt-norev .dwt-rev{display:none}
html body.theme-warm .dw-tabbar.dwt-nometa .dwt-meta{display:none}
html body.theme-warm .dw-tabbar.dwt-icon .dwt-help span{display:none}

/* ── v2.24.0 THE SIDE LIST (dw-side.js 0.1.0; Dillon 2026-10-21, hub Mockups/index-hq-side-list-2026-10-20.html: "I like
   this side list thing"). The shape of the Office job page's side list: 1 page, 1 list on the left, no chip rows.
   The list: headings, items with a small second line, numbered items (a jump down the page), 1 lit item.
   The layout: a .dw-sheet whose host holds a list turns into 2 columns inside the 1600px frame (--dws-g = the frame's
   side gutter, from the screen width, so the list lines up with the tab row). The page column keeps its own scroll.
   Under 861px: back to 1 column; the list folds into 1 picker button that opens it over the page. ── */
html body.theme-warm .dws-host:empty{display:none}
html body.theme-warm .dws{display:block;min-width:0}
html body.theme-warm .dws-pick{display:none}
html body.theme-warm .dws-list{display:flex;flex-direction:column;gap:1px;background:var(--bg1);border:1px solid var(--brd);border-radius:var(--r-md);padding:10px}
html body.theme-warm .dws-g + .dws-g{margin-top:12px}
html body.theme-warm .dws-h{margin:0 0 4px;padding:0 8px;color:var(--t3);font:700 var(--fs-xs)/1.3 var(--sans);text-transform:uppercase;letter-spacing:.04em}
html body.theme-warm .dws-i{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;width:100%;min-height:34px;margin:0;padding:6px 8px;border:0;border-radius:var(--r);background:transparent;color:var(--t2);font:600 var(--fs-md)/1.3 var(--sans);text-align:left;cursor:pointer}
html body.theme-warm .dws-i:hover{background:var(--bg3);color:var(--t1)}
html body.theme-warm .dws-i.on{background:var(--acc-d);box-shadow:inset 3px 0 0 var(--acc);color:var(--t1)}
html body.theme-warm .dws-i:focus-visible{outline:2px solid var(--focus);outline-offset:1px}
html body.theme-warm .dws-n{grid-column:1;display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;margin-right:7px;border-radius:999px;background:var(--acc-d);color:var(--acc);font:700 var(--fs-xs)/1 var(--sans);font-style:normal}
html body.theme-warm .dws-i.on .dws-n{background:var(--acc);color:var(--acc-ink)}
html body.theme-warm .dws-l{grid-column:2;min-width:0;overflow-wrap:anywhere}
html body.theme-warm .dws-em{grid-column:3;margin-left:8px;color:var(--t3);font:500 var(--fs-sm)/1.3 var(--sans);font-style:normal;font-variant-numeric:tabular-nums;white-space:nowrap}
html body.theme-warm .dws-em:empty{display:none}
html body.theme-warm .dws-s{grid-column:2 / -1;display:block;margin-top:1px;color:var(--t3);font:400 var(--fs-sm)/1.3 var(--sans)}
html body.theme-warm .dws-dim{font-weight:500}
html body.theme-warm .dws-dim .dws-l,html body.theme-warm .dws-ext{color:var(--t3)}
html body.theme-warm .dws-warn{margin-left:5px;color:var(--amb)}
html body.theme-warm .dws-badge{align-items:center;justify-content:center;min-width:18px;height:18px;margin-left:6px;padding:0 5px;border-radius:9px;background:var(--red);color:#fff;font:700 var(--fs-xs)/1 var(--sans);vertical-align:1px}
/* the page layout: the list left of the page, inside the frame */
html body.theme-warm .dw-sheet:has(> .dws-host > .dws){--dws-w:260px;--dws-g:max(24px, calc((100vw - var(--dw-frame, 1600px)) / 2));display:grid;grid-template-columns:calc(var(--dws-g) + var(--dws-w)) minmax(0,1fr);grid-template-rows:auto minmax(0,1fr)}
html body.theme-warm .dw-sheet:has(> .dws-host > .dws) > .dw-tabbar{grid-column:1 / -1;grid-row:1}
html body.theme-warm .dw-sheet:has(> .dws-host > .dws) > .dws-host{grid-column:1;grid-row:2;display:block;min-height:0;overflow-y:auto;margin:0;padding:14px 0 24px var(--dws-g);border:0;background:transparent}
html body.theme-warm .dw-sheet:has(> .dws-host > .dws) > .mn{grid-column:2;grid-row:2;min-width:0;min-height:0;--dw-gutter:0px}
html body.theme-warm .dw-sheet:has(> .dws-host > .dws) > .mn > :is(.ct,.tb,.stats-bar){padding-left:18px;padding-right:var(--dws-g)}
/* a phone or a narrow window: 1 column, the list behind 1 picker button */
@media(max-width:860px){
  html body.theme-warm .dw-sheet:has(> .dws-host > .dws){display:flex}
  html body.theme-warm .dw-sheet:has(> .dws-host > .dws) > .dws-host{position:relative;z-index:30;display:block;overflow:visible;padding:8px 12px 0}
  html body.theme-warm .dw-sheet:has(> .dws-host > .dws) > .mn > :is(.ct,.tb,.stats-bar){padding-left:12px;padding-right:12px}
  html body.theme-warm .dws-pick{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;min-height:42px;margin:0;padding:8px 12px;border:2px solid var(--acc);border-radius:var(--r-md);background:var(--bg1);color:var(--t1);font:600 var(--fs-md)/1.2 var(--sans);text-align:left;cursor:pointer}
  html body.theme-warm .dws-list{display:none}
  html body.theme-warm .dws-host.dws-open .dws-list{display:flex;position:absolute;left:12px;right:12px;top:calc(100% + 4px);max-height:70vh;overflow-y:auto;box-shadow:var(--shadow-modal)}
  html body.theme-warm .dws-i{min-height:44px}
}
