/* AdminPortal css 02: Semantic design tokens. Portable across the TenScan Blazor fleet. */

/* ============================================================================
   Tokens are named for ROLE, not appearance.

   The older layer in 01 names tokens after colours (--white, --gray-500,
   --green). That forces light theme to make the names lie: it redefines
   --white to #1B1E24, so `color: var(--white)` renders near-black. Every new
   component then has to guess which lie to use, which is why the skin drifted.

   Here a token says what it is FOR (--foreground, --border, --danger-subtle).
   Both themes assign real values to the same role, so component CSS is written
   once and is theme-correct by construction.

   Legacy names are kept at the bottom as aliases onto these roles, so the
   existing ~4,300 lines keep working while components migrate incrementally.

   Porting to another site in the fleet: copy this file, change the BRAND block
   and nothing else.
   ============================================================================ */

:root {
    /* ---- Brand -------------------------------------------------------------
       The only block that differs per site. Everything else derives from role. */
    --brand: #13EF95;
    --brand-ink: #04120C;           /* text on a filled brand surface */

    /* ---- Surfaces (lowest to highest elevation) ---------------------------- */
    --background: #09090B;          /* page */
    --surface: #0E0E11;             /* rails, headers, sunken strips */
    --card: #121216;                /* panels sitting on the page */
    --card-hover: #17171C;
    --popover: #17171C;             /* menus, dialogs, tooltips */

    /* ---- Ink ---------------------------------------------------------------
       foreground = primary text, muted = labels/secondary, subtle = de-emphasised */
    --foreground: #FAFAFA;
    --foreground-muted: #A1A1AA;
    /* Per-theme, not shared. #71717A is correct on light (#FAFAFA -> 4.66:1) but only
       3.99:1 on dark's --surface and 3.86:1 on --card, and this token paints real text:
       .delta-flat (a KPI figure), .trendchart-axis, .empty-hint, .nav-section-head.
       #8A8A93 measures 4.8:1 on --surface and 4.6:1 on --card. */
    --foreground-subtle: #8A8A93;

    /* ---- Lines -------------------------------------------------------------
       border is the hairline used for the KPI grid; strong is for emphasis. */
    --border: #26262B;
    --border-strong: #35353C;
    --ring: var(--brand);           /* focus ring */

    /* ---- Intent ------------------------------------------------------------
       Each intent has a solid, an ink for text on the solid, and a subtle tint
       for badge/pill backgrounds. Deltas use success/danger, never brand. */
    --primary: var(--brand);
    --primary-ink: var(--brand-ink);
    --primary-subtle: rgba(19, 239, 149, 0.12);

    --success: #34D399;
    --success-ink: #04120C;
    --success-subtle: rgba(52, 211, 153, 0.12);

    --danger: #FB7185;
    --danger-ink: #1A0508;
    --danger-subtle: rgba(251, 113, 133, 0.12);

    --warning: #FBBF24;
    --warning-ink: #1A1200;
    --warning-subtle: rgba(251, 191, 36, 0.12);

    --info: #38BDF8;
    --info-ink: #04121A;
    --info-subtle: rgba(56, 189, 248, 0.12);

    --neutral-subtle: rgba(161, 161, 170, 0.12);

    /* ---- Intent inks for TEXT ---------------------------------------------
       An intent value has two jobs that pull in opposite directions: it fills a
       solid surface (wants to be dark enough for white ink) and it colours text
       on the matching 10-12% tint (wants to be dark enough against a near-white
       tint). One value cannot do both in a light theme - measured on the tints
       these rules actually paint on, the light fills land at 3.0-4.4:1, under
       the 4.5:1 AA floor for text this size.

       So: --{intent} stays the FILL, --{intent}-strong is the ink for text on a
       tint or on --surface. On dark they are the same value (the dark fills
       already measure ~7.9:1); the light block below overrides them.

       Any rule that sets `color:` to an intent must use -strong. Any rule that
       sets `background:` or `border-color:` keeps the plain token. */
    --primary-strong: var(--primary);
    --success-strong: var(--success);
    --danger-strong: var(--danger);
    --warning-strong: var(--warning);
    --info-strong: var(--info);

    /* ---- Charts ------------------------------------------------------------
       Categorical series colours, assigned in this fixed order and never cycled.

       The ORDER is load-bearing, not cosmetic. The obvious sequence - green,
       blue, violet, amber, rose - puts blue next to violet and amber next to
       rose, and those are exactly the two pairs a deuteranope cannot separate:
       measured against the Machado simulation, blue/violet came out at dE 5.2
       in dark theme and rose/amber at 4.7 in light, against a target of 8. The
       light pair was also below the normal-vision floor of 15 (dE 12.8), so it
       was hard to read with full colour vision too.

       Interleaving the hues - green, violet, amber, blue, rose - fixes it with
       no change to any value: worst adjacent pair is now dE 17.3 (dark) and
       20.9 (light), and the light set clears every check.

       Deliberate deviation: the dark steps sit at OKLCH L 0.71-0.84, above the
       0.48-0.67 band a validator expects for dark mode. That band assumes a
       mid-dark surface; ours is #09090B. Stepping down into it drops these to
       2.1-2.7:1 against the card and they go muddy. At the lightness used here
       all five clear 3:1. Contrast against the real surface wins. */
    --chart-1: #13EF95;
    --chart-2: #A78BFA;
    --chart-3: #FBBF24;
    --chart-4: #38BDF8;
    --chart-5: #FB7185;

    /* ---- Geometry ----------------------------------------------------------
       Flat and sharp. Dial --radius up per-site if a softer look is wanted. */
    --radius: 4px;
    --radius-sm: 2px;
    --radius-lg: 8px;
    --radius-pill: 999px;

    --hairline: 1px;

    /* ---- Elevation ---------------------------------------------------------
       Deliberately restrained: dense data reads better flat than floating. */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.32);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.36);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.44);

    /* ---- Motion ------------------------------------------------------------ */
    --transition: 140ms ease;

    /* ---- Overlay channels --------------------------------------------------
       Not colours: raw "r, g, b" triplets consumed as rgba(var(--overlay), a) by
       the ~130 legacy call sites that still tint a surface by alpha. --overlay is
       the ink-coloured tint (light on dark), --overlay-inv its opposite. They must
       be restated per theme rather than aliased, because they are not colours. */
    --overlay: 255, 255, 255;
    --overlay-inv: 0, 0, 0;

    /* ---- Scrim -------------------------------------------------------------
       The wash behind a modal or a mobile drawer. NOT a theme-inverted tint: a
       scrim's job is to push the page back, and pushing back always means darker.
       Built from --overlay-inv it went WHITE in light theme, lifting #F4F4F5 to
       ~#FAFAFA - which is exactly --surface, the drawer's own background, so the
       drawer and the scrimmed page became the same colour.

       Declared once here and used by .sidebar-overlay (06) and .rz-dialog-mask (21).
       Light theme dials the alpha down: less is needed to separate from a pale page. */
    --scrim: rgba(0, 0, 0, 0.55);
}

