/* ==========================================================================
   QRMask Panel — design tokens
   --------------------------------------------------------------------------
   A neutral, Material 3-flavoured system. Every component in app.css consumes
   these tokens and nothing else; no page or component declares a raw colour,
   spacing value or radius. That is what makes "uniform theme across all
   features" a structural property rather than a convention.

   Two rules keep this honest:

   1. COLOURS ARE SEMANTIC, NOT DECORATIVE. --primary, --on-primary,
      --surface, --on-surface, --outline. A component picks a role, never a hue.

   2. HOVER IS A STATE LAYER, NOT A NEW COLOUR. Material derives hover/press by
      overlaying the foreground colour at low alpha. --state-hover / --state-press
      encode that, so a variant cannot invent its own hover - which is exactly the
      class of bug that made the old primary button's hover look broken.
   ========================================================================== */

:root {
    color-scheme: dark;

    /* --- Accent hue -------------------------------------------------------
       One knob for the whole product. Everything derived from it stays
       consistent because nothing else picks a hue.

       199 is the brand hue: the electric cyan of the QRMask PH mark and cover
       art, not a generic UI blue. Changing it re-derives primary, containers
       and the focus ring in both themes at once - and ContrastTest re-measures
       every pair against the new values. */
    --accent-h: 199;

    /* --- Primary -------------------------------------------------------- */
    --primary: hsl(var(--accent-h) 92% 62%);
    --on-primary: #04222e;
    --primary-container: hsl(var(--accent-h) 55% 22%);
    --on-primary-container: hsl(var(--accent-h) 90% 88%);

    /* --- Surfaces (dark: raised surfaces get lighter) --------------------
       Navy-black rather than neutral black, to match the brand's night-sky
       cover art. The tint is slight on purpose: enough to read as the same
       product as the logo, not enough to tint white text. */
    --bg: #0b0f16;
    --surface: #10161f;
    --surface-container: #151c26;
    --surface-container-high: #1b2330;
    --surface-container-highest: #232c3b;

    --on-surface: #e4e8ef;
    --on-surface-variant: #c0c7d2;
    --on-surface-dim: #8b93a1;

    /* Measured, not eyeballed: ContrastTest requires 3:1 for a control boundary (WCAG
       1.4.11). The previous #44424d measured 1.81:1 on --surface - invisible as an input
       border to anyone with low vision, which is precisely the boundary that identifies
       the control. */
    --outline: #616b7a;
    --outline-variant: #2c3542;

    /* --- Semantic -------------------------------------------------------- */
    --success: #7ad99a;
    --success-container: #14351f;
    --on-success-container: #a6f0bd;

    --warning: #efbf6b;
    --warning-container: #3a2b0d;
    --on-warning-container: #ffe0a8;

    --danger: #ef9d9a;
    --danger-container: #40171a;
    --on-danger-container: #ffcfcf;

    /* --- State layers (Material 3) --------------------------------------- */
    --state-hover: 0.08;
    --state-focus: 0.10;
    --state-press: 0.12;
    --state-drag: 0.10;

    /* --- Spacing: a strict 4px grid --------------------------------------
       Only these values may be used for padding, gap and margin. That is what
       stops the "inconsistent spacing" problem at the source. */
    --s-1: 0.25rem;  /*  4 */
    --s-2: 0.5rem;   /*  8 */
    --s-3: 0.75rem;  /* 12 */
    --s-4: 1rem;     /* 16 */
    --s-5: 1.5rem;   /* 24 */
    --s-6: 2rem;     /* 32 */
    --s-7: 3rem;     /* 48 */
    --s-8: 4rem;     /* 64 */

    /* Sub-grid values. A 4px scale has no answer for a 1px separator or the 2px
       breathing room inside a dense chip, so they get names too - otherwise
       "use the tokens" quietly becomes "use the tokens except when it's fiddly",
       which is how inconsistent spacing creeps back in. */
    --hairline: 1px;
    --s-hair: 2px;

    /* --- Type scale ------------------------------------------------------ */
    /* Inter and Roboto are named first so a machine that already has them renders closer
       to the brand, and neither is ever FETCHED: there is no @font-face and no webfont
       link anywhere (D18). On a machine without them this resolves to the OS UI font,
       which is the intended outcome, not a fallback failure - so do not "fix" the
       apparent mismatch by adding a download. */
    --font-sans: "Inter", "Roboto", ui-sans-serif, system-ui, -apple-system,
        "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    --font-mono: ui-monospace, "SFMono-Regular", "Cascadia Mono", "Segoe UI Mono",
        Menlo, Consolas, monospace;

    --fs-label: 0.75rem;     /* 12 */
    --fs-body: 0.875rem;     /* 14 */
    --fs-body-lg: 1rem;      /* 16 */
    --fs-title: 1.125rem;    /* 18 */
    --fs-headline: 1.5rem;   /* 24 */
    --fs-display: 2rem;      /* 32 */

    --fw-normal: 400;
    --fw-medium: 500;
    --fw-semibold: 600;

    --lh-tight: 1.25;
    --lh-normal: 1.5;

    --tracking-tight: -0.015em;
    --tracking-normal: 0;
    --tracking-wide: 0.04em;

    /* --- Shape ----------------------------------------------------------- */
    --r-xs: 4px;
    --r-sm: 8px;
    --r-md: 12px;
    --r-lg: 16px;
    --r-xl: 24px;
    --r-full: 999px;

    /* --- Elevation (Material levels, tuned for dark) --------------------- */
    --e-0: none;
    --e-1: 0 1px 2px rgb(0 0 0 / 0.40), 0 1px 3px 1px rgb(0 0 0 / 0.20);
    --e-2: 0 1px 2px rgb(0 0 0 / 0.40), 0 2px 6px 2px rgb(0 0 0 / 0.20);
    --e-3: 0 1px 3px rgb(0 0 0 / 0.40), 0 4px 8px 3px rgb(0 0 0 / 0.20);
    --e-4: 0 2px 3px rgb(0 0 0 / 0.40), 0 8px 20px 6px rgb(0 0 0 / 0.24);

    /* --- Motion ---------------------------------------------------------- */
    --ease-standard: cubic-bezier(0.2, 0, 0, 1);
    --ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
    --t-fast: 100ms;
    --t-base: 180ms;
    --t-slow: 300ms;

    /* --- Layout ---------------------------------------------------------- */
    --shell-max: 1200px;
    --header-h: 64px;
    --drawer-w: 288px;
    --touch-min: 44px;   /* WCAG 2.5.8 minimum target size */
}

