/* Vibe Check — canonical design tokens (web). Apple-grade dark ramp.
   ONE source of truth: JUCE (VibeColours.h) and iOS (colour assets) are generated to match.
   Mirrored verbatim in web/player/tokens.css — keep the two identical. */
:root{
  /* surfaces (elevation ramp) */
  --base:#0C0C0E;          /* page / app canvas */
  --surface-1:#1C1C1E;     /* cards, players, list rows */
  --surface-2:#2C2C2E;     /* controls, icon tiles, inputs */
  --surface-3:#3A3A3C;     /* topmost stacked controls (rare) */
  --separator:#38383A;
  --hairline:rgba(255,255,255,.10);

  /* text — translucent white, adapts to any surface */
  --text:#ffffff;
  --text-2:rgba(255,255,255,.60);   /* lift to .70 over a hero image */
  --text-3:rgba(255,255,255,.30);

  /* the approved player redesign's surfaces and inks. The mock uses SOLID greys where we used
     white-at-alpha; solid is what it approved, so these are read straight from it. */
  --surface-card:#1A1B1D;   /* the player card                     (was #1C1C1E) */
  --surface-box:#232427;    /* the sender box                      (was #2C2C2E) */
  --txt-lead:#C3C5C9;       /* "sent via" — the footer's lead line */
  --txt-muted:#8E9196;      /* "sent by", expiry, the footer tagline */
  --ink-invert:#101112;     /* dark ink on an inverted (white) chip */
  --txt-bright:#F3F4F5;     /* the wordmark, card and footer — not pure white in the mock */
  --red-ink:#E0403A;        /* the expiry VALUE as text; --red stays for dots, badges, destructive */

  /* one tint — everything tappable */
  /* TWO DECLARED BLUES (Sid, 2026-07-31), superseding the one-blue law.
     --blue is the SURFACE blue: fills, buttons, focus borders, the hero. Read from the approved
     mock's download pill (#2F6BFA, was #3B74F0) and unchanged.
     --blue-text is the TEXT blue, and it exists because the references consistently render small
     blue TEXT one step lighter than the surfaces they sit beside. That is not drift: a fill carries
     its own weight of colour and a 13px label does not, so the same hex reads heavier as a surface
     and thinner as type. One blue was the right rule while everything blue was a surface; the
     moment the design uses blue for both, one value cannot serve both jobs.
     The split is by ROLE, not by size: buttons keep --blue even when their label is the blue part
     (the player's outline actions), because a button is a surface whether or not it is filled. */  /* read from the approved mock's download pill: #2F6BFA (was #3B74F0). This is the PRODUCT-WIDE
     tint, so the studio moves with it — one blue, not a player blue and a studio blue. hover and
     pressed are shifted by the same delta so the three keep their relationship. */
  --blue:#2F6BFA;
  --blue-text:#3B7BFA;      /* small blue TEXT only — never a fill, never a border */
  --blue-hover:#4179FE;
  --blue-pressed:#225AE2;

  /* semantic only — small, sparing, never decorative */
  --red:#FF453A;     /* live / record / destructive */
  --green:#30D158;   /* active / connected / ready / copied — status, badges, dots */
  --green-on:#2F8F4E;/* a SWITCH in its on state. Deeper than the status green on purpose: a 29x16
                        pill is a filled surface, and #30D158 at that area reads as an alert rather
                        than a setting. Read off the studio's ruled control. */
  --orange:#FF9F0A;  /* caution — an expiry's final day only */

  /* the player glass card, over the sender's wallpaper */
  --glass:rgba(0,0,0,.72);
  --well:rgba(255,255,255,.07);   /* waveform well */

  /* type */
  --ui:'Inter',system-ui,-apple-system,BlinkMacSystemFont,sans-serif;
  --mono:'Roboto Mono',ui-monospace,SFMono-Regular,monospace;

  /* ---- THE SHARED SCALE (moved here 2026-08-01) ------------------------------------------------
     These lived TWICE — once in studio.css, once in player.css — with a comment in each warning
     that "the two files declare the token separately, so they must be moved together or they drift
     apart silently". That is not a scale the player inherits, it is a scale the player happens to
     agree with, and the only thing holding the two in step was a comment. Measured on live before
     the move: every shared token computed identically on the studio and both players at 1440 and
     390, so consolidating here is inert by construction — and from now on the player cannot drift
     because there is nothing left to drift from.
     What stayed behind in studio.css: the studio's OWN voices (--t-rowtitle/--t-rowdays/--t-subrow
     and the --t-panel* set). Those are surfaces the player does not have. What moved here: the four
     type voices, their tracking, the weights, the five spacing steps, and the panel's surface/ink
     colours — colours belong in this file with the rest of the ramp, and the player's demoted
     download pill now reads three of them. */

  /* SIZES — four voices. --t-micro is a declared FIFTH step for exactly one thing: the auto-play
     label inside a 38px control slot matched across three transports. */
  --t-title:22px; --t-body:14.5px; --t-caption:13px; --t-mono:12.5px; --t-micro:8px;
  /* TRACKING. -0.015em is a METRIC COMPENSATION, NOT a value copied from a reference — do not
     "correct" it back to -0.005em in a later match-the-reference pass. The approved references
     render in Helvetica Neue; this product is ruled to Inter, which is measurably wider at the same
     size and the same declared tracking. Measured 2026-07-30 on identical strings: +6.6% at weight
     400, +4.3% at 500, +2.1% at 600, +3.5% at 700. Every role's DECLARED tracking already matched,
     so the extra width is the family's metrics and tracking is the only lever; Sid ruled ONE global
     step over per-role hacks. -0.015em because it is already a declared step (--t-title-ls), not a
     new number. It lands the 600/700 roles within ~1.7% and narrows the 400-weight roles without
     closing them: one value cannot do better, because the gap varies with weight. */
  --t-tracking:-0.015em;
  --t-title-ls:-0.015em;           /* the one large voice tightens as it grows */
  --t-mono-ls:var(--t-tracking);   /* ONE mono treatment, product-wide */
  --t-logo-ls:0.34em;              /* the card wordmark */
  --t-logo-foot-ls:0.26em;         /* the footer wordmark */
  --t-w-reg:400; --t-w-med:500; --t-w-semi:600; --t-w-bold:700;

  /* the tracklist row title, on every surface that lists a collection's tracks: the studio list's
     expanded sub-rows and, as of Sid's inheritance ruling (2026-08-01), both players' tracklists.
     Held FLAT at 390 — Sid's earlier ruling that phones do not step this voice down still stands,
     and it is why it is its own token rather than --t-body. */
  --t-subrow:14.5px;

  /* the label under a control (auto-play). Flat at both widths, like --t-subrow: it sits in a
     fixed-size control slot matched across three transports, so stepping it down would break the
     geometry rather than the reading. Declared because no other step is 12px flat. */
  --t-control:12px;

  /* THE WAVEFORM WELL. --well-h is the ruled height (Sid, 2026-08-01); the tiers below it are the
     SHORT-VIEWPORT compaction, a different axis from the ruling — the card is capped to the window
     and something has to give. The values are the player's measured tiers, promoted to tokens so
     the studio can compact identically instead of not at all. */
  --well-h:120px;
  /* THE COMPACT STATE (Sid, 2026-08-02) — a NAMED state of the same shared component, not a
     player-only override. It applies wherever a collection tracklist shares the card, because
     there the list is the most important thing on it and the ceremony is what gives. 84 is not a
     new number: it is the tier the short-viewport scale already declares. See .st-card.has-list in
     sendbox.css, which takes the SMALLER of this and whatever tier the window is on. */
  --well-h-tight:84px;

  /* THE TRANSPORT, both scales declared side by side (Sid, 2026-08-02) — a collection's compact
     scale is a VALUE here, not a second hand-kept copy of the rules. verify-shared-controls
     asserts both, so neither can drift the way the two auto-play switches once did. */
  --hero:88px;   --hero-tight:48px;
  --skip:44px;   --skip-tight:32px;
  --heroGlyph:34px; --heroGlyph-tight:20px;
  --skipGlyph:19px; --skipGlyph-tight:14px;

  /* SPACING — one 6-rhythm, five steps. Nothing sits between steps. */
  --sp-tight:6px; --sp-close:12px; --sp-block:18px; --sp-air:24px; --sp-wide:30px;

  /* the panel's surfaces and inks, read headless off Acetate_Collection.html (2026-07-31) */
  --surface-inset:#202124;     /* inset ground: track panel, fields, url row, quiet buttons */
  --line-inset:#2C2E31;        /* its 1px edge, and the separator between track rows */
  --line-well:#2A2C2F;         /* the well's own window edge */
  --line-card:#26282B;         /* the card's edge */
  --ink-value:#F3F4F5;         /* a value the producer typed or chose */
  --ink-quiet:#C3C5C9;         /* placeholders, durations, the url, time chips */
  --red-del:#E0403A;           /* delete link — the reference's red, softer than the system #FF453A */
  --row-line:#2A2C2F;          /* the studio list's divider ink: an OPAQUE rgb, not --hairline,
                                  which composites to ~rgb(51,51,53) and reads visibly lighter */
}

/* phones step the WHOLE scale down in one move — sizes and spacing together, so the two never
   disagree about what "one step" means at a given width. */
@media (max-width:480px){
  :root{ --t-title:20px; --t-body:13.5px; --t-caption:12px; --t-mono:11.5px; --t-micro:8px;
         --sp-tight:5px; --sp-close:9px; --sp-block:14px; --sp-air:18px; --sp-wide:23px; }
}
