/*
 * The design tokens, and the one place a colour, a font or a size is written
 * down. Components read these custom properties and nothing else: a hex value
 * anywhere outside this file is a bug, and so is a font size typed into a
 * component. The chart controllers read the same properties through
 * `getComputedStyle`, so a table figure and a chart bar cannot disagree.
 *
 * A dark theme later is a second block of the same variables under
 * `prefers-color-scheme: dark` — not a second redesign.
 *
 * The layer order for the whole app is declared here, once, because this is
 * the first stylesheet `layouts/_head` links. Later layers win regardless of
 * specificity, so components never fight the reset and nothing needs
 * `!important` — except the `[hidden]` rule in reset.css and the
 * reduced-motion block in base.css, which say why.
 *
 * Breakpoints cannot be custom properties inside `@media`, so they live here
 * as a comment and these five numbers are the only ones used:
 *
 *    640px   small phones → large phones
 *    768px   phone → tablet; tables and filters stop stacking
 *   1024px   tablet → laptop
 *   1280px   laptop → desktop
 *   1650px   the app shell: the sidebar becomes a column instead of a drawer.
 *            Load-bearing — every page keys off it. Do not move it.
 *
 * Browser baseline: current evergreen (Chrome/Edge 120+, Safari 17.2+,
 * Firefox 121+) — cascade layers, native nesting, `:has()`, `color-mix()`,
 * container queries, `text-wrap: balance`. Nothing here needs a prefix.
 */
@layer reset, tokens, base, layout, components, pages, utilities;

