/*
 * Companion design tokens — foundational stylesheet.
 *
 * Single source of truth for color, spacing, radii, typography, and motion
 * primitives. Components consume these via `var(--token-name)`; nothing in
 * the app should ever hard-code a colour value or pixel size that has a
 * matching token.
 *
 * Three theme branches:
 *   1. `:root` — light defaults.
 *   2. `@media (prefers-color-scheme: dark)` AND `[data-theme="dark"]` —
 *      dark overrides. The OS preference is honoured by default; the
 *      explicit `data-theme` attribute (set by `ThemeService` from the
 *      cookie-persisted user choice) wins when present.
 *   3. `@media (forced-colors: active)` — Windows High Contrast. Map every
 *      surface / text / border token to a `system-color` keyword so the
 *      OS-controlled palette renders a usable UI without the app fighting
 *      it. (Per-control tweaks via `forced-color-adjust: none` are a
 *      per-component concern that belongs with the components themselves.)
 *
 * Motion respects `prefers-reduced-motion: reduce` by collapsing every
 * duration token to `0ms`, so any consumer using `var(--motion-duration-*)`
 * gets the right behaviour without per-component conditionals.
 *
 * System fonts only: no web fonts. The stack falls back through the OS
 * UI font on every major platform so first-paint never blocks on a
 * font-file fetch.
 *
 * ─── Responsive breakpoints ──────────────────────────────────────────────
 *
 * Two canonical viewport thresholds, plus two intentional sub-breakpoints.
 * Use these literals in @media rules — CSS does NOT yet permit custom
 * properties inside media-query values, so `@media (max-width: var(...))`
 * is a no-op and the literals below are the contract:
 *
 *   599px  — `sm` floor. The phone / small-tablet split. Below this:
 *            ListView tables fold to cards, toolbars stack, PageHeader
 *            collapses to single column, the bulk-action bar pads for
 *            the iPhone home-indicator zone, etc.
 *  1024px  — `md` floor. The desktop / tablet split. Below this: AppShell
 *            switches to a drawer + side-sheet AccountMenu.
 *
 * Sub-breakpoints (used sparingly, document the WHY in-line):
 *   380px  — very-narrow micro-tweaks (single header file). Below this
 *            iPhone 5 / older Android scale-down clip applies.
 *   480px  — auth-form padding step + the report-chart compact variant.
 *
 * Do NOT introduce new breakpoint values without an in-line comment
 * justifying why neither 599 nor 1024 fits. The audit pass that landed
 * this comment block collapsed three accidental outliers (520 / 640)
 * onto the 599 baseline — every new value is one more drifter waiting
 * to happen.
 *
 * Browser-support floor: iOS 16+ / Safari 16+ / Edge 100+ / Chrome 100+ /
 * Firefox 100+. The de facto floor is set by WebAuthn passkeys (iOS 16+
 * required to complete enrolment); modern CSS features used freely below
 * that line (popover, `<dialog>`, `:has()`, container queries) are all
 * supported there.
 */

