/* ============================================================================
   Porter design tokens — the single source of truth for the hub's design
   language. Every app imports this (see "How to use" below) instead of
   re-declaring its own palette, type scale, and spacing.

   WHY THIS FILE EXISTS
   --------------------
   Apps used to each re-declare these values by hand ("self-contained styles").
   That convention let the values drift: --text-muted was #666 in Porter, #777
   in Cal, #999 in Castor; border radius was 8px / 10px / a mix; Kit spelled it
   --surface2 with no hyphen. This file ends the drift for the SHELL tokens —
   change a value here and every app moves together. Components still live
   per-app, and so does each app's signature ACCENT colour (see the SHELL note
   below): only the app-neutral shell tokens are shared.

   HOW TO USE
   ----------
   1. Pages-served apps (everything under /apps/ and the root hub) link it in
      <head>, BEFORE the app's own <style>/<link>, so the app can still override
      a token locally if it has a documented reason:

          <link rel="stylesheet" href="/shared/porter-tokens.css" />

      The path is absolute-from-root: the file deploys to porter.<host>/shared/
      via Cloudflare Pages alongside the rest of the repo.

   2. Tally is Worker-served on its own public host, so "/shared/..." routes to
      the Worker, not Pages. Tally inlines these tokens instead of linking — keep
      it in sync by hand, or add a Worker asset route. (Tracked separately.)

   WHAT'S A TOKEN VS. A COMPONENT
   ------------------------------
   Tokens: color, type scale, spacing, radius, fonts, motion, z-index, the
   responsive size knob. Components (buttons, cards, modals, chips, headers)
   stay in each app's stylesheet, built FROM these tokens. See the component
   spec in the repo's design docs for the shared component shapes.
   ============================================================================ */

