/* ============================================================================
   StoreVitals design tokens
   Source of truth for the tenant UI. See STYLE.md for usage rules.
   Light is the default theme; dark is available via OS preference or the
   manual toggle (data-theme attribute on <html>, set by js/theme.js).
   All color pairs used for text meet WCAG AA on their intended surface;
   chart/status hues validated with the dataviz palette validator.
   ========================================================================= */

/* ---- Display face ----
   ONE self-hosted variable woff2 (Space Grotesk, SIL OFL — see fonts/OFL.txt),
   bound to --font-display only: page h1, card h2, KPI values, headline/
   briefing, the donut center value. Body text, tables and every data surface
   stay on --font-sans's system stack, so there is still no build step, the
   app still works offline, and a blocked font is invisible rather than a
   layout break (font-display: swap + the system stack as fallback below). */
@font-face {
  font-family: "StoreVitals Display";
  src: url("fonts/space-grotesk-latin-var.woff2") format("woff2-variations");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---- Surfaces (chrome + 3 elevation levels + inset) ---- */
  /* Raised has to be BRIGHTER than the plane below it, so in light mode the
     split runs downward from white: cards sit a hair off-white and overlays
     keep pure white. mvp44 set both to #ffffff and left this comment (and
     STYLE.md) describing the #fcfcfd split it had just removed, so three
     documented levels were two again — the exact state mvp13 fixed. Restored,
     and the worst text pair on #fcfcfd is --down-text at 4.71:1.

     CHROME is the other direction. The sidebar, top bar and bottom bar used
     --surface-1, so navigation was painted the same white as the cards beside
     it and read as a full-height card with a hairline (mvp55). It now sits
     BELOW the page plane: chrome recedes, content lifts, and the eye goes to
     the numbers. Cards are deliberately untouched — mvp44 measured page->card
     against Plausible, Linear and Shopify and moved it from 1.036:1 to
     ~1.12:1 on purpose. */
  --surface-nav: #dde7ea;          /* chrome: sidebar, top bar, bottom bar */
                                   /* 1.124 against the page (mvp65). Was
                                      #e3ebed at 1.080, which is barely over
                                      the 1.05 the eye reads as one plane. */
  --surface-0: #eef3f4;            /* page plane, cool neutral */
  --surface-1: #fcfcfd;            /* cards, tables, panels */
  --surface-2: #ffffff;            /* raised: popovers, drawer, tooltips (paired with shadow) */
  --surface-inset: #e4edee;        /* recessed: chips, wells, skeletons */
  --scrim: rgba(6, 20, 23, .5);  /* behind every overlay: nav drawer, listing drawer */

  /* ---- Ink ---- */
  --text-primary: #0c1a1d;         /* 18.1:1 on surface-1 */
  --text-secondary: #3d5257;       /* 8.0:1 */
  --text-muted: #546a70;           /* 5.3:1 */

  /* ---- Hairlines ---- */
  --border: #d2e2e4;
  --border-strong: #b3cace;

  /* ---- Accent: teal (the ONE accent) ---- */
  --accent: #0d9488;               /* fills; 7.9:1 with white text */
  --accent-hover: #0f766e;
  --accent-press: #115e59;
  --accent-text: #0f766e;          /* as text on surface-1: 9.9:1 */
  --accent-tint: #d5f2ee;          /* tinted backgrounds, selected chips */
  --on-accent: #ffffff;
  --focus-ring: #0d9488;

  /* ---- Semantic movement (always paired with an arrow or sign) ---- */
  --up-text: #047857;              /* 5.5:1 on surface-1 */
  --up-tint: #d6f5e0;
  --down-text: #be123c;            /* 4.8:1 on surface-1 */
  --down-tint: #ffe0e5;
  /* Caution (mvp117): the amber between up and down, for traffic-light
     states (Listing Vitals). Never alone: always beside a word or a number. */
  --caution-text: #a14a04;          /* 5.9:1 on surface-1 */
  --caution-tint: #fdedc9;

  /* ---- Chart ---- */
  --chart-line: #0d9488;           /* revenue line = accent */
  --chart-line-2: #e0562f;         /* secondary series (visits/last-year), warm vs cool accent */
  --chart-up: #047857;             /* sparkline, rising */
  --chart-down: #be123c;           /* sparkline, falling */
  --chart-grid: #dbe8ea;
  --chart-axis-text: #546a70;

  /* ---- Categorical (3+ series: donuts, stacks, multi-line) ----
     Fixed hue order, never cycled. Re-derived in mvp44 by SIMULATING
     protanopia/deuteranopia/tritanopia and taking the closest pair in Lab,
     rather than by eye — two hand-curated "obviously distinct" sets scored
     WORSE than the set they were meant to replace, because hue separation
     reads as variety to a trichromat and collapses under simulation. It is
     lightness separation that survives.

     The floor is the worst pair across all four vision types, over BOTH
     series-vs-series and series-vs-movement — the second half is what enforces
     the reserved-hue rule below, and the first attempt at this palette missed
     it: a series red landed ΔE 4.3 from --down-text.

       Okabe-Ito, the reference standard ... 10.7
       this set, light ................... 13.7
       this set, dark .................... 13.6

     Dark is an INDEPENDENT search, not the light set lightened: lifting every
     colour onto a dark ground compressed them and dropped the worst pair to
     ΔE 2.5. Dark also holds >=3:1 against --surface-1.

     Never reuse --chart-up/--chart-down hues here — those stay reserved for
     movement, and that is now measured rather than trusted.

     **The SLOT ORDER was re-derived in mvp82 (S14); the SET is untouched.**
     The eight colours are exactly the ones mvp44 validated, so the worst pair
     anywhere in the set is unchanged — what moved is which slots sit NEXT to
     each other, and that is what a stacked bar or a donut actually asks a
     reader to tell apart. The old order walked the hue wheel (blue, violet,
     magenta, red, orange, amber, green, teal), which guarantees neighbours are
     neighbours in hue too: Explore's channel mix put Organic Search and Paid
     Shopping side by side in one stack as two near-identical red-browns, so
     invariant #11's letter was met by the legend and its intent was not.
     Maximising the worst ADJACENT pair over both themes and all four vision
     types, with blue pinned to slot 1, takes that pair from ~6 to ~28. */
  --cat-1: #4688d8;  /* blue */
  --cat-2: #a64517;  /* orange */
  --cat-3: #21cbc9;  /* teal */
  --cat-4: #dead30;  /* amber */
  --cat-5: #db2c8f;  /* magenta */
  --cat-6: #6bcd99;  /* green */
  --cat-7: #d96550;  /* red */
  --cat-8: #6e36a2;  /* violet */
  --cat-other: #8b9ba0;            /* fixed "Other" bucket, never a hue slot */

  /* ---- Type ---- */
  --font-display: "StoreVitals Display", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace; /* admin-only */

  /* type scale (1.25 ratio, 14px base) */
  --fs-xs: 11px;
  --fs-sm: 12.5px;
  --fs-base: 14px;
  --fs-md: 16px;
  --fs-lg: 20px;
  --fs-xl: 25px;
  --fs-2xl: 31px;

  --lh-tight: 1.25;
  --lh-base: 1.55;

  /* ---- Spacing scale ---- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;

  /* ---- Chrome metrics ----
     The mobile bottom bar's height, referenced by everything that has to sit
     clear of it (content padding, the Ask FAB, the Ask panel). It was three
     separate hardcoded `64px` calcs that had already drifted from the bar's
     real height. */
  --bottombar-h: 56px;

  /* ---- Radius ---- */
  --r-sm: 6px;                     /* chips, inputs */
  --r-md: 10px;                    /* cards, buttons */
  --r-lg: 14px;                    /* drawer, large panels */
  --r-full: 999px;                 /* pills */

  /* ---- Elevation ---- */
  --shadow-1: 0 1px 2px rgba(12, 26, 29, 0.07), 0 2px 6px rgba(12, 26, 29, 0.05);
  --shadow-2: 0 2px 4px rgba(12, 26, 29, 0.09), 0 8px 20px rgba(12, 26, 29, 0.09);
  --shadow-3: 0 8px 32px rgba(12, 26, 29, 0.18);

  /* ---- Motion ---- */
  --t-fast: 120ms ease;
  --t-base: 200ms ease;
  --t-slow: 320ms cubic-bezier(0.2, 0, 0, 1);
  --secondary: #e0562f;
  --secondary-text: #c2410c;
  --secondary-tint: #fdece5;
  --chart-area-from: rgba(13, 148, 136, .22);
  --chart-area-to: rgba(13, 148, 136, 0);
  --row-bar: rgba(13, 148, 136, .13);
  --row-bar-2: rgba(224, 86, 47, .13);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --surface-nav: #12181b;
    --surface-0: #1b2124;
    --surface-1: #242b2e;
    --surface-2: #2e3538;
    --surface-inset: #171c1f;
    --scrim: rgba(0, 0, 0, .62);

    --text-primary: #e3e8ea;       /* 13.8:1 on surface-1 */
    --text-secondary: #b3bec2;     /* 8.9:1 */
    --text-muted: #93a0a4;         /* 6.3:1 */

    --border: #333b3e;
    --border-strong: #465052;

    --accent: #2dd4bf;             /* 5.4:1 with dark on-accent text */
    --accent-hover: #5eead4;
    --accent-press: #14b8a6;
    --accent-text: #7fe7d8;        /* as text: 9.2:1 */
    --accent-tint: #133d39;
    --on-accent: #04211d;
    --focus-ring: #2dd4bf;

    --up-text: #a9de9c;
    --up-tint: #1d3e28;
    --down-text: #ff506b;
    /* NOT lifted with the others (mvp66). Red has the least luminance
       headroom here: a tint light enough to sit above the card drops
       `down-text` under AA, and the midpoint lands at 1.003 against the card,
       which is invisible. Left darker than the card, so the badge reads as
       recessed — the direction `--surface-inset` goes. */
    --down-tint: #3f1420;
    --caution-text: #f5c26b;
    --caution-tint: #3a2c10;

    --chart-line: #2dd4bf;
    --chart-line-2: #fb923c;
    --chart-up: #a9de9c;
    --chart-down: #f1415c;
    --chart-grid: #2f3639;
    --chart-axis-text: #8dacb2;

    --cat-1: #366ddd;  /* blue */
    --cat-2: #e49546;  /* orange */
    --cat-3: #70e2ee;  /* teal */
    --cat-4: #f3cd66;  /* amber */
    --cat-5: #cd5c95;  /* magenta */
    --cat-6: #4cbe75;  /* green */
    --cat-7: #cb4520;  /* red */
    --cat-8: #aa93de;  /* violet */
    --cat-other: #7d979d;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.55), 0 10px 24px rgba(0, 0, 0, 0.45);
    --shadow-3: 0 8px 32px rgba(0, 0, 0, 0.65);
    --secondary: #fb923c;
    --secondary-text: #fdba74;
    --secondary-tint: #4c3122;
    --chart-area-from: rgba(45, 212, 191, .26);
    --chart-area-to: rgba(45, 212, 191, 0);
    --row-bar-2: rgba(251, 146, 60, .16);
    --row-bar: rgba(45, 212, 191, .16);
  }
}