:root {
    color-scheme: light dark;

    /* ----- Color: surfaces + text (light defaults) ------------------- */
    /* Aim for >= 7:1 contrast for body text (AAA per WCAG 2.2). */
    --color-surface: #ffffff;
    --color-surface-raised: #fafafa;
    --color-surface-sunken: #f3f3f3;
    --color-text: #1a1a1a;
    /* Hits ~7:1 against `--color-surface` (AAA). On `--color-surface-raised`
       / `--color-surface-sunken` the ratio drops below 4.5:1 — use
       `--color-text` on those surfaces instead. */
    --color-text-muted: #4d4d4d;
    --color-text-on-accent: #ffffff;
    --color-border: #d6d6d6;
    --color-border-strong: #8a8a8a;
    /* Subtle hairline for between-row dividers and card outlines on
       light surfaces. Lower contrast than --color-border, used where
       a hard line would feel heavy. */
    --color-border-subtle: #ececec;

    /* Chrome surface — header + primary sidebar branding frame (and the
       primary CTA skin). The platform brand blue (#0f5fd6 = brand-500)
       is declared once in :root as a LITERAL and intentionally NOT
       redeclared in the dark / data-theme branches: platform identity
       stays the same brand blue on every theme. White text on this blue
       clears WCAG 2.2 AA at body sizes (5.8:1). The hover/active states
       DARKEN the blue via black-alpha overlays so white text only gains
       contrast on the interactive rows — a white-alpha lighten (the old
       treatment on the deep navy) would have dropped the active row
       below AA on this brighter blue. */
    --color-chrome-surface: #0f5fd6;
    --color-chrome-surface-hover: rgba(0, 0, 0, 0.14);
    --color-chrome-surface-active: rgba(0, 0, 0, 0.26);
    --color-chrome-on-surface: #ffffff;
    /* Muted chrome text sits at 0.92 white (was 0.78): on the brighter
       blue, 0.78 only reached ~4.1:1 — below AA for the 14px nav labels.
       0.92 clears AA (~5.2:1); the inactive/active hierarchy now leans on
       weight + the active pill more than on the text tone. */
    --color-chrome-on-surface-muted: rgba(255, 255, 255, 0.92);
    --color-chrome-border: #0c4eaf;
    --color-chrome-border-subtle: rgba(255, 255, 255, 0.24);
    /* Secondary-rail surface — the flyout rail beside the primary sidebar
       reads as a LIGHTER, brand-tinted panel with dark text, so it is
       clearly distinct from the brand-blue primary menu. Unlike the
       constant main chrome, these reference the theme-aware brand tokens:
       a pale-blue wash + dark brand text in light mode, a deep-navy wash +
       light brand text in dark mode — both keep the text well above AA.
       Applies to the DESKTOP rail only; the mobile drawer's slide-in
       secondary panel stays on the blue drawer surface with white text. */
    --color-chrome-secondary-surface: var(--color-brand-subtle);
    --color-chrome-secondary-on-surface: var(--color-brand-on-surface);
    --color-chrome-secondary-on-surface-muted: var(--color-text-muted);
    --color-chrome-secondary-surface-hover: color-mix(in srgb, var(--color-brand) 12%, transparent);
    --color-chrome-secondary-surface-active: color-mix(in srgb, var(--color-brand) 18%, transparent);
    /* brand-300 (not brand-200) gives the open rail's edge a slightly crisper
       hairline against both the pale rail fill and the white content column;
       brand-200 read as nearly invisible, especially in dark mode. */
    --color-chrome-secondary-border: var(--color-brand-300);

    /* ----- Color: brand + state ------------------------------------- */
    /* `--color-brand` is the platform default. `TenantBrandingService`
       overrides it via an inline `<style>` block in App.razor's <head>
       once a tenant is in scope.

       The numeric tint stack (50–900) gives components fine-grained
       control without re-deriving with `color-mix()` in every rule.
       50/100 are wash backgrounds; 500 is the canonical brand;
       700–900 are hover / active / pressed states on dark contexts. */
    --color-brand: #0f5fd6;
    --color-brand-hover: #0c4eaf;
    --color-brand-active: #093d89;

    /* Text-selection highlight — the brand lockup inverted: honeycomb
       amber behind brand-blue text. Same pairing in both themes (the
       amber/blue contrast holds on light and dark surfaces), so the
       base definition is deliberately not theme-overridden. */
    --color-selection-text: #0f5fd6;
    --color-selection-surface: #ffb020;

    --color-brand-subtle: #e6efff;
    --color-brand-50:  #f0f6ff;
    --color-brand-100: #d9e7ff;
    --color-brand-200: #b6ccff;
    --color-brand-300: #87aaff;
    --color-brand-400: #4f86f5;
    --color-brand-500: #0f5fd6;
    --color-brand-600: #0c4eaf;
    --color-brand-700: #093d89;
    --color-brand-800: #072d65;
    --color-brand-900: #051f47;

    --color-success: #137333;
    --color-warning: #b25e00;
    --color-danger: #b3261e;
    --color-info: #1a73a8;

    /* State surfaces — paired (background, on-surface text) tokens for
       inline messaging strips, status pills, and "connection lost"
       toasts. Each pair is tuned for ≥ 4.5:1 contrast in its theme.
       Without these, consumers fall back to `color-mix(state, surface)`
       which can produce sub-AA pairings on the lighter surfaces. */
    --color-success-surface: #e7f6ec;
    --color-success-on-surface: #0c5224;
    --color-warning-surface: #fff8e1;
    --color-warning-on-surface: #5c3d00;
    --color-danger-surface: #b3261e;
    --color-danger-on-surface: #ffffff;
    --color-info-surface: #e1f4fc;
    --color-info-on-surface: #0a4661;
    --color-brand-surface: var(--color-brand-50);
    --color-brand-on-surface: var(--color-brand-700);

    /* Focus ring — visible on every interactive element. The ring is two
       layers (white halo + brand colour) so it stays visible against any
       surface.

       Convention: `outline: 2px solid var(--color-focus-ring); outline-offset: 2px;`
       for inputs and inline controls; `outline-offset: 3px` for button-like
       targets ≥ 40px tall (CTAs, primary submits, action-links). The wider
       offset keeps the ring clear of the button's padded border. */
    --color-focus-ring: var(--color-brand);
    --color-focus-halo: var(--color-surface);

    /* ----- Spacing scale -------------------------------------------- */
    /* 4px base; consumers should compose these rather than introduce
       half-values. */
    --space-0: 0;
    --space-1: 0.25rem;  /*  4px */
    --space-2: 0.5rem;   /*  8px */
    --space-3: 0.75rem;  /* 12px */
    --space-4: 1rem;     /* 16px */
    --space-5: 1.25rem;  /* 20px */
    --space-6: 1.5rem;   /* 24px */
    --space-8: 2rem;     /* 32px */
    --space-10: 2.5rem;  /* 40px */
    --space-12: 3rem;    /* 48px */
    --space-16: 4rem;    /* 64px */

    /* ----- Radii ---------------------------------------------------- */
    --radius-none: 0;
    --radius-sm: 0.125rem;  /* 2px — chips, badges */
    --radius-md: 0.25rem;   /* 4px — controls */
    --radius-lg: 0.5rem;    /* 8px — cards, surfaces */
    --radius-xl: 0.75rem;   /* 12px — modals */
    --radius-full: 9999px;  /* pills, avatars */

    /* ----- Typography ----------------------------------------------- */
    /* Inter Variable is self-hosted (see app.css @font-face). We lead
       the stack with it so post-load text matches the design; the OS
       fallbacks are character-compatible so the pre-load FOUT only
       shifts metrics slightly. Mono stays system — no web mono font. */
    --font-sans: "Inter Variable", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    --font-mono: ui-monospace, "Cascadia Code", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;

    /* Space Grotesk is the brand DISPLAY face (self-hosted, see app.css
       @font-face) — used for headings + the wordmark, not body copy. Falls
       through to the Inter/system sans stack so display text stays legible
       before the face loads (or if it fails). */
    --font-display: "Space Grotesk", var(--font-sans);

    /* Modular type scale — 1.125 ratio anchored at 1rem body text.
       The 5xl/6xl additions are for marketing hero / display copy and
       are deliberately outside the in-app scale (no admin surface
       needs them). */
    --font-size-xs: 0.75rem;     /* 12px */
    --font-size-sm: 0.875rem;    /* 14px */
    --font-size-md: 1rem;        /* 16px — body */
    --font-size-lg: 1.125rem;    /* 18px */
    --font-size-xl: 1.25rem;     /* 20px */
    --font-size-2xl: 1.5rem;     /* 24px */
    --font-size-3xl: 1.875rem;   /* 30px */
    --font-size-4xl: 2.25rem;    /* 36px */
    --font-size-5xl: 3rem;       /* 48px — marketing section heads */
    --font-size-6xl: 3.75rem;    /* 60px — marketing hero */

    --line-height-tight: 1.2;    /* headings */
    --line-height-snug: 1.4;
    --line-height-normal: 1.5;   /* body */
    --line-height-relaxed: 1.6;

    --font-weight-regular: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;

    /* Tighter tracking for large display copy (Inter looks crisper at
       large sizes with negative tracking); normal is the default. */
    --letter-spacing-tightest: -0.025em;
    --letter-spacing-tight: -0.01em;
    --letter-spacing-normal: 0;
    --letter-spacing-wide: 0.04em;

    /* ----- Elevation ------------------------------------------------ */
    /* Shallow shadow stack. Consumers compose these; we don't ship
       deep Material-style elevations.

       Crisp-tech aesthetic uses two-layer shadows: a tight inner cast
       for the surface edge + a soft outer for ambient depth. xl is
       reserved for the hero / dialog tier. `glow` is the brand-
       tinted radial highlight used behind hero CTAs and active
       primary surfaces. */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
    --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
    --shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
    --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.12), 0 8px 16px rgba(0, 0, 0, 0.08);
    --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.6);
    --shadow-glow: 0 0 0 1px rgba(15, 95, 214, 0.15), 0 8px 24px -8px rgba(15, 95, 214, 0.35);

    /* ----- Gradients ------------------------------------------------ */
    /* Marketing-surface mesh + soft brand glow. The radial-gradient
       form is preferred over an animated SVG because it composites on
       the GPU and respects forced-colors automatically when used
       behind a `background-color` that already maps to Canvas. */
    --gradient-hero: radial-gradient(
        ellipse at top,
        var(--color-brand-50) 0%,
        var(--color-surface) 60%);
    --gradient-mesh: radial-gradient(
            circle at 20% 30%,
            color-mix(in srgb, var(--color-brand-200) 35%, transparent) 0%,
            transparent 50%),
        radial-gradient(
            circle at 80% 20%,
            color-mix(in srgb, var(--color-brand-300) 30%, transparent) 0%,
            transparent 50%),
        radial-gradient(
            circle at 50% 80%,
            color-mix(in srgb, var(--color-brand-100) 40%, transparent) 0%,
            transparent 60%);
    --gradient-hairline: linear-gradient(
        to right,
        transparent 0%,
        var(--color-border) 50%,
        transparent 100%);

    /* ----- Motion --------------------------------------------------- */
    /* Durations and easings; honoured by `prefers-reduced-motion` below. */
    --motion-duration-instant: 0ms;
    --motion-duration-fast: 100ms;
    --motion-duration-normal: 200ms;
    --motion-duration-slow: 320ms;
    --motion-duration-slower: 500ms;   /* hero entrance, scroll-reveal */

    /* Material-inspired easings; `standard` is the default for most
       transitions, `emphasized` for entry/exit, `accelerate` for exits.
       `spring` gives a subtle bounce on delightful interactions
       (theme-toggle, CTA hover); never use it on functional motion. */
    --motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);
    --motion-easing-emphasized: cubic-bezier(0.3, 0, 0, 1);
    --motion-easing-accelerate: cubic-bezier(0.3, 0, 1, 1);
    --motion-easing-decelerate: cubic-bezier(0, 0, 0, 1);
    --motion-easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

    /* Per-child step used by `.motion-stagger`. Token-driven so the
       reduced-motion cascade collapses it to 0ms (i.e. no stagger)
       without per-rule conditionals. */
    --motion-stagger-step: 60ms;

    /* ----- Layout / z-index ----------------------------------------- */
    /* Reserve a layer per surface kind so add-hoc `z-index: 9999` can't
       sneak in. */
    --z-base: 0;
    --z-dropdown: 100;
    --z-sticky: 200;
    --z-overlay: 300;
    --z-modal: 400;
    --z-toast: 500;
    --z-tooltip: 600;

    /* ----- Target size ---------------------------------------------- */
    /* WCAG 2.2 SC 2.5.8 (Target Size minimum) requires interactive
       controls to be at least 24x24 CSS px — the AAA floor and a safe
       default for dense pointer-driven surfaces (toolbars, breadcrumb
       links, account-menu rows).
       SC 2.5.5 (Target Size — Enhanced, AA) raises that to 44x44 for
       touch surfaces; components rendered on touch (mobile nav, drawer
       close, full-row tap targets) should consume `--target-size-touch`
       instead. */
    --target-size-minimum: 1.5rem;  /* 24px at default font-size */
    --target-size-touch: 2.75rem;   /* 44px — WCAG 2.5.5 AA touch */
}

