/*
 * AIM Comprehensive Color System
 * Created: May 2025
 * Purpose: Centralized color definitions for the AIM platform
 * Version: 2.0 - Comprehensive refactor
 */

:root {
    /* 
     * ==========================================================================
     * 1. FOUNDATION COLORS
     * ==========================================================================
     */
    
    /* Absolute colors */
    --color-white: #ffffff;
    --color-black: #000000;
    
    /* Brand Foundation Colors */
    --cornerstone-teal-base: #003e52;
    --cornerstone-green-base: #00CCA0;
    --aim-blue-base: var(--brand-primary); /* Derived â€” change --brand-primary to re-theme */
    --aim-accent-base: #56AEFF;

    /*
     * ==========================================================================
     * 1b. DERIVED COLOR SYSTEM
     * Change --brand-primary to re-theme the entire application.
     * All other colors are auto-calculated via color-mix().
     * ==========================================================================
     */

    /* ─── BRAND IDENTITY vs ACTION COLOUR ─────────────────────────────────
       Until May 7 2026 there was a single `--brand-primary` doing two jobs:
         (a) "this is AIM" — navbar, table header strip, brand mark
         (b) "this is something you do" — primary buttons, links, sort arrows
       Slate (#3F5269) reads as identity; saturated blue (#2063D7) reads as
       action. The single token couldn't tell consumers which to grab, so the
       Design Reference's Primary button rendered slate while real-product
       primary buttons rendered blue. Two roles, two tokens.

       Both names point at the SAME root literal in light mode (the slate),
       but `--action-primary` is OKLCH-derived to a saturated mid-blue. Brand
       swap moves both together via --brand-identity, so Forest / Crimson /
       Plum brands re-tint identity AND action simultaneously.

       --brand-primary is kept as a deprecated alias for backwards-compat —
       265+ existing consumers still resolve correctly. New code should use
       --brand-identity (chrome) or --action-primary (do-it affordance). */
    --brand-identity: #3F5269;                                /* slate — the AIM mark */

    /* ─── BUTTON COLOUR HIERARCHY ──────────────────────────────────────────
       Two distinct roles (May 7 2026 — refined after Site Details audit):

         --action-primary  =  slate  = everyday utility button (Edit, Refresh,
                                         Manage, Upload, +Add). 95% of buttons.
                                         Reads as first-class brand chrome,
                                         matches navbar, doesn't shout.
         --action-cta      =  blue   = rare submit-grade button (Save, Confirm,
                                         Submit). Max one per screen.
                                         Blue earns its place by being reserved
                                         for "this is THE action".

       The name --action-cta makes rarity explicit: any developer reaching
       for it pauses and asks "is this really a submit-grade moment?" —
       which is the question we want them asking.

       Brand swap still propagates: --action-primary aliases --brand-identity,
       --action-cta is OKLCH-derived from --brand-identity. */
    --action-primary: var(--brand-identity);                            /* slate, everyday */
    /* --action-cta = blue-700 #1D4ED8, same hex as --color-info-medium so
       hyperlinks inside info-tinted banners reuse this token (one less
       --info-link chain to maintain). For a non-AIM brand swap that wants
       a different CTA hue, override at the brand's :root block. */
    --action-cta:     #1D4ED8;

    /* Backwards-compat alias — DO NOT remove without sweeping consumers. */
    --brand-primary: var(--brand-identity);

    /* ─── BRAND AS FOREGROUND ──────────────────────────────────────────────
       `--brand-identity` is a *chrome fill* colour. In light mode it happens
       to double as a legible foreground (slate #3F5269 on white/#E8EEF6), so
       ~476 declarations across the app were written as
           color: var(--brand-primary | --color-primary | --primary-color
                      | --interactive-base);
       That coincidence does NOT hold in dark mode: `[data-theme="aim-dark"]`
       sets --brand-identity to #44475a, which is byte-identical to
       --surface-raised (the card background). Contrast ratio 1.00 — every one
       of those accents rendered invisible (blank pills in the workflow rail,
       an empty Tier column in Companies & users, unlabelled chips app-wide).
       cornerstone-dark had the same collision at 1.37:1.

       --brand-on-surface is the foreground counterpart: "brand accent, legible
       on whatever this theme's surfaces are". In light themes it aliases the
       identity colour, so light mode is byte-for-byte unchanged; each dark
       theme overrides it to the light end of its own brand ramp.

       USE --brand-on-surface for `color:` / `fill:`. Keep --brand-identity
       (or --action-primary / --action-cta) for `background:`. Enforced by
       CSS11 in CssArchitectureTests. */
    --brand-on-surface: var(--brand-identity);

    /* Same problem, other two roles. A button is ONE object — label, border,
       fill — and all three were reading --brand-identity, so in dark mode all
       three collapsed onto the card colour: label invisible, outline invisible,
       fill invisible. Fixing only the label (2026-07-27, first pass) left
       buttons as floating text with no chrome, which read as WORSE. All three
       roles now have their own token, measured against each theme's surfaces:

         --brand-on-surface         text/icons   target >= 4.5:1 (WCAG AA)
         --brand-border-on-surface  outlines     target >= 3:1   (WCAG 1.4.11)
         --brand-fill-on-surface    solid fills  white label >= 4.5:1 ON it

       Light themes alias --brand-identity for all three, so light mode is
       byte-for-byte unchanged. Only the dark themes carry real values. */
    --brand-border-on-surface: var(--brand-identity);
    --brand-fill-on-surface:   var(--brand-identity);

    /* ═══ FOCUS ═══════════════════════════════════════════════════════════
       One vocabulary for every focusable thing. Added 2026-08-03 after a
       focus-state review found three defects stacked on each other:

       1. aim-shared-ui.css carried a universal `*:focus` (NOT :focus-visible)
          which loaded AFTER aim-consolidated.css and, at equal specificity,
          won. `*:focus` fires on MOUSE CLICK — so clicking any control left
          a hard box stuck on it until you clicked something else.
       2. It painted --aim-primary → --primary-color → --brand-primary, the
          FILL token. CSS11 reserves --brand-border-on-surface for outlines
          for exactly this reason: --brand-primary is near-invisible on an
          aim-dark card, and a hard navy slab on white.
       3. The :focus-visible rule it beat also set
          `border-radius: var(--radius-sm)`, mutating the ELEMENT's own shape
          — pills and the circular stage dots squared off on focus. Never
          needed: `outline` has followed border-radius on its own in every
          browser we support since 2021.

       Offset is 1px, not the old 2px: at AIM density (28px buttons, 8px
       gaps — design language §5.1) a 2px outset ring lands on the
       neighbouring control, which is what made it read as a floating box.

       --focus-ring-color aliases the theme's outline token, so all four
       themes inherit correct values with no redeclaration — same mechanism
       --border-strong already uses. */
    --focus-ring-color:  var(--brand-border-on-surface);
    --focus-ring-width:  2px;
    --focus-ring-offset: 1px;

    /* Halo = the text-control tier. Alpha, so it blooms into whatever
       surface is behind it instead of assuming a card, and so it survives
       both dark themes. Same shape the "current stage" dot already uses
       (WorkflowSection.razor.css). */
    --focus-ring-halo:       color-mix(in srgb, var(--focus-ring-color) 30%, transparent);
    --focus-ring-halo-width: 3px;

    /* Primary palette â€” darkened/lightened from brand */
    --primary-color: var(--brand-primary);
    --primary-hover: color-mix(in srgb, var(--primary-color), black 15%);
    --primary-active: color-mix(in srgb, var(--primary-color), black 25%);
    --primary-light: color-mix(in srgb, var(--primary-color), white 75%);
    --primary-lighter: color-mix(in srgb, var(--primary-color), white 88%);
    --primary-lightest: color-mix(in srgb, var(--primary-color), white 95%);

    /* Primary alpha variants â€” overlays, shadows, borders */
    --primary-alpha-10: color-mix(in srgb, var(--primary-color), transparent 90%);
    --primary-alpha-15: color-mix(in srgb, var(--primary-color), transparent 85%);
    --primary-alpha-25: color-mix(in srgb, var(--primary-color), transparent 75%);
    --primary-alpha-40: color-mix(in srgb, var(--primary-color), transparent 60%);

    /* Secondary palette â€” derived darker shade for dropdown menus, hover chrome */
    --secondary-color: color-mix(in srgb, var(--primary-color), black 10%);
    --secondary-hover: color-mix(in srgb, var(--secondary-color), black 15%);
    --secondary-light: color-mix(in srgb, var(--primary-color), #AAB4C0 70%);
    --secondary-lighter: color-mix(in srgb, var(--primary-color), #D0D6DC 80%);

    /* Interactive palette â€” the "click-me" colour family.
       --interactive-base now aliases --action-primary so the role-named token
       (action) and the affordance-named token (interactive) point at the
       same value. Hover/active are darkening shifts off the action base. */
    --interactive-base: var(--action-primary);
    --interactive-hover: color-mix(in srgb, var(--action-primary), black 20%);
    --interactive-active: color-mix(in srgb, var(--action-primary), black 30%);

    /* Border palette â€” derived from primary opacity */
    --border-subtle: var(--primary-alpha-25);
    --border-strong: var(--primary-alpha-40);

    /* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
       SURFACE LADDER â€” 3-TIER, FORMULA-DERIVED, MULTI-BRAND READY
       â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
       Every surface tier is conceptually a mix of `--brand-primary` with a
       neutral anchor. The mix percentage IS the elevation language:
           Tier 1 (anchor):  brand 10% + neutral
           Tier 2 (content): brand 22% + neutral
           Tier 3 (overlay): brand 38% + neutral
       This makes the system multi-brand:
         - Swap --brand-primary (AIM blue â†’ green / red / purple) and surfaces
           re-tint automatically, preserving the elevation hierarchy.
         - Each tier is a Î”E ~7-9 step from its neighbour in either theme â€”
           visibly distinct without categorical jumps.
       The literal hex values below are pre-computed for the current
       --brand-primary (and hand-tuned where it's worth preserving an iconic
       value, e.g. AIM blue page bg). Override per theme block by re-deriving
       from your theme's brand value.

       SATURATION RULE (Material-derived):
         Light mode â†’ higher tier = LESS tinted (cards become pristine white)
         Dark mode  â†’ higher tier = MORE tinted (cards lift via lighter overlay)
       This inverse-saturation behaviour is why "modal lighter than card" is
       correct in dark mode but "modal whiter than card" is correct in light.

       SEMANTIC ALIASES (use these in component CSS):
         --surface-anchor   = page bg, table headers, sticky toolbars
         --surface-content  = card body, table rows, form panels
         --surface-overlay  = modals, popovers, dropdown menus
       Each comes with a paired text token: --text-on-anchor / --content / --overlay.
       â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

    /* Foundation neutrals â€” the two anchor poles every surface mixes against. */
    --neutral-light: #ffffff;
    --neutral-dark:  #15171f;

    /* TIER 1 â€” page anchor (canvas the rest of the UI sits ON)
       Light-mode saturation rule: tier 1 carries the brand tint; higher tiers
       fade towards white. Brand-swap on this token is what makes the page
       canvas re-tint when --brand-primary changes.
       May 7, 2026 — dialed from 15% → 5% per design refresh. Modern-SaaS
       default (Stripe / Linear / Notion territory): page recedes to almost-
       off-white so cards pop maximally. Resolves to ~#F5F6F8 with AIM brand
       (vs. previous #E2E5E8). Brand swap still works — formula is identical,
       just lower saturation. */
    --surface-base: color-mix(in srgb, var(--brand-primary) 5%, var(--neutral-light));
    --text-on-surface-base: #1A1F2E;

    /* TIER 2 â€” cards / primary content surface
       Pure white by design â€” cards "pop" against the tinted page. A brand swap
       does NOT visibly change cards in light mode (correct per inverse-saturation rule). */
    --surface-raised: var(--neutral-light);
    --text-on-surface-raised: #1A1F2E;

    /* TIER 3 — modals / popovers / dropdown menus.
       Light-mode honest admission (May 7 2026): with the page now at ~5%
       brand mix into white and cards at pure white, --brand-primary @ 4-10%
       cannot produce a perceivable third tier. So in light mode we have
       two real surfaces (page + raised) — the third tier exists via
       border/shadow/backdrop on a different perceptual channel, not colour.

       --surface-elevated resolves to --surface-raised (same colour as cards).
       Components achieve the "elevated" feel via:
         border:     var(--elevated-border)    — 12% slate edge (stronger than card's 10%)
         box-shadow: var(--elevated-shadow)    — 4px 12px @ 8% slate
         backdrop:   var(--elevated-backdrop)  — full-page slate @ 45% behind

       Dark mode KEEPS the 3-tier surface ladder (overrides at line ~1064).
       Dracula has the contrast budget for it. */
    --surface-elevated: var(--surface-raised);
    --text-on-surface-elevated: #1A1F2E;
    --elevated-border:   1px solid color-mix(in srgb, var(--brand-identity) 12%, transparent);
    --elevated-shadow:   0 4px 12px color-mix(in srgb, var(--color-neutral-darkest) 8%, transparent);
    --elevated-backdrop: color-mix(in srgb, var(--color-neutral-darkest) 45%, transparent);
    --shadow-elevated: 0 12px 32px rgba(15, 23, 42, 0.18);

    /* Semantic aliases â€” components opt into these by ROLE, not by tier number.
       "Is this a structural anchor or an elevation lift?" becomes explicit. */
    --surface-anchor:  var(--surface-base);
    --surface-content: var(--surface-raised);
    --surface-overlay: var(--surface-elevated);
    --text-on-anchor:  var(--text-on-surface-base);
    --text-on-content: var(--text-on-surface-raised);
    --text-on-overlay: var(--text-on-surface-elevated);

    /* Stripe & hover â€” design language Â§9 rule: "hover = var(--surface-base)
       tint, NOT a bright highlight". So hover MUST land on --surface-anchor
       (one tier DOWN from --surface-content) in both modes:
         Light: white card â†’ blue-tinted page bg (subtle darken)
         Dark:  dracula bg â†’ deeper navy page bg (subtle darken)
       This consistently darkens on hover regardless of theme.

       Stripe stays as a same-tier subtle brand-mix tint â€” it's NOT a hover
       cue, just a quiet zebra to anchor the eye on long tables. Originally
       8% brand mix; bumped to 12% after user feedback that admin tables read
       as uniform white sheets at typical viewing distance / under JPEG
       screenshot compression. Î”E â‰ˆ 7 against --surface-content â€” still well
       below "noisy" but clearly perceivable as zebra. Dark mode keeps its
       own subtler 3% white-mix value (overridden in [data-theme="aim-dark"]). */
    --surface-row-stripe: color-mix(in srgb, var(--surface-content) 88%, var(--brand-primary));
    --surface-row-hover:  var(--surface-anchor);

    /* Legacy aliases â€” preserved so older CSS that references these tokens
       still resolves to sensible values. Prefer the semantic aliases above. */
    --surface-primary: var(--surface-content);
    --surface-secondary: var(--surface-anchor);
    --surface-hover: var(--surface-row-hover);
    --surface-muted: var(--surface-anchor);
    --text-disabled: #adb5bd;

    /* Bootstrap-era alias (used in 14+ component files) */
    --border-color: #dee2e6;

    /* British-spelling aliases (used by ReportsHub etc.) */
    --colour-surface: #ffffff;
    --colour-text-primary: #1a202c;
    --colour-text-secondary: #4a5568;
    --colour-text-muted: #718096;
    --colour-border: #e2e8f0;

    /*
     * ==========================================================================
     * 2. SEMANTIC COLOR PALETTES
     * ==========================================================================
     */
    
    /* Status palettes — locked Tailwind mapping (May 7 2026):
         -lightest / -bg  =  -100  (pale tinted card / banner bg)
         -medium          =  -700  (solid pill / button bg, white text)
         -dark            =  -900  (text on pale -100 bg, ~9:1+ contrast)
         -light           =  -300  (dim / disabled / decay state)

       Why -dark = -900 not -800: 9:1 contrast at -900 gives headroom for
       any dim/disabled/inactive state to drop a level (to -800) without
       breaking AA. -800 would pass at active state but leave nowhere to go.

       Why warning is orange-700 not amber-700: amber slides toward brown at
       deep stops, losing the "warning" semantic and reading as muted text.
       Orange holds the heat without the glow.

       Why info-100 = blue-100 (#DBEAFE) not sky-100: keeps the info family
       in the same hue as info-medium #1D4ED8, so #1D4ED8-on-#DBEAFE gives
       ~7:1 contrast for hyperlinks inside info banners — same blue as
       --action-cta, doubles as the link colour without a separate token. */

    /* Success — Tailwind Green */
    --color-success-dark:     #14532D;   /* green-900 */
    --color-success-medium:   #15803D;   /* green-700 */
    --color-success-light:    #86EFAC;   /* green-300 */
    --color-success-lightest: #D1FAE5;   /* green-100 */

    /* Warning — Tailwind Orange (NOT amber — amber goes brown at -900) */
    --color-warning-dark:     #7C2D12;   /* orange-900 */
    --color-warning-medium:   #C2410C;   /* orange-700 */
    --color-warning-light:    #FDBA74;   /* orange-300 */
    --color-warning-lightest: #FFEDD5;   /* orange-100 */

    /* Danger — Tailwind Red */
    --color-danger-dark:      #7F1D1D;   /* red-900 */
    --color-danger-medium:    #B91C1C;   /* red-700 */
    --color-danger-light:     #FCA5A5;   /* red-300 */
    --color-danger-lightest:  #FEE2E2;   /* red-100 */

    /* Info — Tailwind Blue (NOT sky — keeps single blue hue across info + cta) */
    --color-info-dark:        #1E3A8A;   /* blue-900 */
    --color-info-medium:      #1D4ED8;   /* blue-700 — same as --action-cta */
    --color-info-light:       #93C5FD;   /* blue-300 */
    --color-info-lightest:    #DBEAFE;   /* blue-100 */

    /* Purple / pink accents — de-facto design tokens that several components
       (CIO/CEO dashboards, StaffPlanningCalendar meeting blocks, DataClassificationBadge
       classification levels) consumed via `var(--token, #hex)` fallbacks. Defining them
       here completes the half-done usage so consumers can drop the hardcoded hex fallback
       (Rule10/CSS01). NOTE: dark-mode variants not yet split — they inherit these light
       values, which is acceptable for these low-frequency accents (see
       feedback_var_alias_dark_mode_redeclaration for the eventual dark split). */
    --color-purple-dark:      #6D28D9;   /* violet-700 */
    --color-purple-medium:    #9333EA;   /* violet-600 */
    --color-purple-light:     #C4B5FD;   /* violet-300 */
    --color-purple-lightest:  #EDE9FE;   /* violet-100 */
    --color-accent-purple:    var(--color-purple-medium);
    --color-accent-pink:      #DB2777;   /* pink-600 */

    /* Neutral Palette (Slate â€” blue-tinted, reads as "tech" not flat Bootstrap grey) */
    --color-neutral-darkest: #0F172A;
    --color-neutral-dark: #1E293B;
    --color-neutral-medium: #64748B;
    --color-neutral-light: #94A3B8;
    --color-neutral-lightest: #F1F5F9;

    /* â”€â”€â”€ Tailwind-style numeric aliases (compat layer) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
       111 component references author against `--color-*-500` / `--color-*-50`
       as if they were Tailwind tokens. They never resolved (the canonical
       token names are -dark/-medium/-light/-lightest), so every consumer was
       silently falling through to a hardcoded hex fallback â€” invisible to
       theme switching and brand re-tinting. These aliases make the numeric
       names resolve to the canonical semantic tokens, so dark mode and
       multi-brand work without touching 20 component files.

       Note: legacy code uses `error` as a synonym for `danger`. New code
       MUST use the canonical names; these aliases are deprecation shims. */
    --color-error-500:   var(--color-danger-medium);
    --color-error-50:    var(--color-danger-lightest);
    --color-danger-500:  var(--color-danger-medium);
    --color-danger-50:   var(--color-danger-lightest);
    --color-warning-500: var(--color-warning-medium);
    --color-warning-50:  var(--color-warning-lightest);
    --color-success-500: var(--color-success-medium);
    --color-success-50:  var(--color-success-lightest);
    --color-info-500:    var(--color-info-medium);
    --color-info-50:     var(--color-info-lightest);
    --color-gray-50:     var(--surface-anchor);
    --aim-danger-light:  color-mix(in srgb, var(--color-danger-medium) 12%, var(--surface-raised));

    /* Tailwind-style scale aliases for --color-primary-{100..900}.
       29 component references author against these as if they were Tailwind
       tokens (`--color-primary-100` for pale tab-badge bg, etc.). They never
       resolved (the canonical names are --brand-primary + interactive-base),
       so every consumer was silently falling through to a hardcoded pale-blue
       hex (#dbeafe etc.) â€” frozen on AIM blue regardless of brand swap.
       Aliases derive from --brand-primary so brand swap re-tints instantly. */
    --color-primary-50:  color-mix(in srgb, var(--brand-primary) 5%,  var(--neutral-light));
    --color-primary-100: color-mix(in srgb, var(--brand-primary) 12%, var(--neutral-light));
    --color-primary-200: color-mix(in srgb, var(--brand-primary) 22%, var(--neutral-light));
    --color-primary-300: color-mix(in srgb, var(--brand-primary) 35%, var(--neutral-light));
    --color-primary-400: color-mix(in srgb, var(--brand-primary) 55%, var(--neutral-light));
    --color-primary-500: var(--brand-primary);
    --color-primary-600: color-mix(in srgb, var(--brand-primary), black 10%);
    --color-primary-700: color-mix(in srgb, var(--brand-primary), black 22%);
    --color-primary-800: color-mix(in srgb, var(--brand-primary), black 35%);
    --color-primary-900: color-mix(in srgb, var(--brand-primary), black 50%);

    /*
     * ==========================================================================
     * 3. COMPONENT-SPECIFIC COLORS
     * ==========================================================================
     */
    
    /* Milestone Status Colors */
    --milestone-bg-default: #fff;
    --milestone-success-bg: var(--color-success-lightest);
    --milestone-warning-bg: var(--color-warning-lightest);
    --milestone-danger-bg: var(--color-danger-lightest);
    
    /* Action Colors */
    --action-break-bg: var(--color-success-medium);
    --action-sort-bg: #d946ef; /* magenta */
    --action-filter-bg: #f97316; /* orange */

    /* Flight Zone Map Overlay Colors (fill / stroke / opacity) */
    --zone-prohibited-fill: #dc2626;
    --zone-prohibited-stroke: #991b1b;
    --zone-prohibited-opacity: 0.4;
    --zone-restricted-fill: #ea580c;
    --zone-restricted-stroke: #c2410c;
    --zone-restricted-opacity: 0.35;
    --zone-danger-fill: #d97706;
    --zone-danger-stroke: #b45309;
    --zone-danger-opacity: 0.3;
    --zone-airport-fill: #2563eb;
    --zone-airport-stroke: #1d4ed8;
    --zone-airport-opacity: 0.3;
    --zone-military-fill: #7c3aed;
    --zone-military-stroke: #6d28d9;
    --zone-military-opacity: 0.3;
    --zone-general-fill: #6b7280;
    --zone-general-stroke: #4b5563;
    --zone-general-opacity: 0.25;
    
    /* 
     * ==========================================================================
     * 4. THEME SYSTEM - AIM LIGHT
     * ==========================================================================
     */
    
    /* AIM Light - Primary Colors (chained to derived system) */
    --aim-light-primary: var(--primary-color);
    --aim-light-secondary: var(--secondary-color);

    /* AIM Light - Background Colors */
    --aim-light-bg-page: var(--surface-base);
    --aim-light-bg-card: #F1F5F9;   /* Slate-100 â€” clean slate, replaces washed-out blue-grey alpha */
    --aim-light-bg-header: #E2E8F0; /* Slate-200 â€” crisp section separator */
    --aim-light-dashboard-bg: var(--surface-raised);

    /* AIM Light - Border Colors */
    --aim-light-border-subtle: var(--primary-alpha-25);
    --aim-light-border-strong: var(--primary-alpha-40);

    /* AIM Light - Text Colors */
    --aim-light-text-primary: #1A1F2E;  /* Dark navy-tinted â€” richer contrast than flat #333 */
    --aim-light-text-secondary: #64748B; /* Slate-500 â€” has blue undertone, not flat grey */
    --aim-light-text-on-color: #FFFFFF;

    /* AIM Light - Interactive Colors (chained to derived system) */
    --aim-light-interactive: var(--interactive-base);
    --aim-light-interactive-hover: var(--interactive-hover);
    
    /* AIM Light - Component Colors */
    --aim-light-site-info-bg-selected: #BFDBFE; /* Blue-200 â€” selected state, clear but not garish */
    --aim-light-input-background: #FFFFFF; /* White inputs â€” modern standard, was grey (looked disabled) */
    --aim-light-card-shadow: 0 1px 3px rgba(15, 23, 42, 0.10), 0 4px 16px rgba(15, 23, 42, 0.08); /* Visible elevation â€” white cards on blue-grey bg */

    /* AIM Light - Card Variables */
    --aim-light-card-bg: #ffffff;
    --aim-light-card-border: #CBD5E1; /* Slate-300 â€” more visible border for contrast */
    --aim-light-card-header-bg: #F8FAFC; /* Slate-50 â€” barely-there header, elegant */

    /* AIM Light - Panel Variables */
    --aim-light-panel-bg: color-mix(in srgb, var(--brand-primary), black 5%);   /* Elevated â€” slightly darker than brand for layering */
    --aim-light-panel-header-bg: var(--brand-primary); /* Matches brand â€” strongest element */
    --aim-light-panel-text: #ffffff;
    --aim-light-panel-text-secondary: #CBD5E1; /* Slate-300 â€” readable secondary on dark */
    --aim-light-panel-border: color-mix(in srgb, var(--brand-primary), white 15%); /* Visible separator on dark surface */
    --aim-light-panel-hover: color-mix(in srgb, var(--brand-primary), white 10%); /* Hover â€” lighter than bg, clear feedback */
    
    /* AIM Light - Posts Panel Variables (Light Background) */
    --aim-light-posts-panel-bg: var(--aim-light-bg-page); /* Use page background for content separation */
    --aim-light-posts-panel-text: var(--aim-light-text-primary); /* Use primary text color */
    
    /* AIM Light - Navbar Variables */
    --aim-light-navbar-bg: var(--brand-primary);  /* Brand primary â€” unified, strong presence */
    --aim-light-navbar-text: #ffffff;
    --aim-light-navbar-hover: color-mix(in srgb, var(--brand-primary), white 10%); /* Lighter hover â€” clear, not flat */
    
    /* AIM Light - Posts Panel Variables (Use theme background) */
    --aim-light-posts-bg: var(--aim-light-bg-page); /* Use page background for content separation */
    --aim-light-posts-text: var(--aim-light-text-primary); /* Use primary text color */
    
    /* 
     * ==========================================================================
     * 5. THEME SYSTEM - AIM DARK
     * ==========================================================================
     */
    
    /* AIM Dark - Primary Colors */
    --aim-dark-primary: #6272a4;
    --aim-dark-secondary: #44475a;
    --aim-dark-accent: #bd93f9;
    --aim-dark-accent2: #8be9fd;
    
    /* AIM Dark - Background Colors */
    --aim-dark-bg-page: #282a36;
    --aim-dark-bg-card: #363950; /* Opaque â€” was rgba(98,114,164,0.2) which appeared invisible */
    --aim-dark-bg-header: #3b3f54; /* Opaque â€” was rgba(98,114,164,0.3) which appeared invisible */
    --aim-dark-dashboard-bg: #444758;
    
    /* AIM Dark - Border Colors */
    /* 2026-07-27 — was rgba(68, 71, 90, 0.6): #44475a, i.e. THE CARD COLOUR
       itself at 60% alpha. Measured 1.30:1 over the page and 1.00:1 over a card
       — every "subtle" border in dark mode was the surface it sat on, which is
       why bordered controls (table pagination, chips, inputs) blended into the
       background. Neutral white-alpha is the dark-UI convention for dividers
       and is brand-independent, so it can't re-collide when the brand swaps.
       Measured composite: 1.87:1 over page · 1.72:1 over card. Deliberately
       still a DIVIDER, not a control outline — controls use --border-strong. */
    --aim-dark-border-subtle: rgba(248, 248, 242, 0.20);
    --aim-dark-border-strong: rgba(98, 114, 164, 0.7);
    
    /* AIM Dark - Text Colors */
    --aim-dark-text-primary: #f8f8f2;
    --aim-dark-text-secondary: #BBBBBB;
    --aim-dark-text-on-color: #FFFFFF;
    
    /* AIM Dark - Interactive Colors */
    --aim-dark-interactive: #bd93f9;
    --aim-dark-interactive-hover: #a97ff0;
    --aim-dark-alert: #ff5555;
    
    /* AIM Dark - Component Colors */
    --aim-dark-site-info-bg-selected: #444758;
    --aim-dark-input-background: #444758;
    --aim-dark-card-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    
    /* AIM Dark - Card Variables */
    --aim-dark-card-bg: #44475a;
    --aim-dark-card-border: rgba(98, 114, 164, 0.3);
    --aim-dark-card-header-bg: #44475a; /* Opaque â€” matches card-bg, lighter than surface-raised (#343746) for visible header */

    /* AIM Dark - Panel Variables â€” must match navbar (--mainnav-bg-color = --primary-color = #6272a4) */
    --aim-dark-panel-bg: var(--aim-dark-primary); /* Same as navbar bg for consistent chrome */
    --aim-dark-panel-header-bg: color-mix(in srgb, var(--aim-dark-primary), black 15%); /* Darker than panel bg for hierarchy */
    --aim-dark-panel-text: #f8f8f2; /* High contrast light text */
    --aim-dark-panel-text-secondary: #d0d0d0; /* Slightly dimmed for secondary text */
    --aim-dark-panel-border: color-mix(in srgb, var(--aim-dark-primary), white 15%); /* Subtle border */
    --aim-dark-panel-hover: color-mix(in srgb, var(--aim-dark-primary), white 10%); /* Subtle hover state */
    
    /* AIM Dark - Posts Panel Variables (Light Background) */
    --aim-dark-posts-panel-bg: var(--aim-dark-bg-page); /* Use page background for content separation */
    --aim-dark-posts-panel-text: var(--aim-dark-text-primary); /* Use primary text color */
    
    /* AIM Dark - Navbar Variables â€” consistent with panel chrome */
    --aim-dark-navbar-bg: var(--aim-dark-primary); /* Matches panel bg for unified chrome */
    --aim-dark-navbar-text: #f8f8f2; /* Maintain high contrast */
    --aim-dark-navbar-hover: color-mix(in srgb, var(--aim-dark-primary), white 10%); /* Subtle hover state */
    
    /* AIM Dark - Posts Panel Variables (Use theme background) */
    --aim-dark-posts-bg: var(--aim-dark-bg-page); /* Use page background for content separation */
    --aim-dark-posts-text: var(--aim-dark-text-primary); /* Use primary text color */
    
    /* 
     * ==========================================================================
     * 6. THEME SYSTEM - CORNERSTONE LIGHT
     * ==========================================================================
     */
    
    /* Cornerstone Light - Primary Colors */
    --cornerstone-light-primary: #003e52;
    --cornerstone-light-secondary: #008E70;
    --cornerstone-light-accent: #00b289;
    
    /* Cornerstone Light - Background Colors */
    --cornerstone-light-bg-page: #FFFFFF;
    --cornerstone-light-bg-card: rgba(0, 62, 82, 0.15);
    --cornerstone-light-bg-header: rgba(0, 62, 82, 0.25);
    --cornerstone-light-dashboard-bg: #f0f0f0;
    
    /* Cornerstone Light - Border Colors */
    --cornerstone-light-border-subtle: rgba(0, 62, 82, 0.2);
    --cornerstone-light-border-strong: rgba(0, 62, 82, 0.35);
    
    /* Cornerstone Light - Text Colors */
    --cornerstone-light-text-primary: #333333;
    --cornerstone-light-text-secondary: #666666;
    --cornerstone-light-text-on-color: #FFFFFF;
    
    /* Cornerstone Light - Interactive Colors */
    --cornerstone-light-interactive: #00b289;
    --cornerstone-light-interactive-hover: #009A75;
    
    /* Cornerstone Light - Component Colors */
    --cornerstone-light-site-info-bg-selected: #668B97;
    --cornerstone-light-input-background: #FFFFFF;
    --cornerstone-light-card-shadow: 0 2px 5px rgba(0, 62, 82, 0.08);
    
    /* Cornerstone Light - Card Variables */
    --cornerstone-light-card-bg: #ffffff;
    --cornerstone-light-card-border: rgba(0, 62, 82, 0.25);
    --cornerstone-light-card-header-bg: rgba(0, 62, 82, 0.1);

    /* Cornerstone Light - Panel Variables (Color Science Based) */
    --cornerstone-light-panel-bg: #003648; /* Primary darkened by 7% for professional teal look */
    --cornerstone-light-panel-header-bg: #002d3a; /* Primary darkened by 15% for hierarchy */
    --cornerstone-light-panel-text: #ffffff; /* High contrast white text */
    --cornerstone-light-panel-text-secondary: #e0f2f5; /* Teal-tinted light text for secondary */
    --cornerstone-light-panel-border: #00515e; /* Primary lightened by 12% for subtle borders */
    --cornerstone-light-panel-hover: #004552; /* Subtle hover state */
    
    /* Cornerstone Light - Navbar Variables (Lighter for Visual Hierarchy) */
    --cornerstone-light-navbar-bg: #00515e; /* Primary lightened by 15% for subtler presence */
    --cornerstone-light-navbar-text: #ffffff; /* Maintain high contrast */
    --cornerstone-light-navbar-hover: #006b7a; /* Lighter hover state */
    
    /* Cornerstone Light - Posts Panel Variables (Use theme background) */
    --cornerstone-light-posts-bg: var(--cornerstone-light-bg-page); /* Use page background for content separation */
    --cornerstone-light-posts-text: var(--cornerstone-light-text-primary); /* Use primary text color */
    
    /* 
     * ==========================================================================
     * 7. THEME SYSTEM - CORNERSTONE DARK
     * ==========================================================================
     */
    
    /* Cornerstone Dark - Primary Colors */
    --cornerstone-dark-primary: #00526B;
    --cornerstone-dark-secondary: #007A61;
    --cornerstone-dark-accent: #00CCA0;
    
    /* Cornerstone Dark - Background Colors */
    --cornerstone-dark-bg-page: #1C2B30;
    --cornerstone-dark-bg-card: #1f3439; /* Opaque â€” was rgba(0,82,107,0.25) which appeared invisible */
    --cornerstone-dark-bg-header: #1e3640; /* Opaque â€” was rgba(0,82,107,0.35) which appeared invisible */
    --cornerstone-dark-dashboard-bg: #253036;
    
    /* Cornerstone Dark - Border Colors */
    --cornerstone-dark-border-subtle: rgba(0, 82, 107, 0.4);
    --cornerstone-dark-border-strong: rgba(0, 122, 97, 0.6);
    
    /* Cornerstone Dark - Text Colors */
    --cornerstone-dark-text-primary: #E8F0F2;
    --cornerstone-dark-text-secondary: #B3C5CB;
    --cornerstone-dark-text-on-color: #FFFFFF;
    
    /* Cornerstone Dark - Interactive Colors */
    --cornerstone-dark-interactive: #00CCA0;
    --cornerstone-dark-interactive-hover: #00E6B5;
    --cornerstone-dark-alert: #FF6B5E;
    
    /* Cornerstone Dark - Component Colors */
    --cornerstone-dark-site-info-bg-selected: rgba(0, 126, 122, 0.4);
    --cornerstone-dark-input-background: rgba(0, 82, 107, 0.4);
    --cornerstone-dark-card-shadow: 0 2px 5px rgba(0, 0, 0, 0.25);
    
    /* Cornerstone Dark - Card Variables */
    --cornerstone-dark-card-bg: #253036;
    --cornerstone-dark-card-border: rgba(0, 82, 107, 0.4);
    --cornerstone-dark-card-header-bg: #1e3640; /* Opaque â€” teal-tinted, visibly distinct from card body */

    /* Cornerstone Dark - Panel Variables (Color Science Based) */
    --cornerstone-dark-panel-bg: #00526B; /* Use primary directly for strong dark teal presence */
    --cornerstone-dark-panel-header-bg: #004259; /* Primary darkened by 18% for strong hierarchy */
    --cornerstone-dark-panel-text: #E8F0F2; /* High contrast light teal text */
    --cornerstone-dark-panel-text-secondary: #B3C5CB; /* Consistent with existing secondary text */
    --cornerstone-dark-panel-border: #006B84; /* Primary lightened by 20% for subtle borders */
    --cornerstone-dark-panel-hover: #005d77; /* Subtle hover state */
    
    /* Cornerstone Dark - Navbar Variables (Missing - Added for proper contrast) */
    --cornerstone-dark-navbar-bg: #00526B; /* Primary for strong presence */
    --cornerstone-dark-navbar-text: #E8F0F2; /* High contrast light text */
    --cornerstone-dark-navbar-hover: #00CCA0; /* Accent color for hover */
    
    /* 
     * ==========================================================================
     * 8. BACKWARD COMPATIBILITY LAYER
     * ==========================================================================
     */
    
    /* Legacy INS -> AIM Light mappings */
    --ins-primary-color: var(--aim-light-primary);
    --ins-primary-border: var(--aim-light-primary);
    --ins-secondary-color: var(--aim-light-secondary);
    --ins-secondary-border: #6293a4;
    --ins-link-highlight: var(--aim-light-accent);
    --ins-input-background: var(--aim-light-input-background);
    --ins-link-background-color: initial;
    --ins-button-text: var(--aim-light-text-on-color);
    --ins-body-bg-color: var(--aim-light-bg-page);
    --ins-body-text-color: var(--aim-light-text-primary);
    --ins-body-link-color: var(--aim-light-interactive);
    --ins-body-link-hover-color: var(--aim-light-interactive-hover);
    --ins-site-info-bg-selected: var(--aim-light-site-info-bg-selected);
    --ins-mainnav-bg-color: var(--aim-light-primary);
    --ins-mainnav-text-color: var(--aim-light-text-on-color);
    --ins-mainnav-link-color: var(--aim-light-text-primary);
    --ins-mainnav-link-hover-color: var(--aim-light-primary);
    --ins-mainnav-link-active-color: var(--aim-light-primary);
    --ins-footer-bg-color: var(--aim-light-text-primary);
    --ins-footer-text-color: #6c757d;
    --ins-footer-link-color: #6c757d;
    --ins-footer-link-hover-color: var(--aim-light-text-on-color);
    --ins-dashboard-bg: var(--aim-light-dashboard-bg);
    
    /* Legacy INS -> AIM Dark mappings */
    --ins-dark-primary-color: var(--aim-dark-primary);
    --ins-dark-primary-border: var(--aim-dark-accent2);
    --ins-dark-secondary-color: var(--aim-dark-secondary);
    --ins-dark-secondary-border: var(--aim-dark-accent2);
    --ins-dark-link-highlight: var(--aim-dark-alert);
    --ins-dark-input-background: var(--aim-dark-input-background);
    --ins-dark-link-background-color: var(--aim-dark-secondary);
    --ins-dark-button-text: var(--aim-dark-text-primary);
    --ins-dark-body-bg-color: var(--aim-dark-bg-page);
    --ins-dark-body-text-color: var(--aim-dark-text-primary);
    --ins-dark-body-link-color: var(--aim-dark-text-primary);
    --ins-dark-body-link-hover-color: #ff79c6;
    --ins-dark-site-info-bg-selected: var(--aim-dark-site-info-bg-selected);
    --ins-dark-mainnav-bg-color: var(--aim-dark-primary);
    --ins-dark-mainnav-text-color: var(--aim-dark-text-primary);
    --ins-dark-mainnav-link-color: var(--aim-dark-text-primary);
    --ins-dark-mainnav-link-hover-color: var(--color-primary);
    --ins-dark-mainnav-link-active-color: var(--aim-dark-accent2);
    --ins-dark-footer-bg-color: var(--aim-dark-bg-page);
    --ins-dark-footer-text-color: var(--aim-dark-text-primary);
    --ins-dark-footer-link-color: var(--aim-dark-alert);
    --ins-dark-footer-link-hover-color: var(--aim-dark-accent);
    --ins-dark-dashboard-bg: var(--aim-dark-dashboard-bg);
    
    /* Legacy Cornerstone mappings */
    --cornerstone-primary-color: var(--cornerstone-light-primary); 
    --cornerstone-primary-border: #001552;
    --cornerstone-secondary-color: var(--cornerstone-light-secondary);
    --cornerstone-secondary-border: #008467;
    --cornerstone-link-highlight: var(--cornerstone-light-accent);
    --cornerstone-input-background: var(--cornerstone-light-input-background);
    --cornerstone-link-background-color: initial;
    --cornerstone-button-text: var(--cornerstone-light-text-on-color);
    --cornerstone-body-bg-color: var(--cornerstone-light-bg-page);
    --cornerstone-body-text-color: var(--cornerstone-light-text-primary);
    --cornerstone-body-link-color: var(--color-primary);
    --cornerstone-body-link-hover-color: #0056b3;
    --cornerstone-site-info-bg-selected: var(--cornerstone-light-site-info-bg-selected);
    --cornerstone-mainnav-bg-color: var(--cornerstone-light-primary);
    --cornerstone-mainnav-text-color: var(--cornerstone-light-text-primary);
    --cornerstone-mainnav-link-color: var(--cornerstone-light-text-primary);
    --cornerstone-mainnav-link-hover-color: var(--color-primary);
    --cornerstone-mainnav-link-active-color: var(--color-primary);
    --cornerstone-footer-bg-color: var(--cornerstone-light-text-primary);
    --cornerstone-footer-text-color: #6c757d;
    --cornerstone-footer-link-color: #6c757d;
    --cornerstone-footer-link-hover-color: var(--cornerstone-light-text-on-color);
    --cornerstone-dashboard-bg: var(--cornerstone-light-dashboard-bg);
    
    /* 
     * ==========================================================================
     * 9. ACTIVE THEME VARIABLES (Default: AIM Light)
     * ==========================================================================
     */
    
    /* Active theme variables â€” primary/secondary/interactive now handled by derived system (section 1b) */
    --primary-border: var(--primary-color);
    --secondary-border: var(--secondary-hover);
    --main-link-color: var(--interactive-base);
    --main-link-highlight: var(--interactive-hover);
    --main-link-background-color: initial;
    --main-button-text: var(--aim-light-text-on-color);
    --main-input-background: var(--aim-light-input-background);
    --body-bg-color: var(--aim-light-bg-page);
    --body-text-color: var(--aim-light-text-primary);
    --body-link-color: var(--aim-light-interactive);
    --body-link-hover-color: var(--aim-light-interactive-hover);
    --site-info-bg-selected: var(--aim-light-site-info-bg-selected);
    --mainnav-bg-color: var(--aim-light-primary); /* Updated to use primary color for themed backgrounds */
    --mainnav-text-color: var(--aim-light-text-on-color); /* Updated for better contrast */
    --mainnav-link-color: var(--aim-light-text-on-color); /* Updated for consistency */
    --mainnav-link-hover-color: var(--aim-light-interactive-hover);
    --mainnav-link-active-color: var(--aim-light-interactive-hover);
    --footer-bg-color: var(--aim-light-bg-page);
    --footer-text-color: var(--aim-light-text-primary);
    --footer-link-color: var(--aim-light-interactive);
    --footer-link-hover-color: var(--aim-light-interactive-hover);
    --dashboard-bg: var(--aim-light-dashboard-bg);

    /* Panel Variables (dynamically mapped to current theme) */
    --panel-bg: var(--aim-light-panel-bg);
    --panel-header-bg: var(--aim-light-panel-header-bg);
    --panel-text: var(--aim-light-panel-text);
    --panel-text-secondary: var(--aim-light-panel-text-secondary);
    --panel-border: var(--aim-light-panel-border);
    --panel-hover: var(--aim-light-panel-hover);
    --card-header-bg: var(--aim-light-card-header-bg);

    /* Common semantic aliases â€” used by RCL module CSS */
    --color-text: var(--aim-light-text-primary);
    --color-text-muted: var(--aim-light-text-secondary);
    --color-text-secondary: var(--aim-light-text-secondary);
    --color-text-primary: var(--aim-light-text-primary);
    /* --color-secondary is referenced in 33+ CSS files (workflow-management.css,
       NotificationBell, WorkflowTimeline, asset-management.css etc.) but was
       previously undefined in the theme cascade â€” every var(--color-secondary)
       silently fell through to the literal #6c757d, which doesn't adapt and made
       subtitle/meta text near-invisible in dark mode. Aliased to the adaptive
       text-secondary token so it flips correctly. */
    --color-secondary: var(--color-text-secondary);
    /* Same defensive aliases for two more "previously undefined" tokens used
       extensively in workflow-management.css (21 callsites) and the aim-table
       system. Without these, --wf-table-header-bg fell through to literal
       #f8f9fa light grey forever (so dark-mode table headers showed light text
       on light grey = invisible) and aim-table cell borders fell through to
       #F1F5F9 (so cell separators were near-white in dark mode, dominating the
       row grid). Aliased to existing adaptive surface/border tokens. */
    --color-table-header-bg: var(--surface-base);
    --color-border-light: var(--border-subtle);
    /* Five more undefined tokens used by AdminUsersList, NotificationBell,
       NotificationsPage, MappingServices, SalesOrder editors, etc. Each was
       falling through to a literal pale-* hex that didn't adapt, paired with
       theme-adaptive text â†’ invisible in dark mode. Aliased to existing
       adaptive tokens so all callsites fix transparently. */
    --color-primary-bg: var(--color-info-lightest);
    --color-primary-bg-hover: var(--color-info-bg);
    --color-hover-bg: var(--surface-base);
    --color-secondary-bg: var(--surface-base);
    --color-secondary-hover: var(--color-text-secondary);
    /* AdminProjectsDashboard, AdminUsersList, LoginForm, RegisterForm,
       UpdateDigitalTwins, file-manager, asset-management, projects.css,
       UserCalendar, QuotingDashboard all use this numeric --surface-1/2/3
       scale that was NEVER defined in any theme block. Every callsite was
       falling through to literal #f8f9fa / #fff / #f0f0f4 â€” so the entire
       AdminProjects page rendered pure white in dark mode. Aliased to the
       canonical adaptive --surface-base/raised tokens.
       Same story for --color-state-success/warning/error which were undefined
       and fell through to literal Bootstrap status hex; aliased to the proper
       semantic --color-{success,warning,danger} family. */
    --surface-1: var(--surface-base);
    --surface-2: var(--surface-raised);
    --surface-3: var(--surface-base);
    --color-state-success: var(--color-success);
    --color-state-warning: var(--color-warning);
    --color-state-error: var(--color-danger);

    /* Top legacy aliases referenced via `var(--TOK, #hex)` across the codebase
       but never actually DEFINED — so the hex fallback was the real value
       (theme-non-adapting). Define them now so consumers' fallbacks can be
       dropped. Each maps to its canonical semantic equivalent.
       (May 7, 2026 — CSS01 decay pass) */
    --status-danger:           var(--color-danger-medium);
    --status-success:          var(--color-success-medium);
    --status-warning:          var(--color-warning-medium);
    --status-info:             var(--color-info-medium);

    /* ── Calendar event-type palette (May 8 2026) ──────────────────────
       Five distinct hues for UserCalendar event types. Was using undefined
       --color-{event-type} tokens with Tailwind hex fallbacks; they all
       converged on blue/slate so dot legends were illegible. Fixed five
       canonical event-type tokens — each a different hue, brand-swappable
       via the underlying status palette.
         dependency → info-blue (#1D4ED8)        — primary "your scheduled work"
         busy       → text-tertiary (#adb5bd)    — neutral grey, recessive
         ooo        → status-warning (amber)     — emphatic "I'm not here"
         meeting    → status-success (green)     — committed time
         travel     → violet (#7c3aed) literal   — purple in light AND dark
       Sister rule for dark mode redeclares travel only (other tokens chain
       through their own dark-mode aliases). */
    --cal-event-dependency: var(--status-info);
    --cal-event-busy:       var(--color-text-tertiary);
    --cal-event-ooo:        var(--status-warning);
    --cal-event-meeting:    var(--status-success);
    --cal-event-travel:     #7c3aed;

    --primary:                 var(--primary-color);
    --danger:                  var(--color-danger-medium);
    --success:                 var(--color-success-medium);
    --warning:                 var(--color-warning-medium);
    --info:                    var(--color-info-medium);
    --surface:                 var(--surface-raised);
    --border-default:          var(--border-subtle);
    --border:                  var(--border-subtle);
    --color-accent:            var(--interactive-base);
    --color-surface-hover:     var(--surface-row-hover);
    --primary-color-hover:     var(--primary-hover);
    --aim-text-muted:          var(--color-text-muted);
    --aim-color-text-secondary: var(--color-text-secondary);
    --color-danger-border:     color-mix(in srgb, var(--color-danger-medium) 30%, transparent);

    /* Disabled state — neutral slate, NOT brand-derived. Disabled is the
       absence of brand expression: a brand-tinted disabled button reads as
       "X but greyed out", a neutral disabled button reads as "just disabled".
       Same colour mistake the navbar made before we split brand from action.
       Light mode value sits on the cool-slate side of grey to stay in family
       with the surface ladder; dark mode equivalent slots between
       --surface-raised and --surface-elevated so disabled buttons recede. */
    --btn-disabled-bg:    #CBD5E1;             /* Tailwind slate-300 — cool neutral */
    --btn-disabled-color: var(--color-text-tertiary);

    /* Pass 2 — define ~70 more legacy undefined aliases so their hex fallbacks
       can be dropped. Grouped by family. */

    /* Status family — text + bg + dark variants of success/warning/danger/info */
    --color-success-text:           var(--color-success-dark);
    --color-success-border:         color-mix(in srgb, var(--color-success-medium) 30%, transparent);
    --color-danger-text:            var(--color-danger-dark);
    --color-danger-hover:           color-mix(in srgb, var(--color-danger-medium), black 10%);
    --color-danger-lighter:         color-mix(in srgb, var(--color-danger-medium) 22%, var(--surface-raised));
    --color-warning-hover:          color-mix(in srgb, var(--color-warning-medium), black 10%);
    --color-warning-400:            var(--color-warning-medium);
    --color-error-400:              var(--color-danger-medium);
    --color-success-800:            var(--color-success-dark);
    --color-warning-800:            var(--color-warning-dark);
    --color-error-800:              var(--color-danger-dark);
    --color-info-800:               var(--color-info-dark);
    --color-status-success-bg:      var(--color-success-bg);
    --color-status-success-text:    var(--color-success-dark);
    --color-status-warning-bg:      var(--color-warning-bg);
    --color-status-warning-text:    var(--color-warning-dark);
    --color-status-info-bg:         var(--color-info-bg);
    --color-status-info-text:       var(--color-info-dark);
    --color-status-draft-bg:        var(--surface-base);
    --color-status-draft-text:      var(--color-text-secondary);
    --status-success-bg:            var(--color-success-bg);
    --status-danger-bg:             var(--color-danger-bg);
    --status-danger-hover:          color-mix(in srgb, var(--color-danger-medium), black 10%);
    --status-warning-dark:          var(--color-warning-dark);
    --success-color:                var(--color-success-medium);
    --danger-color:                 var(--color-danger-medium);
    --success-dark:                 var(--color-success-dark);
    --warning-dark:                 var(--color-warning-dark);
    --color-critical:               var(--color-danger-medium);

    /* Surface aliases — all map to canonical surface ladder */
    --aim-surface:                  var(--surface-raised);
    --aim-color-surface:            var(--surface-raised);
    --aim-color-surface-alt:        var(--surface-base);
    --aim-card-bg:                  var(--surface-raised);
    --aim-surface-muted:            var(--surface-base);
    --color-bg-card:                var(--surface-raised);
    --color-bg-input:               var(--surface-raised);
    --color-background-primary:     var(--surface-raised);
    --color-background-secondary:   var(--surface-base);
    --color-bg-disabled:            var(--surface-base);
    --color-hover:                  var(--surface-row-hover);
    --surface-inverted:             var(--color-text-primary);

    /* Border aliases */
    --color-border-subtle:          var(--border-subtle);
    --border-color-light:           var(--border-subtle);
    --aim-border-light:             var(--border-subtle);
    --wf-border-light:              var(--border-subtle);
    --aim-color-border:             var(--border-subtle);
    --border-input:                 var(--border-subtle);
    --color-primary-border:         color-mix(in srgb, var(--primary-color) 30%, transparent);

    /* aim-color-* family — full mapping to canonical semantic tokens */
    --aim-color-primary:            var(--primary-color);
    --aim-color-primary-light:      var(--primary-light);
    --aim-color-primary-100:        var(--color-primary-100);
    --aim-color-primary-700:        var(--color-primary-700);
    --aim-color-info:               var(--color-info-medium);
    --aim-color-info-light:         var(--color-info-bg);
    --aim-color-warning-100:        var(--color-warning-bg);
    --aim-color-warning-500:        var(--color-warning-medium);
    --aim-color-warning-700:        var(--color-warning-dark);
    --aim-color-success-100:        var(--color-success-bg);
    --aim-color-success-700:        var(--color-success-dark);
    --aim-color-error-100:          var(--color-danger-bg);
    --aim-color-error-700:          var(--color-danger-dark);
    --aim-color-danger:             var(--color-danger-medium);
    --aim-color-danger-light:       var(--color-danger-bg);
    --aim-color-text:               var(--color-text-primary);
    --aim-color-neutral-400:        var(--color-text-tertiary);
    --aim-color-neutral-500:        var(--color-text-secondary);
    --aim-color-neutral-800:        var(--color-text-primary);

    /* aim-* shorthand */
    --aim-info-light:               var(--color-info-bg);
    --aim-warning-light:            var(--color-warning-bg);
    --aim-blue-dark:                color-mix(in srgb, var(--brand-primary), black 25%);
    --aim-primary-hover:            var(--primary-hover);
    --aim-on-primary:               var(--color-text-on-primary);
    --aim-muted:                    var(--color-text-muted);

    /* Interactive variants */
    --interactive-primary:          var(--interactive-base);
    --interactive-primary-hover:    var(--interactive-hover);
    --color-accent-hover:           var(--interactive-hover);
    --accent-dark:                  color-mix(in srgb, var(--interactive-base), black 15%);
    /* ─── DISABLED IS NOT "QUIET" ────────────────────────────────────────
       Until 2026-08-05 this aliased --color-text-tertiary, so the system had
       exactly ONE value for two incompatible meanings: "supporting text you
       can still read" and "you cannot interact with this". Components had no
       way to say the first without also saying the second, so every
       not-yet-started control (Access & Capture's "To book" pill, its 0/4
       pips, unselected filter chips) rendered in the same grey as a genuinely
       dead button. Focus-group evidence, 2026-07-31: two of two users failed
       to find the booking control, rating it 1/5 — "could not find".

       Split. --color-text-tertiary keeps its job (muted but live). Disabled
       gets its own, distinctly flatter value.

       NOTE the standing rule this exists to support: DISABLED IS CARRIED BY
       `opacity: .5` + `cursor: not-allowed`, not by a colour. This token is
       only for the rare case where inert text must keep a fixed value (e.g.
       inside an already-tinted surface where opacity would compound). If you
       are reaching for it on a control, reach for opacity instead. */
    --color-text-disabled:          color-mix(in srgb, var(--color-text-tertiary) 62%, var(--surface-raised));
    --color-primary-lightest:       var(--primary-lightest);
    --primary-color-dark:           color-mix(in srgb, var(--primary-color), black 25%);
    --color-neutral-lighter:        color-mix(in srgb, var(--color-text-tertiary) 30%, var(--surface-raised));

    /* aim-table local tokens promoted to :root.
       Per AIM design language Â§10 (Tables) the canonical "Option A" rule is:
         Headers: var(--surface-base) background, sentence-case labels,
                  letter-spacing 0.03em, color: var(--color-text-secondary).
       Stripe + hover now use SAME-TIER subtle tints (--surface-row-stripe /
       --surface-row-hover) instead of a different surface tier. The previous
       "stripe = surface-base" rule jumped a whole tier of luminance and made
       every other row in dark mode look "dim" because of the contrast gap.
       The new tokens are derived from --surface-raised + a 4-10% brand-primary
       mix, so the zebra reads as a faint hue shift on the same surface. */
    /* Header redesigned May 7, 2026 — Option C "light bar with slate-to-blue
       accent strip". The full-navy band was overpowering on data-dense pages
       and competed with the navbar visually. New pattern:
         bg:    light grey-blue (#ECEFF3) — same family as page bg, raised slightly
         text:  #475569 slate (theme-aware via --color-text-secondary in light)
         strip: 2px gradient bottom border slate(#3F5269) → blue(#2063D7), the
                literal brand-anchor → primary-action transition, so the eye
                reads navbar → strip → button as one coherent system.
       The strip is brand-aware via --brand-primary (slate end) + --interactive-base
       (blue end) so brand swaps re-tint correctly.
       Dark mode keeps its dark band (override at line ~1287) since light bg on
       dark page wouldn't read as chrome. */
    /* Table-internal surface ladder — one slate hue family, four lightness
       steps. Reads as ONE designed object: header (strongest tint) → hover
       (mid) → stripe (faint) → wrapper (white). All from the same hue family
       so the table doesn't feel like header-with-stripes-attached, it feels
       like a structural layer with rows.

       Slate @ 12% / 9% / 4% / 0% = clear value separation, no ambiguity
       about which surface is chrome and which is data. Brand swap re-tints
       the entire ladder via --brand-identity. */
    /* Wrapper is var(--surface-raised) = white in light mode — base of the ladder */

    /* --aim-table-* chrome (header/stripe/hover/cell-border/sticky/nested/divider) is NOT
       defined here any more. It lives ONCE in wwwroot/css/tokens/aim-compat.css, which loads
       after this file in _Layout.cshtml and matched at equal specificity in every theme — so
       the copies that used to sit here were already overridden and had no effect. Removed
       2026-08-18. The severity/accent tokens below are NOT duplicated and remain live here. */
    --aim-table-header-groove: inset 0 1px 0 color-mix(in srgb, var(--brand-identity) 12%, transparent);
    --aim-table-header-strip:  linear-gradient(90deg, var(--brand-identity) 0%, var(--action-cta) 100%);

    /* Selected row stays as a deliberate semantic ACCENT, not part of the
       slate ladder. Stripe is structural chrome (helps eye scan rows);
       selected is content state (marks an active record). Different jobs,
       should look different. Amber tint pops because it's the only non-slate
       surface in the table. */
    --aim-table-row-selected-bg: var(--color-warning-bg);


    /* Card header — DIVERGED from table header (May 8 2026 v2). Cards now
       sit ONE TONE DARKER than tables so the two component families read
       as a clear visual ladder when stacked together (page → card-header
       → table-header → table-cells). Same groove, same padding, same
       letter-spacing — only the bg tint differs.
         Light mode: slate@18% on white  (was slate@12%, same as table)
       Sister rule for dark mode lives in [data-theme="aim-dark"] block. */
    --aim-card-header-bg:     color-mix(in srgb, var(--brand-identity) 18%, white);

    /* â”€â”€â”€ CANONICAL TABLE TOKEN SET â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
       Every table (shared aim-table OR bespoke prefixes like cat-/ap-/rdp-/
       ram-/wf-dep-/val-/rmsv-/cio-/ops-) MUST consume these tokens. Bespoke
       class prefixes are allowed when they earn their keep with unique
       behaviour (nested tree, matrix grid, sticky column), but the chrome
       â€” header, stripe, hover, severity, selected, nested, sticky â€” comes
       from this single source. One token change cascades to every table.
       Theme + brand swap propagate identically across all consumers.

       Semantic naming, not positional, so reading the rule tells you what
       it means: "row-warning-bg" not "tier-2-yellow". */

    /* Header hover / active-sort accent â€” a clean shift to --interactive-base
       (the canonical "interactive blue" across AIM), NOT a lighten of the band.
       Mixing brand-primary with white desaturates toward muddy grey; using a
       saturated accent colour gives the right "click-me" feedback in both
       themes. Brand-swap on the band still works; the accent is intentionally
       AIM's interactive-blue (consistent affordance across the app). */
    --aim-table-header-accent-bg:    var(--interactive-base);
    --aim-table-header-accent-color: var(--color-text-on-primary);

    /* Sort indicator (chevron + column highlight). Decoupled from the header
       text colour so the active-sort header CELL keeps the band's light text
       — the chevron alone carries the "this is the sort column" cue. Light
       mode: the canonical interactive blue. Dark mode: redeclared in the
       [data-theme="aim-dark"] block to a high-contrast accent. */
    --aim-table-sort-indicator-color: var(--interactive-base);

    /* Selected row â€” amber tint (aim-tr--selected, sl-tr--selected, etc.) */
    --aim-table-row-selected-bg: color-mix(in srgb, var(--color-warning-medium) 15%, var(--surface-raised));

    /* Severity row tints â€” base + hover, all theme-adaptive via surface-raised */
    --aim-table-row-success-bg:        color-mix(in srgb, var(--color-success-medium) 10%, var(--surface-raised));
    --aim-table-row-success-hover-bg:  color-mix(in srgb, var(--color-success-medium) 18%, var(--surface-raised));
    --aim-table-row-warning-bg:        color-mix(in srgb, var(--color-warning-medium) 10%, var(--surface-raised));
    --aim-table-row-warning-hover-bg:  color-mix(in srgb, var(--color-warning-medium) 18%, var(--surface-raised));
    --aim-table-row-danger-bg:         color-mix(in srgb, var(--color-danger-medium) 10%, var(--surface-raised));
    --aim-table-row-danger-hover-bg:   color-mix(in srgb, var(--color-danger-medium) 18%, var(--surface-raised));
    --aim-table-row-info-bg:           color-mix(in srgb, var(--color-info-medium) 10%, var(--surface-raised));
    --aim-table-row-info-hover-bg:     color-mix(in srgb, var(--color-info-medium) 18%, var(--surface-raised));

    /* Matrix variants (RoleDefaults roleÃ—capability, ReportAccessMatrix etc.) */
    --aim-table-section-divider-color: var(--color-text-secondary);

    /* Nested-row variants (CompaniesTab cat-table parent/child tree) */
    --aim-table-row-expanded-bg:       color-mix(in srgb, var(--brand-primary) 6%, var(--surface-raised));
    --aim-table-row-nested-add-bg:     color-mix(in srgb, var(--brand-primary) 5%, var(--surface-anchor));
    --color-text-on-primary: var(--aim-light-text-on-color);
    --color-border: var(--aim-light-card-border);
    --color-surface: var(--surface-raised);
    --color-surface-alt: var(--surface-base);
    --color-surface-raised: var(--surface-raised);
    --color-bg: var(--surface-raised);
    --color-bg-secondary: var(--surface-base);
    --color-bg-muted: var(--surface-base);
    --color-background: var(--surface-raised);
    --color-success-bg: var(--color-success-lightest);
    --color-warning-bg: var(--color-warning-lightest);
    --color-danger-bg: var(--color-danger-lightest);
    --color-info-bg: var(--color-info-lightest);
    --color-bg-overlay: var(--color-overlay-darker);
    --color-primary-dark: var(--primary-hover);
    /* Corrected 2026-08-05 (drift audit). --radius-md was 6px and --radius-lg
       8px, but the design language documents them as 8px (cards) and 12px
       (modals). 369 call sites write `var(--radius-md, 8px)` — the fallback
       never fires, so everyone reading the code saw 8px and everyone using the
       app saw 6px. Card corners across the whole product were one tier off the
       spec. The scale now matches the documentation it is measured against;
       this is the fix, not a redesign. */
    --border-radius: 8px;
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-xl: 16px;
    --radius-full: 9999px;

    /* Alias tokens â€” referenced in codebase, mapped to canonical values */
    --color-radius-md: var(--radius-md);
    --fm-border-radius: var(--radius-md);
    --card-border-radius: var(--radius-lg);
    --form-element-border-radius: var(--radius-md);

    --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.10);
    --shadow-md: 0 4px 6px rgba(15, 23, 42, 0.10);
    --shadow-lg: 0 10px 15px rgba(15, 23, 42, 0.10), 0 4px 6px rgba(15, 23, 42, 0.05);
    --shadow-xl: 0 20px 25px rgba(15, 23, 42, 0.10), 0 10px 10px rgba(15, 23, 42, 0.04);
    --shadow-primary: 0 4px 14px rgba(15, 36, 68, 0.2);
    --z-dropdown: 1000;
    --z-modal: 1050;
    --font-size-xs: 0.75rem;
    --font-size-sm: 0.875rem;

    /* Numeric-scale aliases (Bootstrap convention â†’ AIM tokens) */
    --color-error-100: var(--color-danger-lightest);
    --color-error-500: var(--color-danger-medium);
    --color-error-700: var(--color-danger-dark);
    --color-success-100: var(--color-success-lightest);
    --color-success-700: var(--color-success-dark);
    --color-warning-100: var(--color-warning-lightest);
    --color-warning-700: var(--color-warning-dark);
    --color-info-100: var(--color-info-lightest);
    --color-info-700: var(--color-info-dark);
    --color-gray-50: var(--color-neutral-lightest);
    --color-gray-200: var(--aim-light-card-border);
    --color-gray-600: var(--aim-light-text-secondary);
    --color-gray-700: var(--color-neutral-dark);

    /* Additional CSS variable mappings for existing stylesheets */
    --color-accent-blue: var(--aim-light-interactive);
    --color-accent-blue-glow: rgba(67, 120, 181, 0.3);
    --color-border-light: var(--aim-light-border-subtle);
    --color-bg-card-default: var(--aim-light-card-header-bg);
    --color-text-header: var(--aim-light-text-primary);
    --color-bg-header: var(--aim-light-bg-header);
    --color-bg-lightest: var(--aim-light-bg-page);
    --color-text-medium: var(--aim-light-text-secondary);
    --color-neutral-light: var(--aim-light-border-subtle);
    --color-neutral-medium: var(--aim-light-text-secondary);
    --color-bg-subtle: var(--aim-light-bg-card);
    --color-overlay-darkest: rgba(0, 0, 0, 0.8);
    --color-overlay-darker: rgba(0, 0, 0, 0.7);
    --color-white-transparent-30: rgba(255, 255, 255, 0.3);
    --color-white-transparent-40: rgba(255, 255, 255, 0.4);
    --color-white-transparent-20: rgba(255, 255, 255, 0.2);
    --color-white-transparent-10: rgba(255, 255, 255, 0.1);
    --color-danger-light: #ff6b6b;
    --color-close-button: #dc3545;
    --color-panel-primary: var(--aim-light-panel-bg);
    --color-panel-primary-dark: var(--aim-light-panel-hover);
    
    /* 
     * ==========================================================================
     * 10. LEGACY SUPPORT COLORS
     * ==========================================================================
     */
    
    /* Legacy color references â€” aligned to derived system */
    --color-primary: var(--primary-color);
    --color-success: #10B981;
    --color-info: #0EA5E9;
    --color-warning: #F59E0B;
    --color-danger: #EF4444;
    --color-light: #f8f9fa;
    --color-dark: #212529;
    
    /* Milestone backward compatibility aliases */
    --milestone-bg: var(--milestone-bg-default);
    --milestone-success: var(--milestone-success-bg);
    --milestone-warning: var(--milestone-warning-bg);
    --milestone-danger: var(--milestone-danger-bg);

    /* 
     * ==========================================================================
     * 12. LOGIN PAGE COLOR VARIABLES
     * ==========================================================================
     */
    
    /* Login Page Color Variables - Colors only, styling in login-page.css */
    --login-primary: var(--primary-color);
    --login-secondary: var(--secondary-color);
    --login-accent: #E8A450;
    --login-bg: #F8FAFC;
    --login-card-bg: #ffffff;
    --login-text: #1A1F2E;
    --login-text-light: #64748B;
    --login-border: #E2E8F0;
    --login-register-bg: #008E70;
    --login-register-hover: #007A63;
}

/*
 * ==========================================================================
 * 13. THEME SWITCHING â€” Component token overrides per data-theme
 *     Change --brand-primary here to re-theme each variant.
 *     All card/nav/body/panel tokens rewire automatically.
 * ==========================================================================
 */

/* AIM Light is the default (ThemeManager strips data-theme for aim-light).
   All :root values above already default to aim-light. No override needed. */

/* ── NATIVE CONTROL POPUPS (2026-07-27) ────────────────────────────────────
   `color-scheme: dark` is declared inside [data-theme="aim-dark"], and
   ThemeManager.ts sets data-theme on document.BODY. But the browser paints
   native popups — the <select> dropdown list, date pickers, the canvas
   background, scrollbars — from the ROOT element's used color-scheme, which
   never received it. So every native <select> popup rendered as a LIGHT
   listbox on a dark page, and its <option> text inherited the page's (light)
   foreground colour: light-on-white, unreadable.

   This was latent: before the brand-foreground split the option colour was a
   DARK navy, which happened to read on the white popup. Making foregrounds
   correct for dark surfaces surfaced it.

   Mirroring onto <html> is the fix — :has() is already within this project's
   support baseline (css-compat.md sanctions color-mix, Chrome 111+; :has() is
   Chrome 105+ / Safari 15.4+ / Firefox 121+). The html[data-theme] variants are
   belt-and-braces in case the attribute is ever moved to the root element. */
html:has(body[data-theme="aim-dark"]),
html:has(body[data-theme="cornerstone-dark"]),
html[data-theme="aim-dark"],
html[data-theme="cornerstone-dark"] {
    color-scheme: dark;
}

html:has(body[data-theme="cornerstone-light"]),
html[data-theme="cornerstone-light"] {
    color-scheme: light;
}

[data-theme="aim-dark"] {
    /* Dark-mode brand split — same identity/action separation as light mode.
       --brand-identity is Dracula Comment (the dark-theme equivalent of slate).
       --action-primary is OKLCH-derived to a brighter mid-blue (L=65 vs L=48
       in light mode) so it stays visible on dark surfaces. */
    /* PROPER DRACULA DARK MODE (May 7 2026 commitment).
       Pre-rewrite, dark mode used a hue-locked slate palette which gave a
       lavender cast everywhere. Now uses Dracula's canonical roles:
         Current Line #44475a → --brand-identity (chrome — recessive)
         Purple       #bd93f9 → --action-primary (vibrant accent)
         Background   #282a36 → --surface-base   (deepest canvas)
         Comment      #6272a4 → --surface-elevated + --color-text-secondary
                                  (used as Dracula intends)
       Cross-mode delta: light-mode user clicks BLUE buttons, dark-mode
       user clicks PURPLE. Coherent if committed (Vercel / Linear / Anthropic
       Console all do this — light is one personality, dark is another). */
    --brand-identity: #44475a;           /* Dracula Current Line — recessive chrome */
    /* Two-role button hierarchy (mirrors light mode):
         --action-primary = Current Line — everyday utility button, recessive
         --action-cta     = Dracula Purple — rare submit-grade button
       Purple here gives Dracula its identifying CTA pop. Light mode uses
       OKLCH-derived blue from slate; dark mode uses Dracula's canonical
       Purple. Both are "the rare colour" in their respective theme. */
    --action-primary: var(--brand-identity);   /* Current Line — everyday */
    --action-cta:     #bd93f9;                 /* Dracula Purple — rare CTA */
    --brand-primary:  var(--brand-identity);   /* backwards-compat alias */

    /* Brand-as-foreground — see the --brand-on-surface block in :root.
       #44475a (Current Line) IS --surface-raised, so it can never be a
       foreground here. Dracula Comment (#6272a4) lightened ~45% toward
       Foreground (#f8f8f2) keeps the slate-blue identity while clearing AA:
         #B5BCCF on #44475a (card)  → 4.7:1
         #B5BCCF on #282a36 (page)  → 7.4:1
       Deliberately NOT Dracula Purple — this file reserves #bd93f9 for
       --action-cta ("max one per screen"); 476 purple accents would spend
       that rarity.

       Measured against the aim-dark ladder (page #282a36 / card #44475a):
         --brand-on-surface        #A8B8F0   7.31:1 page · 4.70:1 card  AA
         --brand-border-on-surface #8A92B6   4.66:1 page · 2.99:1 card  1.4.11
         --brand-fill-on-surface   #55618A   white label 5.69:1 ON it   AA

       Accent is deliberately BLUER than --color-text-secondary (#BBBBBB, a
       neutral grey at 4.77:1). They sit at near-identical luminance, so hue is
       what separates "brand accent" from "secondary text" — not brightness.

       The fill is only 1.51:1 against the card on its own; that is expected and
       fine. WCAG 1.4.11 wants the COMPONENT distinguishable, and the border
       token carries that at ~3:1. Chasing 3:1 on the fill as well is provably
       impossible here: it would force the fill lighter than L*0.29, which drops
       the white label below 3:1. Border delineates, fill carries the label. */
    --brand-on-surface:        #A8B8F0;
    --brand-border-on-surface: #8A92B6;
    --brand-fill-on-surface:   #55618A;

    /* Tell the browser this surface is dark â€” native controls (select dropdowns,
       date pickers, scrollbars, autofill backgrounds) use OS dark styling instead
       of system light defaults. Without this, `<select>` with `appearance: auto`
       paints itself white-on-dark even when CSS sets `background: var(--surface-raised)`.
       Single line, fixes every native control on every page. */
    color-scheme: dark;

    /* â•â•â• DARK-MODE SURFACE LADDER â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
       Same FORMULA as light mode, different anchor neutral.
         --surface-base:    color-mix(--brand-primary 10%, --neutral-dark)
         --surface-raised:  color-mix(--brand-primary 22%, --neutral-dark)
         --surface-elevated: color-mix(--brand-primary 38%, --neutral-dark)
       Literal values below are pre-computed AND hand-tuned to land on the
       Dracula identity for tier 2 (#282a36 = Dracula Background, iconic).
       Î”E2000 between tiers measured at ~7 (T1â†’T2) and ~8 (T2â†’T3) â€” even
       monotonic ladder, no banding.

       Previous version had T2â†’T3 at Î”E 11 (#44475a was too high a jump,
       made the modal feel like a "different category" not a lifted surface).
       Tier 3 is now closer to tier 2 for an even step.

       SATURATION RULE: each higher tier has MORE brand-primary mixed in.
       This is the inverse of light mode and is correct for dark UIs â€” shadows
       can't carry elevation in dark mode, so a lighter tint takes over the cue. */
    --neutral-dark: #15171f;

    /* Dark-mode saturation rule: each higher tier has MORE brand-primary mixed in.
       Inverse of light mode â€” shadows can't carry elevation in dark UIs, so a
       lighter tint takes over the cue. Brand-swap re-tints ALL three tiers. */
    /* DRACULA SURFACE LADDER — three real surface colours, canonical Dracula stops.
       Tier 1 (page):   Background  #282a36 — deep recessive navy
       Tier 2 (cards):  Current Line #44475a — same as brand-identity, chrome lifts cleanly
       Tier 3 (modals): Comment     #6272a4 — only ever used at this tier
       Switched from formula-based mix to literal Dracula stops since Dracula
       IS the design system in dark mode, not a derivative of brand-primary. */
    --surface-base:     #282a36;        /* Dracula Background — TIER 1 page canvas */
    --text-on-surface-base: #f8f8f2;    /* Dracula Foreground */

    --surface-raised:   #44475a;        /* Dracula Current Line — TIER 2 cards */
    --text-on-surface-raised: #f8f8f2;

    --surface-elevated: #6272a4;        /* Dracula Comment — TIER 3 modals only */
    --text-on-surface-elevated: #f8f8f2;
    --shadow-elevated: 0 16px 40px rgba(0, 0, 0, 0.55);

    /* Solid status pills — same -700 hex across both modes (May 7 2026).
       Counterintuitive but real: dark backgrounds amplify saturation perception,
       so the same 500-level Dracula greens / reds that read as "vibrant" on
       white render as "glowing LED indicator" against Dracula bg. White-text
       contrast still passes at -700 levels, and cross-mode consistency means
       ONE solid-pill colour to maintain rather than two parallel chains. The
       full Dracula palette still drives ACCENTS (action button purple, focus
       rings, links) — just not pill backgrounds. */
    --color-success-medium: #15803D;    /* same as light mode (green-700) */
    --color-warning-medium: #C2410C;    /* same as light mode (orange-700) */
    --color-danger-medium:  #B91C1C;    /* same as light mode (red-700) */
    --color-info-medium:    #1D4ED8;    /* same as light mode (blue-700) */
    --color-success:        #15803D;
    --color-warning:        #C2410C;
    --color-danger:         #B91C1C;
    --color-info:           #1D4ED8;

    /* Calendar event-type — full redeclaration. The four token-chained
       variants must repeat here so the var() chain resolves against the
       dark-mode values (browsers snapshot var() at :root scope using
       light-mode values otherwise — see feedback_var_alias_dark_mode_redeclaration.md
       and CSS04 architecture rule). Travel gets a literal Dracula Purple. */
    --cal-event-dependency: var(--status-info);
    --cal-event-busy:       var(--color-text-tertiary);
    --cal-event-ooo:        var(--status-warning);
    --cal-event-meeting:    var(--status-success);
    --cal-event-travel:     #bd93f9;

    /* Text — Dracula Foreground / Comment / Comment-faded */
    --color-text-primary:   #f8f8f2;    /* 13.36:1 page · 8.59:1 card */

    /* NOTE (2026-07-27): --color-text-secondary is NOT set here. It used to be
       `#6272a4` on this line, but it is redeclared ~175 lines further down in
       this SAME block as `var(--aim-dark-text-secondary)` (= #BBBBBB), and the
       later declaration wins. The dead line survived long enough to mislead a
       contrast audit into "secondary is 1.94:1" when the live value is
       #BBBBBB at 4.77:1 card / 7.42:1 page — already AA. Removed rather than
       left in place: a dead declaration that contradicts the live value is
       exactly the trap CSS04 exists to catch. Change the value at
       --aim-dark-text-secondary, not here.

       --color-text-tertiary IS live here (nothing overrides it) and was the
       real failure: #4d557a measured 1.26:1 on cards and 1.96:1 on the page —
       effectively invisible, and --color-text-disabled aliases it. This is what
       made Access & Capture "dissolve into the background". Retuned to the 3:1
       band, which is the correct target for muted/tertiary text: */
    --color-text-tertiary:  #8E97BA;    /* 4.94:1 page · 3.18:1 card */

    /* Disabled state — neutral slate between Background and Current Line.
       Reads as "recessed/inert" without brand expression. */
    --btn-disabled-bg:    #3F4654;       /* slate between #282a36 and #44475a */
    --btn-disabled-color: #6272a4;       /* Comment — sits on the disabled bg quietly */

    /* Header band — Dracula version, refreshed May 8 2026. Was a gradient
       ending at #44475a (the card surface), so the bottom half of the header
       blended into the card body. Light mode sits the header at slate@12% on
       white — visibly darker/tinted vs the white card. The dark equivalent is
       a flat colour visibly DARKER than the card: 50/50 mix of page anchor
       (#282a36) and card surface (#44475a) ≈ #363a48. Same "header is darker
       than card body" vocabulary in both themes. Groove preserved. */
    /* 2026-07-27 — the --aim-table-header-bg / --aim-table-header-strip that
       used to sit here were DEAD: both keys are redeclared later in this same
       block (search "this block WINS"), so these never applied. Removed rather
       than left in place — three separate dead-duplicate declarations in this
       file misled a contrast audit in one sitting. The design rationale they
       carried is preserved on the live declarations. --aim-table-header-groove
       below is NOT duplicated and is still live. */
    --aim-table-header-groove: inset 0 1px 0 color-mix(in srgb, #f8f8f2 10%, transparent);

    /* Card header — diverged one tone DARKER than table header (May 8 2026 v2).
       Table header = 50/50 page + card ≈ #363a48
       Card header  = 70/30 page + card ≈ #2e313e
       So when both render together (table inside a card, card next to a
       table), the card header sits one slate-step darker. Mirrors the
       light-mode divergence (slate@18% card vs slate@12% table). */
    --aim-card-header-bg:     color-mix(in srgb, var(--surface-base) 70%, var(--surface-raised));

    /* Elevated chrome — modals + popovers re-tint slate→Dracula in dark mode. */
    --elevated-border:   1px solid color-mix(in srgb, var(--brand-identity) 25%, transparent);
    --elevated-shadow:   0 4px 16px rgba(0, 0, 0, 0.40);
    --elevated-backdrop: rgba(0, 0, 0, 0.60);

    /* Semantic aliases â€” same as :root, override here so dark mode picks up
       the dark-tier values via the alias chain. */
    --surface-anchor:  var(--surface-base);
    --surface-content: var(--surface-raised);
    --surface-overlay: var(--surface-elevated);
    --text-on-anchor:  var(--text-on-surface-base);
    --text-on-content: var(--text-on-surface-raised);
    --text-on-overlay: var(--text-on-surface-elevated);

    /* Stripe â€” barely-perceptible lift in dark mode (modern-dark-UI convention:
       Discord / GitHub / Slack all use a tiny lift, not a strong contrast).
       Iteration history:
         v1 (8% brand-mix): brand-primary in dark mode is Dracula Comment
           #6272a4 â€” lighter than anchor â€” produced bright lavender bands.
         v2 (12% neutral-dark mix): subtle darken, but the difference still
           registered as conspicuous alternation against the dracula card bg.
         v3 (this): 3% white mix INTO surface-content â€” Î”E ~2, just enough to
           anchor the eye on long tables, not enough to register as "stripes".

       Hover IS NOT redefined here â€” it inherits from :root which points at
       --surface-anchor, so dark-mode hover correctly resolves to the deeper
       --surface-base. This satisfies design language Â§9: "hover = surface-base
       tint, NOT a bright highlight". */
    --surface-row-stripe: color-mix(in srgb, var(--surface-content), white 3%);

    /* DIRECT TOKEN OVERRIDES â€” short-circuit the cascade.
       The :root chain (`--aim-table-stripe-bg â†’ --surface-row-stripe â†’ color-mix(--surface-content...)`)
       was producing the LIGHT-MODE stripe colour in dark mode on the legacy
       Estates Manager table â€” odd rows rendered as `~#E8EEF6` (Color #F8F8F2
       text on it = contrast 1.05). Diagnosis: nested `var()` resolution through
       three layers + `color-mix()` interacted unpredictably with the body-level
       data-theme override on this Razor Pages host. Setting consumer tokens
       directly to a literal dark mix removes the indirection â€” consumers read
       ONE level deep and get a dark colour.

       Both naming conventions covered:
         `--aim-table-*` â€” used by aim-tables.css system + most RCL components
         `--surface-row-*` â€” used by legacy CSS (estates-manager.css and similar)
       Pinning BOTH ensures the fix reaches consumers regardless of which token
       they reference. */
    --surface-row-stripe:      color-mix(in srgb, var(--surface-raised), white 3%);
    --surface-row-hover:       color-mix(in srgb, var(--surface-raised), black 12%);

    /* Selected row â€” dial back amber tint in dark mode. Light-mode 15% works
       on white; same percentage on dracula-bg renders too brightly. 10% gives
       a recognisable "this row is selected" cue without blowing out the row. */
    --aim-table-row-selected-bg: color-mix(in srgb, var(--color-warning-medium) 10%, var(--surface-raised));

    /* LEGACY SURFACE ALIASES â€” re-declare for dark mode.
       :root has `--surface-1: var(--surface-base);` etc. The var() chain
       evaluates against the cascade visible to the descendant element, BUT
       in practice browsers resolve these aliases against :root's snapshot of
       --surface-base/raised (i.e. the LIGHT-mode value), so descendants in
       dark mode inherit the light value. AdminProjectsDashboard `.ap-root`
       and `.ap-filters` rendered ~`#E2E5E8` / `#FFFFFF` in dark mode for this
       reason. Redeclaring here pins them to the dark `--surface-base`/`--surface-raised`
       directly so every consumer of `--surface-1`/`--surface-2`/`--surface-3`
       picks up the dark surface. Same pattern as the table-token overrides
       above. */
    --surface-1: var(--surface-base);
    --surface-2: var(--surface-raised);
    --surface-3: var(--surface-base);

    /* Same alias-leak fix for the rest of the legacy compat aliases that
       existed only at :root (lines 662-689 in light mode). Without these
       redeclarations, components like AdminUsersList, NotificationBell,
       NotificationsPage, MappingServices editors, SalesOrder editors,
       QuotingDashboard, file-manager all receive light-mode resolutions
       under [data-theme="aim-dark"]. */
    --color-table-header-bg:  var(--surface-base);
    --color-border-light:     var(--border-subtle);
    --color-primary-bg:       var(--color-info-lightest);
    --color-primary-bg-hover: var(--color-info-bg);
    --color-hover-bg:         var(--surface-base);
    --color-secondary-bg:     var(--surface-base);
    --color-secondary-hover:  var(--color-text-secondary);
    --color-state-success:    var(--color-success);
    --color-state-warning:    var(--color-warning);
    --color-state-error:      var(--color-danger);

    /* Brand/primary alias chain â€” same snapshot leak.
       :root has `--primary-color: var(--brand-primary)` (line 37) and
       `--primary-hover: color-mix(--primary-color, black 15%)` (line 38), and
       further down `--color-primary: var(--primary-color)` (line 842). Each
       link in the chain is theme-aware via --brand-primary, but only
       --brand-primary itself is redeclared above (line 887). The aliased
       `--primary-color` / `--primary-hover` / `--color-primary` snapshot the
       LIGHT-mode `--brand-primary` (#3F5269 dark navy). Result: anchor links
       (.wpd-table a, .wpl-* links) rendered dark-navy on dark-surface in
       dark mode = unreadable. Fix is identical to the surface chain â€” pin
       each alias at body scope so it picks up the dark `--brand-primary`. */
    --primary-color:  var(--brand-primary);
    --primary-hover:  color-mix(in srgb, var(--brand-primary), white 15%);
    --color-primary:  var(--primary-color);
    --color-secondary: var(--color-text-secondary);

    /* Status bg/text overrides for dark mode â€” banners + tinted cards.
       Light mode: --color-*-bg = pale pastel (--color-*-lightest), text = deep
       status colour (--color-*-dark). That pattern paired LIGHT bg + DARK text
       reads identically in both themes only because the bg never adapts.
       In dark mode that means banners stay bright pale-pastel against the dark
       page â€” visually loud, "uneeded brightness".
       Fix: dark-mode `--color-*-bg` becomes a dark-tinted variant (12% medium
       mixed into --surface-raised), and `--color-*-dark` flips to the LIGHT
       variant so text on the new dark-tinted bg still reads. Banners + tinted
       cards now adapt: pale-on-light in light mode, dim-tinted-on-dark in
       dark mode. */
    --color-success-bg: color-mix(in srgb, var(--color-success-medium) 12%, var(--surface-raised));
    --color-warning-bg: color-mix(in srgb, var(--color-warning-medium) 12%, var(--surface-raised));
    --color-danger-bg:  color-mix(in srgb, var(--color-danger-medium)  12%, var(--surface-raised));
    --color-info-bg:    color-mix(in srgb, var(--color-info-medium)    12%, var(--surface-raised));

    /* --color-*-lightest must also flip â€” status pills (.status-badge.status-active
       etc.) use lightest+dark together, so without this override the pill bg stays
       pale-pastel while text flips to light = light-on-light unreadable. */
    --color-success-lightest: color-mix(in srgb, var(--color-success-medium) 22%, var(--surface-raised));
    --color-warning-lightest: color-mix(in srgb, var(--color-warning-medium) 22%, var(--surface-raised));
    --color-danger-lightest:  color-mix(in srgb, var(--color-danger-medium)  22%, var(--surface-raised));
    --color-info-lightest:    color-mix(in srgb, var(--color-info-medium)    22%, var(--surface-raised));

    --color-success-dark: var(--color-success-light);
    --color-warning-dark: var(--color-warning-light);
    --color-danger-dark:  var(--color-danger-light);
    --color-info-dark:    var(--color-info-light);
    --surface-primary: var(--aim-dark-bg-card);         /* #363950 â€” replaces #fff */
    --surface-secondary: var(--surface-anchor);         /* unified with light mode (which also points to anchor) so components using --surface-secondary get consistent depth across themes */
    --surface-hover: rgba(255,255,255,0.08);            /* replaces #e9ecef â€” legacy alias, see --surface-row-hover */
    --surface-muted: rgba(0,0,0,0.15);                  /* replaces #fafafa */
    --border-subtle: var(--aim-dark-border-subtle);     /* replaces #e9ecef */
    /* 2026-07-27 — --border-strong was :root-only (`var(--primary-alpha-40)`),
       and --primary-alpha-40 is itself a :root alias off --primary-color, so it
       snapshot-leaked the LIGHT navy at 40% alpha onto dark surfaces = another
       invisible boundary. Pin it to the measured control-outline token so
       "strong border" actually means a boundary you can see: 4.66:1 over the
       page, 2.99:1 over a card. This is the token bordered CONTROLS should use
       (buttons, pagination, inputs); --border-subtle stays a divider. */
    --border-strong: var(--brand-border-on-surface);
    --text-disabled: rgba(248,248,242,0.35);            /* replaces #adb5bd */

    --card-bg: var(--aim-dark-card-bg);
    --card-border: var(--aim-dark-card-border);
    --card-shadow: var(--aim-dark-card-shadow);
    --card-header-bg: var(--aim-dark-card-header-bg);
    --card-accent-primary: var(--primary-color);

    --color-text-header: var(--aim-dark-text-primary);
    --color-text: var(--aim-dark-text-primary);
    --color-text-muted: var(--aim-dark-text-secondary);
    --color-text-secondary: var(--aim-dark-text-secondary);
    --color-text-primary: var(--aim-dark-text-primary);
    --color-border: var(--aim-dark-card-border);

    /* Override aim-consolidated.css :root aliases â€” var() chains don't cross :root â†’ body boundary */
    --text-primary: var(--aim-dark-text-primary);
    --text-secondary: var(--aim-dark-text-secondary);
    --color-surface: var(--surface-raised);
    --color-surface-alt: var(--surface-base);
    --color-surface-raised: var(--surface-raised);
    --color-bg: var(--surface-raised);
    --color-bg-secondary: var(--surface-base);
    --color-bg-muted: var(--surface-base);

    --body-bg-color: var(--aim-dark-bg-page);
    --body-text-color: var(--aim-dark-text-primary);
    --body-link-color: var(--interactive-base);
    --mainnav-bg-color: var(--primary-color);
    --mainnav-text-color: var(--aim-dark-text-primary);
    --mainnav-link-color: var(--aim-dark-text-primary);
    --dashboard-bg: var(--aim-dark-dashboard-bg);

    --panel-bg: var(--aim-dark-panel-bg);
    --panel-header-bg: var(--aim-dark-panel-header-bg);
    --panel-text: var(--aim-dark-panel-text);
    --panel-text-secondary: var(--aim-dark-panel-text-secondary);
    --panel-border: var(--aim-dark-panel-border);
    --panel-hover: var(--aim-dark-panel-hover);

    /* Input and form controls */
    --main-input-background: var(--aim-dark-input-background);
    --main-button-text: var(--aim-dark-text-primary);
    --site-info-bg-selected: var(--aim-dark-site-info-bg-selected);

    /* Footer */
    --footer-bg-color: var(--aim-dark-bg-page);
    --footer-text-color: var(--aim-dark-text-primary);
    --footer-link-color: var(--aim-dark-text-secondary);

    /* Panel button aliases (menu/posts side buttons) */
    --color-panel-primary: var(--aim-dark-panel-bg);
    --color-panel-primary-dark: var(--aim-dark-panel-hover);

    /* Login page */
    --login-bg: var(--aim-dark-bg-page);
    --login-card-bg: var(--aim-dark-card-bg);
    --login-text: var(--aim-dark-text-primary);
    --login-text-light: var(--aim-dark-text-secondary);
    --login-border: var(--aim-dark-card-border);

    /* Semantic alert backgrounds â€” STATIC across themes.
       These are paired with dark text colours (--color-success-dark, --color-danger-dark,
       --color-success-700 etc., none of which are theme-overridden). Mixing the tint with
       the dark page bg in dark mode produced muddy dark cards where the dark text vanished.
       Keep the tint light in both themes so the dark-text+pale-bg pairing always reads.
       Banner classes that want a dark-themed alert should opt in explicitly. */
    --color-success-bg: color-mix(in srgb, var(--color-success-medium) 15%, #ffffff);
    --color-warning-bg: color-mix(in srgb, var(--color-warning-medium) 15%, #ffffff);
    --color-danger-bg: color-mix(in srgb, var(--color-danger-medium) 15%, #ffffff);
    --color-info-bg: color-mix(in srgb, var(--color-info-medium) 15%, #ffffff);

    /* Table/list hover and lightest info tints */
    --color-info-lightest: color-mix(in srgb, var(--color-info-medium) 12%, #ffffff);
    --color-neutral-light: var(--aim-dark-card-border);

    /* 2026-07-27 — MUST come after the static-light block above.
       The block above deliberately keeps --color-*-bg / --color-info-lightest
       PALE in dark mode, because alert banners pair them with dark text
       (--color-*-dark). That is correct for banners. But --color-primary-bg was
       declared earlier as `var(--color-info-lightest)`, so it inherited the pale
       tint — and its consumers pair it with WHITE text, not dark text.

       Live effect: .nd-item--unread in the notifications drawer rendered
       #F8F8F2 on #E4EAFA = 1.13:1. Every UNREAD notification was invisible
       while read ones looked fine — the opposite of the intent, and the reason
       a drawer full of unread items looked "dissolved" (James, 2026-07-27).
       The computed `color` was correct all along; the BACKGROUND was the bug.

       Pinned to their own dark values so they no longer ride the banner chain:
         #3B4876 with white text = 8.30:1 (was 1.13:1). */
    --color-primary-bg:       color-mix(in srgb, var(--color-info-medium) 22%, var(--surface-raised));
    --color-primary-bg-hover: color-mix(in srgb, var(--color-info-medium) 32%, var(--surface-raised));

    /* Gray scale overrides for dark mode readability */
    --color-gray-50: var(--aim-dark-bg-card);
    --color-gray-200: var(--aim-dark-card-border);
    --color-gray-600: var(--aim-dark-text-secondary);
    --color-gray-700: var(--aim-dark-text-primary);

    /* Card default background override */
    --color-bg-card-default: var(--aim-dark-card-header-bg);

    /* British-spelling aliases (used by ReportsHub etc.) */
    --colour-surface: var(--surface-raised);
    --colour-text-primary: var(--aim-dark-text-primary);
    --colour-text-secondary: var(--aim-dark-text-secondary);
    --colour-text-muted: var(--aim-dark-text-secondary);
    --colour-border: var(--aim-dark-card-border);

    /* Bootstrap-era alias (used in 14+ component files) */
    --border-color: var(--aim-dark-card-border);

    /* aim-table dark-mode header — Option C consistent with light mode.
       Light mode has light-grey-blue bg + slate text + gradient strip; dark
       mode mirrors this with a slightly-lifted dark surface + light text +
       same gradient strip (which re-tints automatically because brand-primary
       and interactive-base both have dark-mode overrides).
       Header bg: 8% brand mix into surface-raised (subtle lift over row bg).
       Header text: --color-text-primary (Dracula white) for AA contrast.
       Header border: stays as --border-subtle (the strip carries the visual
       weight, not the cell border). */
    /* 2026-07-27 — this block WINS over the identical keys ~280 lines earlier,
       and its values were self-cancelling in dark mode:
         bg    "8% --brand-primary into --surface-raised" — but in aim-dark
               --brand-primary IS --surface-raised (#44475a), so 8% of X into X
               = X. The header band rendered EXACTLY the card colour: no band.
         strip a gradient from --brand-primary to --interactive-base — both
               #44475a, i.e. a flat invisible strip.
       Restored to the value the (dead) earlier declaration documented at
       length: a flat colour visibly DARKER than the card, 50/50 page+card
       ≈ #363A48, preserving the "header is darker than card body" vocabulary
       shared with light mode. Strip now uses the measured accent tokens so it
       is actually visible. */
    --aim-table-header-strip:  linear-gradient(90deg, var(--brand-border-on-surface) 0%, var(--brand-on-surface) 100%);

    /* CSS04: redeclare the remaining theme-aware aliases at body scope so
       descendants under [data-theme="aim-dark"] pick up the dark cascade.
       Mirrors the :root formulas â€” what matters is that the var() resolves
       against body's overridden --brand-primary / --surface-raised / etc. */

    /* Brand-derived primary scale */
    --aim-blue-base:        var(--brand-primary);
    --primary-active:       color-mix(in srgb, var(--primary-color), white 25%);
    --primary-light:        color-mix(in srgb, var(--primary-color), white 30%);
    --primary-lighter:      color-mix(in srgb, var(--primary-color), white 50%);
    --primary-lightest:     color-mix(in srgb, var(--primary-color), white 70%);
    --primary-border:       var(--primary-color);
    --primary-alpha-10:     color-mix(in srgb, var(--brand-primary) 10%, transparent);
    --primary-alpha-15:     color-mix(in srgb, var(--brand-primary) 15%, transparent);
    --primary-alpha-25:     color-mix(in srgb, var(--brand-primary) 25%, transparent);
    --primary-alpha-40:     color-mix(in srgb, var(--brand-primary) 40%, transparent);

    /* CSS01 decay legacy aliases — match :root definitions so they pick up
       body-scoped theme cascade (see ~line 690+ in :root). */
    --primary:                  var(--primary-color);
    --surface:                  var(--surface-raised);
    --border:                   var(--border-subtle);
    --border-default:           var(--border-subtle);
    --primary-color-hover:      var(--primary-hover);
    --aim-text-muted:           var(--color-text-muted);
    --aim-color-text-secondary: var(--color-text-secondary);

    /* CSS01 decay pass 3 — 35 more theme-aware aliases (May 7) */
    --aim-blue-dark:            color-mix(in srgb, var(--brand-primary), black 25%);
    --aim-border-light:         var(--border-subtle);
    --aim-card-bg:              var(--surface-raised);
    --aim-color-border:         var(--border-subtle);
    --aim-color-neutral-400:    var(--color-text-tertiary);
    --aim-color-neutral-500:    var(--color-text-secondary);
    --aim-color-neutral-800:    var(--color-text-primary);
    --aim-color-primary:        var(--primary-color);
    --aim-color-primary-100:    var(--color-primary-100);
    --aim-color-primary-700:    var(--color-primary-700);
    --aim-color-surface:        var(--surface-raised);
    --aim-color-surface-alt:    var(--surface-base);
    --aim-color-text:           var(--color-text-primary);
    --aim-muted:                var(--color-text-muted);
    --aim-on-primary:           var(--color-text-on-primary);
    --aim-primary-hover:        var(--primary-hover);
    --aim-surface:              var(--surface-raised);
    --aim-surface-muted:        var(--surface-base);
    --border-color-light:       var(--border-subtle);
    --border-input:             var(--border-subtle);
    --color-background-primary: var(--surface-raised);
    --color-background-secondary: var(--surface-base);
    --color-bg-card:            var(--surface-raised);
    --color-bg-disabled:        var(--surface-base);
    --color-bg-input:           var(--surface-raised);
    --color-border-subtle:      var(--border-subtle);
    --color-danger-lighter:     color-mix(in srgb, var(--color-danger-medium) 22%, var(--surface-raised));
    --color-neutral-lighter:    color-mix(in srgb, var(--color-text-tertiary) 30%, var(--surface-raised));
    --color-primary-border:     color-mix(in srgb, var(--primary-color) 30%, transparent);
    --color-status-draft-bg:    var(--surface-base);
    --color-status-draft-text:  var(--color-text-secondary);
    /* CSS04 redeclaration of the :root split — see the long note there. Same
       formula, resolved against THIS theme's --surface-raised (#44475a), so
       disabled recedes toward the card instead of toward white. */
    --color-text-disabled:      color-mix(in srgb, var(--color-text-tertiary) 62%, var(--surface-raised));
    --primary-color-dark:       color-mix(in srgb, var(--primary-color), black 25%);
    --surface-inverted:         var(--color-text-primary);
    --wf-border-light:          var(--border-subtle);

    /* Tailwind-style primary scale derived from --brand-primary */
    --color-primary-50:     color-mix(in srgb, var(--brand-primary) 12%, var(--neutral-dark));
    --color-primary-100:    color-mix(in srgb, var(--brand-primary) 18%, var(--neutral-dark));
    --color-primary-200:    color-mix(in srgb, var(--brand-primary) 28%, var(--neutral-dark));
    --color-primary-300:    color-mix(in srgb, var(--brand-primary) 42%, var(--neutral-dark));
    --color-primary-400:    color-mix(in srgb, var(--brand-primary) 60%, var(--neutral-dark));
    --color-primary-500:    var(--brand-primary);
    --color-primary-600:    color-mix(in srgb, var(--brand-primary), white 12%);
    --color-primary-700:    color-mix(in srgb, var(--brand-primary), white 25%);
    --color-primary-800:    color-mix(in srgb, var(--brand-primary), white 40%);
    --color-primary-900:    color-mix(in srgb, var(--brand-primary), white 55%);
    --color-primary-dark:   var(--primary-hover);

    /* Secondary chain */
    --secondary-color:      color-mix(in srgb, var(--primary-color), white 10%);
    --secondary-light:      color-mix(in srgb, var(--primary-color), #AAB4C0 40%);
    --secondary-lighter:    color-mix(in srgb, var(--primary-color), #D0D6DC 50%);

    /* Interactive accent — alias to --action-primary (defined at top of dark
       block). Same role-name split as light mode. */
    --interactive-base:     var(--action-primary);

    /* Misc */
    --color-background:     var(--surface-raised);

    /* aim-table chrome — row severity, nested, sticky, section divider.
       Header bg / color / border / strip are declared above (line ~1296)
       under the Option C light-bar redesign — don't redeclare here. */
    --aim-table-header-accent-color:   var(--color-text-on-primary);
    /* Sortable/active header HOVER background. MUST be redeclared here: it's
       defined at :root as `var(--interactive-base)`, and although --interactive-base
       is itself redeclared for dark mode, the un-redeclared alias leaked the
       LIGHT --interactive-base (#3F5269 — a blue-slate) into dark mode, painting
       hovered/sorted headers an out-of-place blue that clashed with Dracula
       (see feedback_var_alias_dark_mode_redeclaration.md). Re-pointing it at
       --interactive-base AT this scope resolves to the dark brand slate
       (#44475a, Dracula Current Line) — the recessive everyday-interactive
       accent, matching light mode's use of its own brand colour for the band. */
    --aim-table-header-accent-bg:      var(--interactive-base);

    /* Sort indicator in dark mode — same role as light-mode but Dracula has
       no saturated blue (its --interactive-base aliases to brand slate which
       on the dark header bg would be invisible). Use the light header-text
       colour so the active chevron pops at full opacity against the dark band
       while inactive chevrons stay hidden / faint via opacity rules. */
    --aim-table-sort-indicator-color:  var(--aim-table-header-color);
    --aim-table-row-success-bg:        color-mix(in srgb, var(--color-success-medium) 14%, var(--surface-raised));
    --aim-table-row-success-hover-bg:  color-mix(in srgb, var(--color-success-medium) 24%, var(--surface-raised));
    --aim-table-row-warning-bg:        color-mix(in srgb, var(--color-warning-medium) 14%, var(--surface-raised));
    --aim-table-row-warning-hover-bg:  color-mix(in srgb, var(--color-warning-medium) 24%, var(--surface-raised));
    --aim-table-row-danger-bg:         color-mix(in srgb, var(--color-danger-medium) 14%, var(--surface-raised));
    --aim-table-row-danger-hover-bg:   color-mix(in srgb, var(--color-danger-medium) 24%, var(--surface-raised));
    --aim-table-row-info-bg:           color-mix(in srgb, var(--color-info-medium) 14%, var(--surface-raised));
    --aim-table-row-info-hover-bg:     color-mix(in srgb, var(--color-info-medium) 24%, var(--surface-raised));
    --aim-table-section-divider-color: var(--color-text-secondary);
    /* 2026-07-27 — MUST be redeclared here. :root defines it as
       `var(--aim-table-header-bg)`, and because data-theme is applied at BODY
       scope on the Razor Pages hosts, that :root alias snapshots the LIGHT
       header band. Result: the frozen first columns' header cells rendered as a
       pale block in dark mode — the white "Site reference" corner on the Estates
       Manager grid. Its sibling --aim-table-sticky-col-bg (line above) was
       already redeclared; this one was simply missed. Same class as CSS04. */
    --aim-table-row-expanded-bg:       color-mix(in srgb, var(--brand-primary) 12%, var(--surface-raised));
    --aim-table-row-nested-add-bg:     color-mix(in srgb, var(--brand-primary) 8%, var(--surface-anchor));

    /* Status bg's "danger-light" alias */
    --aim-danger-light:                color-mix(in srgb, var(--color-danger-medium) 14%, var(--surface-raised));
}

[data-theme="cornerstone-light"] {
    --brand-primary: #003e52;
    /* Light theme — brand doubles as a legible foreground on pale surfaces,
       and as a fill under white labels. All three roles alias the brand. */
    --brand-on-surface:        var(--brand-primary);
    --brand-border-on-surface: var(--brand-primary);
    --brand-fill-on-surface:   var(--brand-primary);
    --secondary-color: #008E70;
    --secondary-hover: #006B54;

    --card-bg: var(--cornerstone-light-card-bg);
    --card-border: var(--cornerstone-light-card-border);
    --card-shadow: var(--cornerstone-light-card-shadow);
    --card-header-bg: var(--cornerstone-light-card-header-bg);
    --card-accent-primary: var(--primary-color);

    --color-text-header: var(--cornerstone-light-text-primary);
    --color-text: var(--cornerstone-light-text-primary);
    --color-text-muted: var(--cornerstone-light-text-secondary);
    --color-text-secondary: var(--cornerstone-light-text-secondary);
    --color-text-primary: var(--cornerstone-light-text-primary);
    --color-border: var(--cornerstone-light-card-border);

    --body-bg-color: var(--cornerstone-light-bg-page);
    --body-text-color: var(--cornerstone-light-text-primary);
    --body-link-color: var(--interactive-base);
    --mainnav-bg-color: var(--primary-color);
    --mainnav-text-color: var(--cornerstone-light-text-on-color);
    --mainnav-link-color: var(--cornerstone-light-text-on-color);
    --dashboard-bg: var(--cornerstone-light-dashboard-bg);

    --panel-bg: var(--cornerstone-light-panel-bg);
    --panel-header-bg: var(--cornerstone-light-panel-header-bg);
    --panel-text: var(--cornerstone-light-panel-text);
    --panel-text-secondary: var(--cornerstone-light-panel-text-secondary);
    --panel-border: var(--cornerstone-light-panel-border);
    --panel-hover: var(--cornerstone-light-panel-hover);
}

[data-theme="cornerstone-dark"] {
    color-scheme: dark;            /* Native control + scrollbar dark theming */
    --brand-primary: #00526B;
    /* Brand-as-foreground — see :root. #00526B on --surface-raised (#243B42)
       is 1.37:1. Lightened teal clears AA on both dark tiers:
         #7FB8CC on #243B42 (card)  → 5.4:1
         #7FB8CC on #1C2B30 (page)  → 6.7:1
       Border + fill measured the same way against this theme's own ladder:
         #5A8FA4 border  4.10:1 page · 3.32:1 card   (1.4.11)
         #24647C fill    white label 6.18:1 ON it    (AA) */
    --brand-on-surface:        #7FB8CC;
    --brand-border-on-surface: #5A8FA4;
    --brand-fill-on-surface:   #24647C;
    --border-strong:           var(--brand-border-on-surface);

    /* 2026-07-27 — this theme redeclared NEITHER the table header band nor the
       frozen-column tokens, so all three snapshot-leaked their LIGHT :root
       values onto dark teal surfaces (same defect as the aim-dark
       "white Site reference corner"). Derived from this theme's own ladder
       using the aim-dark formula: header = 50/50 page+card. */
    --secondary-color: #00B289;
    --secondary-hover: #008E6D;
    --surface-base: #1C2B30;
    --surface-raised: #243B42;
    --surface-primary: var(--cornerstone-dark-card-bg);
    --surface-secondary: var(--cornerstone-dark-bg-header);
    --surface-hover: rgba(255,255,255,0.08);
    --surface-muted: rgba(0,0,0,0.15);
    --border-subtle: var(--cornerstone-dark-border-subtle, rgba(0,62,82,0.4));
    --text-disabled: rgba(248,248,242,0.35);

    --card-bg: var(--cornerstone-dark-card-bg);
    --card-border: var(--cornerstone-dark-card-border);
    --card-shadow: var(--cornerstone-dark-card-shadow);
    --card-header-bg: var(--cornerstone-dark-card-header-bg);
    --card-accent-primary: var(--primary-color);

    --color-text-header: var(--cornerstone-dark-text-primary);
    --color-text: var(--cornerstone-dark-text-primary);
    --color-text-muted: var(--cornerstone-dark-text-secondary);
    --color-text-secondary: var(--cornerstone-dark-text-secondary);
    --color-text-primary: var(--cornerstone-dark-text-primary);
    --color-border: var(--cornerstone-dark-card-border);

    /* Override aim-consolidated.css :root aliases â€” var() chains don't cross :root â†’ body boundary */
    --text-primary: var(--cornerstone-dark-text-primary);
    --text-secondary: var(--cornerstone-dark-text-secondary);
    --color-surface: var(--surface-raised);
    --color-surface-alt: var(--surface-base);
    --color-surface-raised: var(--surface-raised);
    --color-bg: var(--surface-raised);
    --color-bg-secondary: var(--surface-base);
    --color-bg-muted: var(--surface-base);

    --body-bg-color: var(--cornerstone-dark-bg-page);
    --body-text-color: var(--cornerstone-dark-text-primary);
    --body-link-color: var(--interactive-base);
    --mainnav-bg-color: var(--primary-color);
    --mainnav-text-color: var(--cornerstone-dark-text-on-color);
    --mainnav-link-color: var(--cornerstone-dark-text-on-color);
    --dashboard-bg: var(--cornerstone-dark-dashboard-bg);

    --panel-bg: var(--cornerstone-dark-panel-bg);
    --panel-header-bg: var(--cornerstone-dark-panel-header-bg);
    --panel-text: var(--cornerstone-dark-panel-text);
    --panel-text-secondary: var(--cornerstone-dark-panel-text-secondary);
    --panel-border: var(--cornerstone-dark-panel-border);
    --panel-hover: var(--cornerstone-dark-panel-hover);

    /* Input and form controls */
    --main-input-background: #2A3D44;
    --main-button-text: var(--cornerstone-dark-text-primary);
    --site-info-bg-selected: #2A3D44;

    /* Footer */
    --footer-bg-color: var(--cornerstone-dark-bg-page);
    --footer-text-color: var(--cornerstone-dark-text-primary);
    --footer-link-color: var(--cornerstone-dark-text-secondary);

    /* Panel button aliases (menu/posts side buttons) */
    --color-panel-primary: var(--cornerstone-dark-panel-bg);
    --color-panel-primary-dark: var(--cornerstone-dark-panel-hover);

    /* Login page */
    --login-bg: var(--cornerstone-dark-bg-page);
    --login-card-bg: var(--cornerstone-dark-card-bg);
    --login-text: var(--cornerstone-dark-text-primary);
    --login-text-light: var(--cornerstone-dark-text-secondary);
    --login-border: var(--cornerstone-dark-card-border);

    /* Semantic alert backgrounds for dark mode */
    --color-success-bg: color-mix(in srgb, var(--color-success-medium), #1C2B30 80%);
    --color-warning-bg: color-mix(in srgb, var(--color-warning-medium), #1C2B30 80%);
    --color-danger-bg: color-mix(in srgb, var(--color-danger-medium), #1C2B30 80%);
    --color-info-bg: color-mix(in srgb, var(--color-info-medium), #1C2B30 80%);

    /* Table/list hover and lightest info tints */
    --color-info-lightest: color-mix(in srgb, var(--color-info-medium), #1C2B30 85%);
    --color-neutral-light: var(--cornerstone-dark-card-border);

    /* Gray scale overrides for dark mode readability */
    --color-gray-50: var(--cornerstone-dark-bg-card);
    --color-gray-200: var(--cornerstone-dark-card-border);
    --color-gray-600: var(--cornerstone-dark-text-secondary);
    --color-gray-700: var(--cornerstone-dark-text-primary);

    /* Card default background override */
    --color-bg-card-default: var(--cornerstone-dark-card-header-bg);

    /* British-spelling aliases (used by ReportsHub etc.) */
    --colour-surface: var(--surface-raised);
    --colour-text-primary: var(--cornerstone-dark-text-primary);
    --colour-text-secondary: var(--cornerstone-dark-text-secondary);
    --colour-text-muted: var(--cornerstone-dark-text-secondary);
    --colour-border: var(--cornerstone-dark-card-border);

    /* Bootstrap-era alias (used in 14+ component files) */
    --border-color: var(--cornerstone-dark-card-border);
}

/*
 * ==========================================================================
 * 11. COLOR THEORY DOCUMENTATION
 * ==========================================================================
 * 
 * DESIGN PRINCIPLES:
 * 
 * 1. COLOR CONTRAST RATIOS (WCAG AA Compliance):
 *    - Normal text: 4.5:1 minimum
 *    - Large text: 3:1 minimum
 *    - UI components: 3:1 minimum
 * 
 * 2. BRAND COLOR RELATIONSHIPS:
 *    - Primary colors establish brand identity
 *    - Secondary colors provide supporting elements
 *    - Accent colors draw attention to key interactions
 * 
 * 3. DARK THEME BEST PRACTICES:
 *    - Reduce overall luminance while maintaining contrast
 *    - Use warmer colors in dark themes to reduce eye strain
 *    - Maintain brand recognition through color temperature
 * 
 * 4. SEMANTIC COLOR USAGE:
 *    - Success (Green): Completion, positive actions
 *    - Warning (Orange): Caution, pending actions  
 *    - Danger (Red): Errors, destructive actions
 *    - Info (Blue): Information, neutral actions
 * 
 * 5. INTERACTION FEEDBACK:
 *    - Hover states: 10-15% darker/lighter
 *    - Active states: 20-25% darker/lighter
 *    - Focus states: Use outline with brand color
 * 
 * ==========================================================================
 */
