/* tokens.css — the design tokens every other stylesheet reads.

   Loaded by base.html before style.css. style.css keeps its long-standing
   names (--bg-base, --text-primary, --accent-primary, --gradient-brand ...)
   as aliases that point here, so a value changes in one place.

   Colour (redo 0, 2026-10-13): warm near-black ground, warm off-white ink,
   ONE accent. The violet-pink-cyan gradient is the logo's, and appears in
   the UI only in the logo and the landing's one hero moment
   (--gradient-logo). The 90/10 refinement (2026-10-17) draws that one
   accent as a pink-to-violet gradient where it already appeared, plus a
   faint ambient glow ("the second light" below); the neutrals are
   untouched. Every pair and its ratio: docs/design/COLOR-AUDIT.md.

   Contrast is WCAG 2.x relative-luminance contrast (w3.org/TR/WCAG21,
   "contrast ratio"); tests/test_responsive_a11y.py section 7 computes it from
   this file and fails below 4.5:1 for text, 3:1 for UI. */

:root {
  /* ── Colour: ground ─────────────────────────────────────────────────────── */
  /* Dark, because the scene is a bedroom studio at night: a screen next to a
     mic in a dim room. Warm, not blue-grey: the neutrals carry a little of the
     off-white's yellow so the ground reads as a room, not a terminal. */
  --bg:        #0e0d0c;
  --surface-1: #151412;   /* cards, sheets, the sidebar */
  --surface-2: #1c1b19;   /* raised: inputs, chips, hover */
  /* One step above --surface-2 by the same increment (+7 to +9 per channel),
     for the few overlays that sit on a raised surface. --faint is NOT for
     use here (4.28:1). */
  --surface-3: #252320;

  /* ── Colour: ink ────────────────────────────────────────────────────────── */
  --ink:    #f5f0e8;      /* 17.1:1 on --bg, 13.8 on --surface-3 */
  --muted:  #a8a29a;      /* secondary text: 7.7 on --bg, 6.2 on --surface-3 */
  /* Non-essential text only (timestamps beside a label that already says it,
     separators). 5.3 on --bg, 5.0 on --surface-1, 4.7 on --surface-2; never
     on --surface-3. */
  --faint:  #8a857d;
  /* Channel triplets, for translucent ink and shade: rgb(var(--ink-rgb) / .1). */
  --ink-rgb:    245 240 232;
  --shade-rgb:  0 0 0;

  /* Hairlines and dividers (not text, decorative): ink at 12%. */
  --line:        rgba(245, 240, 232, .12);
  --line-soft:   rgba(245, 240, 232, .07);
  /* The edge that identifies a form control (WCAG 1.4.11, 3:1): ink at 45%
     measures 4.1 on --bg, 3.9 on --surface-3. */
  --line-control: rgba(245, 240, 232, .45);

  /* ── Colour: the one accent ─────────────────────────────────────────────── */
  /* The logo's pink. Rationed to: the primary button (with --accent-ink
     text), the active-nav indicator, the play button and the waveform's
     played region, and the focus ring. Nothing else is pink. The first four
     draw it as --gradient-accent; the focus ring and caret stay flat. */
  --accent:      #f472b6;   /* 7.3:1 on --bg (UI and text) */
  --accent-rgb:  244 114 182;
  --accent-hover: #f68ec5;  /* --accent mixed 15% toward --ink */
  --accent-ink:  #0e0d0c;   /* text on --accent: 7.3:1 */

  /* ── Colour: the second light (90/10 refinement, 2026-10-17) ─────────────── */
  /* 90% of the screen stays the warm dark neutrals above; the other 10% is
     the accent drawn as a pink-to-violet gradient, the logo's own direction
     (135deg, pink to violet). Rationed like the accent, and to the same
     places plus one: key calls to action, the play button and the played
     waveform, selected-state indicators, the logo, the Cue assistant's pill
     and hint (docs/adr/0017), and a faint ambient glow on the page ground
     (test_responsive_a11y 7l keeps it there). The violet
     end is lighter than the logo's so the dark button text clears 7:1 on
     both ends (docs/reference/derived-constants.md). */
  --accent-2:       #a78bfa;   /* 7.1:1 with --accent-ink */
  --accent-2-rgb:   167 139 250;
  --accent-2-hover: #b39af7;   /* --accent-2 mixed 15% toward --ink */
  --gradient-accent:       linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
  --gradient-accent-hover: linear-gradient(135deg, var(--accent-hover) 0%, var(--accent-2-hover) 100%);
  /* Indicators (bars and underlines) run along their own length. */
  --gradient-accent-x: linear-gradient(90deg, var(--accent), var(--accent-2));
  --gradient-accent-y: linear-gradient(180deg, var(--accent), var(--accent-2));
  /* Light, not paint: at its brightest the glow is no lighter than
     --surface-1, so a card never reads darker than the ground behind it. */
  --glow-ambient:
    radial-gradient(60% 420px at 88% 0%, rgb(var(--accent-2-rgb) / .045), transparent 70%),
    radial-gradient(45% 360px at 30% 0%, rgb(var(--accent-rgb) / .045), transparent 70%);

  /* Keyboard focus: the accent, 2px, offset 2px so it sits on the ground and
     stays visible around a pink button. */
  --focus-ring: var(--accent);

  /* ── Colour: semantic ───────────────────────────────────────────────────── */
  /* A status is a neutral chip with a coloured dot or word, never a tinted
     fill. Each clears 4.5:1 as text on every surface. */
  --success: #86d7a0;       /* 11.3 on --bg */
  --error:   #f28b82;       /* 8.1 on --bg */
  --warning: #f5c26b;       /* 11.9 on --bg */

  /* ── Colour: the brand gradient ─────────────────────────────────────────── */
  /* The logo's own stops. Used in the logo and in the landing's one hero
     moment, nowhere else. */
  --logo-1-rgb: 139 92 246;   /* violet  #8b5cf6 */
  --logo-2-rgb: 236 72 153;   /* pink    #ec4899 */
  --logo-3-rgb: 6 182 212;    /* cyan    #06b6d4 */
  --gradient-logo: linear-gradient(135deg, rgb(var(--logo-1-rgb)) 0%, rgb(var(--logo-2-rgb)) 50%, rgb(var(--logo-3-rgb)) 100%);
  /* The landing hero's flow (static/js/landing-hero.js), left to right: the
     producer's hot pink, magenta, violet where the two voices meet, electric
     blue, the artist's cyan. Read by that script only, nowhere else. */
  --hero-flow-1-rgb: 255 46 126;   /* hot pink */
  --hero-flow-2-rgb: 244 63 190;   /* magenta */
  --hero-flow-3-rgb: 178 76 247;   /* violet */
  --hero-flow-4-rgb: 86 108 255;   /* electric blue */
  --hero-flow-5-rgb: 31 214 240;   /* cyan */

  /* ── Colour: the light band (landing only, optional) ────────────────────── */
  /* No pink text or fill inside it; its primary button is near-black with
     off-white text. */
  --band-bg:    #f5f0e8;
  --band-ink:   #151412;    /* 16.2:1 on --band-bg */
  --band-muted: #5c574f;    /* 6.3:1 on --band-bg */

  /* ── Space ──────────────────────────────────────────────────────────────── */
  /* Side gutter: 20px on a 390px phone (5.2vw = 20.3px), 75px at 1440, capped
     at 100px from 1923px up. */
  --gutter: clamp(20px, 5.2vw, 100px);
  /* Vertical rhythm between page sections (REFERENCE.md §3: viewport-relative). */
  --space-section: clamp(40px, 6vh, 96px);
  --space-block:   clamp(24px, 3vh, 40px);

  /* ── Shape ──────────────────────────────────────────────────────────────── */
  --radius-control: 10px;
  --radius-card:    16px;
  --radius-pill:    999px;
  /* Depth: an offset, soft shadow on what floats; nothing glows. */
  --shadow-float: 0 12px 32px rgb(var(--shade-rgb) / .45), 0 2px 6px rgb(var(--shade-rgb) / .35);

  /* ── Motion ─────────────────────────────────────────────────────────────── */
  /* easeOutQuint-like settle for things that arrive; easeInOutCubic for
     things that move between two states; the reference's menu curve for the
     one large reveal. */
  --ease:    cubic-bezier(.22, 1, .36, 1);
  --ease-io: cubic-bezier(.65, 0, .35, 1);
  --ease-reveal: cubic-bezier(.76, 0, .24, 1);
  --dur-hover: .15s;
  --dur-ui:    .25s;
  --dur-fade:  .4s;

  /* ── Type ───────────────────────────────────────────────────────────────── */
  --font-display: 'Outfit', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-body:    'DM Sans', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  /* Two weights per family (base.html loads exactly these four). */
  --w-body:        400;   /* DM Sans */
  --w-body-strong: 500;   /* DM Sans */
  --w-display:     600;   /* Outfit */
  --w-display-strong: 700; /* Outfit */

  /* Scale. Fluid between a 390px phone and a 1440px desktop; each step about
     1.25x the one below at desktop. Body grows from 15px to 17px (was 13 to
     15), so a phone reads at 15px. The display size is for the landing only,
     capped at 160px (REFERENCE.md: the reference reaches 254px; the cap keeps
     the hero's buttons above the fold at 1280x720). */
  --text-label:   12px;                                  /* uppercase labels; the floor */
  --text-small:   clamp(13px, calc(12px + .14vw), 14px);
  --text-body:    clamp(15px, calc(14px + .21vw), 17px);
  --text-lead:    clamp(17px, calc(15px + .42vw), 21px);
  --text-h3:      clamp(19px, calc(16px + .55vw), 24px);
  --text-h2:      clamp(24px, calc(18px + 1.2vw), 36px);
  --text-h1:      clamp(32px, calc(20px + 2.6vw), 56px);
  --text-display: clamp(48px, calc(8px + 10vw), 160px);
  --text-nav:     clamp(14px, 1.05vw, 16px);
  --track-display: -.035em;
  --track-heading: -.02em;
  --track-nav:  -.01em;
  --track-label: .06em;

  /* ── Redesign scale (ui-overhaul-v1, 2026-10-15) ────────────────────────── */
  /* Added beside the scale above, which the app keeps until each page group
     moves over. Every fluid size is clamp(rem, rem + vw, rem): the rem term
     keeps it growing with the reader's font-size setting (WCAG 1.4.4), which
     a vw-only middle value does not. Derivations: docs/reference/
     derived-constants.md "Redesign scale". */

  /* Display. Leading .85-.9 (the reference's display faces sit at .82-.9);
     Outfit is wider than a condensed face, so .88 keeps descenders clear. */
  --fs-display-xxl: clamp(4rem, 2rem + 10vw, 10rem);    /* 69px @375, 160px from 1280 */
  --fs-display-xl:  clamp(3rem, 1.75rem + 5.5vw, 7rem);  /* 49px @375, 107px @1440 */
  --fs-display-l:   clamp(2.25rem, 1.5rem + 3vw, 4.5rem); /* 36px @375, 67px @1440 */
  --fs-display-m:   clamp(1.75rem, 1.25rem + 1.75vw, 3rem);
  --lh-display:     .88;
  /* Headings that wrap onto lines with descenders. Outfit is mixed case, and
     a line ending in y, g or a comma above a line starting with an ascender
     needs about .945em baseline to baseline before the ink touches
     (measured in Chrome, 375-1440px, step 2c); .98 leaves at least 3% of
     the size clear at every measured pair. The reference sets .82-.9 only
     because its display face is all caps, which has no descenders. The
     hero's three single words stay at --lh-display. */
  --lh-display-stack: .98;
  --track-display-xxl: -.04em;
  /* Text sizes on rem, for new components. */
  --fs-body:  clamp(1rem, .95rem + .2vw, 1.0625rem);    /* 16px → 17px */
  --fs-lead:  clamp(1.0625rem, .95rem + .55vw, 1.375rem);
  --fs-small: .875rem;
  --fs-label: .75rem;

  /* Space: a fixed rem ladder plus three fluid steps. */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: .75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;
  --pad-x:       clamp(1rem, .5rem + 2.2vw, 3rem);      /* side padding: 16px @375, 40px @1440, 3rem from 1818 */
  --pad-section: clamp(4rem, 2.5rem + 5vw, 8rem);
  --grid-max:    101.25rem;                              /* 1620px */
  --grid-gap:    clamp(1.5rem, .5rem + 3.125vw, 3rem);   /* 24px phone, 3rem from 1280px */
  --nav-h:       4.5rem;                                 /* 72px bar */

  /* Shape. */
  --radius-media: .5rem;    /* image and video slots */
  --radius-slab:  1rem;     /* the full-width call-to-action block */

  /* Motion: four steps inside 100-400ms. */
  --dur-1: 100ms;
  --dur-2: 200ms;
  --dur-3: 300ms;   /* the nav's transparent → solid change */
  --dur-4: 400ms;

  /* Focus: one ring, the accent, offset onto the ground. */
  --focus-width:  2px;
  --focus-offset: 2px;
  --target-min:   2.75rem;   /* 44px touch target */
}

/* Breakpoints, mobile-first. 740px is the layout breakpoint (min-width:
   741px for the two-column layouts); 64rem (1024px) is the wide one (the full
   nav, the wide grids). A custom property cannot appear in a media query, so
   each is written out where it is used. */

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-hover: 0s;
    --dur-ui:    0s;
    --dur-fade:  0s;
    --dur-1: 0ms;
    --dur-2: 0ms;
    --dur-3: 0ms;
    --dur-4: 0ms;
  }
}