/* --------------------------------------------------------------------------
   Light theme — token overrides only.
   In Material, light surfaces get DARKER as they rise; dark surfaces get
   lighter. Both directions read as "closer to the viewer".
   -------------------------------------------------------------------------- */
[data-theme="light"] {
    color-scheme: light;

    /* The brand cyan darkened until it carries 14px text on white. The glow colour
       itself is far too light for type; ContrastTest holds this at 4.5:1. */
    --primary: hsl(var(--accent-h) 88% 30%);
    --on-primary: #ffffff;
    --primary-container: hsl(var(--accent-h) 85% 92%);
    --on-primary-container: hsl(var(--accent-h) 75% 16%);

    /* Cool whites, the same family as the dark theme's navy rather than a warm
       paper tone, so the two themes read as one product. */
    --bg: #f4f7fa;
    --surface: #ffffff;
    --surface-container: #f7f9fb;
    --surface-container-high: #eef2f6;
    --surface-container-highest: #e5eaf0;

    --on-surface: #16191d;
    --on-surface-variant: #41474f;
    /* Was #6f747c, measured 4.31:1 on --bg - under the 4.5:1 that 12px hint text needs. */
    --on-surface-dim: #676c74;

    /* Was #c3c6cf, measured 1.71:1 on --surface: an input border that was decoration
       rather than a boundary. ContrastTest holds this at 3:1 or better. */
    --outline: #878c95;
    --outline-variant: #dde3ea;

    --success: #146c2e;
    --success-container: #d3f0d9;
    --on-success-container: #0b3d19;

    --warning: #8a5300;
    --warning-container: #ffe7c2;
    --on-warning-container: #4d2e00;

    --danger: #b3261e;
    --danger-container: #fcd8dc;
    --on-danger-container: #6d1a15;

    --e-1: 0 1px 2px rgb(16 24 40 / 0.06), 0 1px 3px 1px rgb(16 24 40 / 0.08);
    --e-2: 0 1px 2px rgb(16 24 40 / 0.06), 0 2px 6px 2px rgb(16 24 40 / 0.08);
    --e-3: 0 1px 3px rgb(16 24 40 / 0.08), 0 4px 8px 3px rgb(16 24 40 / 0.10);
    --e-4: 0 2px 3px rgb(16 24 40 / 0.08), 0 8px 20px 6px rgb(16 24 40 / 0.12);
}

/* --------------------------------------------------------------------------
   Reduced motion — honour the OS setting rather than animating anyway.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    :root {
        --t-fast: 0ms;
        --t-base: 0ms;
        --t-slow: 0ms;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