/* ----- Dark theme: OS preference -------------------------------------- */

@media (prefers-color-scheme: dark) {
    :root {
        --color-surface: #161616;
        --color-surface-raised: #1f1f1f;
        --color-surface-sunken: #0d0d0d;
        --color-text: #f1f1f1;
        --color-text-muted: #b3b3b3;
        --color-text-on-accent: #ffffff;
        --color-border: #3a3a3a;
        --color-border-strong: #6e6e6e;
        --color-border-subtle: #262626;

        --color-brand: #4d8df0;
        --color-brand-hover: #6fa3f4;
        --color-brand-active: #2c6dcf;
        --color-brand-subtle: #1a2a47;
        /* Dark-theme tint stack: inverted endpoints so 50 is the
           darkest wash and 900 the brightest accent, matching the
           perceptual order of the light stack. */
        --color-brand-50:  #0a1830;
        --color-brand-100: #112247;
        --color-brand-200: #1a3370;
        --color-brand-300: #2c6dcf;
        --color-brand-400: #3a7ae0;
        --color-brand-500: #4d8df0;
        --color-brand-600: #6fa3f4;
        --color-brand-700: #94baf7;
        --color-brand-800: #b9d1fa;
        --color-brand-900: #dde7fc;

        --color-success: #4caf66;
        --color-warning: #d68f3d;
        --color-danger: #f06b6b;
        --color-info: #4fb6e0;

        --color-success-surface: #143821;
        --color-success-on-surface: #9fe7b2;
        --color-warning-surface: #3a2e10;
        --color-warning-on-surface: #f5d28a;
        --color-danger-surface: #5a1c18;
        --color-danger-on-surface: #f6c9c6;
        --color-info-surface: #0d3142;
        --color-info-on-surface: #a5dcf3;
        --color-brand-surface: var(--color-brand-100);
        --color-brand-on-surface: var(--color-brand-700);

        --color-focus-halo: var(--color-surface);

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
        --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
        --shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.55), 0 2px 4px rgba(0, 0, 0, 0.45);
        --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.6), 0 8px 16px rgba(0, 0, 0, 0.5);
        --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.04);
        --shadow-glow: 0 0 0 1px rgba(77, 141, 240, 0.18), 0 8px 24px -8px rgba(77, 141, 240, 0.5);
    }
}