:root[data-theme="dark"] {
  --surface-nav: #12181b;
  --surface-0: #1b2124;
  --surface-1: #242b2e;
  --surface-2: #2e3538;
  --surface-inset: #171c1f;
  --scrim: rgba(0, 0, 0, .62);

  --text-primary: #e3e8ea;
  --text-secondary: #b3bec2;
  --text-muted: #93a0a4;

  --border: #333b3e;
  --border-strong: #465052;

  --accent: #2dd4bf;
  --accent-hover: #5eead4;
  --accent-press: #14b8a6;
  --accent-text: #7fe7d8;
  --accent-tint: #133d39;
  --on-accent: #04211d;
  --focus-ring: #2dd4bf;

  --up-text: #a9de9c;
  --up-tint: #1d3e28;
  --down-text: #ff506b;
  --down-tint: #3f1420;
  /* Caution (mvp117): the amber between up and down, for traffic-light
     states. Never alone: always beside a word or a number. */
  --caution-text: #f5c26b;
  --caution-tint: #3a2c10;

  --chart-line: #2dd4bf;
  --chart-line-2: #fb923c;
  --chart-up: #a9de9c;
  --chart-down: #f1415c;
  --chart-grid: #2f3639;
  --chart-axis-text: #8dacb2;

  --cat-1: #366ddd;  /* blue */
  --cat-2: #e49546;  /* orange */
  --cat-3: #70e2ee;  /* teal */
  --cat-4: #f3cd66;  /* amber */
  --cat-5: #cd5c95;  /* magenta */
  --cat-6: #4cbe75;  /* green */
  --cat-7: #cb4520;  /* red */
  --cat-8: #aa93de;  /* violet */
  --cat-other: #7d979d;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.55), 0 10px 24px rgba(0, 0, 0, 0.45);
  --shadow-3: 0 8px 32px rgba(0, 0, 0, 0.65);
  --secondary: #fb923c;
  --secondary-text: #fdba74;
  --secondary-tint: #4c3122;
  --chart-area-from: rgba(45, 212, 191, .26);
  --chart-area-to: rgba(45, 212, 191, 0);
  --row-bar: rgba(45, 212, 191, .16);
  --row-bar-2: rgba(251, 146, 60, .16);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --t-fast: 0ms;
    --t-base: 0ms;
    --t-slow: 0ms;
  }
}