[data-theme="light"] {
    --background: #F4F4F5;
    --surface: #FAFAFA;
    --card: #FFFFFF;
    --card-hover: #FAFAFA;
    --popover: #FFFFFF;

    --foreground: #18181B;
    --foreground-muted: #52525B;
    --foreground-subtle: #71717A;   /* 4.66:1 on --surface #FAFAFA; already correct here */

    --border: #E4E4E7;
    --border-strong: #D4D4D8;

    /* Saturated neon fails contrast on white; the light theme uses deeper,
       print-friendly versions of the same hues. Roles are unchanged.

       --brand is one step darker than the light --success/--chart-1 (#059669) on
       purpose. It is the only intent whose SOLID fill regularly carries white ink -
       .pill.active, .segmented-count on an active tab, .btn-brand:hover - and
       #FFFFFF on #059669 is 3.77:1, under the AA floor. #047857 takes that to
       5.5:1. The other intents keep their fill: white on --danger #E11D48 already
       measures 4.7:1, and --success / --warning / --info are never used as a solid
       behind text in this portal. */
    --brand: #047857;
    --brand-ink: #FFFFFF;
    --primary-subtle: rgba(5, 150, 105, 0.10);

    --success: #059669;
    --success-ink: #FFFFFF;
    --success-subtle: rgba(5, 150, 105, 0.10);

    --danger: #E11D48;
    --danger-ink: #FFFFFF;
    --danger-subtle: rgba(225, 29, 72, 0.10);

    --warning: #B45309;
    --warning-ink: #FFFFFF;
    --warning-subtle: rgba(180, 83, 9, 0.10);

    --info: #0284C7;
    --info-ink: #FFFFFF;
    --info-subtle: rgba(2, 132, 199, 0.10);

    --neutral-subtle: rgba(82, 82, 91, 0.10);

    /* Text-on-tint inks. One step darker than the fill of the same hue, which is
       what the pre-token light theme used to carry before the single-value token
       collapsed the two roles together.

       Measured (WCAG 2.x) against the tint composited over --card #FFFFFF, which
       is the lightest surface any of these paint on - so every darker surface is
       better, and the sunken --surface #FAFAFA footer that carries the KPI deltas
       is covered too:
         --success-strong on --success-subtle  4.9:1   (fill was 3.3:1)
         --info-strong    on --info-subtle     5.2:1   (fill was 3.6:1)
         --danger-strong  on --danger-subtle   5.3:1   (fill was 4.0:1)
         --warning-strong on --warning-subtle  6.2:1   (fill was 4.4:1)
       and on the page --background #F4F4F5 that .alert-* sits on, the tightest
       case is --info-strong at 4.8:1. All clear the 4.5:1 AA floor for text
       under 18.66px bold. */
    --primary-strong: #047857;
    --success-strong: #047857;
    --danger-strong: #BE123C;
    --warning-strong: #92400E;
    --info-strong: #0369A1;

    /* Same hues, same interleaved order. This set clears all five checks. */
    --chart-1: #059669;
    --chart-2: #7C3AED;
    --chart-3: #B45309;
    --chart-4: #0284C7;
    --chart-5: #E11D48;

    --shadow-sm: 0 1px 2px rgba(24, 24, 27, 0.06);
    --shadow-md: 0 4px 12px rgba(24, 24, 27, 0.08);
    --shadow-lg: 0 12px 32px rgba(24, 24, 27, 0.12);

    --overlay: 0, 0, 0;
    --overlay-inv: 255, 255, 255;

    --scrim: rgba(0, 0, 0, 0.42);
}