@layer tokens {
  :root {
    /* Neutrals. One family, warm-grey, replacing slate/zinc/neutral/gray/stone. */
    --color-ground: #FAFAF7;
    --color-ground-cool: #F5F6F3;
    --color-surface: #FFFFFF;
    --color-surface-raised: #F3F4F0;
    --color-surface-sunken: #EFF1EC;
    --color-row-hover: #EEF3EE;
    --color-rule: #E4E6DF;
    --color-rule-strong: #C9CDC3;
    /* A form field's boundary is the only thing that says "type here", so it
       carries the 3:1 non-text contrast --color-rule-strong cannot. */
    --color-rule-control: #898F84;

    /* Ink. Ratios are against --color-surface; all four also pass on every
       tinted ground (lowest: subtle on accent-tint, 4.7:1). */
    --color-ink: #151814;         /* 17.9:1 */
    --color-ink-soft: #3A3F37;    /* 10.8:1 — news summaries, chips */
    --color-ink-muted: #565C53;   /*  6.9:1 — labels, table headers */
    --color-ink-subtle: #666C61;  /*  5.4:1 — meta, units, placeholder */
    --color-ink-inverse: #FFFFFF;

    /* Accent: actions, focus, the active tab. Deliberately darker and less
       saturated than --color-gain, so a subscribe button never reads as a
       positive number. */
    --color-accent: #0A6E4E;        /* 6.3:1; white on it 6.3:1 */
    --color-accent-strong: #07553C; /* 8.8:1 — hover, pressed, ink on tint */
    --color-accent-tint: #E8F2EC;
    --color-accent-tint-2: #D3E8DC;
    --color-accent-line: #BFDACB;

    --color-link: #0B5FA5;          /* 6.6:1 */
    --color-link-hover: #07447A;    /*  9.9:1 */
    --color-link-visited: #5B3E8C;  /*  8.4:1 — news headlines only */

    /* Gain and loss. Distinguishable under deuteranopia by lightness as well as
       hue, and never the only signal: negatives keep their parentheses. */
    --color-gain: #1F7A33;          /* 5.4:1; 4.9:1 on surface-raised */
    --color-gain-strong: #1F5F2B;
    --color-gain-tint: #E6F2E6;
    --color-gain-line: #BFD9C0;
    --color-loss: #B42318;          /* 6.6:1; 6.0:1 on surface-raised */
    --color-loss-tint: #FBEAE8;
    --color-loss-line: #F0C7C2;
    --color-warn: #8A5A00;          /* 5.9:1 — insider-buying flags */
    --color-warn-tint: #FBF1DC;
    --color-warn-line: #EAD6A8;

    /* The paywall mask, and the forecast-year column ground. */
    --color-mask: #DFE6E0;
    --color-mask-line: #CBD3C9;
    --color-forecast: #F5F6FA;
    --color-forecast-line: #DCDFE8;

    /* Chart marks. Non-text marks that carry meaning are ≥3:1. */
    --color-bar-gain: #5E9E7A;      /* 3.2:1 */
    --color-bar-loss: #C0625A;      /* 4.1:1 */
    --color-grid: #EFF1EC;
    --color-axis: #E4E6DF;
    --color-median: #C9CDC3;
    --color-volume: #C9CDC3;
    --color-series-1: #0A6E4E;
    --color-series-2: #0B5FA5;
    --color-series-3: #A0620B;
    --color-series-4: #7A4E9C;
    --color-series-5: #6E7469;

    /* The treemap's six discrete steps, fill and the text that passes on it.
       Discrete on purpose: a gradient puts its palest tiles at a contrast
       nothing can pass on. */
    --color-ramp-loss-3: #7F1811;   --color-ramp-loss-3-ink: #FFFFFF;  /* ≤ −20%     10.3:1 */
    --color-ramp-loss-2: #B42318;   --color-ramp-loss-2-ink: #FFFFFF;  /* −20…−5%     6.6:1 */
    --color-ramp-loss-1: #EFC2BC;   --color-ramp-loss-1-ink: #6A1A12;  /* −5…0        7.4:1 */
    --color-ramp-gain-1: #DCEBE0;   --color-ramp-gain-1-ink: #14401F;  /* 0…+8%       9.5:1 */
    --color-ramp-gain-2: #6BAA85;   --color-ramp-gain-2-ink: #0F3D22;  /* +8…+25%     4.5:1 */
    --color-ramp-gain-3: #14602A;   --color-ramp-gain-3-ink: #FFFFFF;  /* ≥ +25%      7.7:1 */

    /* The logo mark's three bars. */
    --color-brand-1: #6BAA85;
    --color-brand-2: #2F8546;
    --color-brand-3: #0A6E4E;

    --color-backdrop: color-mix(in srgb, var(--color-ink) 72%, transparent);

    /* Families. Nothing else in the app names a font. */
    --font-prose: "Source Serif 4", Georgia, "Times New Roman", serif;
    --font-ui: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
    --font-data: var(--font-ui);

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

    /*
     * The type scale: a size and the line-height chosen for its job, in pairs.
     * Floors: nothing a reader must read below 12px; table figures 13px on
     * desktop, 14px on a phone (see --text-data below); every input 16px so iOS
     * does not zoom on focus.
     */
    --text-meta-xs: 0.75rem;      --leading-meta-xs: 1.4;    /* 12    stat labels, the smallest text on the site */
    --text-meta: 0.78125rem;      --leading-meta: 1.45;      /* 12.5  bylines, units, captions, legends */
    --text-table-head: 0.75rem;   --leading-table-head: 1.3; /* 12    uppercase column heads */
    --text-data: 0.875rem;        --leading-data: 1.4;       /* 14 → 13 from 768px: table figures */
    --text-ui-sm: 0.84375rem;     --leading-ui-sm: 1.4;      /* 13.5  chips, pill labels, small buttons */
    --text-ui: 0.90625rem;        --leading-ui: 1.4;         /* 14.5  nav, buttons, body UI */
    --text-input: 1rem;           --leading-input: 1.35;     /* 16    every form field */
    --text-prose-sm: 0.96875rem;  --leading-prose-sm: 1.58;  /* 15.5 → 16  news summaries */
    --text-prose: 1.0625rem;      --leading-prose: 1.62;     /* 17    articles, commentary */
    --text-lead: 1.1875rem;       --leading-lead: 1.5;       /* 19    a page's opening paragraph */
    --text-stat: 1.375rem;        --leading-stat: 1.2;       /* 22    header stat values */
    --text-figure-lg: 1.875rem;   --leading-figure-lg: 1.1;  /* 30    index levels */
    --text-wordmark: 1.3125rem;                              /* 21    the logo's "stockrow" */

    /* Four heading steps, all serif 600. */
    --text-h4: 1rem;              --leading-h4: 1.35;        /* 16    panel labels, feature names */
    --text-h3: 1.1875rem;         --leading-h3: 1.3;         /* 19    card and panel titles */
    --text-h2: 1.375rem;          --leading-h2: 1.25;        /* 22 → 26  section headings */
    --text-h1: 1.6875rem;         --leading-h1: 1.15;        /* 27 → 34  page title */

    --tracking-tight: -0.015em;
    --tracking-caps: 0.06em;

    /* Measure for running prose. */
    --measure: 68ch;

    /* Space. A named scale for components to read, not a utility set. */
    --space-3xs: 0.125rem;  /*  2 */
    --space-2xs: 0.25rem;   /*  4 */
    --space-xs: 0.5rem;     /*  8 */
    --space-sm: 0.75rem;    /* 12 */
    --space-md: 1rem;       /* 16 */
    --space-lg: 1.25rem;    /* 20 */
    --space-xl: 1.5rem;     /* 24 */
    --space-2xl: 2rem;      /* 32 */
    --space-3xl: 2.5rem;    /* 40 */
    --space-4xl: 3.5rem;    /* 56 */

    --gutter: var(--space-md);

    /* Shape. */
    --radius-xs: 3px;    /* masked bar */
    --radius-sm: 6px;    /* skeleton, treemap tile */
    --radius-md: 8px;    /* badge, icon button */
    --radius-control: 9px; /* button, input */
    --radius-lg: 12px;   /* panel, notice */
    --radius-xl: 14px;   /* card */
    --radius-pill: 999px;

    --rule-width: 1px;
    --rule-width-strong: 1.5px;

    /* Elevation. Three, and no card shadows: cards are a rule on the ground. */
    --shadow-accent: 0 1px 2px color-mix(in srgb, var(--color-accent-strong) 40%, transparent);
    --shadow-raised: 0 1px 2px color-mix(in srgb, var(--color-ink) 7%, transparent);
    --shadow-pinned-end: -8px 0 8px -6px color-mix(in srgb, var(--color-ink) 12%, transparent);
    --shadow-pinned-start: 8px 0 8px -6px color-mix(in srgb, var(--color-ink) 12%, transparent);
    --shadow-overlay: 0 12px 32px -8px color-mix(in srgb, var(--color-ink) 22%, transparent);

    /* Focus: one ring, everywhere. */
    --focus-ring: 2px solid var(--color-accent);
    --focus-offset: 2px;

    /* Touch targets and controls. */
    --target-min: 2.75rem;     /* 44px */
    --control-height: 2.75rem; /* 44px */
    --control-height-sm: 2.25rem;

    /* The sticky navbar's height, which the statement tables' sticky header
       offsets itself by, so the two cannot drift apart. */
    --navbar-height: 3.5rem;
    --sidebar-width: 18rem;

    --duration-fast: 120ms;
    --duration-slow: 300ms;
  }

  @media (width >= 768px) {
    :root {
      --text-data: 0.8125rem;
      --leading-data: 1.35;
      --text-prose-sm: 1rem;
      --text-h2: 1.5rem;
      --text-h1: 2.125rem;
    }
  }

  @media (width >= 1024px) {
    :root {
      --gutter: var(--space-3xl);
      --navbar-height: 4rem;
      --text-h2: 1.625rem;
    }
  }
}
