/* Xuro design tokens - smoke/grey neutral dark (default) + light theme.
   Product-owner decision: no blue tint anywhere; a warm accent (similar to
   the UI-rebuild mockups) carries all primary/interactive emphasis. Every
   component must consume these custom properties rather than hard-coded
   colors - see XURO_CURRENT_MILESTONE.md's "Theming" contract. */

/* DM Sans, self-hosted (client/public/fonts/, SIL OFL). The same two woff2
   files the Designer ships (TMP-Design public/vendor/fonts), so the shell and
   the Designer are one typeface (owner ruling 2026-09-30: everything DM
   Sans). One variable face per unicode-range subset covers weights 100-900.
   The Content Security Policy is font-src 'self': no font ever loads from a
   third-party host. */
@font-face {
    font-family: "DM Sans";
    src: url("/fonts/DMSans-latin-ext.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "DM Sans";
    src: url("/fonts/DMSans-latin.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
    color-scheme: dark;

    /* Raw neutral ramp - desaturated smoke/grey, deliberately not slate/blue-grey */
    --grey-950: #0b0c0e;
    --grey-900: #111316;
    --grey-850: #15181b;
    --grey-800: #1a1d21;
    --grey-750: #202327;
    --grey-700: #292c31;
    --grey-600: #3a3e44;
    --grey-500: #52565d;
    --grey-400: #74787f;
    --grey-300: #9a9ea5;
    --grey-200: #c2c5ca;
    --grey-100: #e2e4e7;
    --grey-50: #f4f5f6;

    /* Warm accent - matches the mockups' primary action color, no blue.
       UI audit H1 (2026-09-30): every accent carries the design module's
       FULL six-step ramp, byte-identical to TMP-Design's tokens.css, so the
       shell and the Designer paint literally the same colours.
       800/700/600 = the solid fill, hover and press steps (white text on 600
       is 5.80:1 or better); 500/400/300 = text, link and tint steps.
       uiGuards.verify.js parses both files and fails if a ramp drifts. */
    --accent-800-rgb: 118, 36, 24;
    --accent-700-rgb: 148, 49, 34;
    --accent-600-rgb: 178, 62, 44;
    --accent-500-rgb: 226, 84, 63;
    --accent-400-rgb: 234, 107, 87;
    --accent-300-rgb: 242, 143, 126;

    /* FIXED PRODUCT RED (owner ruling 2026-08-25: the Full Review card and
       the "Paid tier" badge must "not change with the theme color").
       Deliberately the SAME values as the default warm accent above, but
       declared separately and NEVER overridden in the [data-accent] blocks
       at the bottom of this file. Anything that must stay red whichever
       accent a user picks reads these, not --accent-*.
       If you add a new accent, do NOT add these here too - that is exactly
       what this family exists to prevent. */
    --fixed-red-600-rgb: 178, 62, 44;
    --fixed-red-500-rgb: 226, 84, 63;
    --fixed-red-400-rgb: 234, 107, 87;

    /* Semantic status colors, as RGB triples so rgba(var(--x-rgb), alpha) works */
    --success-500-rgb: 63, 166, 107;
    --success-400-rgb: 87, 199, 133;
    --warning-500-rgb: 209, 146, 46;
    --warning-400-rgb: 232, 172, 76;
    --critical-500-rgb: 209, 72, 63;
    --critical-400-rgb: 238, 120, 110;
    --info-500-rgb: 74, 144, 184;
    --info-400-rgb: 107, 176, 214;
    --neutral-overlay-rgb: 154, 158, 165;
    --black-rgb: 0, 0, 0;
    --white-rgb: 255, 255, 255;

    /* Surfaces */
    --color-bg-page: var(--grey-950);
    --color-bg-sidebar: var(--grey-900);
    --color-bg-header: var(--grey-900);
    --color-bg-surface: var(--grey-850);
    --color-bg-surface-raised: var(--grey-800);
    --color-bg-surface-hover: var(--grey-750);
    --color-bg-inset: var(--grey-900);

    --color-border-subtle: var(--grey-750);
    --color-border-default: var(--grey-700);
    --color-border-strong: var(--grey-600);

    --color-text-primary: var(--grey-50);
    --color-text-secondary: var(--grey-300);
    /* Audit M6: grey-400 (#74787f) measured 4.02 to 4.41:1 on the surfaces;
       this step clears 4.5:1 on every surface and on the grey-700 badges'
       secondary-text pairing. */
    --color-text-muted: #878b92;
    --color-text-disabled: var(--grey-500);
    --color-text-inverse: var(--grey-950);

    /* Audit H1. --color-accent is for TEXT, links, tints and non-text
       indicators (progress fills, dots). Anything that puts white text on an
       accent fill uses --color-accent-fill (step 600), hover 700, press 800:
       the module's own button fill (TMP-Design tokens.css --accent), so a
       Xuro primary button and a Designer primary button are the same colour.
       Only controls.css (and the pagination selected state in it) may paint
       these; uiGuards.verify.js pins that. */
    --color-accent: rgb(var(--accent-500-rgb));
    --color-accent-strong: rgb(var(--accent-600-rgb));
    --color-accent-soft: rgb(var(--accent-400-rgb));
    --color-accent-contrast: #ffffff;
    --color-accent-bg: rgba(var(--accent-500-rgb), .14);
    --color-accent-fill: rgb(var(--accent-600-rgb));
    --color-accent-fill-hover: rgb(var(--accent-700-rgb));
    --color-accent-fill-press: rgb(var(--accent-800-rgb));

    /* Danger (owner 2026-09-30): a TRUE red for destructive actions, not the
       orange-red the old default accent was. Tailwind red 800/700/600, the
       same ramp as the red accent and the design module's --color-danger-fill.
       Step 600 with white text is 4.83:1. The status "critical" tokens below
       are a separate family (findings) and share no variable with these. */
    --danger-800-rgb: 153, 27, 27;
    --danger-700-rgb: 185, 28, 28;
    --danger-600-rgb: 220, 38, 38;
    --color-danger-fill: rgb(var(--danger-600-rgb));
    --color-danger-fill-hover: rgb(var(--danger-700-rgb));
    --color-danger-fill-press: rgb(var(--danger-800-rgb));
    --color-danger-contrast: #ffffff;

    /* Text on the solid severity fills (the PDF pins). Dark theme keeps the
       old pairing (white, dark on amber); the light theme's severity fills
       are darker (H4), so its amber pin takes white text too. */
    --color-on-critical: #ffffff;
    --color-on-warning: #1a1a1a;
    --color-on-info: #ffffff;

    --color-success: rgb(var(--success-500-rgb));
    --color-success-soft: rgb(var(--success-400-rgb));
    --color-success-bg: rgba(var(--success-500-rgb), .15);

    --color-warning: rgb(var(--warning-500-rgb));
    --color-warning-soft: rgb(var(--warning-400-rgb));
    --color-warning-bg: rgba(var(--warning-500-rgb), .15);

    --color-critical: rgb(var(--critical-500-rgb));
    --color-critical-soft: rgb(var(--critical-400-rgb));
    --color-critical-bg: rgba(var(--critical-500-rgb), .15);

    --color-info: rgb(var(--info-500-rgb));
    --color-info-soft: rgb(var(--info-400-rgb));
    --color-info-bg: rgba(var(--info-500-rgb), .15);

    --color-overlay-soft: rgba(var(--neutral-overlay-rgb), .15);

    /* Review depth TIER IDENTITY colors (SONNET-20260730-TIER-IDENTITY-
       COLORS - owner: "the tiers need more color, the highlighted color
       is the same red for every tier"). Each of the five modes gets its
       own distinct hue used consistently for its gradient strip, its
       name text, its radio control, and - most importantly - its OWN
       selected-state border/tint, so selecting Premium reads gold,
       Ultimate reads amber/bronze, Light reads cool silver, etc., instead
       of every tier collapsing onto the single global accent. No blue
       anywhere (standing owner rule - blue is reserved for the info-
       severity token above). Full keeps the app's signature accent
       untouched, exactly as before.

       Each tier is a "main" + "soft" RGB triple pair (2-stop gradient /
       rgba() base). RGB triples, not rgb()/rgba() wrappers, per this
       file's own convention so rgba(var(--x-rgb), alpha) works anywhere.
       Light theme re-declares the tiers that read as pastel on dark
       surfaces (light, medium, ultimate, premium) with deeper/more
       saturated values below so text/badge contrast holds on white -
       Full is intentionally left alone in both themes since it's just
       --accent-*-rgb, which the rest of the app already treats as theme-
       invariant. */
    --tier-light-rgb: 158, 163, 172;
    --tier-light-soft-rgb: 214, 217, 222;
    --tier-medium-rgb: 48, 163, 135;
    --tier-medium-soft-rgb: 94, 206, 176;
    /* Pinned to the fixed red, not the accent (owner ruling 2026-08-25):
       the Full Review tier must look the same whichever accent is chosen. */
    --tier-full-rgb: var(--fixed-red-500-rgb);
    --tier-full-soft-rgb: var(--fixed-red-400-rgb);
    --tier-ultimate-rgb: 191, 122, 56;
    --tier-ultimate-soft-rgb: 224, 160, 96;
    --tier-premium-rgb: 214, 170, 74;
    --tier-premium-soft-rgb: 244, 208, 122;

    /* Derived semantic handles - one naming pattern components consume via
       data-tier, so ReviewDepthCard.css never inlines an rgba()/rgb() call
       itself. */
    --tier-light-color: rgb(var(--tier-light-rgb));
    --tier-light-strong: rgb(var(--tier-light-soft-rgb));
    --tier-light-bg: rgba(var(--tier-light-rgb), .16);
    --tier-medium-color: rgb(var(--tier-medium-rgb));
    --tier-medium-strong: rgb(var(--tier-medium-soft-rgb));
    --tier-medium-bg: rgba(var(--tier-medium-rgb), .16);
    --tier-full-color: rgb(var(--tier-full-rgb));
    --tier-full-strong: rgb(var(--tier-full-soft-rgb));
    --tier-full-bg: rgba(var(--tier-full-rgb), .16);
    --tier-ultimate-color: rgb(var(--tier-ultimate-rgb));
    --tier-ultimate-strong: rgb(var(--tier-ultimate-soft-rgb));
    --tier-ultimate-bg: rgba(var(--tier-ultimate-rgb), .16);
    --tier-premium-color: rgb(var(--tier-premium-rgb));
    --tier-premium-strong: rgb(var(--tier-premium-soft-rgb));
    --tier-premium-bg: rgba(var(--tier-premium-rgb), .18);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md: 0 8px 24px rgba(0, 0, 0, .35);
    --shadow-lg: 0 20px 56px rgba(0, 0, 0, .58), 0 4px 12px rgba(0, 0, 0, .40);
    /* Audit L13: modal scrim, theme-aware like the module's --surface-overlay. */
    --color-scrim: rgba(8, 8, 7, .66);
    /* Audit L6: one disabled opacity for every control. */
    --disabled-opacity: .4;
    /* Audit H2: the one keyboard focus ring (mirrors the module's
       --focus-ring: a gap in the page colour, then an accent halo). */
    --focus-ring: 0 0 0 2px var(--color-bg-page), 0 0 0 4px rgba(var(--accent-500-rgb), .75);
    /* The ring is drawn as an OUTLINE (2px, 2px off the edge), not a box-shadow:
       component rules set box-shadow for selection and elevation and would
       erase a shadow ring at equal specificity. An outline survives them. */
    --focus-ring-color: rgba(var(--accent-500-rgb), .75);

    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-card: 12px; /* modal and module card radius (owner Q4) */
    --radius-lg: 16px;
    --radius-pill: 999px;

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-10: 40px;

    /* Owner request 2026-07-31: app-wide switch from the terminal-style
       monospace to a clean sans. Owner ruling 2026-09-30: DM Sans, the
       Designer's own typeface (Inter read as the template default). The
       old mono stack is preserved as --font-family-mono for code-like UI. */
    --font-family-base: "DM Sans", -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-family-mono: ui-monospace, "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, monospace;

    /* Type scale (audit M4, 2026-09-30): seven steps and three weights for the
       whole shell. Every font-size in shell CSS is one of these; the guard
       fails on a rem/px literal. (The design module keeps its own scale.) */
    --text-xs: .75rem;
    --text-sm: .82rem;
    --text-base: .9rem;
    --text-md: 1rem;
    --text-lg: 1.25rem;
    --text-xl: 1.5rem;
    --text-2xl: 2.1rem;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;

    --sidebar-width: 248px;
    /* The collapsed icon rail: wide enough for the nav item's 40px hit
       target plus breathing room, narrow enough to be read as a rail rather
       than a thin sidebar. Measured 2026-08-29 - collapsing moves a nav
       icon's centre 5px left (38px -> 33px) as the item switches from
       left-aligned to centred, and returns 184px to the main column. */
    --sidebar-width-collapsed: 64px;
    /* The slim top bar (owner, 2026-10-01: "a little thinner"). The Designer
       page has no Xuro header at all (AppLayout.tsx). */
    --header-height: 44px;

    /* Motion (owner, 2026-10-01). One curve and two durations for everything
       that opens or closes: --motion-base opens, --motion-fast closes (an exit
       is quicker than an entrance). The sidebar uses them first; every popup
       is meant to follow. Reduced motion sets both to 0 below, so anything
       built on these tokens goes instant with no per-component rule. */
    --motion-base: 200ms;
    --motion-fast: 160ms;
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

    /* Motion kit (owner, 2026-10-01): one set of values for every pop-up, the
       same numbers in TMP-Design's tokens.css. --motion-small is for the small
       things (menus, flyouts, popovers, tooltips, hover previews),
       --motion-panel for panels, dialogs and the command palette, --motion-exit
       for a quick fade-out where an element's teardown allows one. Nothing is
       over 200ms, there is no bounce, and only opacity and transform move.
       --motion-shift is the 4px an entrance travels from the side it is
       anchored to. All four go to 0 under reduced motion. uiGuards.verify.js
       (section 16) pins every overlay to these and bans a literal duration. */
    --motion-small: 120ms;
    --motion-panel: 180ms;
    --motion-exit: 90ms;
    --motion-shift: 4px;
    /* Where a motion-enter-shift overlay starts from; an overlay overrides it. */
    --motion-from-x: 0px;
    --motion-from-y: 0px;
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --motion-base: 0ms;
        --motion-fast: 0ms;
        --motion-small: 0ms;
        --motion-panel: 0ms;
        --motion-exit: 0ms;
        --motion-shift: 0px;
    }
}

/* The kit's entrances. An overlay is mounted when it opens, so an animation on
   its own rule plays once per open and never on a first page load. A menu-like
   overlay sets --motion-from-x / --motion-from-y to the offset it starts from
   (the side it hangs off); a dialog uses the scale entrance and its scrim the
   plain fade. */
@keyframes motion-enter-shift {
    from { opacity: 0; transform: translate(var(--motion-from-x), var(--motion-from-y)); }
    to { opacity: 1; transform: none; }
}

@keyframes motion-enter-scale {
    from { opacity: 0; transform: scale(.98); }
    to { opacity: 1; transform: none; }
}

@keyframes motion-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

:root[data-theme="light"] {
    color-scheme: light;

    --color-bg-page: #f3f4f5;
    --color-bg-sidebar: #ffffff;
    --color-bg-header: #ffffff;
    --color-bg-surface: #ffffff;
    --color-bg-surface-raised: #edeeef;
    --color-bg-surface-hover: #e4e6e8;
    --color-bg-inset: #edeeef;

    --color-border-subtle: #e3e5e7;
    --color-border-default: #d2d5d8;
    --color-border-strong: #b6bac0;

    --color-text-primary: #15171a;
    --color-text-secondary: #494d53;
    --color-text-muted: #62666c;
    --color-text-disabled: #9a9ea5;
    --color-text-inverse: #ffffff;

    --shadow-sm: 0 1px 2px rgba(15, 15, 15, .08);
    --shadow-md: 0 8px 24px rgba(15, 15, 15, .1);
    --shadow-lg: 0 20px 56px rgba(24, 22, 20, .18), 0 4px 12px rgba(24, 22, 20, .10);
    --color-scrim: rgba(24, 22, 20, .40);
    --color-on-warning: #ffffff;
    --focus-ring: 0 0 0 2px var(--color-bg-surface), 0 0 0 4px rgba(var(--accent-600-rgb), .70);
    --focus-ring-color: rgba(var(--accent-600-rgb), .85);

    /* Audit H1: on a light ground accent TEXT and links use the 600 step
       (500 measured 3.3 to 3.8:1), the soft/strong steps go darker rather
       than lighter, and the tint reads from 600 too. */
    --color-accent: rgb(var(--accent-600-rgb));
    --color-accent-strong: rgb(var(--accent-700-rgb));
    --color-accent-soft: rgb(var(--accent-700-rgb));
    --color-accent-bg: rgba(var(--accent-600-rgb), .12);

    /* Audit H4: the status colours were never retuned for a light ground
       (Completed 1.82:1, Available 1.40:1, Failed 2.59:1). These are the
       design module's own light hues (TMP-Design tokens.css light block:
       success #1f7a4d, warning #9a6a12, danger #b8332b), a step darker so the
       text also clears 4.5:1 on its own tint over a raised surface, used for
       both the base and the soft (text) step. The tint drops to 10% (it is
       15% in the dark theme) because a tint darkens the ground the text sits
       on. uiGuards.verify.js measures each pair in both themes. The -400
       (text) step is one notch darker again so a pill still clears 4.5:1 on
       a hovered or selected row, the darkest ground it sits on. */
    --success-500-rgb: 24, 110, 68;
    --success-400-rgb: 20, 96, 59;
    --warning-500-rgb: 130, 88, 10;
    --warning-400-rgb: 115, 78, 9;
    --critical-500-rgb: 176, 46, 38;
    --critical-400-rgb: 160, 40, 33;
    --info-500-rgb: 30, 98, 142;
    --info-400-rgb: 26, 88, 128;
    --color-success-bg: rgba(var(--success-500-rgb), .10);
    --color-warning-bg: rgba(var(--warning-500-rgb), .10);
    --color-critical-bg: rgba(var(--critical-500-rgb), .10);
    --color-info-bg: rgba(var(--info-500-rgb), .10);

    /* Tier identity re-tuned for light surfaces - the dark-theme values
       above read as pastel/washed-out on white card backgrounds, so these
       are deeper/more saturated versions of the same hues (contrast, not
       a different palette). Full is deliberately omitted: --accent-*-rgb
       already doesn't change per theme anywhere else in this file. */
    --tier-light-rgb: 86, 92, 101;
    --tier-light-soft-rgb: 140, 146, 154;
    --tier-medium-rgb: 15, 122, 98;
    --tier-medium-soft-rgb: 48, 163, 135;
    --tier-ultimate-rgb: 146, 88, 36;
    --tier-ultimate-soft-rgb: 191, 122, 56;
    --tier-premium-rgb: 158, 118, 34;
    --tier-premium-soft-rgb: 199, 156, 84;
}

* {
    box-sizing: border-box;
}

html, body {
    background: var(--color-bg-page);
    color: var(--color-text-primary);
}

body {
    margin: 0;
    font-family: var(--font-family-base);
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--color-accent-soft);
}