/* ----- Explicit user preference: data-theme on <html> overrides OS ---- */
/* Set by ThemeService. The light branch is here so a user who
   explicitly chose "light" while their OS is dark gets light. */

[data-theme="light"] {
    --color-surface: #ffffff;
    --color-surface-raised: #fafafa;
    --color-surface-sunken: #f3f3f3;
    --color-text: #1a1a1a;
    --color-text-muted: #4d4d4d;
    --color-text-on-accent: #ffffff;
    --color-border: #d6d6d6;
    --color-border-strong: #8a8a8a;
    --color-border-subtle: #ececec;

    --color-brand: #0f5fd6;
    --color-brand-hover: #0c4eaf;
    --color-brand-active: #093d89;
    --color-brand-subtle: #e6efff;
    --color-brand-50:  #f0f6ff;
    --color-brand-100: #d9e7ff;
    --color-brand-200: #b6ccff;
    --color-brand-300: #87aaff;
    --color-brand-400: #4f86f5;
    --color-brand-500: #0f5fd6;
    --color-brand-600: #0c4eaf;
    --color-brand-700: #093d89;
    --color-brand-800: #072d65;
    --color-brand-900: #051f47;

    --color-success: #137333;
    --color-warning: #b25e00;
    --color-danger: #b3261e;
    --color-info: #1a73a8;

    --color-success-surface: #e7f6ec;
    --color-success-on-surface: #0c5224;
    --color-warning-surface: #fff8e1;
    --color-warning-on-surface: #5c3d00;
    --color-danger-surface: #b3261e;
    --color-danger-on-surface: #ffffff;
    --color-info-surface: #e1f4fc;
    --color-info-on-surface: #0a4661;
    --color-brand-surface: var(--color-brand-50);
    --color-brand-on-surface: var(--color-brand-700);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
    --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
    --shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
    --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.12), 0 8px 16px rgba(0, 0, 0, 0.08);
    --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.6);
    --shadow-glow: 0 0 0 1px rgba(15, 95, 214, 0.15), 0 8px 24px -8px rgba(15, 95, 214, 0.35);
}

