/* TradingVox design tokens: the single source of truth for every page in
   this app. Every template loads this file before style.css and must not
   redeclare fonts, colors, or radii locally — add a token here instead.
   Palette aligned to the EZPZ ecosystem identity: deep violet-black ground,
   electric violet as brand accent, warm amber as the "voice is active" accent. */
:root {
  color-scheme: dark;

  /* ---------- Surfaces ---------- */
  --bg: #0B0918;
  --bg-sunken: #060411;
  --bg-elevated: #1B1539;
  --bg-card: #141029;
  --bg-glass: rgba(27, 21, 57, 0.56);
  --bg-overlay: rgba(6, 4, 17, 0.86);
  --bg-orb-glow: #2C2158;  /* inner tint for the hero/voice orb radial gradients */

  /* ---------- Text ---------- */
  /* Three-step scale: --text for headlines/emphasis, --text-muted for body
     copy doing real work (descriptions, features, steps), --text-faint for
     truly decorative/secondary items (eyebrows, captions, small print). */
  --text: #F3F0FF;
  --text-muted: #DDD9F8;
  --text-faint: #B8B3D4;
  --text-on-accent: #17100A;

  /* ---------- Brand accent: electric violet, shared across the ecosystem ----------
     Restraint rule (2026 redesign): --accent/--voice/--data solid fills are for CTAs,
     active/selected states, and meaning-coded indicators (dots, badges, status pills)
     only — not decorative background washes, ambient orb glows, or hover-glow on every
     card. --accent-soft/--voice-dim/--data-dim (the low-opacity tints below) remain
     fine for subtle state backgrounds. Prefer --border-strong plus a small transform
     for generic card hover feedback; reserve --shadow-glow for the one or two moments
     per page that should feel like the primary action (hero CTA, connect button). */
  --accent: #9B6BFF;
  --accent-strong: #B189FF;
  --accent-dim: #6C4BC2;
  --accent-soft: rgba(155, 107, 255, 0.14);
  --accent-glow: rgba(155, 107, 255, 0.45);

  /* ---------- Accent: meaning-coded, not decorative ---------- */
  --voice: #FFB547;        /* voice/speaking state, gold, "moments that matter" */
  --voice-strong: #FFC978;
  --voice-light: #FFD79A;  /* lightest step, for gradient endpoints (e.g. .btn-primary) */
  --voice-dim: rgba(255, 181, 71, 0.14);
  --voice-glow: rgba(255, 181, 71, 0.45);
  --data: #3DDC97;         /* live data / positive */
  --data-strong: #2BB583;  /* darker step, for gradient endpoints */
  --data-dim: rgba(61, 220, 151, 0.14);
  --text-on-data: #06150F; /* body text on a --data/--data-strong surface */
  --data-down: #FF6B7A;    /* negative price movement */
  --data-down-dim: rgba(255, 107, 122, 0.14);
  --data-down-deep: #3A1F30; /* darker step, for the error-state orb gradient */

  /* ---------- Structure ---------- */
  --border: rgba(243, 240, 255, 0.12);
  --border-strong: rgba(243, 240, 255, 0.22);
  --border-hair: rgba(243, 240, 255, 0.08);
  /* Row hover inside a table/list — below --border-hair on purpose: a table
     row that lights up as strongly as a card border reads as selected rather
     than hovered. Added 2026-09-15 for the pricing differences table, which
     had this value inline. */
  --bg-row-hover: rgba(243, 240, 255, 0.025);
  /* Accent-tinted hairline for a tinted pill/badge sitting on --accent-soft.
     Between --accent-soft (0.14, the fill) and --accent (the solid), which is
     too loud as a border at badge size. Added 2026-09-15. */
  --border-accent: rgba(155, 107, 255, 0.25);
  /* The --voice counterpart, for a gold pill on a --voice-dim fill. Must be
     stronger than the fill it sits on (--voice-dim is 0.14) or the border is
     a no-op declaration. Added 2026-09-15. */
  --border-voice: rgba(255, 181, 71, 0.3);

  /* ---------- Type ---------- */
  --font-display: 'Bricolage Grotesque', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'JetBrains Mono', 'SFMono-Regular', Menlo, monospace;
  --font-body: 'Manrope', -apple-system, BlinkMacSystemFont, sans-serif;

  /* Type scale: don't introduce sizes outside this — reuse a step, or add
     a new one here. Bumped a full step up from a typical content-site scale
     on purpose: the
     brief is "app, not website", so the labels stay small (mono/eyebrow tags
     do the quiet work) while everything that carries meaning goes bigger and
     bolder than feels comfortable at first. That contrast is the point.

     Two families share this scale:
     - UI chrome (3xs/2xs/label/xs): badges, mono eyebrows, form labels,
       timestamps, fine print. Meant to read small — don't bump these to
       "fix" perceived smallness, that's their job.
     - Reading copy and titles (body-sm and up): anything a visitor reads
       at length or that names a section/card. --fs-sm (15px) is the floor
       for real paragraph text — nothing a user is meant to read at length
       should go below it. Titles step up cleanly h4 -> h3 -> h2 -> h1;
       reuse the matching step for a title rather than picking a one-off
       size. */
  --fs-3xs: 10px;   /* micro badges, pills, carets, tier tags */
  --fs-2xs: 11px;   /* mono eyebrows/labels, timestamps, micro caps */
  --fs-label: 12px; /* form labels, table headers, compact meta/hints */
  --fs-xs: 13px;    /* fine print, footnotes, secondary meta, small buttons */
  --fs-body-sm: 14px; /* dense secondary copy: inputs, list meta, table cells */
  --fs-sm: 15px;    /* standard paragraph copy — card descriptions, FAQ answers, nav */
  --fs-body: 16px;  /* prose / long-form reading copy */
  --fs-md: 17px;    /* default body base, emphasized copy, lead-in */
  --fs-lead: 18px;  /* lead paragraphs — hero subtext, section intros, CTA copy */
  --fs-h4: 18px;    /* card/component titles: feature cards, modals, list headers */
  --fs-lg: 21px;    /* stat numbers, chat/transcript emphasis text */
  --fs-xl: clamp(24px, 2.8vw, 30px); /* larger stat numbers, brand mark, sub-headings */
  --fs-display: 46px; /* large price/stat display numbers */
  --fs-h3: clamp(22px, 3vw, 26px); /* subsection / major card titles (pricing tiers, eco cards) */
  --fs-h2: clamp(34px, 5vw, 52px); /* section titles */
  --fs-h1: clamp(48px, 8vw, 88px); /* home page flagship hero title only */
  --fs-h1-page: clamp(36px, 5.5vw, 58px); /* every other page's hero title — about,
    pricing, features, faq, terms, privacy, disclosures. Deliberately smaller than
    --fs-h1: the home hero is the one flagship moment, subpages share one consistent
    "page title" size instead of each inventing its own clamp(). */

  /* Weight scale: three roles, not "whatever number looked right". --fw-body is the
     reading default; --fw-emphasis marks UI chrome one step up (nav links, secondary
     buttons, card labels); --fw-strong marks content that should draw the eye without
     being a headline (card titles, stat numbers, primary buttons); --fw-display is
     reserved for actual Bricolage Grotesque headlines (h1/h2) — don't reach for it on
     buttons/badges just because it's available. */
  --fw-body: 500;
  --fw-emphasis: 600;
  --fw-strong: 700;
  --fw-display: 800;

  /* Letter-spacing scale: six named steps, not hand-picked px values per component.
     Tighter than default on display/heading sizes (readable at a glance, denser feel);
     never tightened on --ls-normal contexts — numerals and form inputs lose legibility
     when tracked negative, so pricing numbers/stat displays/inputs stay at 0. --ls-wide
     is the one positive step for uppercase mono eyebrows/labels; --ls-otp is wider
     still, only for authenticator / one-time-code inputs. */
  --ls-tight-xl: -0.03em; /* --fs-h1 / --fs-h1-page display headlines */
  --ls-tight-lg: -0.02em; /* --fs-h2 / --fs-h3 */
  --ls-tight: -0.01em;    /* --fs-h4/--fs-lg/--fs-xl and default body/UI text */
  --ls-normal: 0;         /* numerals, form inputs — do not tighten */
  --ls-wide: 0.02em;      /* mono eyebrows, uppercase labels */
  --ls-otp: 0.28em;       /* authenticator / one-time-code inputs */

  /* ---------- 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;
  --sp-9: 96px;

  /* ---------- Layout ---------- */
  /* One width for every layout/nav/card container site-wide — nav, footer,
     hero, section grids, pricing/feature cards, settings pages. Previously
     --container-max and --container-wide were two different values (and
     settings-layout had a third, hardcoded one), which is exactly what
     produced the page-to-page inconsistency: nav wider than content, one
     page narrower than the next. Both tokens now resolve to the same
     number on purpose — the two class names stay (some markup already uses
     one or the other) but there is only one real width. */
  --container-max: 1440px;
  --container-wide: 1440px;
  --prose-max: 900px; /* the one reading-column width for continuous text
    and Q&A lists — About/FAQ/Terms/Privacy/Disclosures/Contact and the
    pricing page's own FAQ list all share this instead of each picking
    their own number (760/720/820 previously). */
  /* Modal dialog width — narrow on purpose: a confirmation dialog should read
     as one short column, not a page. */
  --modal-max: 460px;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --radius-pill: 100px;

  /* ---------- Elevation ---------- */
  --shadow-card: 0 18px 44px rgba(4, 2, 18, 0.6);
  --shadow-lift: 0 28px 70px -18px rgba(4, 2, 18, 0.75);
  --shadow-glow: 0 0 0 1px var(--accent-soft), 0 18px 50px -12px var(--accent-glow);
  --shadow-glow-voice: 0 0 0 1px var(--voice-dim), 0 18px 50px -12px var(--voice-glow);

  /* ---------- Motion ---------- */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-1: 150ms;
  --dur-2: 250ms;
  --dur-3: 420ms;
  --dur-4: 700ms;

  /* ---------- Z-index scale ---------- */
  --z-base: 1;
  --z-nav: 60;
  --z-dropdown: 70;
  --z-progress: 80;
  --z-cursor: 90;
  /* Above --z-cursor: a modal is the only thing that should ever paint over
     the custom cursor glow. Required because the global `section {
     position: relative }` rule in style.css makes every section its own
     stacking context — an overlay nested in one is painted under later
     sibling sections no matter how high its z-index, so modal elements are
     portalled to <body> by JS and rely on this token from there. */
  --z-modal: 100;

  /* ---------- Texture ---------- */
  --noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* ---------- Ecosystem tier colors ---------- */
  --ecosystem-purple: #9B6BFF;
  --ecosystem-purple-light: #C6ACFF;
  --ecosystem-elite: #f59e0b;
  --ecosystem-elite-strong: #B45309; /* darker step for elite gradients — the one
    color the badge (style.css) and the pricing CTA (pricing.css) must share so
    both render the same amber, instead of two independently hand-picked shades */
  --tier-free: #0D9488;
  --tier-free-light: #34D399;
}