/* COORDINATOR-20260823-ACCENT-THEMES (owner request: user-selectable
   accent themes, kept lite - surfaces and text never change, only the
   accent family). Theme 1 = the default warm Xuro red above. Theme 2
   (light blue) and Theme 3 (hot pink) are explicit owner-sanctioned
   variants: the historic "no blue" rule still governs the DEFAULT
   look; a user choosing Theme 2 is the deliberate exception. Only the
   four accent rgb triplets are overridden - every derived token
   (--color-accent*, tier ladders, pin/pulse colors) follows for free. */
:root[data-accent="blue"] {
    --accent-800-rgb: 24, 65, 154;
    --accent-700-rgb: 30, 81, 193;
    --accent-600-rgb: 37, 99, 235;
    --accent-500-rgb: 96, 165, 250;
    --accent-400-rgb: 147, 197, 253;
    --accent-300-rgb: 191, 219, 254;
}

:root[data-accent="pink"] {
    --accent-800-rgb: 144, 26, 78;
    --accent-700-rgb: 180, 32, 98;
    --accent-600-rgb: 219, 39, 119;
    --accent-500-rgb: 236, 72, 153;
    --accent-400-rgb: 244, 114, 182;
    --accent-300-rgb: 249, 168, 212;
}

/* Chrome batch (2026-09-13), owner item 6: a fourth accent, "neutral" - a
   graphite/slate-smoke ramp, clearly not orange, and the new DEFAULT
   accent for a session that has never chosen one (ThemeProvider.tsx's
   readStoredAccent). An existing user's own stored choice is unaffected.

   Audit H1 (2026-09-30): the ramp below is the design module's own neutral
   ramp, byte for byte (TMP-Design tokens.css). The fill steps are 600/700/800
   (white on 600 is 5.20:1); 500/400/300 are the text and tint steps. */
:root[data-accent="neutral"] {
    --accent-800-rgb: 67, 70, 75;
    --accent-700-rgb: 86, 89, 97;
    --accent-600-rgb: 104, 109, 118;
    --accent-500-rgb: 138, 142, 151;
    --accent-400-rgb: 155, 158, 166;
    --accent-300-rgb: 180, 183, 188;
}

/* Owner UI batch 2 (2026-09-14), item 8: a fifth accent, "red" - a clean,
   saturated signal-red, distinct from "default" (the muted orange-red
   every other accent above is a variation of).

   Audit H1 (2026-09-30): Tailwind's red-800..300 scale, byte-identical to
   the design module's own red ramp (600 = the button fill, 4.83:1 with white
   text). Earlier this file shifted the steps down by one; that shift is gone
   now that the fill is step 600 everywhere. */
:root[data-accent="red"] {
    --accent-800-rgb: 153, 27, 27;
    --accent-700-rgb: 185, 28, 28;
    --accent-600-rgb: 220, 38, 38;
    --accent-500-rgb: 239, 68, 68;
    --accent-400-rgb: 248, 113, 113;
    --accent-300-rgb: 252, 165, 165;
}