[data-theme="dark"] {
    --color-surface: #161616;
    --color-surface-raised: #1f1f1f;
    --color-surface-sunken: #0d0d0d;
    --color-text: #f1f1f1;
    --color-text-muted: #b3b3b3;
    --color-text-on-accent: #ffffff;
    --color-border: #3a3a3a;
    --color-border-strong: #6e6e6e;
    --color-border-subtle: #262626;

    --color-brand: #4d8df0;
    --color-brand-hover: #6fa3f4;
    --color-brand-active: #2c6dcf;
    --color-brand-subtle: #1a2a47;
    --color-brand-50:  #0a1830;
    --color-brand-100: #112247;
    --color-brand-200: #1a3370;
    --color-brand-300: #2c6dcf;
    --color-brand-400: #3a7ae0;
    --color-brand-500: #4d8df0;
    --color-brand-600: #6fa3f4;
    --color-brand-700: #94baf7;
    --color-brand-800: #b9d1fa;
    --color-brand-900: #dde7fc;

    --color-success: #4caf66;
    --color-warning: #d68f3d;
    --color-danger: #f06b6b;
    --color-info: #4fb6e0;

    --color-success-surface: #143821;
    --color-success-on-surface: #9fe7b2;
    --color-warning-surface: #3a2e10;
    --color-warning-on-surface: #f5d28a;
    --color-danger-surface: #5a1c18;
    --color-danger-on-surface: #f6c9c6;
    --color-info-surface: #0d3142;
    --color-info-on-surface: #a5dcf3;
    --color-brand-surface: var(--color-brand-100);
    --color-brand-on-surface: var(--color-brand-700);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.55), 0 2px 4px rgba(0, 0, 0, 0.45);
    --shadow-xl: 0 24px 48px rgba(0, 0, 0, 0.6), 0 8px 16px rgba(0, 0, 0, 0.5);
    --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.04);
    --shadow-glow: 0 0 0 1px rgba(77, 141, 240, 0.18), 0 8px 24px -8px rgba(77, 141, 240, 0.5);
}

