/*
Design tokens -- step 1 of 4 toward the redesigned Strategy Builder
(docs/design/strategy-builder-concept.html, built and reviewed in Strategy
chat). This file defines ONLY the shared custom properties every page draws
from; no component styling lives here (see templates/base.html for how the
base template consumes these, and each page's own <style> block for
anything still page-specific).

--- Platform-core migration (2026-08-31): values now come from charting-v1 ---

Colors, spacing and radius below are ported VERBATIM from charting-v1's own
design tokens -- read directly from that repo's
static/charting/css/app.css (its :root block, its
`@media (prefers-color-scheme: dark)` block, and its `:root[data-theme=
"dark"]` block, which are identical to each other). charting-v1's own header
comment there says it "extends StockProof's... system directly: same
tokens" -- confirmed by diffing against stockproof/screener/static/screener/
css/app.css's own :root block, which carries the identical color/spacing/
radius values under the same names. Either source repo would have produced
the same numbers; charting-v1 was read because it additionally carries the
chart-specific tokens this app's SVG payoff diagrams were checked against
(see analytics/payoff_chart.py -- NOT adopted there; see that module's own
docstring for why).

This is a VALUE swap, not a restructuring: every custom property name below
(--bg, --accent, --profit, etc.) is unchanged from before this migration, so
no template needed editing -- every `var(--accent)` etc. already scattered
across this app's templates now simply resolves to the platform's real
color instead of this app's own one-off palette.

--- The name mapping (fo-analytics name -> charting-v1 source token) ---

  --bg / --bg-elevated       -> --paper / --surface
  --surface / --surface-alt  -> --surface  (charting-v1 itself uses ONE
                                 surface tone for chrome, cards AND form
                                 inputs -- confirmed: its own `.masthead`
                                 and `input, select, textarea` rules both
                                 read plain var(--surface), no second
                                 "alt" tier exists to port. So bg-elevated,
                                 surface and surface-alt all resolve to the
                                 SAME value here -- this collapses a
                                 four-tier ground system this app invented
                                 into the real, three-tier one (paper /
                                 surface, plus the recessed paper-deep this
                                 app has no slot for) the platform actually
                                 has. Not a compromise: porting verbatim
                                 into a token set with fewer real tiers than
                                 this app's names imply necessarily collapses
                                 some of them.)
  --border / --border-strong -> --rule / --rule-strong
  --text                     -> --ink
  --text-muted / --text-faint -> --slate  (charting-v1 has one muted-text
                                 tier, not two; same collapsing reasoning
                                 as the surface tiers above)
  --accent / --accent-strong -> --verified / --verified-ink  (charting-v1's
                                 OWN .btn is background:var(--verified),
                                 hover:var(--verified-ink) -- the identical
                                 base-then-darker-on-hover shape this app's
                                 .btn-primary already has, so this is the
                                 role-correct pairing, not the reverse
                                 pairing charting-v1 happens to use for
                                 plain text links (--verified-ink default,
                                 --verified on hover) -- this app collapses
                                 both roles onto one pair, and the button
                                 fill's contrast requirement against
                                 --on-accent is the harder constraint the
                                 two variants were actually tuned for.)
  --accent-soft / --profit-soft -> a low-alpha tint of --verified, matching
                                 charting-v1's own --verified-tint pattern
                                 (rgba(var(--verified-rgb), 0.08)) exactly --
                                 inlined here as a literal rgba(), matching
                                 this file's own existing convention of not
                                 keeping a separate rgb-components token.
  --profit                   -> --verified-ink  (charting-v1's own
                                 `.gain { color: var(--verified-ink) }`,
                                 read directly, not inferred)
  --loss / --loss-soft        -> --risk / a tint of --risk
                                 (rgba(var(--risk-rgb), 0.09), matching
                                 charting-v1's own --risk-tint alpha;
                                 `.loss { color: var(--risk) }`, also read
                                 directly)
  --on-accent (NEW)          -> --on-accent, verbatim. Replaces the 3
                                 hardcoded on-accent-fill text colors
                                 (#181104 / #100b02) templates/base.html
                                 carried before this migration -- those were
                                 tuned against the OLD amber accent and are
                                 not correct against the new teal one, so
                                 leaving them hardcoded would have shipped
                                 wrong contrast, not merely an unported
                                 value.

--attention (charting-v1's warning/amber token) is NOT ported: this app has
no existing --warning-shaped token slot and no template currently reaches
for one, so there is nothing here for it to replace. Adding an unused token
would be inventing new structure, not porting an existing one -- left out on
purpose, not missed.

--- Spacing and radius: newly available, not yet wired into any template ---

--s1..--s7 and --r/--r-lg below are new to this app -- ported verbatim as
NUMBERS (0.25rem..3rem / 3px,6px), same as charting-v1's own scale, and are
now genuinely available for future component work to draw from. This pass
does NOT retrofit the ~15 templates' own hardcoded padding/gap/border-radius
literals to consume them: unlike the color tokens (already var()-driven
everywhere, so a values-only swap propagates automatically with zero other
file changes), no template currently references a spacing/radius custom
property at all, so "adopting" the scale would mean auditing and rewriting
dozens of hardcoded rem/px values across every page's own <style> block --
exactly the high-blast-radius, low-margin-for-error change this migration
was scoped to avoid, and squarely the surface area of this app's two
just-finished rounds of responsive-breakpoint work (the .scroller pattern,
the card-grid flex-wrap fix, the .tpl-card containing-block fix). Left as a
deliberate follow-up, not a partial/silent attempt.

--- Dark is the DEFAULT, not the media-query branch (unchanged) ---

Every page in this product already renders on a plain black background
today (base.html's `color-scheme: light dark` plus the browser's own UA
dark styling -- see the screenshots taken before this change). Putting dark
values in the bare `:root` and light values behind
`@media (prefers-color-scheme: light)` keeps that as the literal default
for anyone whose OS/browser reports no preference at all, rather than
silently switching every existing user to a light theme they never had.
This structural choice is unchanged by the platform-core migration -- only
the VALUES inside each block moved.

--- Both blocks resolve completely on their own (unchanged) ---

Neither block is a partial diff against the other: the light media query
below restates EVERY color token with its own light value rather than
overriding only the ones that differ, so reading either block alone tells
you the whole palette for that mode. No color here is defined only inside a
media query with no bare-:root fallback. --s1..--s7/--r/--r-lg are the one
exception, deliberately: they do not change between light and dark (neither
do charting-v1's own), so they are declared once in the bare :root only.

--- [data-theme] toggle (nav shell, Phase 2): added on top of the same structure ---

The token migration above left this file prefers-color-scheme-only on
purpose ("no toggle wiring in this pass"). The toggle itself -- the actual
control, the cookie, the view that sets it -- is base.html's and accounts/
theme.py's job; this file's only job is to make an explicit `data-theme`
choice on <html> actually override the OS preference. Ported from
charting-v1's app.css mechanism, but MIRRORED, not copied verbatim:
charting-v1 is light-default, so it only needs one explicit override block,
for `[data-theme="dark"]`, guarded with `:not([data-theme="light"])` on its
dark media query. This file is dark-default (the opposite), so it needs the
inverse: one explicit override block for `[data-theme="light"]`, and the
existing `@media (prefers-color-scheme: light)` block gets a
`:not([data-theme="dark"])` guard so an explicit dark choice can suppress a
light OS preference. No explicit `[data-theme="dark"]` block exists here,
by the same reasoning charting-v1 has no explicit `[data-theme="light"]`
one: it would just restate the bare :root default, and the guard above
already stops a light OS preference (or a light data-theme) from
overriding it. Verified against all 4 real combinations (cookie set or
not, times OS light or dark) before shipping, not assumed from the
symmetry alone.

--- Elevation and the deep ground plane (homepage / builder rail, 2026-09-01) ---

Three tokens added, all ported from the SAME charting-v1 source block the
color/spacing/radius values above came from, under this file's own existing
naming convention (charting-v1's --paper -> this app's --bg, so its
--paper-deep becomes --bg-deep here; --shadow-1/--shadow-2 keep their names,
which are already role names rather than palette names).

  --shadow-1 / --shadow-2  -> charting-v1's own --shadow-1/--shadow-2,
                              verbatim values (0 2px 6px .08 + 0 1px 2px .06,
                              and 0 4px 12px -6px .18). charting-v1 writes
                              them as rgba(var(--ink-rgb), a); this file has
                              no *-rgb tokens and its own documented
                              convention is to inline the literal rgba (see
                              --accent-soft/--loss-soft above), so the ink
                              triplet is inlined PER THEME: 231,234,240 for
                              dark's --text, 24,34,49 for light's. That
                              per-theme split is the point, not an
                              embellishment -- charting-v1 shipped a bug here
                              where --ink-rgb was hardcoded to light mode's
                              value, making a black-on-near-black shadow
                              invisible in dark mode, and fixed it at source
                              by giving dark its own real triplet. Porting the
                              fixed behaviour rather than the broken one.
  --bg-deep                -> charting-v1's --paper-deep, verbatim values
                              (#0B0F16 dark / #E5E8E2 light). One step below
                              --bg: a deeper ground so a full-width band (the
                              homepage trust strip) sits ON something rather
                              than sharing the page's own ground. In dark --
                              this app's default -- that reads as a genuinely
                              darker band; in light it is the deeper paper
                              tone, which is the same ROLE rendered in the
                              light palette, and is what charting-v1's own
                              light-default usage of it looks like.

Unlike --s1..--s7/--r above, these three ARE consumed by the templates added
in the same change (home.html's trust strip and cards, strategy_build.html's
template cards) -- they are not another available-but-unwired addition.
*/

