/*
 * 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 four 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
 *
 * Past 1280 nothing changes: the page runs the full width of the window, a
 * gutter either side (owner, 2026-10-04 — it was centred on a 1400px column
 * before). There was a 1650px breakpoint for the sidebar; the sidebar is
 * gone (tasks/redesign, D5) and so is 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 {
    /*
     * Paper (tasks/redesign, D1). A warm printed page: paper, ink, one deep
     * green for links, actions and gains, and a brick red for losses. Values
     * sampled from the mocks beside tasks/redesign/milestone.md.
     */
    --color-ground: #F4F0E7;        /* paper */
    --color-ground-cool: #EFEAE0;
    --color-surface: #F4F0E7;       /* no white panels: a section is a rule on paper */
    --color-surface-raised: #F0E9DE; /* the following strip, a tooltip, a hover */
    --color-surface-sunken: #EAE3D7;
    --color-field: #FFFDF9;         /* inputs — the one ground lighter than paper */
    --color-row-hover: #ECE5D9;
    --color-rule: #D9D3C7;          /* hairline */
    --color-rule-strong: #1B1A17;   /* section tops, header rules, the double rule */
    /* A form field's boundary is the only thing that says "type here", so it
       carries the 3:1 non-text contrast the hairline cannot. */
    --color-rule-control: #857E72;

    /* Ink. Ratios are against paper; every one also passes on each tinted
       ground the contrast test lists. */
    --color-ink: #1B1A17;           /* 15.3:1 */
    --color-ink-soft: #3A3833;      /* 10.3:1 — news summaries */
    --color-ink-muted: #5E5A53;     /*  6.0:1 — labels, table headers, the dateline */
    --color-ink-subtle: #615D56;    /*  5.8:1 — meta, units, placeholder */
    --color-ink-inverse: #FFFFFF;

    /* One green: actions, links, the active section and gains alike. */
    --color-accent: #305A41;        /* 6.9:1; white on it 7.9:1 */
    --color-accent-strong: #22432F; /*  9.7:1 — hover, pressed */
    --color-accent-tint: #E2E6D9;
    --color-accent-tint-2: #D3DCCB;
    --color-accent-line: #B9C9B5;

    --color-link: #305A41;
    --color-link-hover: #22432F;

    /* Gain and loss. Never the only signal: an arrow or brackets go with them. */
    --color-gain: #305A41;          /* 6.9:1 */
    --color-gain-strong: #22432F;
    --color-gain-tint: #DBE5D7;
    --color-gain-line: #B9C9B5;
    --color-loss: #8E3429;          /* 6.9:1 brick */
    --color-loss-tint: #EFDDD5;
    --color-loss-line: #DDB8AC;
    --color-warn: #6F4C00;          /* 6.8:1 — insider-buying flags */
    --color-warn-tint: #F0E3C4;
    --color-warn-line: #DCC795;

    /* The paywall mask, and the forecast-year column ground. */
    --color-mask: #E2DBCE;
    --color-mask-line: #CFC7B8;
    --color-forecast: #ECE6DA;
    --color-forecast-line: #D9D3C7;

    /* Chart marks. Non-text marks that carry meaning are ≥3:1 on paper. */
    --color-bar-gain: #4F7A5C;      /* 4.3:1 */
    --color-bar-loss: #A44F40;      /* 4.9:1 */
    --color-axis: #D9D3C7;
    --color-median: #B9B1A2;
    --color-volume: #C9C1B2;
    /* Candlesticks: the same two the gnuplot price images bake in
       (Gnuplots::Price), so the company page's live chart and the screener's
       thumbnails read as one chart. */
    --color-candle-gain: #16A34A;
    --color-candle-loss: #EF4444;
    --color-series-1: #305A41;
    --color-series-2: #3E5C7A;
    --color-series-3: #A0620B;
    --color-series-4: #6B4E7A;
    --color-series-5: #7A756C;

    /* The six discrete steps of the treemap and the following strip, 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: #70271E;   --color-ramp-loss-3-ink: #FFFFFF;  /* 10.5:1 */
    --color-ramp-loss-2: #A44F40;   --color-ramp-loss-2-ink: #FFFFFF;  /*  5.6:1 */
    --color-ramp-loss-1: #E9D4CA;   --color-ramp-loss-1-ink: #1B1A17;  /* 12.2:1 */
    --color-ramp-gain-1: #DBE5D7;   --color-ramp-gain-1-ink: #1B1A17;  /* 13.4:1 */
    --color-ramp-gain-2: #83A78E;   --color-ramp-gain-2-ink: #1B1A17;  /*  6.5:1 */
    --color-ramp-gain-3: #305A41;   --color-ramp-gain-3-ink: #FFFFFF;  /*  7.9:1 */

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

    /*
     * Families. Nothing else in the app names a font. The serif is for
     * anything read as a headline or a large figure, the condensed sans for
     * every table, label and control. The only italic is the serif's.
     */
    --font-prose: "Source Serif 4", Georgia, "Times New Roman", serif;
    --font-ui: "IBM Plex Sans Condensed", system-ui, -apple-system, "Segoe UI", sans-serif;
    --font-data: var(--font-ui);

    --weight-regular: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;           /* the serif only: Condensed stops at 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-data-dense: 0.75rem;   --leading-data-dense: 1.35; /* 12   a table that must fit a narrow column */
    --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    stat-bar values, serif */
    --text-figure-lg: 1.75rem;    --leading-figure-lg: 1.1;  /* 28    index levels, serif */
    --text-figure-xl: 2.875rem;   --leading-figure-xl: 1;    /* 46    the company's price, serif */
    --text-wordmark: 1.625rem;                               /* 26 → 34  the inner masthead's "stockrow", serif 700 */
    --text-wordmark-masthead: 2.75rem;                       /* 44    the homepage nameplate, serif 700 */

    /* Every small-caps label, navigation link and tab: Condensed 500, upper
       case, tracked. */
    --text-caps: 0.75rem;         --leading-caps: 1.3;       /* 12 */
    /* The serif italic beside a heading: "Fiscal years to September", "$m". */
    --text-note: 0.9375rem;       --leading-note: 1.3;       /* 15 */

    /* Four heading steps, all serif 700. */
    --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    section heads */
    --text-h1: 1.875rem;          --leading-h1: 1.1;         /* 30 → 40  page title */
    --text-display: 2.5rem;       --leading-display: 1.05;   /* 40 → 56  a company's name */

    /* Paper only (print.css). A printed company page is a reference sheet
       set as densely as Value Line's, read at arm's length with nothing to
       zoom: the 12px floor above is a screen's. */
    --text-print: 0.5625rem;      --leading-print: 1.25;     /* 9     every table and label */
    --text-print-sm: 0.5rem;      --leading-print-sm: 1.2;   /* 8     the statistical array, notes */
    --text-print-title: 1.5rem;                              /* 24    the company's name */

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

    /* 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. Square everywhere (tasks/redesign, D1): a printed page has no
       rounded corners. The names stay so a component that wants a curve back
       has one place to ask; only the pill — the news impact badge — keeps it. */
    --radius-xs: 0;
    --radius-sm: 0;
    --radius-md: 0;
    --radius-control: 0;
    --radius-lg: 0;
    --radius-xl: 0;
    --radius-pill: 999px;

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

    /* Rules instead of boxes. A section opens on a heavy rule; rows part on a
       hairline; the masthead closes on the double rule, drawn as a background
       image (3px ink, a 2px gap, 1px ink) because no border style draws it. */
    --rule-hairline: var(--rule-width) solid var(--color-rule);
    --rule-heavy: 2px solid var(--color-rule-strong);
    --rule-double: linear-gradient(
      var(--color-rule-strong) 0 3px,
      transparent 3px 5px,
      var(--color-rule-strong) 5px 6px
    );
    --rule-double-height: 6px;

    /* Elevation. Paper is flat: what floats — a tooltip, a menu — gets the
       overlay shadow, and a pinned table column keeps the edge shadow that
       says the table scrolls under it. Nothing else casts one. */
    --shadow-accent: none;
    --shadow-raised: none;
    --shadow-overlay: 0 8px 24px -8px color-mix(in srgb, var(--color-ink) 28%, 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;


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

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

  @media (width >= 1024px) {
    :root {
      --gutter: var(--space-3xl);
      --text-h1: 2.5rem;
      --text-display: 3.5rem;
    }
  }
}