/* ----- Explicit user preference: high-contrast ----------------------- */
/* `data-theme="hc"` is set by ThemeService when the user chose the HC
   theme from the toggle. System-color keywords resolve in any context
   — outside `forced-colors: active` they fall back to the browser's
   default mappings (Canvas → white/black, CanvasText → black/white
   depending on prefers-color-scheme), giving a strong contrast palette
   without requiring the user's OS to be in HC mode. Inside
   `forced-colors: active` the OS overrides drive the values instead,
   which is the right behaviour. The duplicated rule block below in
   `@media (forced-colors: active)` re-applies the same mapping for
   all data-theme values so OS HC always wins. */

[data-theme="hc"] {
    --color-surface: Canvas;
    --color-surface-raised: Canvas;
    --color-surface-sunken: Canvas;
    --color-text: CanvasText;
    --color-text-muted: GrayText;
    --color-text-on-accent: HighlightText;
    --color-border: CanvasText;
    --color-border-strong: CanvasText;
    --color-border-subtle: GrayText;

    --color-brand: Highlight;
    --color-brand-hover: Highlight;
    --color-brand-active: Highlight;
    --color-brand-subtle: Canvas;
    /* HC tint stack collapses to system Highlight + Canvas because
       OS palette drives the colour space; the stack remains valid
       (so consumer rules don't break) but every shade resolves to
       the same OS-controlled value. */
    --color-brand-50: Canvas;
    --color-brand-100: Canvas;
    --color-brand-200: Canvas;
    --color-brand-300: Highlight;
    --color-brand-400: Highlight;
    --color-brand-500: Highlight;
    --color-brand-600: Highlight;
    --color-brand-700: Highlight;
    --color-brand-800: Highlight;
    --color-brand-900: Highlight;

    --color-success: CanvasText;
    --color-warning: CanvasText;
    --color-danger: CanvasText;
    --color-info: CanvasText;

    --color-success-surface: Canvas;
    --color-success-on-surface: CanvasText;
    --color-warning-surface: Canvas;
    --color-warning-on-surface: CanvasText;
    --color-danger-surface: Canvas;
    --color-danger-on-surface: CanvasText;
    --color-info-surface: Canvas;
    --color-info-on-surface: CanvasText;
    --color-brand-surface: Canvas;
    --color-brand-on-surface: CanvasText;

    --color-focus-ring: Highlight;
    --color-focus-halo: Canvas;

    --shadow-sm: none;
    --shadow-md: none;
    --shadow-lg: none;
    --shadow-xl: none;
    --shadow-inset: none;
    --shadow-glow: none;

    /* HC kills gradients — the OS palette only carries a handful of
       defined colours, and a gradient would render as a flat slab
       anyway. The tokens still exist so consumer rules don't break. */
    --gradient-hero: Canvas;
    --gradient-mesh: Canvas;
    --gradient-hairline: linear-gradient(to right, CanvasText, CanvasText);
}

