/* ══════════════════════════════════════════════════════════════════════
   tokens.css — design tokens
   ──────────────────────────────────────────────────────────────────────
   Every colour, type size and timing value in the site resolves to one
   of these custom properties. The Spotify integration rewrites the
   --accent-*, --bg-* and --text-* values at runtime via applyTheme()
   in assets/js/theme.js. Nothing else is overwritten.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Base palette — warm dark editorial ─────────────────────────── */
  --bg:     #0f0f11;   /* page background                          */
  --bg-1:   #141417;   /* slightly elevated surfaces (nav, footer) */
  --bg-2:   #1a1a1e;   /* cards, inset panels                      */
  --bg-3:   #202024;   /* deepest surface (code blocks, inputs)    */

  /* ── Text tones ─────────────────────────────────────────────────
     Contrast ratios against --bg:
       --text    ≈ 15.4:1
       --text-2  ≈  7.1:1
       --text-3  ≈  4.6:1  (WCAG AA minimum for body text)
     --text-3 is the floor: do not darken it without re-checking. */
  --text:   #ddd8cf;
  --text-2: #9d9d9f;
  --text-3: #7c7c81;

  /* ── Type scale ─────────────────────────────────────────────────── */
  --fs-xs: 0.875rem;  /* 14px — metadata, tags, labels        */
  --fs-sm: 1rem;      /* 16px — body copy                     */
  --fs-md: 1.125rem;  /* 18px — prominent body / small headings */
  --fs-lg: 1.25rem;   /* 20px — standard headings             */
  --fs-xl: 2rem;      /* 32px — stat values                   */
  --fs-display-sm: clamp(1.8rem, 3vw, 2.5rem);
  --fs-display-lg: clamp(3rem, 6vw, 5.5rem);

  /* ── Spacing scale ──────────────────────────────────────────────── */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 2.5rem;
  --sp-8: 4rem;
  --sp-9: 6rem;

  /* ── Measure ────────────────────────────────────────────────────── */
  --wrap:      1100px;   /* content column width  */
  --gutter:    2rem;     /* page side padding     */
  --nav-h:     4.5rem;   /* fixed header height, used for scroll-margin */

  /* ── Borders & rules ────────────────────────────────────────────── */
  --rule:   rgba(221, 216, 207, 0.08);
  --rule-2: rgba(221, 216, 207, 0.14);

  /* ── Accent colours ─────────────────────────────────────────────
     Overwritten by album-art extraction. The defaults are neutral
     greys so the site reads correctly before Spotify responds. */
  --accent:   #8a8a8a;   /* dominant album colour  */
  --accent-2: #a3a3a3;   /* contrast album colour  */
  --accent-3: #bcbcbc;   /* mid-tone album colour  */

  /* ── Hero gradient cross-fade ───────────────────────────────────
     Written by theme.js from the track tempo. See --grad-* below. */
  --t-grad: 1400ms;

  /* ── BPM animation timing ───────────────────────────────────────
     Updated from Spotify audio features. Default ≈ 100 BPM. */
  --bpm:      600ms;
  --bpm-half: 300ms;

  /* ── Global theme transition ────────────────────────────────────
     Applied to colour-bearing properties so palette swaps ease in
     rather than snapping. */
  --t: 700ms ease;
}


/* ══════════════════════════════════════════════════════════════════════
   HERO GRADIENT STOPS
   ──────────────────────────────────────────────────────────────────────
   Registered so they interpolate. A plain custom property inside a
   gradient snaps to its new value, which makes the hero jump on every
   track change; a registered <color> cross-fades properly.
   @property has been Baseline since July 2024, and degrades gracefully:
   unregistered, the gradient still renders, it just snaps.

   theme.js writes literal rgba() strings here rather than the colours
   being composed in CSS from var(--accent). Interpolating a registered
   property whose value arrives through var() indirection is the least
   reliable corner of @property across engines, and theme.js already has
   the RGB triples in hand.
   ══════════════════════════════════════════════════════════════════════ */

@property --grad-1 {
  syntax: '<color>';
  inherits: true;
  initial-value: rgba(138, 138, 138, 0.34);
}

@property --grad-2 {
  syntax: '<color>';
  inherits: true;
  initial-value: rgba(163, 163, 163, 0.28);
}

@property --grad-3 {
  syntax: '<color>';
  inherits: true;
  initial-value: rgba(188, 188, 188, 0.24);
}

/* The transition belongs on :root, the element whose values actually
   change. Declaring it on the gradient layer would do nothing — the
   value only inherits there. */
:root {
  transition: --grad-1 var(--t-grad) ease,
              --grad-2 var(--t-grad) ease,
              --grad-3 var(--t-grad) ease;
}