:root {
  /* ════════════════════════════════════════════════════════════════════════
     SHELL — the shared, app-neutral layer (per-app icon-colour model)
     ─────────────────────────────────────────────────────────────────────────
     Under the new design model (see DESIGN.md / DESIGN-ROLLOUT.md) colour is
     carried PER APP by its recoloured icon and a few in-content accents. So
     this shared file deliberately holds only what every app shares:

       • surfaces + text tiers          (the cool-dark shell)
       • NEUTRAL STEEL                  (--steel / --steel-dim — the chrome hue)
       • STATUS                         (--success / --warn / --danger, + tints)
       • the scale tokens below         (type, spacing, radius, motion, z-index)
       • the fonts + the size knob

     There is intentionally NO --accent here. Each app declares its own
     signature hue block (--accent + dim/bright/tint, plus a second hue if it
     has a real second axis) in its OWN :root, at migration time. An app that
     hasn't migrated must keep its own accent block locally so it still renders.
     ════════════════════════════════════════════════════════════════════════ */

  /* Surfaces — five-step cool-dark ramp. */
  --bg:           #0b0d10;   /* page background — always dark */
  --surface:      #13151b;   /* cards, headers */
  --surface-2:    #1b1e26;   /* inputs, hover states */
  --surface-3:    #242833;   /* raised insets: steppers, tooltips, auto-fields */
  --border:       #2b2f3a;   /* borders, dividers */

  /* Text tiers. */
  --text:         #e9eaef;   /* primary text */
  --text-muted:   #888ea0;   /* secondary text, labels */
  --text-dim:     #535867;   /* tertiary: hints, placeholders, disabled */

  /* Neutral steel — THE chrome hue. Plain buttons, the wordmark dot, inactive
     tabs, dividers, secondary controls, Porter's own frame. Steel recedes so
     each app's signature colour (declared per-app) leads. Use this where the
     old model would have reached for --accent on chrome. */
  --steel:        #9aa6bd;   /* neutral chrome accent */
  --steel-dim:    #5b6478;   /* dimmed steel — borders, glow partners, hovers */
  --steel-tint:   rgba(154, 166, 189, 0.14);

  /* Semantic status (status ONLY, never decoration). Each has a tint fill.
     Shared and constant across every app — status is the same job everywhere. */
  --success:      #5cb88a;
  --warn:         #e6b04c;
  --danger:       #e07a6a;
  --success-tint: rgba(92, 184, 138, 0.14);
  --warn-tint:    rgba(230, 176, 76, 0.14);
  --danger-tint:  rgba(224, 122, 106, 0.14);

  /* Fonts. Display: Fraunces (warm serif — titles, brand, hero). Body/UI: IBM
     Plex Sans. Data/numbers: IBM Plex Mono (numbers are the content in these
     apps). --font-head kept as an alias of --font-display so older rules that
     reference it still resolve during the app-by-app migration. */
  --font-display: 'Fraunces', Georgia, serif;
  --font-body:    'IBM Plex Sans', system-ui, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, monospace;
  --font-head:    var(--font-display);   /* migration alias */

  /* ── Typography: rem type scale ───────────────────────────────────────────
     rem-based so the whole app scales from ONE knob (html font-size, below).
     Reference these everywhere text is sized — including inline style= in
     JS-generated HTML — never raw px. px equivalents are at the 16px base.
     Leave control glyphs (stepper/icon sizes) and deliberate hero numbers as
     explicit values; size header/chrome icons in em so they track the knob. */
  --fs-2xs:  0.6875rem;  /* 11 — micro labels, badges */
  --fs-xs:   0.75rem;    /* 12 — fine print, dense table cells */
  --fs-sm:   0.8125rem;  /* 13 — secondary copy */
  --fs-md:   0.875rem;   /* 14 — body default for dense apps */
  --fs-base: 1rem;       /* 16 — inputs, comfortable body */
  --fs-lg:   1.375rem;   /* 22 — section/app titles */
  --fs-xl:   1.875rem;   /* 30 — hero numbers, large headings */
  --fs-2xl:  2.875rem;   /* 46 — the big capacity-style number */

  /* Letter-spacing for uppercase mono micro-labels (POINTS, AVAIL, VELOCITY)
     and tracked caps. Serif display titles use near-zero tracking (set locally);
     these apply to the small uppercase Plex Mono / Plex Sans labels. */
  --ls-tight:  0.5px;
  --ls-label:  0.8px;    /* small uppercase labels */
  --ls-title:  0.5px;    /* section titles (serif — minimal tracking) */
  --ls-wide:   1px;      /* tracked caps where wanted */

  /* ── Spacing scale ────────────────────────────────────────────────────────
     One spacing ramp so gaps/padding are consistent across apps. The DEFAULT
     density is comfortable; data-dense zones opt into tighter values
     deliberately (see --space-compact-* and the density note in the spec).
     rem-based so spacing tracks the size knob too. */
  --space-3xs: 0.25rem;  /* 4  — hair gaps, icon-to-text */
  --space-2xs: 0.375rem; /* 6  */
  --space-xs:  0.5rem;   /* 8  — tight gaps, badge padding */
  --space-sm:  0.75rem;  /* 12 — card inner gaps */
  --space-md:  1rem;     /* 16 — default card padding, section gaps */
  --space-lg:  1.5rem;   /* 24 — section separation */
  --space-xl:  2rem;     /* 32 — major regions */
  --space-2xl: 3rem;     /* 48 — page-level breathing room */

  /* ── Radius ───────────────────────────────────────────────────────────────
     Reconciled drift: base settles on 8px (repo default). lg is 10px for cards
     that want the softer corner (Castor's intentional choice) without forcing
     it on inputs/buttons. sm for small controls; pill for chips/toggles. */
  --radius-sm:   6px;
  --radius:      8px;    /* default — inputs, buttons, most cards */
  --radius-lg:   10px;   /* large surfaces opting into softer corners */
  --radius-pill: 999px;  /* chips, toggles, segmented controls */

  /* ── Elevation / shadow ───────────────────────────────────────────────────
     Dark UI leans on borders more than shadows; these are for modals and
     genuinely floating layers only. */
  --shadow-modal: 0 12px 40px rgba(0, 0, 0, 0.5);
  --shadow-pop:   0 4px 14px rgba(0, 0, 0, 0.35);

  /* ── Motion ───────────────────────────────────────────────────────────────
     Shared timings so transitions feel consistent. fast for hovers, base for
     state changes, slow for overlays/sheets. */
  --motion-fast: 0.15s ease;
  --motion-base: 0.2s ease;
  --motion-slow: 0.24s ease;

  /* ── Z-index ladder ───────────────────────────────────────────────────────
     Named layers so apps stop inventing magic numbers (Castor had 100 / 500 /
     9998 / 99999 scattered around). */
  --z-sticky:  100;   /* sticky headers / nav */
  --z-overlay: 500;   /* modal/sheet scrims */
  --z-toast:   900;   /* toasts above modals */
  --z-tooltip: 1000;  /* floating tooltips above everything */

  /* ── App width — the shared content spine ─────────────────────────────────
     ONE width for the whole hub: both the header inner and the body content
     centre on it in EVERY app, so the brand and the content's left edge land
     at the identical screen position no matter which app you're in. This is
     what stops the header brand "shifting" when you swap apps — previously
     each app picked its own width (Porter 960 / Castor 1040 / Cal 720) and the
     brand jumped. Sized to fit the widest app's payload (Castor's sprint grid
     + four nav tabs). Apps differentiate content density INSIDE this frame
     (sidebars, title-tab rails, narrower inner reading columns) — never by
     changing this outer width. The header bar itself is still full-bleed
     (background spans the window); only its INNER contents use this spine. */
  --app-width: 1040px;
  --app-pad:   22px;   /* side padding inside the spine (header + body match) */
}

/* ── The size knob ──────────────────────────────────────────────────────────
   html font-size is the SINGLE desktop knob: the whole rem-based scale (type
   and spacing) grows/shrinks from it. The mobile knob lives in each app's
   stylesheet inside its breakpoint (so apps keep their own breakpoint
   direction) — copy this rule and set a smaller value (~15px) there:

       @media (max-width: 768px) { html { font-size: 15px; } }

   It's here at :root so a brand-new app gets a sane desktop default for free. */
html { font-size: 18px; }