/* ----- Windows High Contrast (OS-forced) ----------------------------- */
/* `forced-colors: active` is what Edge / Windows use under the modern
   high-contrast model (replacing the older `-ms-high-contrast` query).
   Map every surface / text / border / brand token to a `system-color`
   keyword so the OS palette drives the UI. Per-control overrides (e.g.
   icons that need to keep their colour) belong with the components. */

@media (forced-colors: active) {
    :root,
    [data-theme="light"],
    [data-theme="dark"],
    [data-theme="hc"] {
        --color-surface: Canvas;
        --color-surface-raised: Canvas;
        --color-surface-sunken: Canvas;
        --color-text: CanvasText;
        --color-text-muted: GrayText;
        --color-text-on-accent: HighlightText;
        --color-border: CanvasText;
        --color-border-strong: CanvasText;
        --color-border-subtle: GrayText;

        --color-brand: Highlight;
        --color-brand-hover: Highlight;
        --color-brand-active: Highlight;
        --color-brand-subtle: Canvas;
        --color-brand-50: Canvas;
        --color-brand-100: Canvas;
        --color-brand-200: Canvas;
        --color-brand-300: Highlight;
        --color-brand-400: Highlight;
        --color-brand-500: Highlight;
        --color-brand-600: Highlight;
        --color-brand-700: Highlight;
        --color-brand-800: Highlight;
        --color-brand-900: Highlight;

        --color-success: CanvasText;
        --color-warning: CanvasText;
        --color-danger: CanvasText;
        --color-info: CanvasText;

        --color-success-surface: Canvas;
        --color-success-on-surface: CanvasText;
        --color-warning-surface: Canvas;
        --color-warning-on-surface: CanvasText;
        --color-danger-surface: Canvas;
        --color-danger-on-surface: CanvasText;
        --color-info-surface: Canvas;
        --color-info-on-surface: CanvasText;
        --color-brand-surface: Canvas;
        --color-brand-on-surface: CanvasText;

        --color-focus-ring: Highlight;
        --color-focus-halo: Canvas;

        --shadow-sm: none;
        --shadow-md: none;
        --shadow-lg: none;
        --shadow-xl: none;
        --shadow-inset: none;
        --shadow-glow: none;

        --gradient-hero: Canvas;
        --gradient-mesh: Canvas;
        --gradient-hairline: linear-gradient(to right, CanvasText, CanvasText);
    }
}

/* ----- Reduced motion ------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
    :root {
        --motion-duration-instant: 0ms;
        --motion-duration-fast: 0ms;
        --motion-duration-normal: 0ms;
        --motion-duration-slow: 0ms;
        --motion-duration-slower: 0ms;
        --motion-stagger-step: 0ms;
    }
}
