/* Copyright (c) 2026 Goldeneye Technologies LLC. All rights reserved. */
/**************************************************************************/
/********  Design tokens (interim — retuned under Branding milestone)  ****/
/**************************************************************************/
/* Single source of truth for palette, typography, spacing, radii,
   shadows, and motion. Linked from base.html before every other stylesheet
   so downstream rules can `var(--token)` against these values.

   Scope note: the map percent-change diverging color scale
   (MapModule.updateStyles `pct -> rgb()` in static/js/main.js) is
   intentionally NOT tokenized here — the Phase 0 Accessibility milestone
   owns the colorblind-safe palette redesign for that surface.
*/
:root {
  /* ---- Palette: warm-neutral with the Tickerscape brand teal accent ---- */
  --color-bg:            #f7f7f5;   /* page background, off-white */
  --color-bg-elevated:   #ffffff;   /* cards, dropdowns, suggestions */
  --color-bg-muted:      #ececea;   /* footer, code, subtle fills */
  --color-bg-hover:      #ededeb;   /* generic hover surface */
  --color-text:          #1f1f23;   /* primary text, dark grey */
  --color-text-muted:    #5b5b63;   /* secondary text, labels */
  --color-text-inverse:  #ffffff;   /* on dark / accent surfaces */
  --color-border:        #d9d9d2;   /* hairline/divider borders (decorative; 1.4.11-exempt) */
  --color-border-strong: #8c8c82;   /* input/control boundary; AA 1.4.11 >=3:1 on bg + bg-elevated (was #b6b6ad = 1.9:1) */
  --color-accent:        #0a6b78;   /* Tickerscape brand teal (was #06c); link + primary action. AA: 6.2:1 on white, 5.8:1 on --color-bg, 5.2:1 on --color-bg-muted, and white-on-accent = 6.2:1 (all >=4.5). Darkened from the brighter cartographic teal so it clears AA on the muted support-button surface (the brighter #0a7d8c failed there at 4.1:1). */
  --color-accent-hover:  #08545e;   /* accent darker step (8.6:1 on white) */
  --color-focus-ring:    #0a6b78;   /* keyboard focus indicator = brand teal; solid for AA 1.4.11 >=3:1 (6.2:1 on white) */

  /* Status palette mirrors flash classes (global.css `.flash.*`). */
  --color-success-bg:    #efe;
  --color-success-text:  #060;
  --color-info-bg:       #eef;
  --color-info-text:     #009;
  --color-error-bg:      #fee;
  --color-error-text:    #900;

  /* Side nav: brand-tinted dark teal (Prompt 8, 2026-06-26 — was neutral
     near-black #1a1a1d). A very dark desaturated teal so the rail reads as part
     of the Tickerscape colorway without becoming a bright teal that would wreck
     the light-grey nav text. AA preserved: text #a8a8a8 on #122a2f = 6.3:1,
     white = 15:1 (both well above 4.5). The brand teal accent is NOT used as
     nav text (it's only 2.4:1 here); the nav focus ring is inverse-white via the
     sidenav-scoped :focus-visible rule in content_sideNav.css. */
  --color-sidenav-bg:        #122a2f;
  --color-sidenav-text:      #a8a8a8;
  --color-sidenav-text-hover:#ffffff;
  --color-sidenav-bg-hover:  #1d3a40;
  --color-sidenav-divider:   #21424a;

  /* ---- Typography (system font stack per Q8) ---- */
  --font-family-base:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
    Ubuntu, Cantarell, "Helvetica Neue", Arial, "Apple Color Emoji",
    "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
  --font-family-mono:
    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    "Liberation Mono", monospace;

  --font-size-xs:   12px;
  --font-size-sm:   13px;
  --font-size-base: 15px;
  --font-size-lg:   17px;
  --font-size-xl:   20px;
  --font-size-2xl:  28px;

  --line-height-tight: 1.25;
  --line-height-base:  1.55;

  --font-weight-regular:  400;
  --font-weight-medium:   500;
  --font-weight-semibold: 600;

  /* ---- Spacing scale (4 px base) ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 48px;

  /* ---- Radii ---- */
  --radius-sm: 3px;
  --radius-md: 5px;
  --radius-lg: 8px;

  /* ---- Shadows ---- */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12);

  /* ---- Motion ---- */
  --transition-base: 0.2s ease;

  /* ---- Breakpoints (documentation only) ----
     CSS custom properties don't work inside @media query conditions
     (parser-level limitation); these values are documentation hooks for
     the convention, not consumed at runtime. Downstream rules write the
     px value directly: @media (max-width: 768px) { ... } is mobile;
     @media (min-width: 769px) { ... } is desktop. Single boundary —
     no tablet-specific tier (Q1 default; see the 2026-06-22 mobile chunk).

     P21 (2026-08-21) added a SECOND branch to the mobile condition, and it is
     deliberately not a width. 768px is a width boundary, and a phone in
     landscape is WIDE — 844x390 (iPhone 14), 852x393 (15 Pro), 956x440
     (16 Pro Max) — so every modern iPhone fell OUT of the mobile lane when
     rotated and rendered the desktop layout. Every mobile block in this
     codebase therefore now reads:

         @media (max-width: 768px),
                (orientation: landscape) and (max-height: 500px) and (pointer: coarse)

     `max-height: 500px` because the scarce axis in landscape is the height
     (every iPhone in landscape is 375-440px tall; every iPad is 744px+), and
     `pointer: coarse` so a resized DESKTOP window never enters the mobile
     lane. The JS mirror of this string is modules/viewport.js::MOBILE_MQ —
     which carries the full rationale and is the one definition JS gates
     import. Keep the two in sync; CSS cannot import the constant.
  */
  --breakpoint-md: 768px;
  --breakpoint-landscape-max-height: 500px;

  /* ---- Layer scale (documentation only) ----
     Written out here because z-index is the one property in this project whose
     correctness spans files, and because it silently stopped being readable for
     a while: `#content_main.main_unpinned` used to be `position: relative;
     z-index: 0`, a STACKING CONTEXT around the whole page. Every number
     declared inside it was therefore compared only against its siblings, never
     against the body-level chrome — so the hamburger painted over the chart
     overlay and the info panel despite being the smaller number, while
     `#data_table_overlay` (appended to <body> by JS, not in the template) was
     the one modal that escaped and behaved as written. That z-index is gone
     (2026-08-21) and the scale below is now the literal paint order.

     Nothing forms a stacking context between <body> and these elements, so
     ADDING one anywhere in that chain re-breaks the whole scale. Check for that
     first if layering ever looks wrong again.

        10000  .skip-link
         2100  .flash-toast              runtime notice, must clear the modals
         2000  #chart_overlay, #data_table_overlay, #shortcuts_overlay
         1400  #content_sideNav (drawer, mobile)
         1399  #sidenav_backdrop
         1350  .flash-overlay, .campaign-banner    transient map notices
         1250  #search_suggestions       ABOVE the panel: a clipped dropdown is unusable
         1200  .info (bottom / side sheet)
         1150  #search_input, .sidenav-hamburger,
               #content_sideNav (desktop rail)      chrome yields to page content
         1100  .map-more-tools, .map-tooltip
        <=1000 Leaflet panes + controls (Leaflet's own cap)
            1  #footer (mobile; outranks the positioned #content_main)

     The desktop rail sat at 10 until 2026-08-21 and that was the one value the
     removal above actually broke: while #content_main was a stacking context
     the whole map painted at 0, so 10 cleared it; once the context went away
     Leaflet's panes (400) and controls (1000) competed directly and the rail
     painted behind the map. It is chrome, so it joins the hamburger at 1150
     rather than going above the info panel — on desktop the two never overlap
     (rail left, panel right), and the hamburger is the same control at the
     mobile breakpoint. Anything else declared below 1000 that must clear the
     map has the same latent bug.

     The operator-set rule these follow: chart overlay > info panel >
     hamburger / search bar. The two deliberate splits are #search_suggestions
     (above the panel while its input is below it) and the nav drawer + backdrop
     (above the panel, because an open drawer is modal).
     Values are written literally at each site — custom properties would work
     here, but keeping one number per declaration site matches the rest of the
     file's convention for layout constants. <JAS 2026-08-21> */
}