/* ============================================================================
   Legacy aliases

   Maps the appearance-named tokens from 01 onto the roles above so existing
   component CSS keeps rendering while it migrates. Do not use these in new
   code. When a file stops referencing a legacy name, delete its alias.

   These are declared on :root, which IS the <html> element, the same element
   [data-theme="light"] matches. var() resolves against that element's computed
   custom properties, so `--white: var(--foreground)` picks up whichever
   --foreground won the cascade. One declaration is therefore correct in both
   themes, and 21-theme-radzen.css no longer needs a second literal copy.

   Still referenced by markup this layer does not own (19 page-local <style>
   blocks and ~60 inline style attributes):
     --overlay 45, --white 40, --green 22, --gray-500 18, --gray-400 14,
     --gray-300 1, --green-dim 1, --bg-elevated 1.

   Zero references anywhere as of this pass, and therefore free to delete once the
   page migration settles: --bg, --bg-card, --black, --cyan, --yellow, --purple,
   --gray-100, --gray-200, --gray-600, --gray-700, --gray-800. They are kept for
   now only because several pages are being migrated concurrently and a name that
   vanishes mid-run is a confusing failure.
   ============================================================================ */
:root {
    --bg: var(--background);
    --bg-elevated: var(--surface);
    --bg-card: var(--card);
    --black: var(--background);

    /* The ink ramp. In the old naming these got lighter as the number fell; the
       roles carry that meaning now, so 100-300 are all "text" and 600-800 are
       "lines and sunken surfaces" in both themes. */
    --white: var(--foreground);
    --gray-100: var(--foreground);
    --gray-200: var(--foreground);
    --gray-300: var(--foreground);
    --gray-400: var(--foreground-muted);
    --gray-500: var(--foreground-subtle);
    --gray-600: var(--border-strong);
    --gray-700: var(--border);
    --gray-800: var(--surface);

    --green: var(--primary);
    --green-dim: var(--primary-subtle);
    --yellow: var(--warning);
    --cyan: var(--info);
    --purple: var(--chart-3);
}
