/* ==========================================================================
   1. TOKENS - the single source of truth for this app's theme.
   Every rule in every page references these; no rule hardcodes a colour, a
   step of the type scale, a spacing step, a radius, a shadow or a timing.
   Changing the look of the whole site means editing this file and nothing else.

   It lives in its own file rather than inside index.html because the board is
   no longer the only page: /disclosures and /privacy load the same tokens, and
   a second copy of them is a second theme waiting to drift.

   Colour is written with light-dark(), which resolves against color-scheme,
   so the theme switch only has to pin that one property on <html>.
   Every text pair below is measured against WCAG 2.2 AA (4.5:1 body text,
   3:1 for control borders and graphical objects); the ratio is stated where
   the value was chosen to clear a specific bar.
   ========================================================================== */
:root {
  color-scheme: light dark;

  /* --- surface + ink ------------------------------------------------- */
  --page:      light-dark(#f9f9f7, #0d0d0d);
  --surface:   light-dark(#fcfcfb, #1a1a19);
  --surface-2: light-dark(#f2f1ec, #232322);   /* recessed wells: segmented, inputs */
  --ink:       light-dark(#0b0b0b, #f5f4f0);   /* 18.7:1 light / 17.7:1 dark */
  --ink-2:     light-dark(#4a4843, #c3c2b7);   /*  8.7:1 light / 10.9:1 dark */
  --muted:     light-dark(#6b6862, #94918a);   /*  5.3:1 light /  6.2:1 dark */

  /* --- lines ---------------------------------------------------------- */
  --ring:        light-dark(rgba(11,11,11,.10), rgba(255,255,255,.10)); /* decorative */
  --ring-strong: light-dark(#8a8780, #726f68);  /* 3.4:1 / 3.9:1 - control borders */
  --grid:        light-dark(#e1e0d9, #2c2c2a);  /* decorative rules inside tables */
  --baseline:    light-dark(#c3c2b7, #45443f);  /* chart baselines, section rules */

  /* --- meaning -------------------------------------------------------- */
  --up:     light-dark(#046b04, #3ec14a);   /* 6.4:1 / 8.3:1 */
  --down:   light-dark(#c02a2a, #f2726a);   /* 5.5:1 / 6.8:1 */
  /* Pre-market and after-hours legs of a chart line. Neutral by intent: those
     hours are thin, wide-spread trade, and drawing them in the up/down hue
     claimed the same standing as the session itself. Grey says "different
     regime" without hiding the move — the same grey as body-secondary text,
     so it stays legible at 2px in both themes. */
  --extended: var(--muted);
  --accent: light-dark(#8a5a00, #e0a33f);   /* 5.6:1 / 8.8:1 - the call / options accent */
  --focus:  light-dark(#1b6feb, #6aa8ff);   /* 4.4:1 / 8.0:1 */

  /* --- type scale ----------------------------------------------------- */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --t-2xs: 11px;  /* chart axis ticks, micro-captions */
  --t-xs:  12px;  /* captions, counts, hints */
  --t-sm:  13px;  /* secondary body, control labels */
  --t-md:  14px;  /* body */
  --t-lg:  16px;  /* ticker */
  --t-xl:  20px;  /* price */
  --t-2xl: 22px;  /* page title */
  --lh-tight:  1.25;
  --lh-snug:   1.4;
  --lh-normal: 1.5;
  --w-regular:  400;
  --w-medium:   500;
  --w-semibold: 600;
  --w-bold:     700;
  --track-tight: -.011em;   /* headings only */
  --track-caps:   .08em;    /* uppercase eyebrow labels */

  /* --- spacing scale (4px base) ---------------------------------------- */
  /* Two steps below the grid, for seams 4px is too coarse to express: the
     focus standoff, the gutter between bottom-bar tabs, a link's underline. */
  --s-hair: 2px;  --s-tick: 3px;
  --s-1:  4px;  --s-2:  8px;  --s-3: 12px;  --s-4: 16px;
  --s-5: 20px;  --s-6: 24px;  --s-7: 28px;  --s-8: 32px;
  --s-10: 40px; --s-12: 48px;

  /* --- radius ---------------------------------------------------------- */
  --r-sm: 6px; --r-md: 8px; --r-lg: 12px; --r-xl: 16px; --r-full: 999px;

  /* --- elevation -------------------------------------------------------- */
  --sh-1: 0 1px 2px light-dark(rgba(11,11,11,.05), rgba(0,0,0,.35));
  --sh-2: 0 1px 3px light-dark(rgba(11,11,11,.07), rgba(0,0,0,.45)),
          0 4px 12px light-dark(rgba(11,11,11,.05), rgba(0,0,0,.35));
  --sh-3: 0 8px 24px light-dark(rgba(11,11,11,.10), rgba(0,0,0,.55));
  --sh-4: 0 24px 64px light-dark(rgba(11,11,11,.18), rgba(0,0,0,.70));
  /* The phone bottom bar throws its shadow upward, onto the board it covers. */
  --sh-up: 0 -6px 24px light-dark(rgba(11,11,11,.12), rgba(0,0,0,.5));

  /* --- focus + blur ------------------------------------------------------ */
  --focus-w:    2px;   /* the ring itself; --s-hair is its standoff */
  /* A field's focus, as opposed to a button's. A hard rectangle drawn around a
     42px number sitting inside a rounded field is a box in a box - so a field
     shell answers focus by taking the focus colour on its own border and
     bleeding a soft halo off it, and the outline ring stays for the buttons. */
  --sh-focus:   0 0 0 3px light-dark(rgba(27,111,235,.20), rgba(106,168,255,.24));
  --blur-veil:  3px;   /* over a tile whose results never reached the feed */
  --blur-scrim: 6px;   /* behind an expanded tile */

  /* --- motion ----------------------------------------------------------- */
  --dur-1: 120ms;   /* colour / opacity feedback */
  --dur-2: 200ms;   /* small position + size changes */
  --dur-3: 300ms;   /* the expand transition */
  --dur-wait: 1600ms; /* one breath of the chart well while its data is in flight.
                         An order slower than the durations above on purpose:
                         they answer a hand, this only has to say "still coming"
                         without asking to be watched. */
  --ease-out: cubic-bezier(.2, .8, .2, 1);    /* entrances */
  --ease-in:  cubic-bezier(.4, 0, 1, 1);      /* exits */
  --ease-std: cubic-bezier(.4, 0, .2, 1);     /* state changes */

  /* --- component tokens -------------------------------------------------- */
  --control-h:    32px;   /* every pill / input / select in the chrome */
  --control-h-lg: 44px;   /* touch target on coarse pointers */
  --card-pad:     var(--s-5);
  --icon:         1em;
  --tile-ctl:     26px;   /* the star and expand buttons on a tile */
  --tile-ctl-lg:  32px;   /* ...and their coarse-pointer size */
  --tile-icon:    15px;
  --tile-icon-lg: 17px;
  --stripe:       3px;    /* the left edge marker: live call, or a verdict */
  --icon-md:      18px;   /* the pinned overlay close glyph */
  --axis-h:       18px;   /* the chart's tick strip */
  --search-w:     220px;  /* the search field in the chrome */
  /* The header's date/refresh line, held at the width it ends up at. It ships
     reading "Loading…" and fills in with "Wed, Sep 22 · prices updated 11:59 AM
     ET" - measured at 241px, the widest that format goes. Left to size itself
     the span grew from 55px to ~240px when the calendar landed, which re-wrapped
     the header and pushed the whole page down 30px: the board's second-largest
     layout shift. Reserving the filled width makes the first paint wrap where
     the filled one does. */
  --status-w:     244px;
  /* The market-session indicator, held at the width of its longest reading —
     "Market closed · opens Wed 9:30 AM ET", measured rendered at 266px. Same
     job as --status-w: it ships empty and fills in after the first paint, and a
     span that grows re-wraps the header row above the board. */
  --session-w:    266px;
  --fnum-w:       42px;   /* the numeric filter inputs - bare, inside a field shell */
  --fnum-w-lg:    50px;   /* ...on phones, where the type is larger */
  --mark-w:       26px;   /* the wordmark glyph, cut to the title's cap height */
  --mark-h:       23px;
  --ftoggle-h:    36px;   /* the filter disclosure on phones */
  --overlay-btn:  38px;   /* the close control on phones */
  --tap:          46px;   /* phone bottom-bar target */

  /* --- layout ------------------------------------------------------------- */
  --container:  1280px;   /* the board */
  --overlay-w:  1080px;   /* an expanded tile */
  --tile-min:     340px;  /* a board column's floor before it reflows */
  --fhead-w:      176px;  /* the filter head, held wide enough for "Filters · 5" + Clear */
  --fbody-w:      320px;  /* the dials' floor before they drop under the head */
  --settings-w:   320px;  /* the settings sheet */
  --settings-gap: 110px;  /* chrome the sheet must not grow under */
  --detail-col:   360px;  /* the options column inside an expanded tile */
  --news-col:     260px;  /* the news list's column floor */
  --chart-h-min:  220px;  /* the expanded tile's chart */
  --chart-h-max:  380px;
  --bottom-bar:    76px;  /* what the phone tab bar reserves under the board */
  --header-h:      72px;  /* sticky header, so scroll-margin clears it */
  /* These two are shared with app.js and must not drift from it: --chart-h is
     the SVG viewBox height in draw(), --hist-h the one in renderHistory(). The
     viewBox must match the rendered height because the chart is drawn with
     preserveAspectRatio="none" - let them diverge and every stroke is scaled
     unevenly, so vertical rules come out thinner than horizontal ones. */
  --chart-h:      128px;
  --hist-h:        24px;
}
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }
/* Set by applyTheme() for the single frame that swaps the scheme. A theme change
   repaints every token at once; easing half of them there splits controls into
   mismatched colour pairs mid-flight (see applyTheme in app.js). */
:root.theme-swap, :root.theme-swap *, :root.theme-swap *::before, :root.theme-swap *::after {
  transition: none !important;
}
