/* Design tokens — single source of truth for every page in this app.
   Linked by dashboard.html and analyzer.html. Previously this block was
   duplicated inline in both files and had already drifted: analyzer.html still
   carried --accent-blue #3b82f6 (4.82:1) while dashboard.html had been
   corrected to #6da6ed (7.03:1). Same token name, two meanings, one product.

   Values are solved in OKLCH against their actual surface, then emitted as hex
   so the rgba() tints derived from them stay coherent. Contrast figures in the
   comments are measured against --surface-raised, the tighter of the two
   surfaces. Do not "tidy" a value without re-measuring it. */

:root {
    /* --- Roles, not swatches ---------------------------------------
       Every value below was solved in OKLCH against its actual surface
       and then emitted as hex, so the derived rgba() tints elsewhere in
       this file stay coherent. Hue is preserved from the original
       palette; only lightness moved, and only where contrast failed.
       Colours already clearing AAA (warn, info) were left alone rather
       than dragged to a uniform number.

       Target is WCAG AAA (7:1) for anything carrying text, per
       PRODUCT.md. Measured on --surface-raised, the tighter of the two
       surfaces. */

    /* Surfaces */
    --surface-canvas: #090d16;
    --surface-raised: #111827;
    --surface-sunken: #0b1120;

    /* Borders. Two roles: decorative separation vs. a control boundary,
       which WCAG 1.4.11 requires to hit 3:1. The old single border at
       1.29:1 against the input made form fields nearly invisible.
       Solved against the RAISED surface, not the sunken one the control
       sits on: the two surfaces differ by only ~1.2:1, so the border is
       the sole delineation and has to clear 3:1 on the harder side. */
    --border-subtle: #1f293d;
    --border-control: #5e6671;   /* 3.05:1 on raised, 3.24:1 on sunken */
    /* Hover elevation. Used by three controls and the deal card; promoted to a
       token because it repeats, not because every value deserves one. It is a
       SURFACE, never text: at 1.72:1 against the raised surface it would be
       invisible as a foreground, while text sitting ON it measures 9.37:1. */
    --surface-hover: #374151;

    /* Text. --text-secondary is a TINTED NEUTRAL (chroma 0.012 toward
       the action hue), not a blue — it must never read as interactive. */
    --text-primary: #f3f4f6;     /* 16.12:1 */
    --text-secondary: #9ea4ab;   /*  7.06:1 — was #9ca3af at 6.99, just under AAA */

    /* Action. The only colour that means "you can click this". */
    --action: #6da6ed;           /*  7.03:1 — was #3b82f6 at 4.82 */
    /* Pressed / gradient-stop shade of the action role. Three uses, so it
       earns a token; it is never text, so its 3.43:1 is not a text failure. */
    --action-strong: #2563eb;

    /* State. pass/fail are deliberately staggered in LIGHTNESS, not just
       hue: solved to an identical 7:1 they had identical luminance, which
       erases the distinction under deuteranopia (separation 1.26 -> 1.58
       after staggering) and tritanopia (1.00 -> 1.32). */
    --state-pass: #3eb975;       /*  7.10:1 */
    --state-fail: #ebada5;       /*  9.34:1 */
    --state-warn: #f59e0b;       /*  8.26:1 — unchanged, already AAA */
    --state-info: #14b8a6;       /*  7.13:1 — unchanged, already AAA */
    /* Deliberately near-colourless: an unsourced number should look
       drained, not coloured. Fills the PRODUCT.md principle that
       estimated / verified / unavailable must be distinguishable. */
    --state-unverified: #808286; /*  4.61:1 */


    /* --- Type ------------------------------------------------------------
       Replaces Inter. PRODUCT.md names "generic dark SaaS template" as the
       primary anti-reference and Inter is that template's signature face; the
       mechanical scan flags it independently as saturated.

       IBM Plex was drawn for an engineering identity, which is the voice this
       product asked for — it states findings, it does not sell them.

       Plex Mono is not decoration. Every figure in this interface is a
       measurement in an aligned column, which is the one sanctioned use of
       monospace; it also disambiguates 0/O and 1/l in dense financial data.
       Sans and mono give genuine role contrast without a second identity. */
    --font-sans: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
    --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

    /* Role scale, replacing 12 arbitrary px values whose 1px neighbours
       (13/14, 16/17, 17/18, 18/19) could not carry distinct jobs.
       rem, not px, so user font-size settings are honoured.
       Floor is 12px: 11px was the single most-used size on the page. This
       sits below the 16px web default deliberately — PRODUCT.md makes density
       a stated feature — but 11px was indefensible even under that licence. */
    --text-2xs:  0.75rem;    /* 12px — column labels, metadata */
    --text-xs:   0.8125rem;  /* 13px — table figures */
    --text-sm:   0.875rem;   /* 14px — table body, reason text */
    --text-base: 1rem;       /* 16px — prose */
    --text-lg:   1.125rem;   /* 18px — card titles */
    --text-xl:   1.25rem;    /* 20px — section headings */
    --text-2xl:  1.375rem;   /* 22px */
    --text-3xl:  1.75rem;    /* 28px — KPI values */
    --text-4xl:  2.625rem;   /* 42px — the calculator's single hero result */

    /* Light text on a dark surface needs compensation on all three axes:
       a little more leading, a little more tracking, one more weight step.
       Applied as tokens so the compensation is consistent, not ad hoc. */
    --leading-tight: 1.3;
    --leading-body: 1.55;
    --tracking-label: 0.06em;   /* uppercase labels only */
    --tracking-tight: -0.01em;  /* large figures */

    /* --- Legacy aliases --------------------------------------------
       19 existing declarations reference the old names. Aliasing rather
       than renaming keeps this a colour change, not a refactor. */
    --bg-dark: var(--surface-canvas);
    --card-bg: var(--surface-raised);
    --input-bg: var(--surface-sunken);
    --border-color: var(--border-subtle);
    --text-main: var(--text-primary);
    --text-sub: var(--text-secondary);
    --accent-blue: var(--action);
    --accent-green: var(--state-pass);
    --accent-red: var(--state-fail);
    --accent-teal: var(--state-info);
    --accent-amber: var(--state-warn);
}
