/* ============================================================================
   NWC Design Tokens — the single source of truth for the app's visual language.

   PRINCIPLES
   ----------
   1. Every color, spacing value, radius, shadow, and z-index in the app
      should reference a token here. Hardcoded values in component CSS are
      a smell — promote to a token if it's reused, replace with the closest
      token if it's a near-miss.

   2. Tokens are semantic where it matters (--surface-default,
      --text-primary) and primitive where semantics don't add clarity
      (--space-md, --radius-sm). When in doubt, semantic.

   3. Aligned with Bootstrap's variable names where they overlap, so any
      remaining Bootstrap utility classes blend rather than conflict.

   4. Dark mode is a separate handoff — but every token here is structured
      so dark-mode override is a [data-theme="dark"] block, nothing else.

   5. NO HARDCODED COLORS IN THIS FILE. The hex values here are the SOURCE.
      Everywhere else, use var(--token-name).
   ============================================================================ */

:root {
  /* ── Color primitives — the raw palette ────────────────────────────── */
  /* Grays (aligned to Bootstrap gray scale) */
  --gray-50:   #f8f9fa;
  --gray-100:  #f1f3f5;
  --gray-200:  #e9ecef;
  --gray-300:  #dee2e6;
  --gray-400:  #ced4da;
  --gray-500:  #adb5bd;
  --gray-600:  #6c757d;
  --gray-700:  #495057;
  --gray-800:  #343a40;
  --gray-900:  #212529;

  /* Brand */
  --brand-teal-500:   #11998e;   /* Compliance table-header start, the green accent */
  --brand-teal-300:   #38ef7d;   /* Compliance table-header end */
  --brand-burgundy:   #5b2333;   /* Winemaking-forms section titles */

  /* Functional palette (Bootstrap-aligned) */
  --blue-500:    #0d6efd;
  --blue-600:    #1b6ec2;
  --blue-700:    #1861ac;
  --blue-100:    #e7f1ff;
  --green-100:   #d1e7dd;
  --green-500:   #16a34a;        /* Copilot plan-status active/complete */
  --green-500-rgb: 22, 163, 74;  /* composable — W13 WeightTags organic/coverage icon tints at multiple alphas */
  --green-700:   #155724;
  --yellow-100:  #fff3cd;
  --yellow-700:  #856404;
  --red-500:     #dc3545;
  --red-700:     #b32121;
  --orange-500:  #fd7e14;
  --white:       #ffffff;
  --black:       #000000;

  /* ── Tailwind palette primitives ───────────────────────────────────── */
  /* Added 2026-05-19 to absorb the Tailwind literals that the .razor.css
     sweep left alone. Primitives only — no dark-mode override yet (current
     behavior is literal hex in both themes; tokens preserve that exactly).
     If/when we want dark-mode behavior on these, override in the dark block. */
  --slate-50:    #f8fafc;
  --slate-100:   #f1f5f9;
  --slate-200:   #e2e8f0;
  --slate-300:   #cbd5e1;
  --slate-400:   #94a3b8;
  --slate-500:   #64748b;
  --slate-600:   #475569;
  --slate-700:   #334155;
  --slate-800:   #1e293b;
  --slate-900:   #0f172a;

  --indigo-400:  #818cf8;
  --indigo-500:  #6366f1;
  --indigo-600:  #4f46e5;
  --indigo-600-rgb: 79, 70, 229;  /* composable — W13 ExtractionReview/WeightTags reuse at several alphas (selected-row, active-card, icon tints) */

  --amber-50:    #fffbeb;         /* fills the rung below --amber-100 — W13 WeightTags warning/coverage-yellow cards */
  --amber-100:   #fef3c7;
  --amber-300:   #fcd34d;         /* fills the rung between --amber-100/--amber-500 — W13 WeightTags warning/coverage-yellow card border */
  --amber-500:   #f59e0b;
  --amber-600:   #d97706;
  --amber-500-rgb: 245, 158, 11;  /* composable, e.g. LabelNewPanel is-warning focus ring — same pattern as --blue-500-rgb */

  --emerald-500: #10b981;       /* badge accents */
  --pink-500:    #ec4899;
  --purple-500:  #a855f7;

  /* ── Semantic surfaces ─────────────────────────────────────────────── */
  --surface-default:    var(--white);          /* Card, panel, modal background */
  --surface-subtle:     var(--gray-50);        /* Light-gray page background */
  --surface-muted:      var(--gray-100);       /* Hover/inactive backgrounds */
  --surface-emphasis:   var(--gray-200);       /* Selected row, active tab background */
  --surface-inverse:    var(--gray-900);       /* Code blocks, dark surfaces */

  /* ── Semantic text ─────────────────────────────────────────────────── */
  --text-primary:       var(--gray-900);
  --text-secondary:     var(--gray-700);
  --text-muted:         var(--gray-600);
  --text-disabled:      var(--gray-500);
  --text-on-inverse:    var(--white);
  --text-on-brand:      var(--white);
  --text-link:          #0071c1;               /* Slightly darker than blue-500 for AA contrast */

  /* ── Semantic borders ──────────────────────────────────────────────── */
  --border-default:     var(--gray-300);
  --border-subtle:      var(--gray-200);
  --border-strong:      var(--gray-400);
  --border-focus:       var(--blue-500);

  /* ── Brand & accent ────────────────────────────────────────────────── */
  --accent-primary:     var(--brand-teal-500);    /* Compliance accent, single source */
  --accent-primary-soft:rgba(17, 153, 142, 0.15); /* Focus ring, subtle backgrounds */
  --accent-gradient:    linear-gradient(135deg, var(--brand-teal-500) 0%, var(--brand-teal-300) 100%);
  --accent-burgundy:    var(--brand-burgundy);
  --accent-preview-header: linear-gradient(135deg, #667eea 0%, #764ba2 100%); /* COLA/Label preview panel header */
  /* TTB Registry indigo accent family (periwinkle headers/borders/links). Exact-match
     light — #667eea is a distinct periwinkle (≠ --indigo-500 #6366f1); dark lifts to indigo. */
  --accent-preview:        #667eea;   /* TTB group/section borders, header labels, chain links */
  --accent-preview-strong: #4a5bd4;   /* TTB link hover */
  --accent-preview-bg:     #f8f9ff;   /* TTB FBN subsection / search-panel background */
  --accent-preview-border: #d0d5f0;   /* TTB FBN search-panel border */
  --accent-preview-soft:   rgba(102, 126, 234, 0.15); /* Focus ring, LabelCola SearchSortBar (W11) */

  /* ── Interactive (buttons/links) ───────────────────────────────────── */
  --interactive-primary:        var(--blue-600);
  --interactive-primary-hover:  var(--blue-700);
  --interactive-primary-border: var(--blue-700);

  /* ── State (status badges, validation) ─────────────────────────────── */
  --state-success-bg:   var(--green-100);
  --state-success-fg:   var(--green-700);
  --state-warning-bg:   var(--yellow-100);
  --state-warning-fg:   var(--yellow-700);
  --state-danger-bg:    #f8d7da;
  --state-danger-fg:    var(--red-700);
  --state-info-bg:      var(--blue-100);
  --state-info-fg:      var(--blue-700);
  --state-neutral-bg:   var(--gray-200);
  --state-neutral-fg:   var(--gray-700);

  --state-valid-outline:   #26b050;
  --state-invalid-outline: var(--red-500);

  /* ── Compliance: urgency row backgrounds (full-row tints) ─────────────
     A 4-tier scale on the Filings/Contracts tables: low → --state-warning-bg
     (yellow), medium → --urgency-medium-bg (orange), high → --state-danger-bg
     (pink-red), overdue → --urgency-overdue (solid red, white text). The two
     bespoke tiers have no semantic home, so they carry exact light values. */
  --urgency-medium-bg:  #fff3e0;   /* orange tier between warning and danger */
  --urgency-overdue:    #d32f2f;   /* solid-red overdue/expired row, white text */

  /* ── Compliance: permit type-badge gradients (brand-coded affordances) ── */
  --permit-badge-purple: linear-gradient(135deg, #6f42c1 0%, #9b59b6 100%);          /* ABC  */
  --permit-badge-green:  linear-gradient(135deg, #198754 0%, #2ecc71 100%);          /* CDFA */
  --permit-badge-orange: linear-gradient(135deg, #e67e22 0%, #f39c12 100%);          /* FBN  */
  --permit-badge-red:    linear-gradient(135deg, var(--red-500) 0%, #e74c3c 100%);   /* FDA  */

  /* ── Compliance: permit trade-name chip (deep teal on pale teal) ──────
     Exact-match — #0d7a6e/#e8f5f3 are deeper/paler than --accent-primary
     (#11998e) / --accent-primary-soft (translucent), so don't reuse those. */
  --permit-tradename-bg: #e8f5f3;
  --permit-tradename-fg: #0d7a6e;

  /* ── Spacing scale ─────────────────────────────────────────────────── */
  --space-3xs:  0.125rem;  /*  2px */
  --space-2xs:  0.25rem;   /*  4px */
  --space-xs:   0.375rem;  /*  6px */
  --space-sm:   0.5rem;    /*  8px */
  --space-md:   0.75rem;   /* 12px */
  --space-lg:   1rem;      /* 16px */
  --space-xl:   1.5rem;    /* 24px */
  --space-2xl:  2rem;      /* 32px */
  --space-3xl:  3rem;      /* 48px */

  /* ── Breakpoints (DOCUMENTED CONVENTION, not usable as CSS custom properties) ──
     CSS custom properties cannot appear in an @media prelude ("@media (min-width: var(--bp-md))"
     is invalid CSS), so these three values are NOT consumed via var() — they exist here as the
     single documented source of the app's de-facto breakpoint convention, already in use across
     33+ hardcoded px values in .razor.css files before this token block existed. Every NEW
     responsive rule should use these literal px values (576 / 768 / 1024) rather than picking a
     new one. See docs/LAYOUT-PATTERNS.md "adaptive page recipe" for the full usage note,
     including when to reach for a container query (nwc-adaptive.js / <AdaptiveRegion>) instead of
     a viewport @media — viewport queries don't fire correctly inside a SlidingPanel.
       --bp-sm: 576px   — phone landscape / large-phone breakpoint (rarely used alone)
       --bp-md: 768px   — the shell's phone/desktop split (BottomNav, MainLayout, SlidingPanel
                           mobile-full-width). Matches the existing 767.98/768 convention.
       --bp-lg: 1024px  — the tablet band's upper edge (769-1024px = tablet; >1024px = desktop) */
  --bp-sm: 576px;
  --bp-md: 768px;
  --bp-lg: 1024px;

  /* ── Border radii ──────────────────────────────────────────────────── */
  --radius-xs:  3px;
  --radius-sm:  4px;
  --radius-md:  6px;
  --radius-lg:  8px;
  --radius-xl:  12px;
  --radius-pill: 999px;

  /* ── Shadows ───────────────────────────────────────────────────────── */
  --shadow-sm:    0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md:    0 2px 4px rgba(0, 0, 0, 0.06);
  --shadow-lg:    0 2px 8px rgba(0, 0, 0, 0.08);
  --shadow-xl:    0 5px 15px rgba(0, 0, 0, 0.30);   /* custom-panel-container */
  --shadow-focus: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
  --shadow-focus-accent: 0 0 0 3px var(--accent-primary-soft);
  --confirm-dialog-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);   /* Shared/ConfirmDialogPanel */

  /* ── Typography ────────────────────────────────────────────────────── */
  --font-family-body:    'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-family-mono:    'SF Mono', 'Monaco', 'Inconsolata', ui-monospace, SFMono-Regular, Menlo, monospace;

  --font-size-2xs:  0.65rem;
  --font-size-xs:   0.7rem;
  --font-size-sm:   0.75rem;
  --font-size-md:   0.85rem;
  --font-size-base: 0.9rem;
  --font-size-lg:   1rem;
  --font-size-xl:   1.1rem;
  --font-size-2xl:  1.25rem;

  --font-weight-normal:   400;
  --font-weight-medium:   500;
  --font-weight-semibold: 600;
  --font-weight-bold:     700;

  --line-height-tight:  1.25;
  --line-height-normal: 1.5;

  /* ── Letter spacing (for uppercase eyebrow labels) ─────────────────── */
  --letter-spacing-wide:  0.03em;
  --letter-spacing-wider: 0.05em;
  --letter-spacing-widest:0.06em;

  /* ── Z-index scale (DOCUMENT WHAT BEATS WHAT) ──────────────────────── */
  /* Lower section: in-flow stacking */
  --z-base:        1;       /* sticky table headers inside content */
  --z-raised:      5;       /* sticky toolbars inside a page */
  --z-card-overlay: 10;     /* small badges/icons floating over a BottlingSchedule appointment card */
  --z-sticky:      100;     /* page-level sticky headers */
  --z-bottom-nav:  990;     /* mobile bottom tab bar — above content, below the nav drawer (998/999) + modals */

  /* Fixed BottomNav bar's own height + safe-area, so anything needing to clear it
     (main's mobile padding-bottom, a full-height workspace's mobile height calc,
     the floating CopilotPanel's mobile bottom offset) references one value
     instead of re-deriving "4rem + safe-area" per call site. */
  --bottom-nav-clearance: calc(4rem + env(safe-area-inset-bottom));

  /* Middle section: floating UI */
  --z-dropdown-backdrop: 1000; /* click-outside catcher */
  --z-error-ui:    1000;    /* blazor-error-ui */
  --z-dropdown:    1001;    /* dropdown menus (must beat backdrop) */
  --z-slot-badge:  1050;    /* admin slot indicator */
  --z-modal:       1060;    /* sliding panels and modals */
  --z-dialog-backdrop: 1070; /* backdrop for a dialog that must dim an OPEN SlidingPanel (.nwc-modal-backdrop--over-panel) */
  --z-dialog-host: 1080;    /* .nwc-dialog-host — centered dialog over a SlidingPanel, below lightbox (1090) */
  --z-lightbox:    1090;    /* DocumentPageLightboxPanel — above --z-modal so it can layer over a SlidingPanel, below --z-theme-toggle. Same tier as --z-labelcola-lightbox (kept separate — domain-scoped alias, not renamed). */
  --z-theme-toggle: 1100;   /* fixed page-level affordances (peer of .drawer-toggle) */
  --z-reconnect:   1200;    /* components-reconnect-modal — above EVERY panel/modal on purpose:
                               once the circuit is down the whole UI is inert, so the notice must
                               never render behind the dead surface it is explaining. */
  /* Top section: drag-and-drop and tooltips */
  --z-drag-indicator: 9999; /* bottling drag-drop drop indicator */

  /* ── Transitions ───────────────────────────────────────────────────── */
  --transition-fast:    120ms ease;
  --transition-default: 150ms ease-out;
  --transition-slow:    180ms ease;

  /* ── App-specific component tokens ─────────────────────────────────── */
  --table-header-bg:        var(--accent-gradient);
  --table-header-fg:        var(--text-on-brand);
  --table-row-hover:        #f0faf9;            /* Tinted accent-primary at low opacity */
  --table-cell-padding-y:   var(--space-xs);
  --table-cell-padding-x:   var(--space-md);

  --panel-shadow:           var(--shadow-xl);
  --panel-radius:           var(--radius-lg);

  --tab-active-color:       var(--accent-primary);
  --tab-active-border:      var(--accent-primary);
  --tab-inactive-color:     var(--text-muted);

  --search-bar-bg:          var(--surface-subtle);
  --search-bar-border:      var(--border-subtle);
  --search-bar-radius:      var(--radius-lg);

  --form-input-focus-outline: var(--blue-500);
  --form-input-focus-offset:  2px;
  --form-input-min-height:    44px;

  --status-badge-radius:    var(--radius-sm);
  --status-badge-padding:   0.125rem 0.5rem;
  --status-badge-font-size: var(--font-size-sm);

  /* ── Bottling drag-drop accent (intentional brand color, dark-mode-stable) ── */
  --dnd-indicator-color:    #ffd700;            /* Gold — drag-drop drop indicator */
  --dnd-indicator-shadow:   0 0 4px rgba(255, 215, 0, 0.6);
  --dnd-empty-outline:      rgba(255, 215, 0, 0.35);

  /* ── Bottling schedule board ───────────────────────────────────────────
     Appointment-row gradients are differentiation colors (the DB-driven
     varietal card colors are separate inline styles, out of scope). Exact
     light values; the dark block darkens them so the row's inherited (and
     therefore auto-flipped, light) text stays legible. The blue "Other
     Appointment" gradient must stay distinctly blue = "NOT a bottling". */
  --appt-other-gradient:     linear-gradient(to right, rgba(109, 213, 250, 0.8), rgba(41, 128, 185, 0.8));
  --appt-multiday-gradient:  linear-gradient(to right, rgba(255, 193, 7, 0.85), rgba(255, 152, 0, 0.85));
  --appt-multiday-border:    #e65100;
  --appt-otherline-gradient: linear-gradient(to right, rgba(147, 112, 219, 0.8), rgba(106, 90, 205, 0.8));

  /* Skeleton-loader shimmer (transient; the shimmer animation is disabled
     under VR, so it never appears in a baseline capture). */
  --skeleton-base:      #e0e0e0;
  --skeleton-highlight: #f0f0f0;

  /* Sign-off status circles — traffic-light gradients (blue/green/yellow/red).
     Tiny icons with a white ring, no text on them, so they're dark-stable like
     --dnd-indicator-color: tokenized for hygiene, no dark override needed. */
  --signoff-info-gradient:    linear-gradient(45deg, #42a5f5, #1565c0);
  --signoff-success-gradient: linear-gradient(45deg, #81c784, #388e3c);
  --signoff-warning-gradient: linear-gradient(45deg, #ffb74d, #ff9800);
  --signoff-danger-gradient:  linear-gradient(45deg, #ef5350, #b71c1c);

  /* Work-request alert badge red — used as TEXT/BORDER (the solid white-on-red
     count pill stays a hardcoded literal, per the white-on-fill rule). */
  --wr-alert:        #e74c3c;
  --wr-alert-strong: #c0392b;

  /* Snow-dropper appointment indicator (Screw Cap +Snow snowflake icon). */
  --snow-dropper-fg: #1565c0;

  /* Calendar cell elevation + "today" highlight glow (MonthCalendar). */
  --calendar-cell-shadow: #92a1d1;
  --calendar-today-glow:  #a3bfe0;

  /* ── Work-request status badges + callouts ─────────────────────────────
     Shared by WorkRequestDetailView + WorkRequestReviewPanel; one source kills
     the byte-duplicated palette. The warning/accepted backgrounds reuse the
     existing --yellow-100 / --green-100 tokens (no bespoke bg needed). */
  --wr-status-info-bg:        #cfe2ff;
  --wr-status-info-fg:        #084298;
  --wr-status-info-border:    #9ec5fe;
  --wr-status-warning-fg:     #664d03;
  --wr-status-warning-border: #ffe69c;
  --wr-status-revision-bg:    #ffe5d0;
  --wr-status-revision-fg:    #842029;
  --wr-status-accepted-fg:    #0f5132;

  /* ── Date chip (Other Appointment panel — Material-blue chip family) ──── */
  --chip-info-bg:       #e3f2fd;
  --chip-info-border:   #90caf9;
  --chip-info-fg:       #1565c0;
  --chip-info-hover-bg: #bbdefb;
  --chip-info-hover-fg: #0d47a1;

  /* ── App-shell blue ─────────────────────────────────────────────────────
     The brand navy/blue that forms the app chrome (MainLayout/.sidebar,
     NwcAppHeader's nav drawer, NavMenu, NavButtonNavMenu, BlendingLayout's
     topbar). Split by ROLE because one color can't serve both jobs in dark:
       --app-shell-blue        FILL — gradient start stops + the UserMenu
                               avatar; white text rides it, so dark DEEPENS to
                               navy to keep that text legible.
       --app-shell-blue-bright gradient bright end; also stands in as the
                               BlendingLayout text/border accent. Its dark value
                               stays a DEEP blue (#0a52a8) on purpose — that
                               layout's surrounding surfaces aren't themed yet,
                               so a *lightened* accent would lose contrast on
                               them (graduate it to a real accent when the
                               Blending folder is themed).
     The two share the same LIGHT value but diverge in dark — don't "dedupe". */
  --app-shell-blue:        #052e76;
  --app-shell-blue-bright: #0366d6;

  /* App-shell gradients, expressed from the fill+bright pair so dark cascades
     automatically (no separate dark override needed — see the dark block).
     rgb(5,46,118) === #052e76, so the 180° gradient is pixel-identical to its
     prior literal. The 90° variant (0→100%) is BlendingLayout's topbar. */
  --app-shell-gradient:   linear-gradient(180deg, var(--app-shell-blue) 0%, var(--app-shell-blue-bright) 70%);
  --app-shell-gradient-h: linear-gradient(90deg, var(--app-shell-blue) 0%, var(--app-shell-blue-bright) 100%);

  /* MainLayout collapsed drawer-toggle hover — the toggle sits on the page bg
     (which DOES theme dark), so the glyph must lighten in dark while light
     stays the exact navy literal. Hover bg is a faint navy tint. */
  --app-shell-toggle-fg:       #052e76;
  --app-shell-toggle-hover-bg: rgba(5, 46, 118, 0.08);

  /* SecondaryLayout sidebar — a separate PURPLE identity, NOT part of the blue
     family; kept as a whole-gradient token (light = the exact prior literal). */
  --secondary-shell-gradient: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);

  /* ── W2 cohort (Shared/ root + DataGrid) — added 2026-07-07 ──────────────
     Everything below is dark-stable (no [data-theme="dark"] override) unless
     noted: either it rides the always-dark app-shell gradient (on-shell-*),
     is an alpha-black overlay that reads fine on any surface, or belongs to
     a component (BlendingLayout workspace, crop editor, tooltip) that isn't
     dark-mode-integrated yet — preserving its exact current appearance in
     both themes rather than guessing an unverified dark palette. */

  /* Overlay backdrop scale — graduated dim levels found duplicated verbatim
     across NwcAppHeader/SlidingPanel/NavMenu/BottomNav. */
  --overlay-backdrop-soft:   rgba(0, 0, 0, 0.4);   /* bottom-sheet backdrop */
  --overlay-backdrop-dim:    rgba(0, 0, 0, 0.5);   /* nav drawer, sliding panel */
  --overlay-backdrop-strong: rgba(0, 0, 0, 0.6);   /* mobile full-nav overlay */

  /* "On shell" — chrome riding the app-shell-blue gradient (drawer-toggle,
     theme-toggle, NavMenu links, UserMenu badge). White-on-navy, so it reads
     correctly regardless of app theme — the gradient itself is what shifts. */
  --on-shell-fg:                rgba(255, 255, 255, 0.78);
  --on-shell-fg-strong:         rgba(255, 255, 255, 0.8);
  --on-shell-fg-dim:            rgba(255, 255, 255, 0.7);
  --on-shell-fg-faint:          rgba(255, 255, 255, 0.5);
  --on-shell-fg-subtle:         rgba(255, 255, 255, 0.35);
  --on-shell-fg-muted:          #d7d7d7;   /* legacy NavButtonNavMenu link text */
  --on-shell-hover-bg:          rgba(255, 255, 255, 0.1);
  --on-shell-hover-bg-soft:     rgba(255, 255, 255, 0.12);
  --on-shell-hover-bg-strong:   rgba(255, 255, 255, 0.14);
  --on-shell-hover-border:      rgba(255, 255, 255, 0.4);
  --on-shell-active-bg:         rgba(255, 255, 255, 0.15);
  --on-shell-border:            rgba(255, 255, 255, 0.25);
  --on-shell-pressed-bg:        rgba(255, 255, 255, 0.2);
  --on-shell-pressed-bg-strong: rgba(255, 255, 255, 0.25);
  --on-shell-warn-bg:           rgba(255, 200, 50, 0.15);  /* UserMenu not-authenticated */
  --on-shell-warn-border:       rgba(255, 200, 50, 0.3);
  --on-shell-warn-fg:           rgba(255, 200, 50, 0.8);

  /* Bespoke shadows — distinct geometry from the --shadow-* card scale, so
     kept as their own named tokens rather than forced into a near-miss. */
  --shadow-top-sm:       0 -1px 8px rgba(0, 0, 0, 0.06);   /* BottomNav bar */
  --shadow-top-lg:       0 -4px 20px rgba(0, 0, 0, 0.18);  /* BottomNav sheet */
  --nav-drawer-shadow:   2px 0 12px rgba(0, 0, 0, 0.3);    /* NwcAppHeader drawer */
  --panel-slide-shadow:  -4px 0 20px rgba(0, 0, 0, 0.15);  /* SlidingPanel */
  --dropdown-menu-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1); /* DataGridToolbar filter menu */

  /* Tooltip — simple dark bubble, unaffected by app theme. */
  --tooltip-bg:    #363636;
  --tooltip-arrow: #555;

  /* BlendingLayout workspace — a self-contained blue-gray design language
     (Untitled-UI-style neutrals) not yet dark-mode-integrated; not covered
     by the VR corpus. Named 1:1 from the prior literals, no dark override,
     so today's appearance is unchanged in either theme. */
  --ws-border:            #d0d5dd;
  --ws-divider:            #e0e3e8;
  --ws-text-strong:       #344054;
  --ws-text-strongest:    #1d2939;
  --ws-text-secondary:    #475467;
  --ws-text-muted:        #667085;
  --ws-icon-muted:        #98a2b3;
  --ws-surface-hover:     #f0f2f5;
  --ws-surface-hover-alt: #eef0f4;
  --ws-active-tint:       #e8f0fe;
  --ws-active-bg:         #e0e7f1;
  --ws-panel-bg:          #fafbfc;
  --ws-panel-header-bg:   #f8f9fb;
  --ws-topbar-link-hover: #d0e4ff;
  --ws-status-draft:      #fdb022;
  --ws-status-saved:      #32d583;
  --ws-dropdown-shadow:   0 8px 24px rgba(0, 0, 0, 0.15);

  /* ImageCaptureEditor — quick-action theming + the full-screen crop overlay
     (the overlay is intentionally dark regardless of app theme, like a photo
     editor convention — no dark override needed). */
  --capture-accent:               #3b82f6;
  --capture-accent-light:         #60a5fa;
  --capture-action-camera-bg:     linear-gradient(135deg, #e7f3ff 0%, #dbeafe 100%);
  --capture-action-camera-border: #93c5fd;
  --capture-action-camera-fg:     #1d4ed8;
  --capture-action-gallery-bg:    linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
  --capture-action-gallery-border:#86efac;
  --capture-action-gallery-fg:    #15803d;
  --capture-remove-btn-shadow:    0 2px 4px rgba(0, 0, 0, 0.1);
  --capture-drag-tint:            rgba(13, 110, 253, 0.04);
  --crop-overlay-bg:      #1a1a1a;
  --crop-overlay-backdrop: rgba(0, 0, 0, 0.9);
  --crop-panel-bg:        rgba(0, 0, 0, 0.8);
  --crop-btn-bg:          rgba(255, 255, 255, 0.1);
  --crop-btn-bg-subtle:   rgba(255, 255, 255, 0.05);
  --crop-btn-bg-active:   rgba(255, 255, 255, 0.2);
  --crop-divider:         rgba(255, 255, 255, 0.15);
  --crop-fg-muted:        rgba(255, 255, 255, 0.8);
  --crop-confirm-bg:      #22c55e;

  /* MonthCalendar hover glow — the black counterpart to --calendar-today-glow,
     a bespoke 5-layer neumorphic shadow used exactly once. */
  --calendar-hover-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;

  /* Legacy fixed-header z-index gap — NavButtonTopLayout / NavButtonNavMenu
     (an older top-nav-button layout pattern, superseded by the sidebar
     NavMenu but still present in the tree). Sits between the dropdown tier
     (1001) and the slot-badge tier (1050). */
  --z-page-header-fixed: 1030;
  --z-navbar:             1000;  /* same tier as z-dropdown-backdrop/z-error-ui */
  --z-mobile-nav-backdrop: 998;  /* NavMenu full-screen mobile drawer backdrop — above bottom-nav (990), below dropdown tier (1000) */
  --z-mobile-nav-sidebar:  999;  /* NavMenu full-screen mobile drawer itself */
  --z-user-menu-backdrop:  1040; /* backs the user-dropdown popover (z-modal, 1060) */
  --z-crop-overlay:       10000; /* ImageCaptureEditor full-screen crop UI — above everything, incl. drag-indicator (9999) */

  /* ── W3 cohort (Shared/Inventory) — added 2026-07-07 ──────────────────────
     Split by dark-mode readiness: CategoryTree/ItemGrid/InventoryInspector/
     IssueStockPanel/etc. are built on the --gray-* scale (already fully dark-
     integrated), so their tokens below get real [data-theme="dark"] overrides.
     UnassignedReceiptsPanel is built entirely on the --slate-* / --amber-*
     Tailwind PRIMITIVES, which per their 2026-05-19 addition comment have "no
     dark-mode override yet" — so its badge/tint tokens stay dark-STABLE
     (same value in both themes) to avoid a half-dark component where badges
     flip but the surrounding slate-toned tabs/table don't (the NwcDataGrid
     lesson from W2). */

  /* Bootstrap "success" green — reused across confidence/step-done indicators;
     distinct from --green-500 (copilot) and --state-success-fg (#155724). */
  --green-600: #198754;

  /* Lot freshness / stock-level status (IssueStockPanel, ItemGrid, InventoryInspector) */
  --inv-expired-bg:            #ffe2e2;
  --inv-expired-active-bg:     #ffd1d1;
  --inv-expired-active-border: #ffc4c4;
  --inv-low-selected-bg:       #ffe9a8;

  /* Quantity delta colors (movement table +/-; reused by AgingReportPanel buckets) */
  --inv-qty-positive: #1d6f33;
  --inv-qty-negative: #b32424;

  /* Default-supplier row highlight (InventoryInspector — gray-scale, dark-integrated) */
  --inv-default-supplier-bg: #f8fbff;

  /* "Selected option" tint (Export/MatchInvoice panels — gray-scale, dark-integrated) */
  --inv-selected-tint-bg: #f0f5ff;

  /* AgingReportPanel buckets (fresh/old; mid reuses --yellow-100/700, aged reuses inv-expired-bg/inv-qty-negative) */
  --inv-aging-fresh-bg: #d1f0d8;
  --inv-aging-old-bg:   #ffe4b5;
  --inv-aging-old-fg:   #8b4513;

  /* ── UnassignedReceiptsPanel (slate-scale, NOT dark-integrated) — dark-stable ──
     No [data-theme="dark"] override for any of these; see note above. */
  --inv-subtle-info-bg:     #eff6ff;   /* bulk-actions bar bg, row hover */
  --inv-subtle-info-border: #bfdbfe;   /* bulk-actions bar border */
  --inv-row-unassigned-bg:  #fffbeb;
  --inv-profile-link-fg:    #2563eb;
  --material-badge-glass-bg:    #dbeafe;
  --material-badge-glass-fg:    #1d4ed8;
  --material-badge-closure-bg:  #fce7f3;
  --material-badge-closure-fg:  #be185d;
  --material-badge-capsule-bg:  #f3e8ff;
  --material-badge-capsule-fg:  #7c3aed;
  --material-badge-label-bg:    #ffedd5;
  --material-badge-label-fg:    #c2410c;
  --material-badge-foil-bg:     #ccfbf1;
  --material-badge-foil-fg:     #0d9488;
  --amber-800:                  #92400e;  /* extends the amber-100/500/600 Tailwind primitives, same "no dark override yet" family */
  --receipt-status-assigned-bg: #dcfce7;
  --receipt-status-assigned-fg: #166534;
  --receipt-status-partial-fg:  #1e40af;

  /* ── W4 cohort (Bottling/Schedule) — added 2026-07-07 ─────────────────────
     wr-badge-* pair with --wr-alert (already dark-integrated), so they get
     real dark overrides below. The "empty" badge variant and the other
     black/white alpha overlays here are arbitrary neutral chrome riding a
     colored gradient, not tied to a themed semantic color — dark-stable,
     same treatment as W2's overlay-backdrop-* / on-shell-* tokens. */
  --wr-badge-bg-subtle: rgba(231, 76, 60, 0.15);
  --wr-badge-bg-hover:  rgba(231, 76, 60, 0.25);
  --wr-badge-pulse-shadow-start: 0 0 0 0 rgba(231, 76, 60, 0.3);
  --wr-badge-pulse-shadow-peak:  0 0 8px 2px rgba(231, 76, 60, 0.2);

  --wr-badge-empty-border:       rgba(255, 255, 255, 0.3);
  --wr-badge-empty-fg:           rgba(255, 255, 255, 0.6);
  --wr-badge-empty-hover-bg:     rgba(255, 255, 255, 0.1);
  --wr-badge-empty-hover-fg:     rgba(255, 255, 255, 0.8);
  --wr-badge-empty-hover-border: rgba(255, 255, 255, 0.5);

  /* Snow-dropper glow — pairs with --snow-dropper-fg (already dark-integrated). */
  --snow-dropper-shadow: 0 0 6px rgba(21, 101, 192, 0.7), 0 1px 2px rgba(0, 0, 0, 0.4);

  /* Selected-date checkbox tint — pairs with --blue-500 (already dark-integrated). */
  --checkbox-checked-bg: rgba(13, 110, 253, 0.1);

  /* BottlingSchedule badge chrome riding colored gradients — arbitrary
     neutral overlays, dark-stable like the W2 overlay-backdrop-* precedent. */
  --date-range-badge-bg: rgba(0, 0, 0, 0.15);
  --otherline-badge-bg:  rgba(255, 255, 255, 0.3);

  /* WorkRequestReviewPanel sidebar hover/select tint — legacy Bootstrap-4
     primary blue (#007bff), distinct from --blue-500 (#0d6efd); dark-stable
     low-alpha overlay, not tied to a themed semantic color. */
  --wr-sidebar-item-hover-bg:    rgba(0, 123, 255, 0.04);
  --wr-sidebar-item-selected-bg: rgba(0, 123, 255, 0.08);

  /* ── W5 cohort (BulkWineDesk) — added 2026-07-07 ──────────────────────────
     BulkWineDesk consumes NwcDataGrid, which is pinned to var(--white) (see
     W2's note above) because this page isn't dark-integrated. Tokenizing it
     now must NOT flip its own shell/pane chrome dark either — that would
     recreate the same half-dark mismatch NwcDataGrid's pin was built to avoid,
     just inverted. So these are dark-stable (no [data-theme="dark"] override)
     by the same deliberate choice, not an oversight. */
  --bwd-muted-icon:      #868e96;
  --bwd-warn-strong:     #b45309;
  --bwd-tree-active-fg:  #1e3a8a;
  --bwd-row-archived-bg: #fafafa;
  --bwd-muted-fg:        #9ca3af;
  --bwd-asking-fg:       #047857;

  /* InlineEditCell — same dark-stable rationale (hosted inside BulkWineDesk's
     grid; error/danger tint has no existing near-miss token). */
  --bwd-focus-ring:            #0d6efd44;
  --bwd-danger-border-subtle:  #f5c2c7;
  --bwd-danger-bg-subtle:      #fff5f6;

  /* ── W6 cohort (Materials) — added 2026-07-07 ─────────────────────────────
     InventoryManager/MaterialsHub sit on the same un-dark-integrated
     slate-* / indigo-* / amber-* Tailwind primitives as W3's UnassignedReceiptsPanel
     and W5's BulkWineDesk — dark-stable by the same deliberate choice, not an
     oversight. Named for this domain (inv-* / mat-*) rather than borrowed from
     --ws-* / --bwd-* even where hex values happen to coincide, since those two
     families are explicitly scoped to their own unrelated components. */
  --inv-muted-fg:               #868e96;
  --inv-report-header-bg:       #fafbfc;
  --inv-warn-row-bg:            #fff8e1;
  --inv-fw-notice-bg:           #fff8e6;
  --inv-fw-notice-border:       #f0c14b;
  --inv-fw-notice-border-strong: #e6a817;
  --inv-fw-notice-fg:           #5e4400;

  /* MaterialsHub pulse-card tints — each pairs with an existing scale primitive
     at reduced alpha (indigo-600/cyan-accent/amber-500); kept as literal rgba()
     rather than color-mix() to match this migration's plain-substitution scope. */
  --mat-pulse-action-bg:      rgba(79, 70, 229, 0.05);   /* = --indigo-600 */
  --mat-pulse-action-border:  rgba(79, 70, 229, 0.2);
  --mat-pulse-transit-bg:     rgba(8, 145, 178, 0.05);   /* = --mat-cyan-accent */
  --mat-pulse-transit-border: rgba(8, 145, 178, 0.2);
  --mat-pulse-warn-bg:        rgba(245, 158, 11, 0.08);  /* = --amber-500 */
  --mat-pulse-warn-border:    rgba(245, 158, 11, 0.35);
  --mat-warn-strong-fg:       #b45309;
  --mat-cyan-accent:          #0891b2;

  /* MaterialsHub stock-type icon chips — solid fg reuses the matching
     material-badge-* / inv-* fg where one already exists exactly. */
  --mat-icon-bottle-bg: rgba(8, 145, 178, 0.1);
  --mat-icon-cork-bg:   rgba(124, 58, 237, 0.1);
  --mat-icon-foil-bg:   rgba(194, 65, 12, 0.1);
  --mat-icon-label-bg:  rgba(217, 119, 6, 0.1);
  --mat-icon-box-bg:    rgba(37, 99, 235, 0.1);

  --mat-stock-bar-low:   #dc2626;
  --mat-status-watch-bg: #fef9c3;
  --mat-status-watch-fg: #854d0e;
  --mat-status-low-bg:   #fee2e2;
  --mat-status-low-fg:   #991b1b;
  --mat-link-hover-bg:     #eef2ff;
  --mat-link-hover-border: #a5b4fc;
  --mat-link-hover-fg:     #3730a3;

  /* ── W7 cohort (Vessels + WineLots) — added 2026-07-07 ────────────────────
     TankSpecs's toolbar gray, debug-red borders, and grey divider stay
     dark-stable: this page has no other consumer verifying a dark guess
     beyond its own VR capture, and the red/grey are pre-existing debug-era
     literals (not tokenized as a design choice, just preserved as-is).
     WineLotPanel's residual row divider/hover are also dark-stable — the
     panel is click-gated (_showWineLotPanel in WineLotsPage), same
     no-unverified-dark-guess rationale as BlendingLayout/ImageCaptureEditor.
     WineLotsPage's vintage-tab-bar cyan family IS corpus-covered
     (winelots-main renders it unconditionally), so it gets real dark
     treatment below where lightening helps contrast. */
  --vessel-header-bg:    #f2f2f2;  /* TankSpecs sticky th + upper-row toolbar bg */
  --vessel-debug-border: red;     /* TankSpecs pre-existing debug border (mainContainer/sticky-search) */
  --vessel-divider:      grey;    /* TankSpecs .flex-container border-bottom */

  --z-vessel-table-header:  998;  /* TankSpecs sticky th */
  --z-vessel-toolbar:      1000;  /* TankSpecs .upper-row */
  --z-vessel-sticky-search: 999;  /* TankSpecs .sticky-search */

  --winelot-row-divider:  #f0f0f0; /* WineLotPanel row border */
  --winelot-row-hover-bg: #f0f4ff; /* WineLotPanel row hover */

  --winelot-tabs-border:       #D7DBDD; /* WineLotsPage vintage-tab bar divider */
  --winelot-tab-fg:            #16A2D7; /* WineLotsPage vintage-tab text */
  --winelot-tab-active-border: #4EBBE4; /* WineLotsPage selected-tab underline — already bright, dark-stable */

  /* ── W8 cohort (Lab + LabQc) — added 2026-07-08 ────────────────────────────
     LabQcRoundEntry's AnalysisTabContent/O2Co2FilterTabContent grid tables,
     QcSectionCard, PackagingProfileSidebar/ProfileMaterialCard/ProfileFieldEditor,
     PackagingQcSection badges, and TankGallonsSection. --blue-500-rgb is a
     comma-triplet primitive (not a color) so the several rgba(--blue-500, X%)
     focus-ring/selection literals scattered across this cohort stay in sync
     with --blue-500 automatically, incl. across the dark override. */
  --blue-500-rgb: 13, 110, 253;

  --labqc-grid-border:        #c0c0c0;  /* Analysis/O2Co2 grid cell borders */
  --labqc-grid-border-strong: #a0a0a0;  /* Analysis/O2Co2 grid header dividers */
  --labqc-grid-divider:       #d0d0d0;  /* Analysis inline-sample/recheck input divider */
  --labqc-grid-fade-rgb:      255, 255, 255;  /* Analysis grid right-edge scroll-fade gradient */
  --labqc-other-date-bg:        #f5f8fa;  /* grid cells from a different bottling date (read-only) */
  --labqc-other-date-header-bg: #e8f0f5;
  --labqc-other-date-border:    #6c9ec8;
  --labqc-input-hover-bg: #f5f5f5;  /* grid input hover tint */
  --labqc-recheck-bg:     #fafafa;  /* recheck-input / metadata-cell / value-only-row / saved-row tint */
  --labqc-focus-ring:     #0078d4;  /* Fluent-blue grid input focus ring — dark-stable, bright enough on both */
  --labqc-divider-subtle:    #f1f3f4;  /* PackagingProfileSidebar material-item header/footer hairline */
  --labqc-input-focus-border: #86b7fe;  /* Bootstrap-style lighter-blue input focus border */

  --labqc-success-fg:       #198754;  /* Bootstrap-success green reused across add-btn/spec-ok/badges/dot-complete */
  --labqc-success-fg-hover: #146c43;
  --labqc-spec-ok-bg:   #f8fff8;   /* pale-green spec-pass input/row tint */
  --labqc-spec-warn-bg: #fff5f5;  /* pale-red spec-warn input tint */
  --labqc-average-row-bg: #e8f5e9;  /* Capacity tab computed-average row tint (distinct shade from spec-ok) */

  --labqc-selected-bg: #f0f7ff;  /* selected material card / totals row pale-blue tint */
  --labqc-lot-bg: #fffbeb;       /* lot-number field/row pale-amber highlight (ProfileFieldEditor + ProfileMaterialCard) */
  --labqc-select-btn-hover: #0a58ca;  /* ProfileMaterialCard select-btn hover — Bootstrap link-hover blue, darker than --blue-700 */
  --labqc-collapsed-header-bg: #fafbfc;  /* QcSectionCard collapsed-header near-white tint; also LabQcRoundEntry's qc-context-bar */
  --labqc-status-empty-bg: #f0f0f0;      /* QcSectionCard status-empty pill */

  /* ── LabQcRoundEntry.razor.css tokens (W8b) — added 2026-07-08 ───────────
     Only the page's LIVE selectors are tokenized here; the file also
     contains a large confirmed-orphaned legacy block (old compact-header/
     tab-bar/patrol-table/capacity-table markup superseded by the extracted
     LabQc/Components/* children and the current context-bar + QcSectionCard
     layout — an explicit in-file dev comment at the entry-table section
     already documents one dead rule removed for the same reason). That
     block's hardcoded colors are deliberately left untouched — dead-code
     cleanup candidate, out of scope for the token migration, same treatment
     as BlendingLayout.razor.css from W2/W3-W7. */
  --labqc-tank-pill-border:   #b6d4fe;  /* context-pill.tank-pill border; also save-badge.saving border */
  --labqc-specs-strip-border: #e2ecf5;  /* analysis-specs-strip bottom border */
  --labqc-warning-border:     #ffecb5;  /* shared pale-amber warning border (profile-warning-banner x2, save-badge.unsaved) */
  --labqc-warning-icon-fg:    #e0a800;  /* profile-warning-banner icon */
  --labqc-badge-success-border: #badbcc;  /* session-badge/save-badge "success" pill border */
  --labqc-badge-neutral-border: #d3d6d8;  /* session-badge.session-closed pill border */
  --labqc-status-fail-fg: #842029;  /* swab-status.fail (Bootstrap danger-text-emphasis) */

  --labqc-badge-warning-bg: #ffc107;  /* shiner/lot amber badges — dark-stable */
  --labqc-badge-neutral-bg: #e2e3e5;  /* closure-badge (Bootstrap secondary-subtle) */
  --labqc-badge-neutral-fg: #41464b;
  --labqc-badge-success-fg: #0f5132;  /* package-badge / status-complete pill fg */
  --labqc-badge-info-bg: #cff4fc;     /* silk-badge (Bootstrap info-subtle) */
  --labqc-badge-info-fg: #055160;

  /* Snow-dropper indicator family — distinct Material-blue from the existing
     --snow-dropper-fg (#1565c0, Bottling schedule board); PackagingQcSection's
     own snow-indicator/snow-dropper-row use a slightly different blue (#1976d2). */
  --labqc-snow-fg:     #1976d2;
  --labqc-snow-bg:     #e3f2fd;
  --labqc-snow-border: #90caf9;
  --labqc-snow-row-bg: rgba(25, 118, 210, 0.05);

  /* PackagingProfileSidebar's OWN snow indicator — a distinct cyan, not the
     blue --labqc-snow-fg family above (different component, different icon). */
  --labqc-snow-cyan-fg:     #00bcd4;
  --labqc-snow-cyan-fg-rgb: 0, 188, 212;

  --labqc-verify-ok-bg:  rgba(25, 135, 84, 0.1);   /* PackagingQc verification-cell tints */
  --labqc-verify-bad-bg: rgba(220, 53, 69, 0.1);

  --z-labqc-backdrop: 1040;  /* MaterialSelector modal-backdrop — below --z-modal (1060) */

  /* ── W8 stragglers (LabQc) — added 2026-07-08 ─────────────────────────────
     Small remaining live gaps found on a re-audit: QcSectionCard's own
     card/hover shadow (shared with LabQcRoundEntry's .qc-sticky-header,
     same exact value), PackagingProfileSidebar's mobile fixed-position
     shadows, ProfileMaterialCard's hover shadow, and CapacityTabContent's
     section shadow. LabQcRoundEntry's and MaterialSelector's .modal-backdrop
     reuse the existing --overlay-backdrop-dim primitive directly (exact
     match) — no new token needed for those. */
  --labqc-card-shadow:       0 2px 4px rgba(0, 0, 0, 0.08);  /* = --dailyflow-header-shadow, fresh alias; shared by QcSectionCard + LabQcRoundEntry .qc-sticky-header */
  --labqc-card-shadow-hover: 0 2px 8px rgba(0, 0, 0, 0.1);   /* QcSectionCard:hover */
  --labqc-sidebar-shadow:        2px 0 8px rgba(0, 0, 0, 0.15);  /* PackagingProfileSidebar mobile fixed-position */
  --labqc-sidebar-toggle-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);   /* PackagingProfileSidebar collapsed toggle button */
  --labqc-material-card-hover-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);  /* ProfileMaterialCard:hover */
  --labqc-capacity-section-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);  /* = --dailyflow-card-shadow, fresh alias; CapacityTabContent .capacity-section */

  /* ── W9 cohort (Bottling/DailyFlow/Components) — added 2026-07-08 ────────
     DailyFlowPanelContent's extracted-child components. Split by dark-mode
     readiness the same way as prior cohorts: components built on the
     --gray-* / --surface-* scale get real dark overrides below; DailyFlowChangeCard
     and the appointment-gradient tokens sit on their own bespoke palettes
     (Tailwind-default-gray timeline dots, appt gradients matching the
     BottlingSchedule board family) and stay dark-stable where no corpus
     page currently exercises their dark rendering, same rationale as W3/W5/W6. */
  --dailyflow-spec-warning-border: #ffc107;  /* DrawingSearchPicker/ProfileGroupSidebar spec-drift banner border — Bootstrap warning, dark-stable */

  --dailyflow-hover-shadow:        0 2px 8px rgba(0, 0, 0, 0.15);  /* thumbnail/image hover elevation (Cola/Label/ProfileImageGallery) */
  --dailyflow-hover-shadow-sm:     0 2px 4px rgba(0, 0, 0, 0.15);  /* smaller hover elevation (DailyFlowListHelper/WeekNavigator appt buttons) */
  --dailyflow-linked-thumb-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);  /* LabelColaPicker linked-thumbnail hover, distinct blur radius from the shared 8px variant */
  --dailyflow-popover-shadow:      0 4px 12px rgba(0, 0, 0, 0.12);  /* CaseCodeSuggestionsPopover */
  --dailyflow-badge-shadow:        0 1px 3px rgba(0, 0, 0, 0.2);   /* BottlingDatesComponent sequence-badge */
  --dailyflow-header-shadow:       0 2px 4px rgba(0, 0, 0, 0.08);  /* WeekNavigatorComponent sticky header */
  --dailyflow-search-results-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);  /* WeekNavigatorComponent search dropdown */
  --dailyflow-card-shadow:         0 1px 3px rgba(0, 0, 0, 0.1);   /* DailyFlowListHelperComponent date-group card */
  --dailyflow-magnifier-shadow:    0 0 0 3px rgba(var(--blue-500-rgb), 0.15), 0 4px 12px rgba(0, 0, 0, 0.2);  /* BolScanPanel magnifier lens ring */

  --dailyflow-suggestion-chip-hover-bg: #e8f0fe;  /* LabelColaPicker suggestion-chip hover */
  --dailyflow-composition-icon-fg: #20c997;       /* BottlingCompositionSnipComponent header icon */
  --dailyflow-purple-accent:       #6f42c1;       /* header icon color shared by RunHeader/Dates/Winemaking components — dark-stable, medium-saturation Bootstrap purple reads on both */
  --dailyflow-info-badge-bg:       #e7f3ff;       /* pale-blue badge/chip bg, reused across Dates/Packaging/RunHeader components */
  --dailyflow-info-badge-hover-bg: #d0e8ff;       /* client-badge hover */
  --dailyflow-info-badge-fg:       #004085;       /* pairs with --dailyflow-info-badge-bg for stat-badge.expected/halfway */
  --dailyflow-bond-number-fg:      #666;          /* RunHeader bond-number muted text */
  --dailyflow-link-hover-fg:       #0a58ca;       /* Cola/MaterialStatusSection link hover — same Bootstrap link-hover blue as --labqc-select-btn-hover */
  --dailyflow-delete-btn-hover-bg: #a71d2a;       /* ProfileImageGallery delete-button hover */
  --dailyflow-image-type-fg:       #868e96;       /* ColaComponent image-type caption — same value as W5's --bwd-muted-icon, named fresh per the W6 domain-scoping precedent */
  --dailyflow-header-tag-bg:       rgba(255, 255, 255, 0.2);  /* BottlingDatesComponent case-count-header pill — white-on-colored-chrome, dark-stable like the on-shell-* family */

  --dailyflow-today-accent:       #17a2b8;   /* DailyFlowListHelperComponent "today" accent (Bootstrap info cyan) */
  --dailyflow-today-accent-hover: #138496;
  --dailyflow-today-accent-rgb:   23, 162, 184;  /* feeds the today.date-group box-shadow */
  --dailyflow-empty-fg:           #888;      /* DailyFlowListHelperComponent sp-empty */
  --dailyflow-subtle-bg:          #fafafa;   /* WeekNavigatorComponent day-cell/search-footer subtle bg */
  --dailyflow-today-tint-bg:      #f0f7ff;   /* WeekNavigatorComponent .week-nav-day.today */
  --dailyflow-current-tint-bg:    #f0fff4;   /* WeekNavigatorComponent .week-nav-day.current */

  --dailyflow-organic-fg: #f44336;             /* BottlingRunHeaderComponent organic-stamp (Material red, distinct from --red-500) */
  --dailyflow-organic-bg: rgba(244, 67, 54, 0.1);

  /* Appointment-badge gradients — visually paired with the BottlingSchedule
     board's --appt-other-gradient/--appt-multiday-gradient but at a slightly
     different alpha (0.85/0.9 vs 0.8/0.85); kept as distinct tokens rather
     than collapsed onto the board's values to preserve exact pixel fidelity. */
  --dailyflow-other-appt-gradient:    linear-gradient(to right, rgba(109, 213, 250, 0.85), rgba(41, 128, 185, 0.85));
  --dailyflow-multiday-appt-gradient: linear-gradient(to right, rgba(255, 193, 7, 0.9), rgba(255, 152, 0, 0.9));

  /* DailyFlowChangeCard timeline — built entirely on Tailwind's DEFAULT gray
     scale (distinct from this file's --slate-* Tailwind primitives) plus
     Tailwind's colored-50/600 pairs for 4-way event-type coding. Same
     un-dark-integrated treatment as W3's UnassignedReceiptsPanel: dark-stable,
     no [data-theme="dark"] override, since this card isn't corpus-covered
     for dark verification yet. --dailyflow-dot-default-fg/--dailyflow-dot-status-fg
     reuse the existing --indigo-600/--amber-600 PRIMITIVES (exact hex match);
     the others are fresh domain-scoped tokens per the W6 naming precedent. */
  --dailyflow-timeline-text:      #1f2937;
  --dailyflow-timeline-muted:     #6b7280;
  --dailyflow-timeline-connector: #e5e7eb;
  --dailyflow-timeline-faint:     #9ca3af;
  --dailyflow-timeline-strong:    #111827;
  --dailyflow-dot-default-bg: #eef2ff;
  --dailyflow-dot-default-fg: var(--indigo-600);
  --dailyflow-dot-created-bg: #ecfdf5;
  --dailyflow-dot-created-fg: #059669;
  --dailyflow-dot-deleted-bg: #fef2f2;
  --dailyflow-dot-deleted-fg: #dc2626;
  --dailyflow-dot-moved-bg:   #eff6ff;
  --dailyflow-dot-moved-fg:   #2563eb;
  --dailyflow-dot-status-bg:  #fffbeb;
  --dailyflow-dot-status-fg:  var(--amber-600);

  --dailyflow-diff-has-border: #a3cfbb;  /* ProfileGroupSidebar diff-tag.diff-has border, pairs with --green-100/--wr-status-accepted-fg */

  /* ── W9 cohort (Bottling/DailyFlow/Panels) — added 2026-07-08 ────────────
     SlidingPanel bodies (COLA/Label/Supplies/PreflightPanel etc). Continues
     the Components block's token family; several colors here exactly match
     Bootstrap/gray-scale PRIMITIVES already defined above and are reused
     directly rather than re-declared (see the per-file commit notes). */
  --dailyflow-mismatch-bg: #fff8e6;  /* BottlingCOLAPanel bond-mismatch card bg */
  --dailyflow-zoom-hint-bg:        rgba(0, 0, 0, 0.6);  /* thumbnail/preview zoom-hint pill, shared COLA+Label panels */
  --dailyflow-zoom-hint-hover-bg:  rgba(0, 0, 0, 0.8);
  --dailyflow-zoom-hint-bg-strong: rgba(0, 0, 0, 0.7);  /* BottlingLabelPanel's centered preview zoom-hint, distinct alpha from the thumbnail variant */
  --dailyflow-preview-overlay-shadow: 0 12px 48px rgba(0, 0, 0, 0.4);  /* BottlingCOLAPanel hover-preview-overlay */

  --dailyflow-suggestion-accent:      #3d5a99;  /* shared "AI suggestion" accent — COLA+Label panel headers, hover borders, info bars */
  --dailyflow-suggestion-accent-rgb:  61, 90, 153;
  --dailyflow-suggestion-banner-gradient: linear-gradient(135deg, #f0f4ff 0%, #e8f0fe 100%);  /* BottlingCOLAPanel suggestion-banner */
  --dailyflow-suggestion-banner-border:   #c5d5f0;
  --dailyflow-suggestion-info-bar-bg:     #eef3ff;  /* BottlingLabelPanel suggestion-info-bar — distinct near-miss from the banner gradient's stop colors, kept separate for pixel fidelity */
  --dailyflow-suggestion-info-bar-border: #c5d5f5;
  --dailyflow-suggested-accent:           #7baaf7;  /* BottlingLabelPanel .sp-card.suggested border/ring */
  --dailyflow-suggestion-badge-gradient:  linear-gradient(135deg, #4a7cf7 0%, var(--dailyflow-suggestion-accent) 100%);
  --dailyflow-dismiss-hover-bg: rgba(0, 0, 0, 0.08);
  --dailyflow-dismiss-hover-fg: #333;
  --dailyflow-suggestion-row-border: #e0e0e0;
  --dailyflow-thumb-placeholder-bg:  #f1f1f1;
  --dailyflow-no-image-fg:           #aaa;
  --dailyflow-confidence-bg:      #d4edda;  /* BottlingCOLAPanel suggestion-confidence badge — Bootstrap green-subtle, distinct from --green-100 */
  --dailyflow-confidence-high-bg: #c3e6cb;

  --dailyflow-danger-hover-bg: rgba(220, 53, 69, 0.15);  /* BottlingLabelPanel date-clear-btn hover — = --red-500 at 15% */
  --dailyflow-lightbox-overlay-bg:     rgba(0, 0, 0, 0.85);
  --dailyflow-lightbox-img-shadow:     0 8px 32px rgba(0, 0, 0, 0.5);
  --dailyflow-lightbox-close-hover-bg: rgba(255, 255, 255, 0.4);
  --dailyflow-lightbox-hint-fg:        rgba(255, 255, 255, 0.6);
  --dailyflow-po-chip-border: #9eeaf9;  /* SuppliesPanel receipt-po-chip border, pairs with --labqc-badge-info-bg/-fg */
  --dailyflow-pipeline-row-bg: #f5f9ff;  /* SuppliesPanel status-row.pipeline-row */

  /* Bespoke ultra-high overlay tiers for the COLA/Label panels' hover-preview,
     lightbox, and delete-confirm dialog — all sit above --z-crop-overlay
     (10000), the previous top of the documented scale. Hover-preview reuses
     --z-crop-overlay's exact value (10000); lightbox/confirm-dialog extend
     the scale one and two steps above it. --dailyflow-z-confirm-dialog is
     passed to Shared/ConfirmDialogPanel.razor's ZIndexOverride param by
     BottlingLabelPanel (the only caller needing to clear the lightbox tier);
     every other ConfirmDialogPanel instance uses the component's default
     var(--z-modal). */
  --dailyflow-z-lightbox:        10002;
  --dailyflow-z-confirm-dialog:  10003;

  /* ── W9 cohort (Bottling/DailyFlow/Sections) — added 2026-07-08 ────────── */
  --dailyflow-naked-dates-bg:       #fffef5;  /* PackagingProfileSection naked-dates-section — near-white warm tint */
  --dailyflow-naked-dates-hover-bg: #ffeeba;  /* naked-dates-header/-header:hover — more saturated than --yellow-100 */

  /* ── W9 cohort (Bottling/DailyFlow/SignOff) — added 2026-07-08 ───────────
     Pure-saturated attention-glow shadows for the COLA/Label sign-off alarm
     states. Dark-stable (no override below) — these are bright colored
     glows meant to read as an alert regardless of page theme, same
     treatment as the Panels zoom-hint/lightbox scrim family. */
  --dailyflow-alarm-shadow:    0 0 10px rgba(255, 0, 0, 0.7);
  --dailyflow-accepted-shadow: 0 0 10px rgba(0, 255, 0, 0.7);
  --dailyflow-waiver-shadow:   0 0 10px 5px rgba(255, 149, 0, 0.7);

  /* ── W9 cohort (Bottling/DailyFlow root) — added 2026-07-08 ───────────────
     DailyFlowPanelContent.razor.css is 928 lines; ~530 of them (a whole
     legacy card-grid layout — .newCard/.cardTest/.cardStyle* / .left-column/
     .right-column/.testingContainer/.packagingMaterials-* / etc.) are
     confirmed-orphaned dead CSS, superseded by the current collapsed-
     toolbar/section-card layout — verified against the .razor markup, zero
     matches for any class in that block. Same treatment as W8's
     LabQcRoundEntry.razor.css orphaned-CSS finding: NOT touched, NOT
     tokenized, out of scope. Only the live tail (collapsed-toolbar,
     collapsed-tab incl. rundetails/status variants, section-card, notepad
     side panel) is tokenized below. See the W9 handoff for the full
     live/dead class inventory. */
  --dailyflow-rundetails-bg-start:      #e3f2fd;
  --dailyflow-rundetails-bg-end:        #bbdefb;
  --dailyflow-rundetails-border:        #64b5f6;
  --dailyflow-rundetails-fg:            #1565c0;
  --dailyflow-rundetails-hover-bg-start: #bbdefb;
  --dailyflow-rundetails-hover-bg-end:   #90caf9;

  /* Pure-saturated status accents on the collapsed-tab status dots — same
     alarm/accepted/waiver family as SignOff's shadows above, distinct
     values (border alpha 0.5, glow radius 6px vs SignOff's 10px). Dark-
     stable, same reasoning. */
  --dailyflow-status-alarm-border:    rgba(255, 0, 0, 0.5);
  --dailyflow-status-alarm-glow:      0 0 6px rgba(255, 0, 0, 0.6);
  --dailyflow-status-accepted-border: rgba(0, 255, 0, 0.5);
  --dailyflow-status-accepted-glow:   0 0 6px rgba(0, 255, 0, 0.6);
  --dailyflow-status-waiver-border:   rgba(255, 149, 0, 0.5);
  --dailyflow-status-waiver-glow:     0 0 6px rgba(255, 149, 0, 0.6);

  --dailyflow-section-card-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.15);

  /* ── W9 straggler (DailyFlowPanelContent .card) — added 2026-07-08 ────────
     One live rule missed by the root-cohort pass above: `.card` (used
     alongside `.section-card` on every article — `class="card section-card
     ..."`) still carried its own bare box-shadow. Same geometry as
     --dailyflow-section-card-shadow, double the alpha — kept distinct
     rather than collapsed, to preserve exact pixel fidelity. */
  --dailyflow-legacy-card-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.3);

  /* ── W10 cohort (Winemaking/ProjectWorkspacePage) ──────────────────────────
     Dark-stable component tokens: pure-saturated status-dot accents and the
     delete-confirm danger banner are narrow interactive-only states not
     exercised by the winemaking-workspace VR capture (no [data-theme="dark"]
     override — same reasoning as DailyFlow's status-dot family above). */
  --workspace-danger-border: #fda29b;
  --workspace-danger-text:   #7f1d1d;
  --workspace-status-draft:  #fdb022;
  --workspace-status-saved:  #32d583;
  --workspace-status-active-border: #12b76a;

  /* ── W10 straggler (Winemaking/ProjectWorkspacePage nav-flyout) — added
     2026-07-08. Three live rules missed by the original cohort pass: the
     narrow-viewport conversations flyout drawer + its backdrop, and the
     mirrored artifact overlay drawer. Dark-stable (interactive-only,
     narrow-viewport states not exercised by the winemaking-workspace VR
     capture — same reasoning as the danger/status tokens above). */
  --wm-nav-flyout-shadow:         8px 0 24px rgba(0, 0, 0, 0.18);
  --wm-nav-flyout-backdrop-bg:    rgba(15, 23, 42, 0.12);  /* = --slate-900 at 12% */
  --wm-artifact-drawer-shadow:    -8px 0 24px rgba(0, 0, 0, 0.12);

  /* ── W10 cohort (Winemaking/WinemakingSchedule) ────────────────────────────
     --wmsched-cell-bg gets a real [data-theme="dark"] override below (this
     page is now corpus-covered by winemaking-schedule, so the dark value is
     VR-verified, not guessed). The hover/active states are translucent alpha
     overlays instead — they read correctly over any base surface in either
     theme without needing their own override, and aren't exercised by a
     static VR capture anyway (hover/active are interactive-only). */
  --wmsched-cell-bg: #f0f7ff;
  --wmsched-cell-hover-gradient: linear-gradient(to right, rgba(46, 204, 113, 0.15), rgba(243, 156, 18, 0.15));
  --wmsched-cell-active-bg: rgba(168, 85, 247, 0.18);
  --wmsched-header-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.4);  /* .calendar-header sticky shadow — straggler, added 2026-07-08 */

  /* ── W11 cohort (LabelCola/ColaCardItem + LabelCardItem) ───────────────────
     Shared card box-shadow pair — identical values were duplicated across
     both card components (COLA cards and Label cards render in the same
     grid). Real dark override below — labelcola-manager (corpus) renders a
     populated card grid in both themes. Hover is interactive-only (not
     exercised by a static VR capture) — dark value is a judgment call. */
  --label-card-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  --label-card-shadow-hover: 0 4px 16px rgba(0, 0, 0, 0.10);

  /* Custom <select> caret (Bootstrap's own default indicator SVG, #343a40 stroke).
     A data: URI can't reference CSS variables, so the whole background-image
     is the token — dark gets a light-stroke variant below instead of going
     invisible against a dark field background. */
  --select-caret-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");

  /* LabelViewPanel (W11) — translucent-white overlays sitting ON a saturated
     colored bar (--blue-500) or a near-black image lightbox scrim, not on the
     page surface. Theme-invariant by design (same in both themes) — no
     [data-theme="dark"] override needed, same reasoning as --white above. */
  --overlay-on-brand-bg: rgba(255, 255, 255, 0.15);
  --overlay-on-brand-fg: rgba(255, 255, 255, 0.8);
  --overlay-on-scrim-fg: rgba(255, 255, 255, 0.5);

  /* Same #868e96 value as --bwd-muted-icon / --inv-muted-fg / --dailyflow-image-type-fg
     — named fresh per the established domain-scoping precedent. No dark override on
     any of those siblings either (this muted caption gray is left theme-invariant). */
  --labelcola-muted-fg: #868e96;
  /* Same #0f5132 family as --wr-status-accepted-fg / --labqc-badge-success-fg —
     dark override below matches their #4eef85 treatment. */
  --labelcola-success-fg: #0f5132;
  /* Romantic-statement callout (LabelViewPanel) — pale pink bg + burgundy accent,
     reuses --accent-burgundy for the text/border. Dark override below. */
  --labelcola-romantic-bg: #fdf8f8;
  /* OCR raw-JSON viewer (LabelViewPanel) — intentionally an always-dark code block
     regardless of site theme (matches how code/syntax viewers conventionally read),
     no [data-theme="dark"] override. */
  --labelcola-code-bg: #1e1e1e;
  --labelcola-code-fg: #d4d4d4;
  /* Status-tint overlays on the stats-bar (--blue-500) — same theme-invariant
     reasoning as --overlay-on-brand-*. */
  --labelcola-stat-approved-bg: rgba(25, 135, 84, 0.4);
  --labelcola-stat-pending-bg: rgba(255, 193, 7, 0.4);

  /* LabelManager (W11) — status/notice/lightbox family. Dark overrides below
     follow this file's general pattern: bg becomes a dark-tinted surface,
     fg lifts to a brighter version of the same hue. */
  --labelcola-status-success-bg:     #e3f5e9;  /* inspector-status.approved, flag.on — reused 2x in this file */
  --labelcola-status-success-border: #9bd6ad;  /* flag.on border */
  --labelcola-status-success-fg:     #1a7d3b;  /* inspector-status.approved, flag.on, proof-stat-ok — reused 3x */
  --labelcola-status-warning-fg:     #8a6100;  /* inspector-status.pending (bg reuses existing --yellow-100, exact match) */
  --labelcola-status-warning-fg-strong: #b9621f;  /* proof-stat-warn — distinct, more-orange warning shade */
  --labelcola-status-danger-bg:      #fdeaea;  /* flag.fail bg */
  --labelcola-status-danger-border:  #e7a5a5;  /* flag.fail border */
  --labelcola-status-danger-fg:      #b02a2a;  /* flag.fail fg */
  /* Same 4-value family as --inv-fw-notice-* (Inventory), named fresh per the
     established domain-scoping precedent (identical values, different domain). */
  --labelcola-notice-bg:            #fff8e6;
  --labelcola-notice-border:        #f0c14b;
  --labelcola-notice-border-strong: #e6a817;
  --labelcola-notice-fg:            #5e4400;
  /* Same value as --wr-alert-strong — LabelManager's PDF-icon red. */
  --labelcola-alert-strong: #c0392b;
  /* Pale danger tint for the extraction-errors panel — distinct from --state-danger-bg. */
  --labelcola-extract-error-bg:     #fff8f5;
  --labelcola-extract-error-border: #f5c6c6;
  /* Same value as --dailyflow-lightbox-overlay-bg, aliased per domain-scoping precedent. */
  --labelcola-lightbox-overlay-bg: rgba(0, 0, 0, 0.85);
  --labelcola-lightbox-img-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
  --z-labelcola-lightbox: 1090;  /* between --z-modal (1060) and --z-theme-toggle (1100) */

  /* LabelNewPanel (W11) — a self-contained Tailwind color micro-palette,
     distinct from this app's Bootstrap-esque gray/blue/red scale (same
     numeric shade name ≠ same value across the two systems, so these do NOT
     map onto --gray-N/--blue-500/etc by number). No [data-theme="dark"]
     overrides — matching the existing --amber-100/500/600/800 "Tailwind
     primitives, no dark override yet" precedent already established in this
     same file (ocr-check-badge, is-warning). #92400e reuses --amber-800
     directly rather than a new alias since it's the exact same primitive. */
  --lnp-bg-gradient-end: #eef1f5;      /* label-panel-container gradient end */
  --lnp-text-strong: #374151;          /* section-title, label b */
  --lnp-text-muted: #6b7280;           /* label, image-label */
  --lnp-surface-subtle: #f9fafb;       /* image-preview/compliance-row/ocr-scan-section bg */
  --lnp-border: #e5e7eb;               /* image-preview/compliance-row/email-section border */
  --lnp-border-input: #d1d5db;         /* input border, ocr-scan-section dashed border */
  --lnp-text-input: #1f2937;           /* input text */
  --lnp-focus-border: #3b82f6;
  --lnp-focus-ring: rgba(59, 130, 246, 0.15);
  --lnp-info-gradient-start: #eff6ff;  /* ocr-scanning-indicator + ai-prompt-card share this gradient */
  --lnp-info-gradient-end: #dbeafe;
  --lnp-info-border: #93c5fd;
  --lnp-info-fg: #1d4ed8;              /* ocr-scanning-indicator text */
  --lnp-info-icon: #2563eb;            /* ai-prompt-icon */
  --lnp-info-strong: #1e40af;          /* ai-prompt-content strong */
  --lnp-info-shadow: rgba(59, 130, 246, 0.1);
  --lnp-muted-body: #4b5563;           /* ai-prompt-content p */
  --lnp-success-bg: #ecfdf5;           /* bol-file-indicator; ocr-complete-indicator gradient start */
  --lnp-success-gradient-end: #d1fae5;
  --lnp-success-border: #6ee7b7;
  --lnp-success-fg: #047857;
  --lnp-danger-border: #ef4444;
  --lnp-danger-fg: #dc2626;            /* field-error text */
  --lnp-danger-ring: rgba(239, 68, 68, 0.15);
  --lnp-badge-gradient-end: #fde68a;   /* ocr-check-badge, paired with --amber-100 start */
  --lnp-badge-border: #fcd34d;         /* ocr-check-badge + ai-error-card border */
  --lnp-warn-gradient-start: #fefce8;  /* ai-error-card */
  --lnp-warn-gradient-end: #fef9c3;
  --lnp-warn-fg: #713f12;
  --lnp-warn-link: #a16207;
  --lnp-shadow-card: 0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
  --lnp-shadow-input: 0 1px 2px rgba(0, 0, 0, 0.04);  /* reused across 7 input/focus rules */
  --lnp-shadow-email: 0 1px 3px rgba(0, 0, 0, 0.05);

  /* ── W12 cohort (Packaging) ────────────────────────────────────────────────
     Bootstrap's raw $warning fill — a missing rung between --yellow-100 and
     --yellow-700 in the existing primitive ladder, needed literally (not the
     100/700 semantic shades) by GlassOas and DocumentInbox. Dark-stable, no
     override, same as the amber/slate Tailwind-primitive extensions above. */
  --yellow-500: #ffc107;
  --yellow-500-rgb: 255, 193, 7;

  /* Shared chrome duplicated across the cohort's non-corpus files (GlassOas,
     DocumentInbox, ReceiveShipment) — dark-stable, none of these are exercised
     by a static VR capture (collapsed sections, hover-only dropdowns, or
     detail views not opened by default). */
  --pkg-divider:          #f0f0f0;   /* GlassOas .go-section, DocumentInbox invoice/bol-match dividers */
  --pkg-dropdown-shadow:  0 4px 12px rgba(0, 0, 0, 0.1);   /* ReceiveShipment + DocumentInbox search-dropdowns */
  --pkg-card-tint-bg-end: #f0f4ff;   /* pairs with --accent-preview-bg (already dark-integrated) as the gradient start */

  /* GlassStatus (W12, corpus-covered by packaging-glass-status) — summary
     cards + row thumbnails render in the VR capture, so these get real dark
     overrides below. gs-card--warning isn't triggered by the corpus data (0
     unmatched at capture time) — its dark value is a best-effort match to the
     verified danger-card treatment, not independently VR-confirmed. */
  --pkg-card-warning-bg-start: #fffbeb;
  --pkg-card-danger-bg-start:  #fef2f2;
  --pkg-card-danger-bg-end:    #fee2e2;
  --pkg-card-danger-border:    #ef4444;
  --pkg-thumb-border:          #e5e7eb;
  --pkg-thumb-hover-shadow:    0 8px 24px rgba(0, 0, 0, 0.25);   /* hover-only, interactive */

  /* GlassStatus's SlidingPanel detail view (closed by default — not corpus-
     visible) + GlassLibrary's collapsed import section / upload-review-only
     match fields — dark-stable, best-effort like the rest of this block. */
  --pkg-muted-body:      #4b5563;
  --pkg-text-muted:      #6b7280;
  --pkg-panel-bg-subtle: #fafbfc;   /* = --inv-report-header-bg/--ws-panel-bg, fresh alias per this file's domain-scoping precedent */
  --pkg-link-hover-fg:   #3730a3;   /* = --mat-link-hover-fg, fresh alias */
  --pkg-success-bg:      #f0fdf4;
  --pkg-success-border:  #bbf7d0;
  --pkg-success-fg:      #166534;
  --pkg-badge-reviewed-bg: #dcfce7;   /* pairs with --pkg-success-fg */
  --pkg-badge-approved-fg: #15803d;   /* pairs with --pkg-success-bg */

  /* Inventory.razor.css (Packaging domain) — near-duplicate of the Materials
     domain's mh-icon-* / material-badge-* icon-tint family (identical rgba/hex
     literals, different page). Named fresh for this domain per the same
     domain-scoping precedent as W6's inv-* / mat-* additions, rather than
     cross-referencing Materials' tokens. Dark-stable — this page isn't dark-
     integrated and isn't corpus-covered. */
  --pkg-icon-glass-bg:   rgba(8, 145, 178, 0.1);
  --pkg-icon-glass-fg:   #0891b2;
  --pkg-icon-closure-bg: rgba(124, 58, 237, 0.1);
  --pkg-icon-closure-fg: #7c3aed;
  --pkg-icon-capsule-bg: rgba(194, 65, 12, 0.1);
  --pkg-icon-capsule-fg: #c2410c;
  --pkg-icon-label-bg:   rgba(217, 119, 6, 0.1);    /* fg already var(--amber-600) */
  --pkg-icon-box-bg:     rgba(37, 99, 235, 0.1);
  --pkg-icon-box-fg:     #2563eb;
  --pkg-icon-muted-bg:   rgba(100, 116, 139, 0.1);  /* fg already var(--slate-500) */

  /* LabelProofs.razor.css — Tailwind blue/gray micro-palette (upload AI-prompt
     card, scan indicator, staged-image previews, lightbox, status badges).
     Not corpus-covered; dark-stable like LabelNewPanel/LabelViewPanel in W11. */
  --pkg-text-strong:  #374151;
  --pkg-border-input: #d1d5db;
  --pkg-shadow-badge:       0 1px 4px rgba(0, 0, 0, 0.15);
  --pkg-shadow-thumb-hover: 0 2px 8px rgba(0, 0, 0, 0.15);
  --pkg-info-gradient-start: #eff6ff;
  --pkg-info-gradient-end:   #dbeafe;
  --pkg-info-border:         #bfdbfe;
  --pkg-info-icon:      #3b82f6;
  --pkg-info-fg-soft:   #1e3a5f;
  --pkg-info-fg-strong: #1e40af;   /* also LabelProofs' badge-uploaded fg */
  --pkg-danger-icon: #dc2626;   /* = --lnp-danger-fg/--mat-stock-bar-low/--dailyflow-dot-deleted-fg, fresh alias */
  --pkg-lightbox-overlay-bg: rgba(0, 0, 0, 0.82);
  --pkg-lightbox-img-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
  --pkg-shadow-footer: 0 -2px 8px rgba(0, 0, 0, 0.06);

  /* ClosureLibrary.razor.css — cork accent (icon tint + category badge). */
  --pkg-cork-bg: rgba(139, 90, 43, 0.12);
  --pkg-cork-fg: #8b5a2b;

  /* ── W13 cohort (Harvest) ────────────────────────────────────────────────
     WeightTags (corpus-covered by harvest-weighttags — dashboard cards render
     real data: organic tons, missing-scans warning, scan-coverage). Coverage
     yellow/red states aren't triggered by the corpus's current data (97.9%
     coverage renders green), so their tokens are best-effort like the rest
     of this block pending real trigger data. */
  --hvt-card-icon-scan-bg: rgba(6, 182, 212, 0.1);
  --hvt-card-icon-scan-fg: #0891b2;   /* = --pkg-icon-glass-fg, fresh alias per W12's domain-scoping precedent */

  --hvt-coverage-green-bg-start: #f0fdf4;
  --hvt-coverage-green-bg-end:   #dcfce7;
  --hvt-coverage-green-border:   #86efac;

  --hvt-coverage-red-bg-start: #fef2f2;
  --hvt-coverage-red-bg-end:   #fee2e2;
  --hvt-coverage-red-border:   #fca5a5;
  --hvt-coverage-red-icon-bg:  rgba(220, 38, 38, 0.1);
  --hvt-coverage-red-icon-fg:  #dc2626;   /* = --pkg-danger-icon/--lnp-danger-fg/--mat-stock-bar-low, fresh alias */

  --hvt-icon-coverage-yellow-bg: rgba(217, 119, 6, 0.12);   /* fg already var(--amber-600) */

  --hvt-bulk-bar-bg:     #eef2ff;   /* WeightTags bulk-actions bar; also WeightTagBulkUploadPanel drop-area + hover */
  --hvt-bulk-bar-border: #c7d2fe;

  --hvt-selected-row-bg: rgba(var(--indigo-600-rgb), 0.06);

  /* ExtractionReview — corpus-covered (admin-extraction-review renders a
     real 3800+-row doc-type breakdown). Both gradient stops below are fresh,
     deliberately dark-STABLE aliases (NOT var(--accent-preview-bg), which
     flips to a dark navy in dark mode — pairing a flipping start with a
     non-flipping end produced a half-dark/half-light card with washed-out
     text, caught via the real dark VR capture during W13). Classification
     icon/badge colors below stay dark-stable too, same non-corpus-verified-
     shade caveat as the rest of this block. */
  --hvt-er-card-gradient-start:  #f8f9ff;   /* = --accent-preview-bg's LIGHT value only — do not swap to the var, see note above */
  --hvt-er-card-gradient-end:    #f0f4ff;
  --hvt-er-active-gradient-end:  #e0e7ff;   /* active-card start reuses var(--hvt-bulk-bar-bg) */
  --hvt-er-active-shadow:        0 0 0 2px rgba(var(--indigo-600-rgb), 0.2);
  --hvt-er-icon-indigo-bg:       rgba(var(--indigo-600-rgb), 0.1);
  --hvt-er-icon-weighttag-bg:    rgba(16, 185, 129, 0.1);   /* = --emerald-500 */
  --hvt-er-icon-bol-bg:          rgba(245, 158, 11, 0.1);   /* = --amber-500 */
  --hvt-er-icon-cola-bg:         rgba(99, 102, 241, 0.1);   /* = --indigo-500 */
  --hvt-er-icon-permit-bg:       rgba(14, 165, 233, 0.1);
  --hvt-er-icon-permit-fg:       #0ea5e9;
  --hvt-er-icon-invoice-bg:      rgba(168, 85, 247, 0.1);   /* = --purple-500 */
  --hvt-er-icon-label-bg:        rgba(236, 72, 153, 0.1);   /* = --pink-500 */
  --hvt-er-icon-glass-bg:        rgba(20, 184, 166, 0.1);
  --hvt-er-icon-glass-fg:        #14b8a6;
  --hvt-er-badge-confirmed-bg:   #3b82f6;
  --hvt-er-item-selected-shadow: 0 0 0 2px rgba(var(--indigo-600-rgb), 0.25);

  /* ── W13 cohort (Blending) ───────────────────────────────────────────────
     BlendCompositionSummary's composition-bar violet ladder (corpus-covered
     indirectly — the bar/dot elements aren't in the blending-trialblend
     capture's default view, best-effort). --blend-bar-primary already
     reuses var(--indigo-500); these extend the same ladder. */
  --blend-bar-secondary:   #8b5cf6;
  --blend-bar-tertiary:    #a78bfa;
  --blend-bar-quaternary:  #c4b5fd;
  --blend-bar-muted:       #d1d5db;

  /* LotExplorerPanel — extends the existing --ws-* BlendingLayout-workspace
     family (see this file's own note above: "self-contained blue-gray design
     language (Untitled-UI-style neutrals) not yet dark-mode-integrated; not
     covered by the VR corpus"). Most of LotExplorerPanel's literals are EXACT
     matches to existing --ws-* tokens (reused directly in the .razor.css);
     the new tokens below extend the SAME family for values without an
     existing rung, rather than borrowing from --inv-* / other domains per the
     established domain-scoping precedent. Dark-stable, no override, same
     policy as the rest of --ws-*. */
  --ws-surface-hover-strong:    #e4e7eb;   /* lot-group-header:hover */
  --ws-divider-subtle:          #f5f6f8;   /* lot-row border-bottom */
  --ws-row-expanded-bg:         #f0f5ff;   /* = --inv-selected-tint-bg, fresh ws-alias */
  --ws-select-hover-bg:         #0b5ed7;   /* btn-select-lot:hover — Bootstrap primary-hover */
  --ws-select-hover-border:     #0a58ca;   /* = --labqc-select-btn-hover/--dailyflow-link-hover-fg, fresh ws-alias */
  --ws-focus-shadow:            0 0 0 2px rgba(3, 102, 214, 0.12);   /* = --app-shell-blue-bright (#0366d6) at 12%, focus ring */
  --ws-warn-tint-bg:            #fff8e1;   /* = --inv-warn-row-bg, fresh ws-alias */
  --ws-warn-tint-border:        #f0e6c0;
  --ws-warn-tint-border-strong: #d4c5a0;
  --ws-text-body:               #2d2d2d;   /* lot-vessel-summary */
  --ws-burgundy-tint-bg:        #f8eef0;   /* pairs with --accent-burgundy */

  --ws-badge-fermenting-bg: #fce7f3;  --ws-badge-fermenting-fg: #9d174d;
  --ws-badge-ml-bg:         #e0e7ff;  --ws-badge-ml-fg:         #3730a3;
  --ws-badge-settling-bg:   #e0f2fe;  --ws-badge-settling-fg:   #0369a1;
  --ws-badge-coldsoak-bg:   #cffafe;  --ws-badge-coldsoak-fg:   #155e75;
  --ws-badge-prerelease-bg: #d1fae5;  --ws-badge-prerelease-fg: #065f46;
  --ws-badge-received-bg:   #ede9fe;  --ws-badge-received-fg:   #5b21b6;
  --ws-badge-default-bg:    #f3f4f6;  --ws-badge-default-fg:    #475467;   /* fg = --ws-text-secondary value */

  /* ── W14 cohort (Admin) ──────────────────────────────────────────────────
     None of the CopilotDashboard/CopilotAnalytics/CopilotSessionDetail
     colors below are corpus-verified — all three depend on
     ICopilotAuditAdminService, which requires a real Firebase bearer token
     that this harness's DevBypass auth doesn't provide, so every page
     behind it renders empty/error in a static capture regardless of settle
     time or a real record id (see W14 handoff §4). Dark-stable/best-effort,
     same non-corpus-visible precedent as GlassLibrary's collapsed sections. */
  --admin-metric-error-bg:     #fef2f2;
  --admin-metric-error-border: #fca5a5;
  --admin-metric-error-fg:     #dc2626;   /* fresh alias, = --pkg-danger-icon/--hvt-coverage-red-icon-fg/etc. */
  --admin-metric-warning-bg:     #fefce8;
  --admin-metric-warning-border: #fde68a;   /* = --lnp-badge-gradient-end, fresh alias */

  --admin-panel-bg-subtle: #fafbfc;   /* = --ws-panel-bg/--inv-report-header-bg/--pkg-panel-bg-subtle, fresh alias */
  --admin-code-highlight-fg: #d63384;
  --admin-rule-bg:     #f0f4f0;   /* pairs with var(--nwc-primary) tint */
  --admin-rule-border: #d4e2d4;

  --admin-turn-user-bg:     #e8f4fd;
  --admin-turn-user-border: #2196f3;   /* Material blue-500, distinct from --blue-500/#0d6efd */
  --admin-turn-assistant-bg: #f0f7f0;   /* pairs with var(--nwc-primary) tint, like --admin-rule-bg */
  --admin-field-modified-bg: #fffcf0;

  /* CaseGoodsBolPanel.razor.css (Pages/Admin/Shipping) — SlidingPanel content
     opened conditionally from DailyFlowPanelContent/CaseGoodsBolPage, not
     open by default — not corpus-visible, dark-stable/best-effort. Own
     "bol-" prefix (matches this component's own CSS class prefix) since it
     has enough of its own palette to warrant sub-scoping, same precedent as
     --hvt-er-* / --ws-* within their parent cohorts. */
  --bol-linked-bg:       #f0faf4;   /* .bol-run-card.linked, pairs with var(--green-600) border */
  --bol-chip-mono-bg:    #dde3ea;
  --bol-muted-fg:        #9ca3af;   /* = --bwd-muted-fg/--dailyflow-timeline-faint, fresh alias */
  --bol-skel-highlight:  #f4f5f7;   /* skeleton-loader shimmer */
  --bol-tint-bg:         #e7f3ff;   /* = --dailyflow-info-badge-bg, fresh alias — autofill tag + run badge */
  --bol-link-fg:         #0a58ca;   /* = --labqc-select-btn-hover/--dailyflow-link-hover-fg/--ws-select-hover-border, fresh alias */
  --bol-bond-parent-bg:  #fff9e6;
  --bol-bond-parent-fg:  #664d03;
  --bol-ctx-bg:          #f0f7ff;   /* = --labqc-selected-bg/--dailyflow-today-tint-bg/--wmsched-cell-bg, fresh alias */
  --bol-ctx-border:      #b6d4fe;
  --bol-ctx-identity-fg: #1a3a5c;

  /* ── W14 cohort (Maintenance) ────────────────────────────────────────────
     MaintenanceMain is corpus-covered (maintenance-main renders real work
     orders with live status/urgency badges) — the badge/pill colors below
     are real-data-verified. MaintenanceControlPanel/MaintenancePanel are
     SlidingPanel content, not open by default — dark-stable/best-effort. */
  --maint-dot-hidden-bg: rgba(255, 255, 255, 0.8);   /* filter-pill active-dot hide state */
  --maint-photo-overlay-hover-bg: rgba(0, 0, 0, 0.3);   /* MaintenancePanel photo-tile hover scrim */
  --maint-divider:     #f0f0f0;   /* = --pkg-divider, fresh alias — MaintenanceControlPanel comm-entry */
  --maint-text-faint:  #888;   /* MaintenanceControlPanel comm-date */

  /* ── W14 cohort (Supply) ─────────────────────────────────────────────────
     SupplyOrdersPage is corpus-covered (supply-orders) — the summary-card
     active/selected-row tint below renders in the default "Received" tab.
     Drawer/confirm-overlay are interaction-gated, not corpus-visible. */
  --supply-selected-bg: #eef5ff;   /* summary-card.active + order-table selected row */

  /* ── CopilotPanel cohort (NWCWebApp2022.Copilot) — added 2026-07-08 ───────
     Parked separately from the per-page W-waves (2026-07-08) because this
     panel renders on nearly every page with a Copilot chat, so it would
     otherwise get rediscovered piecemeal once per cohort. Unlike the
     LabelNewPanel/UnassignedReceiptsPanel/BulkWineDesk "Tailwind primitives,
     no dark override yet" precedent, this file WAS the reported defect (a
     bright-white chat panel sitting inside otherwise-dark pages), so it gets
     real [data-theme="dark"] treatment below rather than staying dark-stable.
     Panel chrome (surfaces/borders/text) is Tailwind's default gray scale,
     close enough to this app's existing --surface-* / --border-* / --text-*
     scale to alias directly (near-miss substitution, tokens.css principle 2)
     and inherit its dark handling for free — those literals are replaced
     in CopilotPanel.razor.css directly, no new tokens needed for them.
     Everything below is this panel's OWN accent/status palette — minted
     fresh per the W6 domain-scoping precedent rather than borrowed from
     another domain's dark-stable token (borrowing would leave Copilot's own
     colors without real dark support, the opposite of the point of this
     cohort). */
  --copilot-accent:             #2563eb;   /* send button, user bubble, resize-handle grip, input focus */
  --copilot-accent-rgb:         37, 99, 235;
  --copilot-accent-strong:      #1d4ed8;   /* send-btn hover, entity-chip hover fg */
  --copilot-accent-deep:        #1e40af;   /* fg text on accent-bg (entity badge, severity-low) */
  --copilot-accent-soft:        #93c5fd;   /* send-btn disabled bg, chip-hover border */
  --copilot-accent-tint:        #eff6ff;   /* chip hover bg, entity-chip bg */
  --copilot-accent-tint-border: #bfdbfe;   /* entity-chip border */
  --copilot-accent-bg:          #dbeafe;   /* entity badge bg, severity-low bg */

  --copilot-toast-bg:     #ecfdf5;   /* lot-copied confirmation toast */
  --copilot-toast-border: #a7f3d0;
  --copilot-toast-fg:     #065f46;
  --copilot-toast-code-bg: rgba(255, 255, 255, 0.7);  /* lightening overlay for the <code> chip inside the toast */

  --copilot-badge-high-bg:     #dcfce7;   /* field-update badge: high confidence */
  --copilot-badge-high-fg:     #166534;
  --copilot-badge-medium-bg:   #fef9c3;   /* field-update badge: medium confidence; also budget-warning/budget-low banners */
  --copilot-badge-medium-fg:   #854d0e;
  --copilot-badge-inferred-bg: #e0e7ff;   /* field-update badge: inferred */
  --copilot-badge-inferred-fg: #3730a3;

  --copilot-severity-critical-bg: #fecaca;  /* bug-report severity pill; -fg doubles as .copilot-error text */
  --copilot-severity-critical-fg: #991b1b;
  --copilot-severity-high-bg:     #fed7aa;
  --copilot-severity-high-fg:     #9a3412;
  /* severity-medium reuses --copilot-badge-medium-*, severity-low reuses --copilot-accent-bg/-deep — identical hex already */

  --copilot-access-warning-bg: #fffbeb;
  --copilot-access-warning-fg: #92400e;

  --copilot-danger-bg: #fef2f2;   /* .copilot-error background; fg reuses --copilot-severity-critical-fg */

  --copilot-progress-ok:      #22c55e;   /* budget-fill default */
  --copilot-progress-warning: #eab308;   /* budget-fill.warning */
  --copilot-progress-danger:  #ef4444;   /* budget-fill.danger, attach-remove bg, file-chip icon */

  --copilot-submit-bg:           #f0fdf4;   /* bug-report submit card */
  --copilot-submit-border:       #bbf7d0;
  --copilot-submit-hover-bg:     #15803d;   /* submit-btn hover; base bg reuses --green-500 */
  --copilot-submit-disabled-bg:  #86efac;

  --copilot-copysuccess-border: #badbcc;   /* header-action.copy-success border (bg/fg reuse --green-100/--wr-status-accepted-fg) */

  --copilot-shadow-toggle:       0 2px 8px rgba(0, 0, 0, 0.12);
  --copilot-shadow-toggle-hover: 0 4px 12px rgba(0, 0, 0, 0.16);
  --copilot-shadow-panel:        0 8px 32px rgba(0, 0, 0, 0.16);  /* shared by .copilot-panel and .copilot-lot-peek */

  /* ── W15 cohort (long tail, batch 1) — added 2026-07-08 ───────────────────
     Small, unrelated one-off pages — each gets a tiny domain block rather
     than sharing a prefix. #fff/white keyword literals throughout this
     batch reuse --white directly (general primitive, no new token). */
  --equip-card-shadow:       0 4px 8px 0 rgba(0, 0, 0, 0.2);   /* EquipmentMain .card */
  --equip-card-shadow-hover: 0 8px 16px 0 rgba(0, 0, 0, 0.2);  /* EquipmentMain .card:hover */

  --mobile-share-card-shadow:      0 6px 24px rgba(0, 0, 0, 0.08);  /* FilterabilityShareCard */
  --mobile-share-statusbar-shadow: 0 1px 1px rgba(0, 0, 0, 0.12);   /* FilterabilityShareCard .status-bar text-shadow */

  --contacts-confirm-overlay-bg:  rgba(0, 0, 0, 0.3);           /* BusinessCleanup .confirmation-overlay backdrop */
  --contacts-confirm-banner-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);  /* BusinessCleanup .confirmation-banner */

  --pumpover-highlight-row-bg: #f5f5a5;  /* shared by PumpOversMain + PumpOverContractPanel .highlight-row (near-duplicate files) */

  /* ── Pumpover harvest.* worksheet (Pages/PumpOver/HarvestView) — added 2026-08-07 ──
     A 13-column daily worksheet with three slot rows per lot, read at arm's length in a
     cellar. Two values the general scale has no rung for:
       --pohv-focus-ring  a 2px ring — HALF the weight of --shadow-focus (0.25rem = 4px),
                          which swamps a 24px-tall control. Composed from --blue-500-rgb so
                          it tracks that token's dark-mode lift automatically.
       --pohv-row-alt     the alternating band. ⛔ NOT a row zebra: one band covers a lot's
                          AM/MD/PM rows TOGETHER, which is what makes three sibling <tr>s
                          read as one block. Deliberately barely-there — at 13 columns a
                          visible fill fights the data it is supposed to group.
     Dark lifts --pohv-row-alt only: 3.5% of a blue on a near-black surface is invisible. */
  --pohv-focus-ring: 0 0 0 2px rgba(var(--blue-500-rgb), 0.35);
  --pohv-row-alt:    rgba(var(--blue-500-rgb), 0.035);

  /* ── W15 cohort (long tail, batch 2) — added 2026-07-08 ───────────────────
     Misc/Forecast reuses --blue-500-rgb directly (exact match, no new
     token). Misc/NumberPad investigated and SKIPPED — no @page route, no
     consumer anywhere in the solution (only referenced by its own
     .razor.cs), and its :checked ~ sibling-selector animation has no
     matching <input type="checkbox"> in its own markup, so it could never
     fire even if wired in — confirmed-dead prototype, same treatment as
     this session's other orphaned-CSS findings. */
  /* ── Harvest dashboard section tokens (--hd-*) — added 2026-07-10 ─────────
     The first "section theme" seam (Phase-3 plan D3): harvest .razor.css consumes
     only --hd-* names, each mapping to a primitive or semantic token, so the
     section reskins from this one block; the next section copies the pattern with
     its own prefix. Replaces the dead --projected-sticky and --projected-glow-shadow
     aliases (the legacy #sticky card they described was rebuilt as .client-card,
     which these now style). --hd-card-bg is a modernized take on the legacy
     #f83d23 card — deepened just enough that white text clears WCAG AA
     (#f83d23 vs white was ~3.7:1; this is ~4.9:1). */
  --hd-card-bg:        #7b1f2e;   /* Stage 3 (B): deep bordeaux — was fire-red #d93a20; wine-themed + no clash with the danger-red "Short" badges */
  --hd-card-fg:        #ffffff;
  --hd-card-fg-muted:  rgba(255, 255, 255, 0.85);
  --hd-card-border:    rgba(0, 0, 0, 0.15);
  --hd-card-shadow:    var(--shadow-md);
  --hd-group-divider:  var(--border-strong);
  /* Stage 3 (A) density dial — one place to tune the table's rhythm. */
  --hd-cell-pad-y:     var(--space-2xs);   /*  4px — even vertical row rhythm */
  --hd-cell-pad-x:     var(--space-md);    /* 12px — consistent column gutter (was a loose 20px) */

  --samplerequest-divider:         #e0e3e8;  /* = --ws-divider, fresh alias */
  --samplerequest-muted-fg:        #98a2b3;  /* = --ws-icon-muted, fresh alias */
  --samplerequest-scrollbar-thumb: #c1c7cd;

  --shipping-chip-hover-bg:  #e8f0fe;                          /* = --dailyflow-suggestion-chip-hover-bg, fresh alias */
  --shipping-backdrop-bg:    rgba(0, 0, 0, 0.45);               /* _LegEditPanel backdrop */
  --shipping-panel-shadow:   -4px 0 24px rgba(0, 0, 0, 0.18);   /* _LegEditPanel slide-in shadow */
  --shipping-divider:        #f0f0f0;   /* = --pkg-divider/--maint-divider, fresh alias */

  /* ── W15 cohort (long tail, batch 3 — Shared/Components) — added 2026-07-08
     Autocomplete/picker components. The dropdown-menu shadow repeats
     byte-identical across 7 sibling files in this same folder (already
     flagged by css-duplicate-audit) — one shared token, not 7 fresh
     aliases, since these are genuinely the same pattern, not coincidental
     cross-domain duplicates. #0366d6/#198754/white reuse existing general
     primitives directly (exact matches, same precedent as
     LotExplorerPanel's --app-shell-blue-bright reuse from W13). */
  --shared-autocomplete-dropdown-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);

  --shared-autocomplete-status-draft: #fdb022;  /* = --ws-status-draft/--workspace-status-draft, fresh alias */
  --shared-autocomplete-status-saved: #32d583;  /* = --ws-status-saved/--workspace-status-saved, fresh alias */
  --shared-autocomplete-muted-dot:    #98a2b3;  /* = --ws-icon-muted/--samplerequest-muted-fg, fresh alias */
  --shared-autocomplete-badge-draft-fg: #b54708;
  --shared-autocomplete-badge-saved-fg: #027a48;
  --shared-autocomplete-active-warning-fg: #ffe28a;  /* FilterabilityAutocomplete .text-warning brightened on the active/highlighted row */

  /* ── W15 cohort (long tail, batch 4 — Booking) — added 2026-07-08 ────────
     AddBookingPanel.razor.css (renamed from AddBooking.razor.css during the
     2026-07-12 facelift) had a dead #autoExpandTextarea rule — no element in
     the markup carried that id; the same visual effect was applied via an
     inline style="" on the actual <textarea> instead. Removed in that same
     facelift pass. bookingCalendar.razor.css's .calendar-day /
     .empty-Day:hover are ALSO dead (case-drifted from the live markup's
     "calendar"/"empty-day" — a real pre-existing bug, not fixed here) but
     .currentDayShadow IS live, applied dynamically via the shadowEffect()
     C# method in the code-behind (not a static markup reference, hence
     invisible to a plain grep). */
  --booking-invalid-glow: rgba(220, 53, 69, 0.15);  /* = --dailyflow-danger-hover-bg, fresh alias; = --red-500 at 15% */
  --booking-toggle-active-bg: #2196f3;   /* = --admin-turn-user-border, fresh alias; classic toggle-switch "on" color */
  --booking-parent-gradient: linear-gradient(135deg, rgba(245, 247, 250, 0.6), rgba(195, 207, 226, 0.8), rgba(128, 0, 128, 0.2));
  /* Clean accent ring for today's card — replaced the old double blue glow
     (0 0 20px/40px blue at .7) in the 2026-07-23 BookingMain uniform pass. */
  --booking-currentday-glow: 0 0 0 2px var(--accent-primary), var(--shadow-md);
  --booking-table-header-bg: #f2f2f2;   /* = --vessel-header-bg, fresh alias */

  /* ── W15 cohort (long tail, batch 5 — Contracts/EmailFunctions/WineProfile)
     — added 2026-07-08. ContractMain.razor.css and wineprofilemain.razor.css
     are near-identical copy-paste siblings (same gradient/border/shadow
     literals repeated verbatim, several already flagged by
     css-duplicate-audit) — one shared token family, not two domain
     fresh-aliases, same "genuinely the same pattern" reasoning as W15
     batch 3's shared autocomplete dropdown shadow. */
  --legacy-cardgrid-header-gradient: linear-gradient(135deg, #E0F2FF 0%, #B0D1FF 60%, #B0C4DE 100%);
  --legacy-cardgrid-border:    #B0B0B0;
  --legacy-cardgrid-shadow-sm: 0 4px 6px rgba(0, 0, 0, 0.1);
  --legacy-cardgrid-shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.2);

  --wineprofile-tankitem-shadow:       0 5px 10px rgba(0, 0, 0, 0.1);   /* distinct geometry from --legacy-cardgrid-shadow-sm */
  --wineprofile-tankitem-hover-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);  /* same geometry as --legacy-cardgrid-shadow-lg, higher alpha */

  --contracts-upload-btn-hover-bg: #0b5ed7;  /* = --ws-select-hover-bg, fresh alias */

  /* EmailLabelComponent.razor.css's own comment says it "matches
     LabelNewPanel visual language" — reusing --lnp-* tokens DIRECTLY
     (not fresh-aliasing) since the coupling is explicit, not coincidental.
     Only 2 of its 11 colors have no --lnp-* equivalent. */
  --email-deselected-bg: #f3f4f6;  /* = --ws-badge-default-bg, fresh alias */
  --email-deselected-fg: #9ca3af;  /* = --bwd-muted-fg/--dailyflow-timeline-faint/--bol-muted-fg, fresh alias */

  /* ── W15 cohort (long tail, batch 6 — real gaps missed by batches 1-5)
     — added 2026-07-08. A full re-audit (prompted by a concurrent
     session's roadmap-doc note) found two folders the original sweep
     missed entirely: Pages/Home/ (only checked Pages/Misc/Forecast.razor.css,
     which is embedded IN Home's index page, never the Home/ folder itself)
     and root Shared/ (only checked Pages/Shared/Components/, never the
     top-level Shared/ folder the roadmap's row 18 list didn't separately
     call out). Both are real, live gaps — closed here. */
  --home-btn-remove-bg: rgba(255, 255, 255, 0.9);   /* HomeScreenSettingsPanel image-slot remove button */
  --home-gallery-item-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);  /* = --dailyflow-search-results-shadow/--shared-autocomplete-dropdown-shadow, fresh alias */
  --home-gallery-overlay-gradient: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
  --home-btn-delete-bg: rgba(220, 53, 69, 0.9);

  --csd-border:             #e5e7eb;  /* = --lnp-border, fresh alias */
  --csd-muted-fg:           #6b7280;  /* = --lnp-text-muted, fresh alias */
  --csd-border-input:       #d1d5db;  /* = --lnp-border-input, fresh alias */
  --csd-token-hover-border: #1a5f2a;
  --csd-token-hover-bg:     #f0f9f0;
  --csd-muted-body:         #4b5563;  /* = --lnp-muted-body/--pkg-muted-body, fresh alias */
  --csd-empty-fg:           #9ca3af;  /* = --bwd-muted-fg/--email-deselected-fg, fresh alias */

  /* ── W15 cohort (long tail, batch 7 — TankMismatchReport) — added
     2026-07-08. Pages/Reports/TankMismatch/TankMismatchReport.razor.css
     was missed by every folder sweep (Pages/Reports/ wasn't in the
     roadmap's original folder list at all, and a separate recon pass
     had incorrectly logged "Reports/ confirmed no .razor.css files" —
     it only checked the top-level folder, not this subfolder). A
     self-contained bespoke mauve/purple micro-palette, same treatment
     as W11's LabelNewPanel — dark-stable, no override, not corpus-
     verified for dark mode yet. */
  --tr-accent:          #4a2545;   /* title, active/hover tab */
  --tr-muted-fg:        #6b6471;
  --tr-border:          #d9d3dc;
  --tr-surface-subtle:  #faf8fb;
  --tr-stat-value-fg:   #1a1a1a;
  --tr-bad-border:      #e6b4ae;
  --tr-bad-bg:          #fdecea;   /* bad-stat bg + mismatch row bg */
  --tr-bad-fg:          #b3261e;
  --tr-divider:         #e7e2ea;
  --tr-table-border:    #c9c2cc;
  --tr-strong-fg:       #2c2533;
  --tr-muted-light-fg:  #9b94a1;
  --tr-check-fg:        #4a4350;
  --tr-badge-ok-bg:     #e6f4ea;
  --tr-badge-ok-fg:     #1e7e34;
  --tr-badge-bad-bg:    #f9d7d3;
  --tr-badge-muted-bg:  #ece9ee;
  --tr-resolve-overlay-bg: rgba(20, 14, 26, 0.35);   /* mauve-tinted, not pure black — matches this page's own palette */
  --tr-resolve-panel-shadow: -4px 0 24px rgba(0, 0, 0, 0.18);   /* = --shipping-panel-shadow, fresh alias */

  /* ── W17 cohort (out-of-scope population, batch A) — added 2026-07-08
     Bottling/CellarWork + Compliance/Manager. #0366d6 reuses
     --app-shell-blue-bright directly (exact match, established primitive). */
  --cw-enrichment-bg:      #f0f4ff;   /* = --winelot-row-hover-bg/--pkg-card-tint-bg-end/--hvt-er-card-gradient-end, fresh alias */
  --cw-enrichment-border:  #c7d7fe;
  --cw-loading-bg:         #f9fafb;   /* = --lnp-surface-subtle, fresh alias */
  --cw-loading-border:     #e0e3e8;   /* = --ws-divider/--samplerequest-divider, fresh alias */
  --cw-loading-accent:     #98a2b3;   /* = --ws-icon-muted/--samplerequest-muted-fg/--shared-autocomplete-muted-dot, fresh alias */
  --cw-pill-bg:            #e8eeff;
  --cw-pill-fg:            #1d2939;   /* = --ws-text-strongest, fresh alias */
  --cw-pill-icon-fg:       #5b7cd3;
  --cw-pill-muted-bg:      #f2f4f7;
  --cw-pill-muted-fg:      #667085;   /* = --ws-text-muted, fresh alias */
  --cw-pill-vessel-bg:     #e8f5e9;   /* = --labqc-average-row-bg, fresh alias */
  --cw-pill-vessel-fg:     #1b5e20;
  --cw-pill-vessel-icon-fg: #2e7d32;
  --cw-pill-blend-bg:      #ede9fe;   /* = --ws-badge-received-bg, fresh alias */
  --cw-pill-blend-fg:      #4338ca;
  --cw-pill-blend-hover-bg: #ddd6fe;
  --cw-pill-blend-icon-fg: #5b21b6;   /* = --ws-badge-received-fg, fresh alias */
  --cw-strip-divider:      #dbe4ff;
  --cw-analysis-fg:        #475467;   /* = --ws-text-secondary/--ws-badge-default-fg, fresh alias */

  --er-selected-border:    #1e3a8a;   /* = --bwd-tree-active-fg, fresh alias */
  --er-signal-ok:          #1a7d3b;   /* = --labelcola-status-success-fg, fresh alias */
  --er-signal-warning:     #f1c44d;
  --er-signal-overdue:     #c0392b;   /* = --wr-alert-strong/--labelcola-alert-strong, fresh alias */
  --er-signal-overdue-shadow: 0 0 0 2px rgba(192, 57, 43, 0.18);
  --er-warn-badge-bg:      #fff4d6;
  --er-warn-badge-fg:      #8a6100;   /* = --labelcola-status-warning-fg, fresh alias */

  /* ── W17 cohort (out-of-scope population, batch B) — added 2026-07-08
     Bottling/Manager — BottlingChangesManager (--bcm-*) + the "Bottling
     History Manager" feature's 3 files, ClientRail/DateInspector/
     HistoryGrid (--bh-*, one shared family since the files' own header
     comments document them as one feature, same reasoning as W15 batch 3's
     shared autocomplete token). #0366d6/#0b5ed7/yellow-500/green-600/
     indigo-600/amber-600/slate-50/white reuse existing general primitives
     directly. */
  --bcm-muted-fg:   #6b7280;   /* = --lnp-text-muted/--ws-text-muted/--pkg-text-muted, fresh alias */
  --bcm-divider:    #e5e7eb;   /* = --lnp-border/--csd-border/--dailyflow-timeline-connector, fresh alias */
  --bcm-created-fg: #059669;   /* = --dailyflow-dot-created-fg, fresh alias */
  --bcm-deleted-fg: #dc2626;   /* = --mat-stock-bar-low/--dailyflow-dot-deleted-fg/etc, fresh alias */
  --bcm-moved-fg:   #2563eb;   /* = --inv-profile-link-fg/--dailyflow-dot-moved-fg/etc, fresh alias */
  --bcm-summary-fg: #374151;   /* = --lnp-text-strong/--pkg-text-strong, fresh alias */
  --bcm-client-fg:  #111827;   /* = --dailyflow-timeline-strong, fresh alias */

  --bh-selected-bg:      #e9f3ff;   /* shared ClientRail + HistoryGrid */
  --bh-selected-fg:      #0b5ed7;   /* = --ws-select-hover-bg, fresh alias */
  --bh-subtabs-bg:       #fafbfc;   /* = --ws-panel-bg/--inv-report-header-bg/etc, fresh alias */
  --bh-active-tab-fg:    #1e3a8a;   /* = --bwd-tree-active-fg/--er-selected-border, fresh alias */
  --bh-muted-fg:         #868e96;   /* = --bwd-muted-icon/--inv-muted-fg/--dailyflow-image-type-fg/--labelcola-muted-fg, fresh alias */
  --bh-header-gradient:       linear-gradient(135deg, #0366d6 0%, #0b5ed7 100%);
  --bh-header-hover-gradient: linear-gradient(135deg, #0b5ed7 0%, #004494 100%);
  --bh-purple-accent:    #6f42c1;   /* = --dailyflow-purple-accent, fresh alias */

  /* ── W17 cohort (out-of-scope population, batch C) — added 2026-07-08
     Calendar/ProductionCalendar — already extensively uses var(--x,
     #fallback) chains (the file's own header comment shows deliberate
     css-drift-gate-aware discipline); only 2 genuinely bare literals
     survived. */
  --pcal-loading-veil-bg: rgba(255, 255, 255, 0.35);   /* = --on-shell-fg-subtle, fresh alias (different semantic use — loading veil, not on-shell text) */

  /* ── W17 cohort (out-of-scope population, batch D) — added 2026-07-08
     Components/Shared/ — genuinely shared, widely-reused components
     (DocumentViewer has 7 consumers across Bottling/Packaging/BulkWineDesk/
     Contacts/LabelCola/Materials/Harvest). DocumentViewer's magnifier-lens
     box-shadow is an EXACT match for --dailyflow-magnifier-shadow (same
     UI pattern, a magnifying-glass lens ring) — reused directly rather
     than fresh-aliased, same precedent as --app-shell-blue-bright reuse.
     FilterChip/ProjectionStatusChip both had their own code comments
     deliberately deferring tokenization ("kept as literals... tokenize
     later if reused") — now genuinely reused (4 and 1 consumers
     respectively), so tokenizing now honors that original intent. */
  --filterchip-active-bg:     #ffe9a8;   /* = --inv-low-selected-bg, fresh alias — the "sticky amber" treatment per this file's own comment */
  --filterchip-active-border: #f0c14b;   /* = --inv-fw-notice-border/--labelcola-notice-border, fresh alias */
  --filterchip-active-fg:     #5e4400;   /* = --inv-fw-notice-fg/--labelcola-notice-fg, fresh alias */

  --projchip-on-bg:      #d4edda;   /* = --dailyflow-confidence-bg, fresh alias */
  --projchip-on-border:  #9fd7ad;
  --projchip-off-border: #d6dade;

  /* ── W17 cohort (out-of-scope population, batch E) — added 2026-07-08
     Bottling/Campaigns — one shared --camp-* family across all 6 files
     in this feature (same "genuinely one feature" reasoning as W15 batch
     3/5 and W17 batch B). Several exact matches reuse existing general
     primitives or strongly-related DailyFlow "suggestion" tokens directly
     (gray-50/blue-500/gray-600/gray-900/gray-700/white/shadow-md/
     ws-active-bg/app-shell-blue-bright/ws-status-draft/ws-text-secondary/
     dailyflow-suggestion-* / dailyflow-confidence-*) rather than
     fresh-aliasing, since the semantic match is strong (e.g. SkuLabelColaPicker's
     suggestion banner is the same "AI suggestion" concept as BottlingCOLAPanel's). */
  --camp-card-border:   #eaecf0;
  --camp-card-bg:       #f9fafb;   /* = --lnp-surface-subtle, fresh alias */
  --camp-dates-accent:  #0ba5ec;
  --camp-skus-accent:   #7a5af8;
  --camp-border-dashed: #d0d5dd;   /* shared CampaignDatesSection + SkuTabsRow */
  --camp-muted-fg:      #667085;   /* = --ws-text-muted, fresh alias; shared CampaignDatesSection + SkuTabsRow */
  --camp-expected-bg:     #eff8ff;
  --camp-expected-fg:     #175cd3;
  --camp-expected-border: #b2ddff;
  --camp-strong-fg:     #344054;   /* = --ws-text-strongest, fresh alias; shared CampaignSkusSection + SkuTabsRow */
  --camp-badge-bg:      #e7f0ff;   /* CampaignSupplyOrdersSection component-badge */
  --camp-border:        #e0e0e0;   /* = --skeleton-base/--dailyflow-suggestion-row-border, fresh alias; shared SkuDetailPanel + SkuLabelColaPicker */
  --camp-faint-fg:      #666;      /* shared SkuDetailPanel + SkuLabelColaPicker */
  --camp-border-light:  #ddd;      /* shared SkuDetailPanel + SkuLabelColaPicker */
  --camp-quiet-fg:      #555;      /* shared SkuDetailPanel + SkuLabelColaPicker */
  --camp-panel-bg:        #fafbfc; /* = --ws-panel-bg family, fresh alias; SkuDetailPanel */
  --camp-panel-header-bg: #f5f6f8; /* = --ws-divider-subtle, fresh alias; SkuDetailPanel */
  --camp-empty-fg:      #888;      /* SkuDetailPanel */
  --camp-hairline:      #eee;      /* SkuLabelColaPicker */
  --camp-dismiss-fg:       #999;   /* shared SkuLabelColaPicker (multiple) */
  --camp-dismiss-hover-fg: #333;   /* SkuLabelColaPicker */
  --camp-linked-bg:     #f0f7ff;   /* fresh alias, many-aliased family; SkuLabelColaPicker */
  --camp-linked-border: #b8d4ff;   /* SkuLabelColaPicker */
  --camp-placeholder-bg:     #f0f0f0;  /* fresh alias, many-aliased family; SkuLabelColaPicker (2 uses) */
  --camp-placeholder-fg:     #bbb;     /* SkuLabelColaPicker */
  --camp-placeholder-fg-alt: #aaa;     /* SkuLabelColaPicker */
  --camp-tabs-divider:      #e0e3e8;   /* = --ws-divider, fresh alias; SkuTabsRow */
  --camp-tabs-bg:           #f8f9fb;   /* SkuTabsRow */
  --camp-tabs-hover-bg:     #eef0f4;   /* SkuTabsRow */
  --camp-tabs-hover-border: #98a2b3;   /* = --ws-icon-muted family, fresh alias; SkuTabsRow */
  --camp-tabs-active-shadow: 0 1px 3px rgba(3, 102, 214, 0.15);  /* = --app-shell-blue-bright at 15% */
  --camp-tabs-cancelled-accent:   #f97066;  /* SkuTabsRow */
  --camp-tabs-transferred-accent: #36bffa;  /* SkuTabsRow */
  --camp-tabs-size-bg:  #f2f4f7;   /* SkuTabsRow */
  --camp-tabs-badge-bg: #e4e7ec;   /* SkuTabsRow */
}

/* ============================================================================
   DARK MODE

   Strategy: override only the PRIMITIVE color tokens. Semantic tokens
   (surface-*, text-*, border-*) reference the primitives via var() and
   inherit the dark values automatically. Component tokens
   (table-header-bg, etc.) reference the semantic tokens and likewise
   inherit.

   This means dark mode is ~30 lines of overrides instead of ~150.
   ============================================================================ */

[data-theme="dark"] {
  /* Inverted gray scale — darker numerically is now lighter visually */
  --gray-50:   #1a1d20;   /* darkest surface */
  --gray-100:  #212529;   /* page background */
  --gray-200:  #2b3035;   /* card/panel background */
  --gray-300:  #373b40;   /* borders, dividers */
  --gray-400:  #495057;   /* subtle text */
  --gray-500:  #6c757d;   /* muted text */
  --gray-600:  #adb5bd;   /* secondary text */
  --gray-700:  #ced4da;   /* primary text */
  --gray-800:  #dee2e6;   /* high-emphasis text */
  --gray-900:  #f8f9fa;   /* highest contrast */

  /* Brand stays the same chroma but slightly desaturated — teal reads
     punchy on white but garish on dark; pull a little saturation out. */
  --brand-teal-500:   #1ab2a4;   /* slightly brighter for contrast on dark */
  --brand-teal-300:   #4eef85;   /* the gradient companion stays vivid */
  --brand-burgundy:   #c47a8a;   /* dusty rose — still reads as burgundy accent on dark */

  /* Functional colors — lift the muted ones, leave the saturated ones */
  --blue-500:    #4d94ff;
  --blue-600:    #2d7fff;
  --blue-700:    #1b6ec2;
  --blue-100:    #1e3a5f;
  --green-100:   #1e3a2a;
  --green-500:   #4eef85;
  --green-500-rgb: 78, 239, 133;  /* mirrors --green-500 dark exactly */
  --green-700:   #4eef85;
  --yellow-100:  #3a2f0e;
  --yellow-700:  #f5d572;
  --red-500:     #ff5560;
  --red-700:     #c4424d;
  --orange-500:  #ff9a4d;
  --white:       #ffffff;       /* stays white — used for absolute high-contrast */
  --black:       #000000;

  /* Re-point semantic surfaces. Light mode points --surface-default at
     --white; on dark we want the near-black card background instead. */
  --surface-default:    var(--gray-200);
  --surface-subtle:     var(--gray-100);
  --surface-muted:      var(--gray-300);
  --surface-emphasis:   var(--gray-400);
  --surface-inverse:    var(--gray-900);   /* light surface on dark theme — for high-contrast modals if needed */

  /* Text — these flip via the gray scale, but call them out for clarity */
  --text-primary:       var(--gray-800);
  --text-secondary:     var(--gray-700);
  --text-muted:         var(--gray-600);
  --text-disabled:      var(--gray-500);
  --text-on-inverse:    var(--gray-100);
  --text-on-brand:      var(--white);
  --text-link:          #6ab7ff;            /* lighter blue for AA on dark */

  /* Borders — also flip via gray scale, called out for clarity */
  --border-default:     var(--gray-400);
  --border-subtle:      var(--gray-300);
  --border-strong:      var(--gray-500);
  --border-focus:       var(--blue-500);

  /* Shadows — opacity-based shadows look washed on dark; punch them up */
  --shadow-sm:    0 1px 2px rgba(0, 0, 0, 0.40);
  --shadow-md:    0 2px 4px rgba(0, 0, 0, 0.45);
  --shadow-lg:    0 2px 8px rgba(0, 0, 0, 0.50);
  --shadow-xl:    0 5px 20px rgba(0, 0, 0, 0.60);
  --shadow-focus: 0 0 0 0.25rem rgba(77, 148, 255, 0.30);
  --shadow-focus-accent: 0 0 0 3px rgba(26, 178, 164, 0.25);

  /* State backgrounds — light-mode #f8d7da reads jarring on dark */
  --state-danger-bg:    #3a1f23;

  /* Table row hover — the light-mode #f0faf9 (tinted teal) needs a
     dark equivalent. Dark hover is *brighter* than the row, not darker. */
  --table-row-hover:   #2e4543;

  /* Drag-and-drop gold — keep, but with stronger shadow on dark */
  --dnd-indicator-shadow: 0 0 8px rgba(255, 215, 0, 0.80);

  /* Compliance urgency row backgrounds — dark tints parallel to --state-*-bg.
     overdue stays a deep red that keeps bold white text legible on dark. */
  --urgency-medium-bg:  #3a2814;   /* dark amber, sits between #3a2f0e and #3a1f23 */
  --urgency-overdue:    #cf3a3a;

  /* Permit badge gradients — darkened ~15% so white text stays legible on dark */
  --permit-badge-purple: linear-gradient(135deg, #5e389f 0%, #834c98 100%);
  --permit-badge-green:  linear-gradient(135deg, #14724a 0%, #27ad60 100%);
  --permit-badge-orange: linear-gradient(135deg, #c46a1d 0%, #cf8410 100%);
  --permit-badge-red:    linear-gradient(135deg, #bb2d3b 0%, #c43a2e 100%);

  /* Permit trade-name chip — dark teal surface + lighter teal text */
  --permit-tradename-bg: #163029;
  --permit-tradename-fg: #4ec9b8;

  /* TTB Registry indigo accent family — lift foreground to the indigo primitives,
     bespoke deep-indigo surfaces for the FBN subsection bg/border. */
  --accent-preview:        var(--indigo-400);   /* #818cf8 */
  --accent-preview-strong: var(--indigo-500);   /* #6366f1 */
  --accent-preview-bg:     #1e2444;
  --accent-preview-border: #2d3561;
  --accent-preview-soft:   rgba(129, 140, 248, 0.20); /* = --indigo-400 dark at higher alpha (dark focus rings need more opacity) */

  /* Bottling schedule board — darken the appointment-row gradients so the
     row's auto-flipped (light) text reads on the dark board. Blue stays blue
     ("NOT a bottling"), amber stays amber, purple stays purple. */
  --appt-other-gradient:     linear-gradient(to right, rgba(30, 96, 145, 0.92), rgba(18, 58, 95, 0.94));
  --appt-multiday-gradient:  linear-gradient(to right, rgba(150, 112, 12, 0.92), rgba(120, 80, 10, 0.94));
  --appt-multiday-border:    #cc5a00;
  --appt-otherline-gradient: linear-gradient(to right, rgba(98, 74, 155, 0.92), rgba(72, 60, 140, 0.94));

  /* Skeleton shimmer — dark grays so the loader doesn't flash white on dark. */
  --skeleton-base:      #2b3035;
  --skeleton-highlight: #373b40;

  /* Work-request alert red — lift to a lighter red so it reads as text/border
     on dark surfaces (the count-pill fill stays its hardcoded #e74c3c). */
  --wr-alert:        #ff6b5e;
  --wr-alert-strong: #e0584d;

  /* Snow-dropper icon — lighter blue for contrast on a dark card. */
  --snow-dropper-fg: #5aa0e8;

  /* Calendar elevation + today glow — muted on dark (cell shadow subtle, the
     today highlight kept light enough to still pop around the dark cell). */
  --calendar-cell-shadow: #2c3a52;
  --calendar-today-glow:  #5a7cb0;

  /* Work-request status badges + callouts — deep tinted bg + light fg,
     parallel to the --state-* dark treatment. */
  --wr-status-info-bg:        #16335c;
  --wr-status-info-fg:        #9ec5fe;
  --wr-status-info-border:    #2d4a78;
  --wr-status-warning-fg:     #f5d572;
  --wr-status-warning-border: #5c4a1e;
  --wr-status-revision-bg:    #3a2417;
  --wr-status-revision-fg:    #f0a58a;
  --wr-status-accepted-fg:    #4eef85;

  /* Date chip — dark Material-blue */
  --chip-info-bg:       #1a2f4a;
  --chip-info-border:   #2d4a78;
  --chip-info-fg:       #5aa0e8;
  --chip-info-hover-bg: #234260;
  --chip-info-hover-fg: #8ec0f0;

  /* App-shell blue — deepen the FILL so white nav links/avatar text stay
     legible on dark; the gradients (--app-shell-gradient / -gradient-h)
     re-resolve from these primitives automatically, so they need no explicit
     dark override (this reproduces the prior #04204f→#0a52a8 dark gradient
     byte-for-byte). */
  --app-shell-blue:        #04204f;
  --app-shell-blue-bright: #0a52a8;

  /* Collapsed drawer-toggle hover — glyph lifts to an AA-legible blue on the
     dark page bg (#052e76 navy would be ~1.2 contrast, invisible); the hover
     tint becomes a faint light-blue (navy at 8% is invisible on dark). */
  --app-shell-toggle-fg:       #4d94ff;
  --app-shell-toggle-hover-bg: rgba(77, 148, 255, 0.12);

  /* SecondaryLayout purple — deepen both stops so white nav text stays legible. */
  --secondary-shell-gradient: linear-gradient(180deg, #031b46 0%, #26042e 70%);

  /* ── W3 cohort (Shared/Inventory) dark overrides ──────────────────────────
     Only the gray-scale, dark-integrated tokens get overrides here. The
     UnassignedReceiptsPanel slate-scale tokens (material-badge-*, inv-subtle-
     info-*, inv-row-unassigned-bg, inv-profile-link-fg, receipt-status-*,
     amber-800) are deliberately absent — they stay dark-stable, see the
     :root block comment. */
  --green-600: #4eef85;   /* reuse the same bright dark-green as --green-500 dark */

  --inv-expired-bg:            #3a1f1f;
  --inv-expired-active-bg:     #4a2424;
  --inv-expired-active-border: #5a2c2c;
  --inv-low-selected-bg:       #4a3d14;

  --inv-qty-positive: #4eef85;
  --inv-qty-negative: #ff5560;   /* same as --red-500 dark */

  --inv-default-supplier-bg: #16233a;
  --inv-selected-tint-bg:    #16233a;

  --inv-aging-fresh-bg: #1e3a2a;   /* same as --green-100 dark */
  --inv-aging-old-bg:   #3a2a10;
  --inv-aging-old-fg:   #d99a5b;

  /* ── W4 cohort (Bottling/Schedule) dark overrides ──────────────────────────
     wr-badge-* re-derive from --wr-alert's dark RGB (255, 107, 94 / #ff6b5e).
     wr-badge-empty-* / date-range-badge-bg/otherline-badge-bg/wr-sidebar-item-*
     are deliberately absent — they stay dark-stable, see the :root comment. */
  --wr-badge-bg-subtle: rgba(255, 107, 94, 0.15);
  --wr-badge-bg-hover:  rgba(255, 107, 94, 0.25);
  --wr-badge-pulse-shadow-start: 0 0 0 0 rgba(255, 107, 94, 0.3);
  --wr-badge-pulse-shadow-peak:  0 0 8px 2px rgba(255, 107, 94, 0.2);

  /* Snow-dropper glow — re-derive from --snow-dropper-fg's dark RGB (90, 160, 232 / #5aa0e8). */
  --snow-dropper-shadow: 0 0 6px rgba(90, 160, 232, 0.7), 0 1px 2px rgba(0, 0, 0, 0.4);

  /* Selected-date checkbox tint — re-derive from --blue-500's dark RGB (77, 148, 255 / #4d94ff). */
  --checkbox-checked-bg: rgba(77, 148, 255, 0.1);

  /* ── W7 cohort (Vessels + WineLots) dark overrides ─────────────────────────
     Only WineLotsPage's tab-bar divider/text get real treatment (corpus-
     covered by winelots-main). TankSpecs's toolbar bg/debug-border/divider,
     WineLotPanel's row divider/hover, and the tab-active-border (already
     bright enough) stay dark-stable — see :root comment. */
  --winelot-tabs-border: #373b40;  /* same weight as --gray-300 dark */
  --winelot-tab-fg:      #5cc4ea;  /* lightened for AA contrast on dark */

  /* ── W8 cohort (Lab + LabQc) dark overrides ────────────────────────────────
     --labqc-focus-ring, --labqc-success-fg(-hover), --labqc-badge-warning-bg,
     and --labqc-snow-cyan-fg(-rgb) are deliberately absent — bright/saturated
     enough to stay dark-stable, see the :root comment. */
  --blue-500-rgb: 77, 148, 255;  /* mirrors --blue-500 dark exactly */

  --labqc-grid-border:        #495057;  /* ~gray-400 dark weight */
  --labqc-grid-border-strong: #6c757d;  /* ~gray-500 dark weight */
  --labqc-grid-divider:       #4a5158;
  --labqc-grid-fade-rgb:      43, 48, 53;  /* = --gray-200 dark = --surface-default dark, so the fade blends into the card */
  --labqc-other-date-bg:        #1a2a35;
  --labqc-other-date-header-bg: #16232e;
  --labqc-other-date-border:    #7db3dc;
  --labqc-input-hover-bg: #373b40;  /* ~gray-300 dark weight, a lift over the dark cell bg */
  --labqc-recheck-bg:     #2f3339;  /* barely lighter than --surface-default dark, same subtle relationship as light mode */
  --labqc-divider-subtle:     #373b40;  /* ~gray-300 dark weight */
  --labqc-input-focus-border: #6ab7ff;  /* matches the dark --text-link lighter blue */

  --labqc-spec-ok-bg:   #16281c;
  --labqc-spec-warn-bg: #2a1418;
  --labqc-average-row-bg: #16281c;

  --labqc-selected-bg: #16233a;
  --labqc-lot-bg: #3a2f0e;  /* = --yellow-100 dark weight */
  --labqc-select-btn-hover: #6ab7ff;  /* matches dark --text-link */
  --labqc-collapsed-header-bg: #2f3339;  /* barely lighter than --surface-default dark */
  --labqc-status-empty-bg: #373b40;      /* ~gray-300 dark weight */

  --labqc-tank-pill-border:   #3d5a78;
  --labqc-specs-strip-border: #233246;
  --labqc-warning-border:     #5c4a1e;  /* = --wr-status-warning-border dark weight */
  --labqc-warning-icon-fg:    #f5d572;  /* = --yellow-700 dark */
  --labqc-badge-success-border: #1e3a2a;  /* = --green-100 dark weight */
  --labqc-badge-neutral-border: #4a4d50;
  --labqc-status-fail-fg: #ff8a94;  /* lightened red for AA contrast on dark */

  --labqc-badge-neutral-bg: #3a3d40;
  --labqc-badge-neutral-fg: #c3c7cb;
  --labqc-badge-success-fg: #4eef85;
  --labqc-badge-info-bg: #1a3a42;
  --labqc-badge-info-fg: #6fd7ea;

  --labqc-snow-fg:     #5aa0e8;
  --labqc-snow-bg:     #16283a;
  --labqc-snow-border: #3d5a78;
  --labqc-snow-row-bg: rgba(90, 160, 232, 0.12);

  --labqc-verify-ok-bg:  rgba(78, 239, 133, 0.15);
  --labqc-verify-bad-bg: rgba(255, 85, 96, 0.15);

  /* ── W9 cohort (Bottling/DailyFlow/Components) dark overrides ─────────────
     Only the gray/surface-integrated tokens get real treatment: info-badge
     family, today/current tints, link-hover, bond-number, organic-stamp,
     and the empty/subtle-bg pair. The appt-gradient pair, purple-accent,
     header-tag-bg, --dailyflow-today-accent(-hover/-rgb) (Bootstrap info
     cyan — already legible on dark unstyled, confirmed by direct screenshot
     comparison; brightening it further was an unforced change, reverted),
     and all --dailyflow-timeline-* / --dailyflow-dot-* tokens are deliberately
     absent — dark-stable, see the :root comment. */
  --dailyflow-info-badge-bg:       #16335c;   /* = --wr-status-info-bg dark weight */
  --dailyflow-info-badge-hover-bg: #1e4270;
  --dailyflow-info-badge-fg:       #9ec5fe;   /* = --wr-status-info-fg dark */
  --dailyflow-bond-number-fg:      #adb5bd;   /* = --gray-600 dark weight */
  --dailyflow-link-hover-fg:       #6ab7ff;   /* matches dark --text-link, same as --labqc-select-btn-hover dark */
  --dailyflow-empty-fg:            #6c757d;   /* = --gray-500 dark weight */
  --dailyflow-subtle-bg:           #26292c;   /* barely lighter than --surface-default dark */
  --dailyflow-today-tint-bg:       #1a2f4a;   /* = --chip-info-bg dark */
  --dailyflow-current-tint-bg:     #1e3a2a;   /* = --green-100 dark weight */
  --dailyflow-organic-fg: #ff6b60;
  --dailyflow-organic-bg: rgba(255, 107, 96, 0.18);

  /* ── W9 cohort (Bottling/DailyFlow/Panels) dark overrides ─────────────────
     Several Panels colors were hardcoded pale-light cards/badges that never
     adapted to dark (same white-card-on-dark-page bug class as Components'
     .date-group finding) — mismatch-bg, the suggestion banner/info-bar/row
     family, thumb-placeholder, confidence badges, and pipeline-row all get
     real dark treatment here. The zoom-hint/lightbox/preview-overlay family
     stays dark-stable (they're black scrims/chrome sitting on TOP of an
     image, not page-background-dependent) along with --dailyflow-suggested-
     accent, --dailyflow-po-chip-border, --dailyflow-dismiss-hover-*, and the
     badge gradient — see the :root comment for each. */
  --dailyflow-mismatch-bg: #3a2f0e;  /* = --yellow-100 dark weight */
  --dailyflow-suggestion-accent: #8fa8d9;  /* lightened navy for AA contrast once its card background goes dark */
  --dailyflow-suggestion-accent-rgb: 143, 168, 217;
  --dailyflow-suggestion-banner-gradient: linear-gradient(135deg, #1a2340 0%, #16233a 100%);
  --dailyflow-suggestion-banner-border:   #2d3a5c;
  --dailyflow-suggestion-info-bar-bg:     #1a2340;
  --dailyflow-suggestion-info-bar-border: #2d3a5c;
  --dailyflow-suggestion-row-border: #3a3d40;  /* ~gray-300 dark weight */
  --dailyflow-thumb-placeholder-bg: #2b3035;   /* = --gray-200 dark */
  --dailyflow-no-image-fg:          #6c757d;   /* = --gray-500 dark weight */
  --dailyflow-confidence-bg:      #16281c;   /* = --labqc-spec-ok-bg dark weight */
  --dailyflow-confidence-high-bg: #1e3a2a;   /* = --green-100 dark weight */
  --dailyflow-pipeline-row-bg: #16233a;      /* = --inv-selected-tint-bg dark weight */

  /* W9 cohort (Bottling/DailyFlow/Sections) dark overrides */
  --dailyflow-naked-dates-bg:       #2b2410;  /* warm-dark tint, same family as --yellow-100 dark (#3a2f0e) but one step subtler for the section's near-white base */
  --dailyflow-naked-dates-hover-bg: #4a3c14;  /* more-saturated warm-dark counterpart to the hover state */

  /* W9 cohort (Bottling/DailyFlow root) dark overrides — collapsed-tab's
     "Run Details" special tab is a pale-blue-on-white badge in light mode;
     without an override it's the same white-card-on-dark-page bug class
     found throughout this cohort. Reuses the same navy-gradient family as
     the Panels suggestion-banner for visual consistency across the cohort.
     Status-dot border/glow tokens are dark-stable (pure-saturated alert
     colors, not page-background-dependent) — no override needed. */
  --dailyflow-rundetails-bg-start:       #1a2340;
  --dailyflow-rundetails-bg-end:         #16233a;
  --dailyflow-rundetails-border:         #2d3a5c;
  --dailyflow-rundetails-fg:             #8fa8d9;  /* lightened navy for AA contrast, matches --dailyflow-suggestion-accent's dark treatment */
  --dailyflow-rundetails-hover-bg-start: #223a5e;
  --dailyflow-rundetails-hover-bg-end:   #1c2d4a;

  /* ── W10 cohort (Winemaking/WinemakingSchedule) dark override ──────────────
     Was a hardcoded #f0f7ff pale-blue with no dark treatment at all — a real
     pre-existing bug (near-invisible low-contrast text on the team-cell
     pills in dark mode, confirmed by direct screenshot before this fix).
     Reuses the same soft-blue-panel dark value as --chip-info-bg for
     consistency with the rest of the app's "info tint" family. */
  --wmsched-cell-bg: #1a2f4a;

  /* ── W11 cohort (LabelCola/ColaCardItem + LabelCardItem) dark override ────
     Same blur/spread as --shadow-lg dark for the resting shadow (shadows
     need more opacity to read over a dark card background); hover is
     interactive-only (not VR-verified) — a proportionally deeper alpha. */
  --label-card-shadow: 0 2px 8px rgba(0, 0, 0, 0.50);
  --label-card-shadow-hover: 0 4px 16px rgba(0, 0, 0, 0.60);

  /* Light-stroke variant of the custom <select> caret so it stays visible
     against a dark field background — see the :root definition. */
  --select-caret-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");

  --labelcola-success-fg: #4eef85;
  --labelcola-romantic-bg: #2e1f22;   /* dark maroon-tinted surface, same family as green-100 dark's tinted-surface pattern */

  /* LabelManager (W11) dark overrides — status/danger family lifts to brighter
     hues (matches this file's --green-600/--red-500/--yellow-700 dark
     treatment elsewhere); notice/lightbox stay theme-invariant (same
     reasoning as --inv-fw-notice-* having no dark override either, and
     lightbox scrims/shadows being dark by design regardless of theme). */
  --labelcola-status-success-bg:     #1e3a2a;   /* = --green-100 dark weight */
  --labelcola-status-success-border: #2f6b45;
  --labelcola-status-success-fg:     #4eef85;   /* = --green-600/--green-700 dark */
  --labelcola-status-warning-fg:     #f5d572;   /* = --yellow-700 dark */
  --labelcola-status-warning-fg-strong: #f0a860;
  --labelcola-status-danger-bg:      #3a1f23;   /* = --state-danger-bg dark weight */
  --labelcola-status-danger-border:  #7a3a3f;
  --labelcola-status-danger-fg:      #ff5560;   /* = --red-500 dark */
  --labelcola-alert-strong: #ff5560;   /* = --red-500 dark */
  --labelcola-extract-error-bg:     #3a2422;
  --labelcola-extract-error-border: #6b3535;

  /* ── W12 cohort (Packaging) dark override ──────────────────────────────────
     Only the tokens actually exercised by the packaging-glass-status VR
     capture get a real (verified) dark value: the "Needs Attention" danger
     card (this cohort's data has 1 alert) and the row bottle-drawing
     thumbnails. gs-card--warning's dark value is a best-effort match to the
     verified danger treatment (not independently triggered by the corpus
     data — 0 unmatched at capture time). Everything else in this cohort stays
     dark-stable, same non-corpus reasoning as its :root definition. */
  --pkg-card-warning-bg-start: #2b2410;   /* = --dailyflow-naked-dates-bg family, warm-dark tint */
  --pkg-card-danger-bg-start:  #3a1f23;   /* = --state-danger-bg dark weight */
  --pkg-card-danger-bg-end:    #402024;   /* slightly more saturated than the start, mirrors the light gradient's direction */
  --pkg-card-danger-border:    #ff5560;   /* = --red-500 dark */
  --pkg-thumb-border:          #373b40;   /* = --gray-300 dark (border-subtle weight) */

  /* ── Harvest dashboard (--hd-*) dark overrides ─────────────────────────
     The client card's ember bg reads garish on dark at full light-mode chroma —
     deepen it; the border flips to a light hairline (dark-surface convention).
     Every other --hd-* token inherits via semantic-token indirection. */
  --hd-card-bg:     #5a1622;   /* Stage 3 (B): dark bordeaux — was #b23018 */
  --hd-card-border: rgba(255, 255, 255, 0.10);

  /* ── CopilotPanel cohort dark overrides ────────────────────────────────
     Panel chrome inherits dark treatment for free via --surface-* / --border-* /
     --text-*. Only this panel's own accent/status palette needs explicit
     overrides — lifted/desaturated per the same conventions used throughout
     this block (muted tones lighten, saturated ones stay punchy, shadows
     gain opacity). */
  --copilot-accent:             #5b93f5;
  --copilot-accent-rgb:         91, 147, 245;
  --copilot-accent-strong:      #3b74d6;
  --copilot-accent-deep:        #a8c8fa;
  --copilot-accent-soft:        #3d5a8a;
  --copilot-accent-tint:        #16233d;
  --copilot-accent-tint-border: #2d4a78;   /* = --chip-info-border dark weight */
  --copilot-accent-bg:          #1c355c;

  --copilot-toast-bg:     #133226;
  --copilot-toast-border: #2f6b52;
  --copilot-toast-fg:     #4eef85;   /* = --green-500 dark */
  --copilot-toast-code-bg: rgba(0, 0, 0, 0.25);   /* a scrim reads better than a light patch on a dark toast */

  --copilot-badge-high-bg:     #16321f;
  --copilot-badge-high-fg:     #4eef85;
  --copilot-badge-medium-bg:   #3a3410;
  --copilot-badge-medium-fg:   #f5d572;   /* = --yellow-700 dark */
  --copilot-badge-inferred-bg: #262d52;
  --copilot-badge-inferred-fg: #a5b0f5;

  --copilot-severity-critical-bg: #3a1f23;  /* = --state-danger-bg dark weight */
  --copilot-severity-critical-fg: #ff8a8a;
  --copilot-severity-high-bg:     #3a2610;
  --copilot-severity-high-fg:     #ffab6b;

  --copilot-access-warning-bg: #332b10;
  --copilot-access-warning-fg: #f0a85a;

  --copilot-danger-bg: #3a1f1f;

  --copilot-progress-ok:      #4eef85;
  --copilot-progress-warning: #f5d572;
  --copilot-progress-danger:  #ff6b6b;

  --copilot-submit-bg:          #16261a;
  --copilot-submit-border:      #2f6b45;
  --copilot-submit-hover-bg:    #1f9d4d;
  --copilot-submit-disabled-bg: #2f5c3d;

  --copilot-copysuccess-border: #2f6b52;

  --copilot-shadow-toggle:       0 2px 8px rgba(0, 0, 0, 0.35);
  --copilot-shadow-toggle-hover: 0 4px 12px rgba(0, 0, 0, 0.42);
  --copilot-shadow-panel:        0 8px 32px rgba(0, 0, 0, 0.50);

  /* Pumpover worksheet: the lot-group band needs roughly double the alpha to register on a
     near-black surface. --pohv-focus-ring needs NO override — it is composed from
     --blue-500-rgb, which is already lifted above. */
  --pohv-row-alt: rgba(var(--blue-500-rgb), 0.07);
}

/* ── Bootstrap variable shadowing ─────────────────────────────────────
   The app uses Bootstrap utility classes (.bg-light, .text-muted, .table,
   etc.) that reference Bootstrap's own --bs-* variables. Shadow them so
   utility-classed elements respect the theme. */
[data-theme="dark"] {
  --bs-body-bg:           var(--surface-subtle);
  --bs-body-color:        var(--text-primary);
  --bs-secondary-bg:      var(--surface-muted);
  --bs-tertiary-bg:       var(--surface-emphasis);
  --bs-secondary-color:   var(--text-muted);
  --bs-border-color:      var(--border-default);
  --bs-border-color-translucent: rgba(255, 255, 255, 0.15);
  --bs-light:             var(--surface-default);
  --bs-light-rgb:         43, 48, 53;   /* gray-200 in rgb */
  --bs-dark:              var(--gray-900);
  --bs-dark-rgb:          248, 249, 250;
  --bs-primary:           var(--blue-500);
  --bs-primary-rgb:       77, 148, 255;
  --bs-primary-bg-subtle: var(--blue-100);
  --bs-link-color:        var(--text-link);
  --bs-link-hover-color:  var(--blue-500);
}

/* ── Body background — the one global rule that has to be explicit
   because <body> isn't inside any component scope. Applies to both
   themes via the cascading semantic tokens. */
body {
  background-color: var(--surface-subtle);
  color: var(--text-primary);
}

/* ── Image inversion / opacity on dark ─────────────────────────────────
   Logos and screenshots designed for light backgrounds can look harsh
   on dark. No automatic invert — too risky for product photos, wine
   labels, scan previews. Mark specific elements with .no-theme-invert
   when an opt-out is needed. Empty selector registered for future use. */
[data-theme="dark"] img:not(.no-theme-invert) {
  /* placeholder — populate per-context when a specific image needs help */
}