:root {
  --bg: #10151E;
  --bg-elevated: #1A2330;
  --surface: #1A2330;
  --surface-alt: #1A2330;
  --border: #202A38;
  --border-strong: #2E3A4B;

  --text: #E7EAF0;
  --text-muted: #94A1B3;
  --text-faint: #94A1B3;

  --accent: #2FC7AF;
  --accent-soft: rgba(47, 199, 175, .08);
  --accent-strong: #5FDCC7;

  --profit: #5FDCC7;
  --profit-soft: rgba(47, 199, 175, .08);
  --loss: #F28B7D;
  --loss-soft: rgba(242, 139, 125, .09);

  --on-accent: #10151E;

  --bg-deep: #0B0F16;
  --shadow-1: 0 2px 6px rgba(231, 234, 240, .08), 0 1px 2px rgba(231, 234, 240, .06);
  --shadow-2: 0 4px 12px -6px rgba(231, 234, 240, .18);

  --s1: 0.25rem; --s2: 0.5rem; --s3: 0.75rem; --s4: 1rem;
  --s5: 1.5rem; --s6: 2rem; --s7: 3rem;
  --r: 3px; --r-lg: 6px;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #EEF0EC;
    --bg-elevated: #FBFCFA;
    --surface: #FBFCFA;
    --surface-alt: #FBFCFA;
    --border: #D7DBD5;
    --border-strong: #BFC5BD;

    --text: #182231;
    --text-muted: #5B6572;
    --text-faint: #5B6572;

    --accent: #0E6E63;
    --accent-soft: rgba(14, 110, 99, .08);
    --accent-strong: #0A5751;

    --profit: #0A5751;
    --profit-soft: rgba(14, 110, 99, .08);
    --loss: #A23B2E;
    --loss-soft: rgba(162, 59, 46, .09);

    --on-accent: #FFFFFF;

    --bg-deep: #E5E8E2;
    --shadow-1: 0 2px 6px rgba(24, 34, 49, .08), 0 1px 2px rgba(24, 34, 49, .06);
    --shadow-2: 0 4px 12px -6px rgba(24, 34, 49, .18);
  }
}

/* The one explicit override this direction needs: an explicit `light`
   choice must win even when the OS itself prefers dark (the media query
   above never even evaluates in that case). No explicit `[data-theme=
   "dark"]` block exists by design -- see the header comment above. */
:root[data-theme="light"] {
  --bg: #EEF0EC;
  --bg-elevated: #FBFCFA;
  --surface: #FBFCFA;
  --surface-alt: #FBFCFA;
  --border: #D7DBD5;
  --border-strong: #BFC5BD;

  --text: #182231;
  --text-muted: #5B6572;
  --text-faint: #5B6572;

  --accent: #0E6E63;
  --accent-soft: rgba(14, 110, 99, .08);
  --accent-strong: #0A5751;

  --profit: #0A5751;
  --profit-soft: rgba(14, 110, 99, .08);
  --loss: #A23B2E;
  --loss-soft: rgba(162, 59, 46, .09);

  --on-accent: #FFFFFF;

  --bg-deep: #E5E8E2;
  --shadow-1: 0 2px 6px rgba(24, 34, 49, .08), 0 1px 2px rgba(24, 34, 49, .06);
  --shadow-2: 0 4px 12px -6px rgba(24, 34, 49, .18);
}
