/*! RelaxingJazz.com · rj.css · design system + shell (FOUNDATION)
 *
 * "Saint Lucia after dark": a deep night sky with a whisper of indigo, warm gold, a little sunset coral,
 * lagoon teal for live and positive states. Playfair Display for display type (with one italic gold <em>
 * per headline), Outfit for the interface. Signature motifs: the thin gold horizon line and the Pitons.
 *
 * Everyone else uses ONLY the tokens and classes in this file. Page files add layout in {page}.css.
 *
 * ── WCAG 2.x contrast, computed (relative luminance, alpha composited over --bg) ──────────────────────
 *  Body text needs 4.5:1, large text and UI parts 3:1. Every pair below passes AA. Regenerate with the
 *  script in _reports/fix-F2.md (it reads this file) if you touch a colour. Last run: 2026-10-06.
 *  Gold has two jobs: --gold is gold as TEXT (links, eyebrows, rules, focus), --gold-fill is gold as a
 *  FILL (primary buttons, play discs, filled badges) with --on-gold-fill on top. In Night they are the
 *  same colour; in Day the fill is the warm signature gold and the text gold stays dark for AA.
 *
 *  DARK ("Night", the default)
 *             bg       raised   sunken   surface* s-solid  s-hover
 *   --text    16.42    15.43    16.85    14.97    14.61    13.25
 *   --text-2  10.14     9.53    10.41     9.24     9.03     8.18
 *   --text-3   6.19     5.81     6.35     5.64     5.50     4.99
 *   --gold    10.37     9.74    10.64     9.45     9.23     8.37
 *   --gold-2  13.62    12.80    13.98    12.42    12.12    10.99
 *   --coral    8.96     8.42     9.19     8.16     7.97     7.23
 *   --lagoon  11.16    10.49    11.45    10.18     9.93     9.01
 *   --love     7.91     7.44     8.12     7.21     7.04     6.38
 *   --live    11.43    10.74    11.73    10.42    10.17     9.22
 *   --danger   8.70     8.18     8.93     7.93     7.74     7.02
 *   --on-gold on --gold 9.92 · on --gold-2 13.03
 *   --on-gold-fill on --gold-fill 9.92 · on --gold-fill-2 13.03 (the fill is --gold)
 *   UI 3:1 → --focus 10.66–13.55 · --border-strong 3.01–3.83 (over bg, sunken, surface-solid, surface-hover)
 *   Tinted fills (token text on a 14% wash of itself, worst case): gold 7.04 · coral 6.25 · lagoon 7.37
 *   · love 5.64 · danger 6.11
 *
 *  LIGHT ("Day")
 *             bg       raised   sunken   surface* s-solid  s-hover
 *   --text    14.90    16.09    13.37    16.12    16.66    14.14
 *   --text-2   8.47     9.15     7.60     9.17     9.48     8.04
 *   --text-3   5.79     6.25     5.20     6.27     6.48     5.50
 *   --gold     5.46     5.90     4.90     5.91     6.11     5.19
 *   --gold-2   6.95     7.51     6.24     7.52     7.78     6.60
 *   --coral    5.98     6.46     5.36     6.47     6.69     5.68
 *   --lagoon   5.99     6.47     5.37     6.48     6.70     5.69
 *   --love     6.28     6.78     5.64     6.80     7.03     5.96
 *   --live     5.99     6.47     5.37     6.48     6.70     5.69
 *   --danger   5.86     6.33     5.26     6.34     6.55     5.56
 *   --on-gold on --gold 6.01 · on --gold-2 7.65 (selection, the checked switch)
 *   --on-gold-fill #1f1606 on --gold-fill #c99a3a 6.95 · on --gold-fill-2 #d4a94f 8.16
 *   (the fill against the page is 2.25–2.51: decorative, the dark label or icon on it carries the meaning)
 *   UI 3:1 → --focus 4.90–6.11 · --border-strong 3.18–3.96
 *   Tinted fills (token text on a 10% wash of itself, worst case): gold 4.77 · coral 5.16 · lagoon 5.16
 *   · love 5.37 · danger 5.01
 *
 *  * surface = the glass card colour composited over --bg. The old site's --text-muted #5a564f was 2.71:1.
 * ─────────────────────────────────────────────────────────────────────────────────────────────────────── */

/* ============================================================== 1. Fonts (self-hosted, latin, OFL) ==== */
/* Google Fonts serves variable files to modern browsers, so one file covers every weight we use. */
@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 300 600;
  font-display: swap;
  src: url("../fonts/outfit-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Playfair Display";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/playfair-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Playfair Display";
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/playfair-italic-latin-var-2.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Metric-matched fallbacks (computed from the real fonts) so the swap barely shifts the layout. */
@font-face { font-family: "Outfit Fallback"; src: local("Arial"), local("Helvetica Neue"), local("Helvetica"); size-adjust: 99.2%; ascent-override: 100.8%; descent-override: 26.2%; line-gap-override: 0%; }
@font-face { font-family: "Playfair Fallback"; src: local("Georgia"); size-adjust: 101.5%; ascent-override: 106.6%; descent-override: 24.7%; line-gap-override: 0%; }
@font-face { font-family: "Playfair Fallback"; font-style: italic; src: local("Georgia Italic"), local("Georgia-Italic"); size-adjust: 94.6%; ascent-override: 114.4%; descent-override: 26.5%; line-gap-override: 0%; }

/* ============================================================== 2. Tokens ============================ */
:root {
  /* Type */
  --font-display: "Playfair Display", "Playfair Fallback", Georgia, "Times New Roman", serif;
  --font-ui: "Outfit", "Outfit Fallback", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  /* Fluid scale: 360 px → 1280 px viewport, ratio 1.17 → 1.25, base 16 → 17.5 px */
  --step--2: clamp(0.781rem, 0.774rem + 0.033vw, 0.800rem);
  --step--1: clamp(0.855rem, 0.847rem + 0.035vw, 0.875rem);
  --step-0:  clamp(1.000rem, 0.963rem + 0.163vw, 1.094rem);
  --step-1:  clamp(1.170rem, 1.093rem + 0.343vw, 1.367rem);
  --step-2:  clamp(1.369rem, 1.236rem + 0.591vw, 1.709rem);
  --step-3:  clamp(1.602rem, 1.392rem + 0.930vw, 2.136rem);
  --step-4:  clamp(1.874rem, 1.562rem + 1.385vw, 2.670rem);
  --step-5:  clamp(2.192rem, 1.744rem + 1.992vw, 3.338rem);
  --step-6:  clamp(2.565rem, 1.936rem + 2.795vw, 4.172rem);

  /* Space (4 → 128 px) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;
  --gutter: clamp(1rem, 4vw, 2.5rem);

  /* Shape */
  --radius-s: 8px;
  --radius-m: 14px;
  --radius-l: 22px;
  --radius-pill: 999px;

  /* Layout. Media queries are in em, so a larger default text size switches to the compact layouts sooner.
     --header-h is how much of the viewport the sticky header covers (0 when it isn't sticky, see §10).
     --player-h is the bar's MINIMUM height: it grows with the text, and theme-boot.js publishes the real
     height as --player-space for the page's bottom padding (falling back to --player-h without JS). */
  --container: 1200px;
  --container-narrow: 760px;
  --header-h: 68px;
  --player-h: max(76px, 2.5rem + 26px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --player-cover: var(--player-space, calc(var(--player-h) + var(--safe-bottom)));

  /* Inner-page hero rhythm: every page's eyebrow and H1 land at the same place (Home has its own hub). */
  --page-hero-pad-top: clamp(3rem, 2rem + 4vw, 6rem);
  --page-hero-pad-bottom: clamp(2rem, 1.5rem + 2vw, 3rem);
  --page-hero-title: var(--step-6);

  /* Motion: slow, calm, ease-out, never bouncy */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-1: 200ms;
  --dur-2: 320ms;
  --dur-3: 600ms;

  /* ---------- Colour: NIGHT (default) ---------- */
  color-scheme: dark;
  --bg: #0b0d1b;
  --bg-raised: #11142a;
  --bg-sunken: #080915;
  --surface: rgba(24, 28, 58, 0.66);
  --surface-solid: #151935;
  --surface-hover: #1c2143;
  --border: rgba(232, 208, 160, 0.12);
  --border-strong: #6e6a85;
  --text: #f2ece1;
  --text-2: #c3bbad;
  --text-3: #958fa2;
  --gold: #dfb968;               /* gold as TEXT, lines, rules and focus: always AA on every background */
  --gold-2: #f1d699;
  --on-gold: #191306;            /* text on a --gold background (selection, the checked switch) */
  --gold-fill: var(--gold);      /* gold as a FILL: primary buttons, play discs, badges, record labels */
  --gold-fill-2: var(--gold-2);  /* … their hover */
  --on-gold-fill: var(--on-gold);/* text and icons on --gold-fill / --gold-fill-2 */
  --coral: #ff9474;
  --lagoon: #5fd8c8;
  --love: #ff7d93;
  --live: #62dcb6;
  --danger: #ff8e86;
  --focus: #f4d27e;
  --glow: #dfb968;               /* set from the current album art by rj.js; gold until then */
  --tint: 14%;                   /* strength of the wash behind tinted badges, chips and pressed buttons */
  --pitons-ink: #05060e;         /* the mountains against the night sky */
  --scrim: rgba(4, 5, 12, 0.66);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.35), 0 2px 8px rgba(0, 0, 0, 0.18);
  --shadow-2: 0 6px 18px rgba(0, 0, 0, 0.32), 0 2px 6px rgba(0, 0, 0, 0.2);
  --shadow-3: 0 24px 60px -12px rgba(0, 0, 0, 0.6), 0 8px 20px rgba(0, 0, 0, 0.3);
  --horizon: linear-gradient(90deg, transparent, var(--gold) 18%, var(--gold) 82%, transparent);
}

:root[data-theme="light"] {
  /* ---------- Colour: DAY (warm sand and paper, deep-ink text, AA-safe dark gold for text) ----------
     Gold is split in two here: the dark --gold keeps text, links and focus rings AA, while fills use the
     station's warm signature gold (--gold-fill) with dark ink on top, so buttons don't read as brown. */
  color-scheme: light;
  --bg: #f5efe3;
  --bg-raised: #fbf8f1;
  --bg-sunken: #ebe3d2;
  --surface: rgba(255, 252, 246, 0.72);
  --surface-solid: #fffcf6;
  --surface-hover: #f1e9da;
  --border: rgba(70, 50, 20, 0.14);
  --border-strong: #877d6c;
  --text: #1b1a2c;
  --text-2: #46415a;
  --text-3: #5f5a6c;
  --gold: #7e5a10;
  --gold-2: #6b4b0c;
  --on-gold: #fffaf0;
  --gold-fill: #c99a3a;
  --gold-fill-2: #d4a94f;
  --on-gold-fill: #1f1606;
  --coral: #9b3c25;
  --lagoon: #08665b;
  --love: #a22842;
  --live: #08665b;
  --danger: #ad2a20;
  --focus: #7e5a10;
  --glow: #c99a43;
  --tint: 10%;
  --pitons-ink: #d8cbb2;
  --scrim: rgba(40, 32, 20, 0.42);
  --shadow-1: 0 1px 2px rgba(60, 40, 10, 0.08), 0 2px 8px rgba(60, 40, 10, 0.06);
  --shadow-2: 0 8px 22px rgba(60, 40, 10, 0.1), 0 2px 6px rgba(60, 40, 10, 0.06);
  --shadow-3: 0 24px 60px -16px rgba(60, 40, 10, 0.28), 0 8px 20px rgba(60, 40, 10, 0.1);
}

/* ============================================================== 3. Base ============================== */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scrollbar-gutter: stable;
  scroll-padding-top: calc(var(--header-h) + var(--space-4));
  scroll-padding-bottom: calc(var(--player-cover) + var(--space-4));
  background: var(--bg);
  scrollbar-color: var(--border-strong) transparent;
}
/* No global smooth scrolling: router swaps and programmatic scrolls are instant. rj.js smooth-scrolls
   same-page #hash links itself, and only when the listener allows motion. */
html:has(dialog[open]) { overflow: hidden; }
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  position: relative;
  isolation: isolate;
  overflow-x: clip;
  padding-bottom: var(--player-cover);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.6;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
/* The night sky: faint stars above the fold (Night), a warm sun haze (Day). Fixed, behind everything. */
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto 0;
  height: 80vh;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(1px 1px at 17px 23px, rgba(255, 244, 220, 0.75), transparent 60%),
    radial-gradient(1px 1px at 131px 87px, rgba(255, 244, 220, 0.55), transparent 60%),
    radial-gradient(1.4px 1.4px at 211px 161px, rgba(255, 244, 220, 0.7), transparent 60%),
    radial-gradient(1px 1px at 59px 199px, rgba(200, 210, 255, 0.5), transparent 60%),
    radial-gradient(120% 70% at 50% -10%, rgba(54, 62, 140, 0.32), transparent 70%);
  background-size: 271px 271px, 337px 337px, 419px 419px, 293px 293px, 100% 100%;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.5) 45%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.5) 45%, transparent 100%);
  opacity: 0.6;
}
:root[data-theme="light"] body::before {
  background-image: radial-gradient(70% 60% at 88% -12%, rgba(240, 190, 110, 0.32), transparent 70%),
    radial-gradient(60% 50% at 0% 0%, rgba(255, 255, 255, 0.6), transparent 70%);
  background-size: 100% 100%, 100% 100%;
  opacity: 1;
}
/* Paper grain, a whisper: makes flat colour feel like a printed sleeve. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .55 0 0 0 0 .5 0 0 0 0 .42 0 0 0 .9 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}
:root[data-theme="light"] body::after { opacity: 0.09; }

main { flex: 1 0 auto; display: block; }
main:focus { outline: none; }
main h1:focus:not(:focus-visible) { outline: none; }

img, svg, video, canvas, picture { display: block; max-width: 100%; }
img { height: auto; }
svg { fill: currentColor; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; }
button:disabled, [aria-disabled="true"] { cursor: not-allowed; }
p, h1, h2, h3, h4, h5, h6, figure, blockquote, dl, dd { margin: 0; }
ul[class], ol[class] { margin: 0; padding: 0; list-style: none; }
[hidden] { display: none !important; }
abbr[title] { text-decoration: underline dotted; text-underline-offset: 0.2em; }
hr { border: 0; height: 1px; background: var(--border); margin: var(--space-7) 0; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--text);
  text-wrap: balance;
}
h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
h1 em, h2 em, h3 em, h4 em, .h-display em, .brand__word em {
  font-style: italic;
  color: var(--gold);
  font-weight: 400;
}
p { text-wrap: pretty; }
strong, b { font-weight: 600; }
small { font-size: var(--step--1); }

a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--gold) 55%, transparent);
  text-underline-offset: 0.22em;
  transition: color var(--dur-1) var(--ease), text-decoration-color var(--dur-1) var(--ease);
}
a:hover { color: var(--gold); text-decoration-color: currentColor; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}
summary:focus-visible, [role="button"]:focus-visible, [role="tab"]:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
::selection { background: var(--gold); color: var(--on-gold); }

kbd {
  display: inline-block;
  min-width: 1.8em;
  padding: 0.1em 0.45em;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: var(--bg-sunken);
  font-family: var(--font-ui);
  font-size: 0.85em;
  font-weight: 500;
  text-align: center;
  line-height: 1.4;
}

/* JS / no-JS */
.no-js-only { display: none; }
html:not(.js) .no-js-only { display: revert; }
html:not(.js) .js-only { display: none !important; }

/* ============================================================== 4. Utilities ========================= */
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}
.skip-link {
  position: fixed;
  left: var(--space-4);
  top: var(--space-3);
  z-index: 100;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-pill);
  background: var(--gold-fill);
  color: var(--on-gold-fill);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur-1) var(--ease);
}
.skip-link:focus, .skip-link:focus-visible { transform: none; color: var(--on-gold-fill); }
.skip-link + .skip-link { left: calc(var(--space-4) + 12.5rem); }

.icon {
  width: 1.25em;
  height: 1.25em;
  flex: none;
  display: inline-block;
  vertical-align: -0.22em;
  fill: currentColor;
}
.icon--sm { width: 1em; height: 1em; }
.icon--lg { width: 1.6em; height: 1.6em; }
.icon--ext { width: 0.8em; height: 0.8em; margin-left: 0.3em; vertical-align: 0; opacity: 0.75; }

/* ============================================================== 5. Layout ============================ */
.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}
.container--narrow { width: min(100% - 2 * var(--gutter), var(--container-narrow)); margin-inline: auto; }
.section { padding-block: clamp(var(--space-7), 8vw, var(--space-9)); }
.section--tight { padding-block: clamp(var(--space-6), 5vw, var(--space-8)); }
.section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-3) var(--space-6);
  margin-bottom: clamp(var(--space-5), 4vw, var(--space-7));
}
.section__head > :first-child { max-width: 46rem; }
.section__head h2 { margin-top: var(--space-2); }
.section__head .lede { margin-top: var(--space-3); }
.section__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-weight: 500;
  font-size: var(--step--1);
  letter-spacing: 0.02em;
  color: var(--gold);
  text-decoration: none;
  min-height: 44px;
}
.section__link:hover { color: var(--gold-2); }
.section__link .icon { transition: transform var(--dur-1) var(--ease); }
.section__link:hover .icon { transform: translateX(3px); }

.stack { display: flex; flex-direction: column; gap: var(--stack-gap, var(--space-4)); }
.stack--s { --stack-gap: var(--space-2); }
.stack--l { --stack-gap: var(--space-6); }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cluster-gap, var(--space-3)); }
.cluster--tight { --cluster-gap: var(--space-2); }
.grid { display: grid; gap: var(--grid-gap, clamp(var(--space-4), 2.5vw, var(--space-6))); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 40em) {   /* 640px at the default text size */
  .grid--2, .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 60em) {   /* 960px */
  .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 71.25em) { /* 1140px */
  .grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Inner-page hero: <section class="page-hero"> … <h1 class="page-hero__title">. Every page's eyebrow and H1
   land at the same y and size, so nothing jumps on a page swap. Side panels align to the top
   (.page-hero__grid), never centre against the text. Page CSS may use the tokens directly, with fallbacks. */
.page-hero { padding-top: var(--page-hero-pad-top); padding-bottom: var(--page-hero-pad-bottom); }
.page-hero .page-hero__title { font-size: var(--page-hero-title); }
.page-hero__grid { align-items: start; }

/* The gold horizon line: the station's signature divider. Add --pitons for the mountains on the line.
   overflow: visible because <hr> is overflow: hidden in the UA sheet, which would clip the mountains.
   width: 100% because a grid or flex item with auto side margins would otherwise shrink to nothing. */
.divider-horizon {
  position: relative;
  display: block;
  width: 100%;
  height: 1px;
  margin: clamp(var(--space-6), 6vw, var(--space-8)) auto;
  border: 0;
  overflow: visible;
  background: var(--horizon);
  opacity: 0.7;
}
.divider-horizon--pitons { opacity: 1; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--gold) 70%, transparent) 18%, color-mix(in srgb, var(--gold) 70%, transparent) 82%, transparent); }
.divider-horizon--pitons::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: min(220px, 50%);
  aspect-ratio: 1200 / 160;
  transform: translateX(-50%);
  background: var(--text-3);
  opacity: 0.55;
  -webkit-mask: url("../img/pitons.svg") center bottom / 100% 100% no-repeat;
  mask: url("../img/pitons.svg") center bottom / 100% 100% no-repeat;
}
/* Gros & Petit Piton silhouette, coloured by `color`. Size it with width; height follows. */
.pitons {
  display: block;
  width: 100%;
  aspect-ratio: 1200 / 160;
  background-color: currentColor;
  -webkit-mask: url("../img/pitons.svg") center bottom / 100% 100% no-repeat;
  mask: url("../img/pitons.svg") center bottom / 100% 100% no-repeat;
}

/* ============================================================== 6. Typography ======================== */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.8em;
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.16em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--gold);
}
.eyebrow::before {
  content: "";
  width: 1.9em;
  height: 1px;
  background: currentColor;
  opacity: 0.8;
  flex: none;
}
.eyebrow--plain::before { display: none; }
.h-display {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--step-6);
  line-height: 1.04;
  letter-spacing: -0.018em;
  color: var(--text);
  text-wrap: balance;
}
.h-display em { padding-right: 0.04em; }
.lede {
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.55;
  color: var(--text-2);
  max-width: 60ch;
}
.prose {
  max-width: 68ch;
  color: var(--text-2);
  line-height: 1.75;
}
.prose > * + * { margin-top: 1.1em; }
.prose h2, .prose h3 { color: var(--text); margin-top: 1.8em; }
.prose h2 + *, .prose h3 + * { margin-top: 0.6em; }
.prose a { color: var(--gold); }
.prose a:hover { color: var(--gold-2); }
.prose strong { color: var(--text); }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li + li { margin-top: 0.4em; }
.prose li::marker { color: var(--gold); }
.prose blockquote {
  padding-left: var(--space-5);
  border-left: 2px solid var(--gold);
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--text);
}
.prose img { border-radius: var(--radius-m); }
.prose--lead > p:first-child { font-size: var(--step-1); color: var(--text); }
.muted { color: var(--text-3); }
.tabular { font-variant-numeric: tabular-nums; }

/* ============================================================== 7. Surfaces ========================== */
.card {
  position: relative;
  padding: clamp(var(--space-5), 3vw, var(--space-6));
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  background: var(--surface-solid);
  box-shadow: var(--shadow-1);
}
.card--glass { background: var(--surface-solid); }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .card--glass {
    background: var(--surface);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
  }
}
.card--link {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: transform var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease);
}
.card--link .card__link { text-decoration: none; color: inherit; }
.card--link .card__link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.card--link:hover, .card--link:focus-within {
  border-color: color-mix(in srgb, var(--gold) 38%, transparent);
  box-shadow: var(--shadow-2);
  background-color: var(--surface-hover);
}
.card--link:has(.card__link:focus-visible) { outline: 2px solid var(--focus); outline-offset: 3px; }
.card--link .card__link:focus-visible { outline: none; }
@media (prefers-reduced-motion: no-preference) {
  .card--link:hover { transform: translateY(-3px); }
}
.card__title { font-size: var(--step-2); }
.card__title + * { margin-top: var(--space-2); }

/* ============================================================== 8. Controls ========================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55em;
  min-height: 44px;
  padding: 0.6em 1.35em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-hover);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  /* One line whenever it fits, like nowrap (no shrinking in flex rows), but a label that is wider than
     its container (large text, 400% zoom) wraps instead of pushing the page sideways. */
  flex-shrink: 0;
  max-width: 100%;
  white-space: normal;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease), box-shadow var(--dur-2) var(--ease), transform var(--dur-1) var(--ease);
}
.btn:hover { border-color: var(--gold); color: var(--text); }
.btn:active { transform: translateY(1px); }
.btn--primary {
  border-color: var(--gold-fill);
  background: var(--gold-fill);
  color: var(--on-gold-fill);
  box-shadow: 0 8px 26px -10px color-mix(in srgb, var(--gold-fill) 70%, transparent);
}
.btn--primary:hover { background: var(--gold-fill-2); border-color: var(--gold-fill-2); color: var(--on-gold-fill); }
.btn--ghost { background: transparent; }
.btn--ghost:hover { background: var(--surface-hover); }
.btn--sm { min-height: 36px; padding: 0.4em 1em; }
.btn--lg { min-height: 56px; padding: 0.8em 1.8em; font-size: var(--step-0); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }
.btn .icon { width: 1.15em; height: 1.15em; }

.icon-btn {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-2);
  transition: background-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.icon-btn:hover { background: var(--surface-hover); color: var(--text); }
.icon-btn[aria-pressed="true"] { color: var(--gold); }
.icon-btn--sm { width: 36px; height: 36px; }
.icon-btn .icon { width: 22px; height: 22px; }
.icon-btn--sm .icon { width: 19px; height: 19px; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  min-height: 36px;
  padding: 0.35em 1em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-2);
  font-size: var(--step--1);
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
a.chip:hover, button.chip:hover { border-color: var(--gold); color: var(--text); }
.chip[aria-pressed="true"], .chip[aria-current="page"], .chip[aria-current="true"] {
  border-color: var(--gold);
  background: color-mix(in srgb, var(--gold) var(--tint), transparent);
  color: var(--gold);
}
.chip[aria-pressed="true"]::before {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: currentColor;
}
.chip--more { border-style: dashed; color: var(--text-3); }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.2em 0.7em;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--text-3) var(--tint), transparent);
  color: var(--text-2);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}
.badge--live { color: var(--live); background: color-mix(in srgb, var(--live) var(--tint), transparent); }
.badge--live::before {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 0 currentColor;
}
.badge--new { color: var(--coral); background: color-mix(in srgb, var(--coral) var(--tint), transparent); }
.badge--gold { color: var(--gold); background: color-mix(in srgb, var(--gold) var(--tint), transparent); }
.badge--gold-fill { color: var(--on-gold-fill); background: var(--gold-fill); }

/* Tabs (WAI-ARIA; wire with RJ.ui.tabs) */
.tabs {
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  scrollbar-width: none;
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-6);
  scroll-snap-type: x proximity;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  position: relative;
  flex: none;
  min-height: 48px;
  padding: 0.6em 1.1em;
  border: 0;
  background: none;
  color: var(--text-2);
  font-size: var(--step-0);
  font-weight: 500;
  white-space: nowrap;
  scroll-snap-align: start;
  transition: color var(--dur-1) var(--ease);
}
.tab::after {
  content: "";
  position: absolute;
  left: 0.9em;
  right: 0.9em;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--gold);
  transform: scaleX(0);
  transition: transform var(--dur-2) var(--ease);
}
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--text); }
.tab[aria-selected="true"]::after { transform: scaleX(1); }
.tab:focus-visible { outline-offset: -3px; border-radius: var(--radius-s); }
[role="tabpanel"]:focus-visible { outline-offset: 6px; border-radius: var(--radius-s); }

/* Forms */
.field { display: grid; gap: var(--space-2); }
.field__label { font-size: var(--step--1); font-weight: 500; color: var(--text); }
.field__hint { font-size: var(--step--1); color: var(--text-3); line-height: 1.5; }
.field__error { font-size: var(--step--1); color: var(--danger); }
.field--switch { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: var(--space-3); }
.field--switch .field__hint { grid-column: 1 / -1; }
.input,
.field input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
.field textarea,
.select {
  width: 100%;
  min-height: 48px;
  padding: 0.6em 1em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-m);
  background: var(--bg-sunken);
  color: var(--text);
  line-height: 1.4;
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.field textarea { min-height: 8rem; resize: vertical; }
.input:hover, .select:hover, .field input:hover, .field textarea:hover { border-color: var(--text-3); }
.input:focus-visible, .select:focus-visible, .field input:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--gold);
}
::placeholder { color: var(--text-3); opacity: 1; }
.select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 2.6em;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.25em) 52%, calc(100% - 0.95em) 52%;
  background-size: 0.32em 0.32em, 0.32em 0.32em;
  background-repeat: no-repeat;
  cursor: pointer;
}
.select option { background: var(--surface-solid); color: var(--text); }
.search-field { position: relative; display: flex; align-items: center; }
.search-field > .icon {
  position: absolute;
  left: 1.05em;
  width: 1.2em;
  height: 1.2em;
  color: var(--text-3);
  pointer-events: none;
}
.search-field input {
  width: 100%;
  min-height: 52px;
  padding: 0.7em 1.2em 0.7em 3em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  color: var(--text);
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.search-field input::-webkit-search-cancel-button { filter: grayscale(1); opacity: 0.6; }
.search-field input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--gold); }
.search-field .btn { position: absolute; right: 6px; min-height: 40px; }
.search-field:has(.btn) input { padding-right: 7.5em; }

/* Range (volume) – --val (0–100) paints the gold fill; rj.js keeps it in sync. */
.range {
  --val: 80;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-width: 80px;
  height: 28px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
.range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--gold) calc(var(--val) * 1%), var(--border-strong) calc(var(--val) * 1%));
}
.range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -6px;
  border: 2px solid var(--bg-raised);
  border-radius: 50%;
  background: var(--gold-2);
  box-shadow: 0 0 0 1px var(--gold);
}
.range::-moz-range-track { height: 4px; border-radius: 4px; background: var(--border-strong); }
.range::-moz-range-progress { height: 4px; border-radius: 4px; background: var(--gold); }
.range::-moz-range-thumb { width: 14px; height: 14px; border: 2px solid var(--bg-raised); border-radius: 50%; background: var(--gold-2); box-shadow: 0 0 0 1px var(--gold); }
.range:focus-visible { outline-offset: 2px; border-radius: 4px; }

/* Switch: <input type="checkbox" role="switch" class="switch"> */
.switch {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  flex: none;
  width: 46px;
  height: 28px;
  margin: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.switch::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--text-3);
  transition: transform var(--dur-2) var(--ease), background-color var(--dur-1) var(--ease);
}
.switch:checked { background: var(--gold); border-color: var(--gold); }
.switch:checked::before { transform: translateX(18px); background: var(--on-gold); }

/* External-link cue: <a class="ext" target="_blank" rel="noopener">Label <svg class="icon icon--ext">…</svg>
   <span class="visually-hidden">(opens in new tab)</span></a> (rj_ext() / RJ.ui.extLink() build it) */
.ext { white-space: normal; }
.ext .icon--ext { display: inline-block; }

/* Disclosure (FAQ, "how it works", help): <details class="disclosure"><summary>Question</summary>
   <div class="disclosure__body">…</div></details>. Stack them; each one draws the rule above it. */
.disclosure { border-top: 1px solid var(--border); }
.disclosure > summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding-block: var(--space-2);
  font-weight: 500;
  line-height: 1.35;
  list-style: none;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease);
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::after {
  content: "+";
  content: "+" / "";
  flex: none;
  margin-left: auto;
  color: var(--gold);
  font-size: 1.25em;
  font-weight: 400;
  line-height: 1;
}
.disclosure[open] > summary::after { content: "−"; content: "−" / ""; }
.disclosure > summary:hover { color: var(--gold); }
.disclosure__body { padding-bottom: var(--space-4); color: var(--text-2); }

/* ============================================================== 9. Music components ================== */
/* Album art: square, lazy, fades in, placeholder (initials on a hue gradient) when missing or broken. */
.art {
  position: relative;
  display: block;
  flex: none;
  width: var(--art-size, 100%);
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--radius-s);
  background: var(--bg-sunken);
  box-shadow: inset 0 0 0 1px var(--border);
  container-type: inline-size;
}
.art--48 { --art-size: 48px; border-radius: 6px; }
.art--64 { --art-size: 64px; }
.art--160 { --art-size: 160px; border-radius: var(--radius-m); }
.art--300 { --art-size: 300px; border-radius: var(--radius-m); }
.art--600 { --art-size: 600px; border-radius: var(--radius-l); }
.art--fluid { --art-size: 100%; }
.art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-3) var(--ease);
}
.art img.is-loaded, .art img[data-static] { opacity: 1; }
.art__ph {
  --ph-h: 38;
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 90% at 20% 10%, hsl(calc(var(--ph-h) + 20) 55% 42% / 0.85), transparent 60%),
    linear-gradient(140deg, hsl(var(--ph-h) 42% 26%), hsl(calc(var(--ph-h) + 48) 46% 14%));
  color: rgba(255, 246, 228, 0.92);
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.1rem;
  font-size: clamp(0.8rem, 34cqi, 9rem);
  line-height: 1;
  letter-spacing: 0.02em;
  user-select: none;
}
.art__ph::after {
  content: "";
  position: absolute;
  inset: auto 12% 12% 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(241, 214, 153, 0.7), transparent);
}
:root[data-theme="light"] .art__ph {
  background:
    radial-gradient(120% 90% at 20% 10%, hsl(calc(var(--ph-h) + 20) 60% 86% / 0.9), transparent 60%),
    linear-gradient(140deg, hsl(var(--ph-h) 46% 80%), hsl(calc(var(--ph-h) + 48) 38% 66%));
  color: #2a2134;
}
:root[data-theme="light"] .art__ph::after { background: linear-gradient(90deg, transparent, rgba(126, 90, 16, 0.6), transparent); }

/* Love it ♥ (aria-pressed) + "Not for me". Built by RJ.ui.loveButton(). */
.love-group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.love-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  min-height: 40px;
  padding: 0.35em 0.95em;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-2);
  font-size: var(--step--1);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), background-color var(--dur-1) var(--ease);
}
.love-btn .icon { width: 1.2em; height: 1.2em; }
.love-btn .icon--heart-filled { display: none; }
.love-btn:hover { color: var(--love); border-color: var(--love); }
.love-btn[aria-pressed="true"] {
  color: var(--love);
  border-color: color-mix(in srgb, var(--love) 60%, transparent);
  background: color-mix(in srgb, var(--love) var(--tint), transparent);
}
.love-btn[aria-pressed="true"] .icon--heart { display: none; }
.love-btn[aria-pressed="true"] .icon--heart-filled { display: inline-block; }
.love-btn[aria-disabled="true"] { opacity: 0.55; }
.love-btn[aria-disabled="true"]:hover { color: var(--text-2); border-color: var(--border-strong); }
.love-btn.is-busy { opacity: 0.8; }
.love-btn__count:empty { display: none; }
.love-btn--sm { min-height: 34px; padding: 0.3em 0.7em; font-size: var(--step--2); gap: 0.3em; }
.love-btn--lg { min-height: 52px; padding: 0.5em 1.4em; font-size: var(--step-0); gap: 0.55em; }
.love-btn--lg .icon { width: 1.35em; height: 1.35em; }
.love-btn--lg .love-btn__count { padding-left: 0.6em; margin-left: 0.15em; border-left: 1px solid currentColor; border-left-color: color-mix(in srgb, currentColor 35%, transparent); }
@media (prefers-reduced-motion: no-preference) {
  .love-btn.is-popping .icon--heart-filled { animation: rj-heart var(--dur-3) var(--ease); }
}
@keyframes rj-heart { 0% { transform: scale(0.7); } 45% { transform: scale(1.18); } 100% { transform: scale(1); } }
.vote-nope {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  min-height: 34px;
  padding: 0.2em 0.1em;
  border: 0;
  background: none;
  color: var(--text-3);
  font-size: var(--step--1);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.25em;
  transition: color var(--dur-1) var(--ease), text-decoration-color var(--dur-1) var(--ease);
}
.vote-nope:hover { color: var(--text-2); text-decoration-color: currentColor; }
.vote-nope[aria-pressed="true"] { color: var(--text); }
.vote-nope .icon { width: 1.15em; height: 1.15em; }
.vote-nope .icon--nope-filled { display: none; }
.vote-nope[aria-pressed="true"] .icon--nope { display: none; }
.vote-nope[aria-pressed="true"] .icon--nope-filled { display: inline-block; }
/* small/medium thumbs-down: a round pill beside the heart */
.vote-nope--sm, .vote-nope--md { justify-content: center; min-width: 34px; padding: 0.3em 0.55em; border: 1px solid var(--border-strong); border-radius: var(--radius-pill); color: var(--text-2); text-decoration: none; }
.vote-nope--sm { font-size: var(--step--2); }
.vote-nope--sm:hover, .vote-nope--md:hover { color: var(--text); border-color: var(--text-2); }
.vote-nope--sm[aria-pressed="true"], .vote-nope--md[aria-pressed="true"] { color: var(--text); border-color: var(--text-2); background: color-mix(in srgb, var(--text) 10%, transparent); }
.player-bar__love .love-group { flex-wrap: nowrap; gap: var(--space-2); }
.vote-nope[aria-disabled="true"] { opacity: 0.55; text-decoration: none; }

/* Find menu: <details class="find-menu"> with Apple Music / Spotify / YouTube search links */
.find-menu { position: relative; display: inline-block; }
.find-menu > summary { list-style: none; }
.find-menu > summary::-webkit-details-marker { display: none; }
.find-menu__toggle { color: var(--text-3); }
.find-menu[open] > .find-menu__toggle { background: var(--surface-hover); color: var(--gold); }
.find-menu__panel { right: 0; top: calc(100% + 6px); }
.find-menu--up .find-menu__panel { top: auto; bottom: calc(100% + 6px); }
.find-menu--left .find-menu__panel { right: auto; left: 0; }
.find-menu__title { padding: var(--space-2) var(--space-3) var(--space-1); font-size: var(--step--2); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-3); }
.find-menu__list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 44px;
  padding: 0.45em var(--space-3);
  border-radius: var(--radius-s);
  color: var(--text);
  text-decoration: none;
}
.find-menu__list a:hover { background: var(--surface-hover); color: var(--gold); }

.popover {
  position: absolute;
  z-index: 30;
  min-width: 13.5rem;
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-m);
  background: var(--surface-solid);
  box-shadow: var(--shadow-3);
}
@media (prefers-reduced-motion: no-preference) {
  .popover { animation: rj-rise var(--dur-1) var(--ease); }
}

/* Track row: <li class="track"> art · title/artist/album · time · actions (RJ.ui.trackRow) */
.track-list { display: block; margin: 0; padding: 0; list-style: none; }
.track {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  grid-template-areas: "art main meta actions";
  align-items: center;
  gap: var(--space-2) clamp(var(--space-3), 2vw, var(--space-5));
  padding: var(--space-3) var(--space-2);
  border-bottom: 1px solid var(--border);
  list-style: none;
  transition: background-color var(--dur-1) var(--ease);
}
.track:hover { background: color-mix(in srgb, var(--surface-hover) 55%, transparent); }
.track--ranked { grid-template-columns: 4rem auto minmax(0, 1fr) auto auto; grid-template-areas: "rank art main meta actions"; }
.track__rank { grid-area: rank; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.track__art { grid-area: art; }
.track__art .art { --art-size: 56px; }
.track__main { grid-area: main; min-width: 0; }
.track__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-weight: 500;
  line-height: 1.35;
  color: var(--text);
}
.track__artist { display: block; margin-top: 2px; color: var(--text-2); font-size: var(--step--1); line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.track__artist a { text-decoration: none; color: inherit; }
.track__artist a:hover { color: var(--gold); text-decoration: underline; }
.track__album { display: block; color: var(--text-3); font-size: var(--step--2); font-style: italic; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.track__meta { grid-area: meta; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; color: var(--text-3); font-size: var(--step--1); font-variant-numeric: tabular-nums; white-space: nowrap; }
.track__meta .track__ago { font-size: var(--step--2); }
.track__actions { grid-area: actions; display: flex; align-items: center; gap: var(--space-1); }
.track.is-current { background: linear-gradient(90deg, color-mix(in srgb, var(--gold) 9%, transparent), transparent 70%); box-shadow: inset 2px 0 0 var(--gold); }
.track.is-current .track__time { color: var(--live); }
.track--compact { padding-block: var(--space-2); gap: var(--space-2) var(--space-3); }
.track--compact .track__art .art { --art-size: 44px; }
.track--compact .track__album { display: none; }
@media (max-width: 37.4375em) { /* below 600px */
  .track { grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "art main actions" "art meta actions"; row-gap: 0; padding-inline: 0; }
  .track--ranked { grid-template-columns: 2.4rem auto minmax(0, 1fr) auto; grid-template-areas: "rank art main actions" "rank art meta actions"; }
  /* The meta line may wrap (each part stays whole) and stays inside its column, so a long one such as
     "On air · since 8:12 pm" never runs under the heart and search buttons on narrow phones. */
  .track__meta { flex-direction: row; flex-wrap: wrap; align-items: center; column-gap: var(--space-2); row-gap: 0; justify-self: start; min-width: 0; max-width: 100%; white-space: normal; font-size: var(--step--2); }
  .track__meta > * { white-space: nowrap; }
  .track__meta .track__ago::before { content: "· "; }
  .track__art .art { --art-size: 48px; }
  .track__album { display: none; }
}

/* Track card: for rails ("Just played") – RJ.ui.trackCard */
.track-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  width: 100%;
  min-width: 0;
}
.track-card .art { --art-size: 100%; border-radius: var(--radius-m); box-shadow: var(--shadow-2), inset 0 0 0 1px var(--border); }
.track-card__body { min-width: 0; }
.track-card__title { font-family: var(--font-display); font-size: var(--step-1); font-weight: 500; line-height: 1.25; color: var(--text); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.track-card__artist { color: var(--text-2); font-size: var(--step--1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.track-card__artist a { color: inherit; text-decoration: none; }
.track-card__artist a:hover { color: var(--gold); text-decoration: underline; }
.track-card__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); color: var(--text-3); font-size: var(--step--2); font-variant-numeric: tabular-nums; }

/* Charts: rank numerals and movement */
.rank {
  display: block;
  min-width: 2ch;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--step-3);
  line-height: 1;
  text-align: right;
  color: var(--text-2);
  font-variant-numeric: lining-nums tabular-nums;
}
.rank--top { color: var(--gold); }
.rank--xl { font-size: var(--step-5); }
.move {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.04em;
  line-height: 1.2;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.move .icon { width: 0.95em; height: 0.95em; vertical-align: 0; }
.move--up { color: var(--lagoon); }
.move--down { color: var(--text-2); }
.move--same { color: var(--text-3); }
.move--new { color: var(--coral); }
.move--re { color: var(--gold); }

/* Progress: <div class="progress" role="progressbar"><span class="progress__bar"></span></div>, set --p (0–1) */
.progress {
  --p: 0;
  position: relative;
  display: block;
  height: 4px;
  overflow: hidden;
  border-radius: 4px;
  background: color-mix(in srgb, var(--text-3) 26%, transparent);
}
.progress__bar {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--gold), var(--gold-2));
  transform: scaleX(var(--p));
  transform-origin: left center;
  transition: transform 1s linear;
}
.progress--live .progress__bar { background: var(--horizon); transform: none; opacity: 0.6; }

/* Equaliser bars: <span class="eq-bars" aria-hidden="true"><i></i><i></i><i></i><i></i></span> */
.eq-bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 0.95em; color: var(--live); vertical-align: -0.05em; }
.eq-bars i { display: block; width: 3px; height: 100%; border-radius: 1px; background: currentColor; transform-origin: bottom; transform: scaleY(0.3); }
.eq-bars i:nth-child(2) { transform: scaleY(0.55); }
.eq-bars i:nth-child(3) { transform: scaleY(0.4); }
@media (prefers-reduced-motion: no-preference) {
  html[data-playing="true"] .eq-bars i { animation: rj-eq 1.1s var(--ease-in-out) infinite alternate; }
  html[data-playing="true"] .eq-bars i:nth-child(2) { animation-duration: 0.8s; animation-delay: -0.4s; }
  html[data-playing="true"] .eq-bars i:nth-child(3) { animation-duration: 1.3s; animation-delay: -0.2s; }
  html[data-playing="true"] .eq-bars i:nth-child(4) { animation-duration: 0.95s; animation-delay: -0.7s; }
}
@keyframes rj-eq { from { transform: scaleY(0.2); } to { transform: scaleY(1); } }

/* Loading, empty and error states */
.skeleton {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-s);
  background: color-mix(in srgb, var(--text-3) 14%, var(--bg-sunken));
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 7%, transparent), transparent);
  transform: translateX(-100%);
}
@media (prefers-reduced-motion: no-preference) {
  .skeleton::after { animation: rj-shimmer 1.6s var(--ease-in-out) infinite; }
}
@keyframes rj-shimmer { to { transform: translateX(100%); } }
.skeleton__line { height: 0.8em; width: 70%; border-radius: 4px; }
.skeleton__line + .skeleton__line { margin-top: 0.6em; width: 45%; }
.skeleton-list { display: block; }
.skeleton-row { display: grid; grid-template-columns: 56px minmax(0, 1fr) 4rem; gap: var(--space-4); align-items: center; padding: var(--space-3) var(--space-2); border-bottom: 1px solid var(--border); }
.skeleton-row .skeleton--art { width: 56px; aspect-ratio: 1; }
.skeleton-row .skeleton--meta { height: 0.8em; }
.skeleton-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 160px), 1fr)); gap: var(--space-5); }
.skeleton-card .skeleton--art { width: 100%; aspect-ratio: 1; border-radius: var(--radius-m); margin-bottom: var(--space-3); }
.empty-state, .error-state {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding: clamp(var(--space-6), 5vw, var(--space-8)) var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  background: color-mix(in srgb, var(--surface-solid) 60%, transparent);
  text-align: center;
}
.empty-state::before {
  content: "";
  width: 120px;
  aspect-ratio: 1200 / 160;
  background: var(--text-3);
  opacity: 0.6;
  -webkit-mask: url("../img/pitons.svg") center / 100% 100% no-repeat;
  mask: url("../img/pitons.svg") center / 100% 100% no-repeat;
}
.empty-state__msg, .error-state__msg { max-width: 42ch; font-family: var(--font-display); font-style: italic; font-size: var(--step-1); line-height: 1.45; color: var(--text-2); }
.error-state__icon { width: 2rem; height: 2rem; color: var(--danger); }

/* Toast (#toast, role=status) – RJ.ui.toast() */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--player-cover) + var(--space-4));
  z-index: 60;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: max-content;
  max-width: min(92vw, 34rem);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--border);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius-m);
  background: var(--surface-solid);
  box-shadow: var(--shadow-3);
  color: var(--text);
  font-size: var(--step--1);
  line-height: 1.45;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 14px);
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease), visibility 0s linear var(--dur-2);
  visibility: hidden;
}
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; visibility: visible; transition-delay: 0s; }
.toast__msg { flex: 1 1 auto; }
.toast__action { flex: none; }
.toast__copy { width: 100%; margin-top: var(--space-2); }
.toast--error { border-left-color: var(--danger); }

/* Dialog sheets (<dialog class="sheet">): the menu and the player options */
.sheet {
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--surface-solid);
  color: var(--text);
  box-shadow: var(--shadow-3);
  overscroll-behavior: contain;
}
.sheet::backdrop { background: var(--scrim); }
@media (prefers-reduced-motion: no-preference) {
  .sheet[open] { animation: rj-sheet-in var(--dur-2) var(--ease); }
  .sheet[open]::backdrop { animation: rj-fade var(--dur-2) var(--ease); }
}
/* A small centred dialog (e.g. the iPhone install steps) */
.sheet--center {
  inset: 0;
  margin: auto;
  width: min(440px, calc(100vw - 2 * var(--gutter)));
  max-height: min(90dvh, 640px);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
}
.sheet__body { padding: clamp(var(--space-5), 4vw, var(--space-6)); }
@media (prefers-reduced-motion: no-preference) {
  .sheet--center[open] { animation-name: rj-rise; }
}
@keyframes rj-sheet-in { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
@keyframes rj-sheet-up { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: none; } }
@keyframes rj-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes rj-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ============================================================== 10. Shell: header ==================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  min-height: var(--header-h);
  background: color-mix(in srgb, var(--bg) 96%, transparent);
  view-transition-name: site-header;
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .site-header { background: var(--bg); }
}
.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--horizon);
  opacity: 0.35;
}
/* The inner row is a size container, so the nav folds into the menu button whenever it no longer fits:
   at a narrower window OR a larger text size (the query is in rem, which follows the text size). */
.site-header__inner { display: flex; align-items: center; gap: var(--space-5); min-height: var(--header-h); container: site-header / inline-size; }
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  margin-right: auto;
  color: var(--text);
  text-decoration: none;
}
.brand:hover { color: var(--text); }
.brand__badge { width: 54px; height: 54px; border-radius: 50%; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35)); transition: transform var(--dur-3) var(--ease); }
@media (prefers-reduced-motion: no-preference) {
  .brand:hover .brand__badge { transform: rotate(-8deg); }
}
.brand__word { font-family: var(--font-display); font-size: var(--step-2); line-height: 1; letter-spacing: -0.005em; }
.brand__word em { padding-left: 0.04em; }
.site-nav__list { display: flex; align-items: center; gap: clamp(0.1rem, 1.2vw, 1rem); }
.site-nav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.55em;
  color: var(--text-2);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  white-space: nowrap;
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0.55em;
  right: 0.55em;
  bottom: 9px;
  height: 1px;
  background: var(--horizon);
  transform: scaleX(0);
  transition: transform var(--dur-2) var(--ease);
}
.site-nav a:hover { color: var(--text); }
.site-nav a:hover::after { transform: scaleX(0.6); }
.site-nav a[aria-current="page"], .site-nav a.is-section { color: var(--text); }
.site-nav a[aria-current="page"]::after, .site-nav a.is-section::after { transform: scaleX(1); background: var(--gold); }
.site-header__tools { display: flex; align-items: center; gap: var(--space-1); }
.theme-toggle .theme-toggle__moon { display: none; }
:root[data-theme="light"] .theme-toggle .theme-toggle__sun { display: none; }
:root[data-theme="light"] .theme-toggle .theme-toggle__moon { display: inline-block; }
.menu-btn { display: none; }
/* The header row needs about 330px + 29rem: 788px at 16px text, 1020px at 24px, 1294px at 32px (the badge
   and buttons are fixed px, the words grow). The threshold keeps 60–80px of slack at every size. Browsers
   without container queries use the old em breakpoint (em in a media query follows the browser's text size). */
@container site-header (max-width: calc(360px + 31rem)) {
  .site-nav { display: none; }
  .menu-btn { display: inline-grid; }
}
@supports not (container-type: inline-size) {
  @media (max-width: 59.9375em) {
    .site-nav { display: none; }
    .menu-btn { display: inline-grid; }
  }
}
@media (max-width: 23.75em) { /* 380px */
  .brand__word { font-size: var(--step-1); }
  .brand__badge { width: 46px; height: 46px; }
}

/* Mobile menu sheet: a record-sleeve tracklist */
.nav-sheet {
  inset: 0 0 0 auto;
  width: min(420px, 92vw);
  height: 100%;
  max-height: 100%;
  border-left: 1px solid var(--border);
  background: var(--bg-raised);
}
.nav-sheet__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100%;
  padding: var(--space-4) var(--space-5) calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
  overflow: hidden;
}
.nav-sheet__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-6); }
.nav-sheet__list { display: grid; gap: var(--space-1); }
.nav-sheet__list a {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  min-height: 52px;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.2;
  text-decoration: none;
}
.nav-sheet__num { flex: none; width: 2.2rem; font-family: var(--font-ui); font-size: var(--step--1); font-weight: 500; letter-spacing: 0.1em; color: var(--gold); }
.nav-sheet__list a:hover .nav-label, .nav-sheet__list a[aria-current="page"] .nav-label { font-style: italic; color: var(--gold); }
.nav-sheet__list a[aria-current="page"] .nav-sheet__num::after { content: " ●"; font-size: 0.6em; vertical-align: 0.2em; }
.nav-sheet__foot { display: grid; gap: var(--space-2); margin-top: var(--space-6); color: var(--text-2); font-size: var(--step--1); }
.nav-sheet__mail { display: inline-flex; align-items: center; gap: 0.5em; min-height: 44px; color: var(--gold); text-decoration: none; }
.nav-sheet__pitons { margin-top: auto; padding-top: var(--space-7); color: var(--pitons-ink); position: relative; left: calc(-1 * var(--space-5)); width: calc(100% + 2 * var(--space-5)); }
:root:not([data-theme="light"]) .nav-sheet__pitons { color: #070815; }

/* ============================================================== 11. Shell: footer ==================== */
.site-footer { position: relative; margin-top: clamp(var(--space-8), 10vw, var(--space-10)); color: var(--text-2); font-size: var(--step--1); }
.site-footer__skyline { position: relative; display: flex; justify-content: center; }
.site-footer__skyline::after {
  /* the sea horizon: mountains sit on it */
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--horizon);
  opacity: 0.75;
}
.site-footer__pitons { width: min(100%, 1400px); color: var(--pitons-ink); }
.site-footer__body { background: var(--bg-sunken); padding: clamp(var(--space-6), 6vw, var(--space-8)) 0 var(--space-6); }
.site-footer__grid { display: grid; gap: var(--space-6) var(--space-7); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 45em) { .site-footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } .site-footer__brand { grid-column: 1 / -1; } }
@media (min-width: 67.5em) { .site-footer__grid { grid-template-columns: 1.6fr 1fr 1.1fr 1.2fr; } .site-footer__brand { grid-column: auto; } }
.brand--footer { margin: 0 0 var(--space-4); }
.brand--footer .brand__badge { width: 56px; height: 56px; }
.brand--footer .brand__word { font-size: var(--step-2); }
.site-footer__motto { max-width: 36ch; line-height: 1.6; }
.site-footer__since { margin-top: var(--space-4); }
.site-footer__heading { margin-bottom: var(--space-3); font-family: var(--font-ui); font-size: var(--step--2); font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); }
.site-footer__list { display: grid; gap: 0; }
.site-footer__list a { display: inline-flex; align-items: center; min-height: 34px; color: var(--text-2); text-decoration: none; }
.site-footer__list a:hover, .site-footer__list a[aria-current="page"] { color: var(--text); text-decoration: underline; text-decoration-color: var(--gold); }
.site-footer__install { margin-top: var(--space-3); }
.site-footer__contact p + p { margin-top: var(--space-3); }
.site-footer__mail { display: inline-flex; align-items: center; gap: 0.5em; min-height: 44px; color: var(--gold); text-decoration: none; font-weight: 500; }
.site-footer__mail:hover { color: var(--gold-2); text-decoration: underline; }
.site-footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
  color: var(--text-3);
  font-size: var(--step--2);
  letter-spacing: 0.02em;
}
.site-footer__base a { color: inherit; }

/* ============================================================== 12. Shell: the player bar ============ */
.player-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  min-height: calc(var(--player-h) + var(--safe-bottom));
  padding: 0 max(var(--space-3), env(safe-area-inset-right, 0px)) var(--safe-bottom) max(var(--space-3), env(safe-area-inset-left, 0px));
  background: var(--bg-raised);
  box-shadow: 0 -10px 30px -12px rgba(0, 0, 0, 0.5);
  view-transition-name: player-bar;
  contain: layout;               /* no paint containment: nothing inside may ever be clipped */
  transition: transform var(--dur-2) var(--ease);
}
:root[data-theme="light"] .player-bar { box-shadow: 0 -10px 30px -16px rgba(60, 40, 10, 0.3); }
.player-bar:focus { outline: none; }
.player-bar:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; }
.player-bar::before {
  /* the gold horizon along the top edge */
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: var(--horizon);
  opacity: 0.5;
}
.player-bar__progress { position: absolute; left: 0; right: 0; top: 0; height: 2px; overflow: hidden; pointer-events: none; }
.player-bar__progress-fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--gold), var(--gold-2));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1s linear, opacity var(--dur-2) var(--ease);
  opacity: 0;
}
.player-bar__progress-fill.is-active { opacity: 1; }
.player-bar__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-4);
  width: min(100%, 1360px);
  min-height: var(--player-h);   /* a minimum, never a fixed height: large text or text spacing grows the bar */
  padding-block: var(--space-1);
  margin-inline: auto;
}
.player-bar__now { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.player-bar__art { flex: none; padding: 0; border: 0; border-radius: 8px; background: none; line-height: 0; }
.player-bar__art .art { --art-size: 52px; border-radius: 8px; box-shadow: var(--shadow-1), inset 0 0 0 1px var(--border); }
.player-bar__art .art img { opacity: 1; }
.player-bar__meta { min-width: 0; line-height: 1.3; }
.player-bar__title { overflow: hidden; color: var(--text); font-weight: 500; text-overflow: ellipsis; white-space: nowrap; }
.player-bar__artist, .player-bar__statusline { overflow: hidden; color: var(--text-2); font-size: var(--step--1); text-overflow: ellipsis; white-space: nowrap; }
.player-bar__statusline { display: none; color: var(--gold); }
.player-bar__love { flex: none; }
.player-bar__love:empty { display: none; }
.player-bar__center { display: flex; align-items: center; gap: var(--space-3); }
.player-bar__tools { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2); }
.player-bar__volume { display: flex; align-items: center; gap: var(--space-1); width: 150px; }
html.no-volume [data-volume], html.no-volume .player-bar__volume .range { display: none; }
html.no-volume .player-bar__volume { width: auto; }
.player-bar__nojs { display: none; }
html:not(.js) .player-bar__nojs { display: block; position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; background: var(--bg-raised); color: var(--gold); font-weight: 500; }
.mute-btn__off { display: none; }
[data-player-action="mute"][aria-pressed="true"] .mute-btn__on { display: none; }
[data-player-action="mute"][aria-pressed="true"] .mute-btn__off { display: inline-block; }
[data-player-action="mute"][aria-pressed="true"] { color: var(--coral); }

/* The big round play button (any [data-player-action=toggle] can use .play-btn__play / .play-btn__pause icons) */
.play-btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 54px;
  height: 54px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--gold-fill);
  color: var(--on-gold-fill);
  box-shadow: 0 6px 22px -6px color-mix(in srgb, var(--gold-fill) 75%, transparent);
  transition: background-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.play-btn:hover { background: var(--gold-fill-2); }
.play-btn:active { transform: scale(0.96); }
.play-btn .icon { width: 24px; height: 24px; }
.play-btn .play-btn__play { transform: translateX(1px); }
.play-btn--lg { width: 76px; height: 76px; }
.play-btn--lg .icon { width: 32px; height: 32px; }
.play-btn__pause { display: none; }
html[data-player-state="playing"] .play-btn__play,
html[data-player-state="connecting"] .play-btn__play,
html[data-player-state="reconnecting"] .play-btn__play { display: none; }
html[data-player-state="playing"] .play-btn__pause,
html[data-player-state="connecting"] .play-btn__pause,
html[data-player-state="reconnecting"] .play-btn__pause { display: inline-block; }
/* connecting / reconnecting: a slow ring turns around the button */
.play-btn::after {
  content: "";
  position: absolute;
  inset: -5px;
  border: 2px solid transparent;
  border-radius: 50%;
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease);
}
html[data-player-state="connecting"] .play-btn::after,
html[data-player-state="reconnecting"] .play-btn::after {
  opacity: 1;
  border-top-color: var(--gold);
  border-right-color: color-mix(in srgb, var(--gold) 35%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  html[data-player-state="connecting"] .play-btn::after,
  html[data-player-state="reconnecting"] .play-btn::after { animation: rj-spin 1.1s linear infinite; }
}
@keyframes rj-spin { to { transform: rotate(360deg); } }

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  min-width: 5.5em;
  padding: 0.25em 0.75em;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--text-3) var(--tint), transparent);
  color: var(--text-3);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.status-pill__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.player-bar[data-state="playing"] .status-pill { color: var(--live); background: color-mix(in srgb, var(--live) var(--tint), transparent); }
.player-bar[data-state="connecting"] .status-pill,
.player-bar[data-state="reconnecting"] .status-pill { color: var(--gold); background: color-mix(in srgb, var(--gold) var(--tint), transparent); }
.player-bar[data-state="error"] .status-pill { color: var(--danger); background: color-mix(in srgb, var(--danger) var(--tint), transparent); }
@media (prefers-reduced-motion: no-preference) {
  .player-bar[data-state="playing"] .status-pill__dot { animation: rj-pulse 2.4s var(--ease) infinite; }
  .player-bar[data-state="connecting"] .status-pill__dot,
  .player-bar[data-state="reconnecting"] .status-pill__dot { animation: rj-blink 1s var(--ease-in-out) infinite alternate; }
}
@keyframes rj-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 55%, transparent); } 70%, 100% { box-shadow: 0 0 0 7px transparent; } }
@keyframes rj-blink { from { opacity: 1; } to { opacity: 0.25; } }

@media (max-width: 59.9375em) { /* below 960px */
  .player-bar__volume { display: none; }
}
@media (max-width: 44.9375em) { /* below 720px */
  :root { --player-h: max(70px, 2.5rem + 20px); }
  .player-bar__inner { grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--space-2); }
  .player-bar__center { order: 2; }
  .player-bar__tools { order: 3; }
  .player-bar__center .status-pill { display: none; }
  .player-bar__art .art { --art-size: 46px; }
  .play-btn { width: 50px; height: 50px; }
  .player-bar__love .love-btn__count { display: none; }
  /* status replaces the artist line while connecting / reconnecting / in error */
  .player-bar[data-state="connecting"] .player-bar__artist,
  .player-bar[data-state="reconnecting"] .player-bar__artist,
  .player-bar[data-state="error"] .player-bar__artist { display: none; }
  .player-bar[data-state="connecting"] .player-bar__statusline,
  .player-bar[data-state="reconnecting"] .player-bar__statusline,
  .player-bar[data-state="error"] .player-bar__statusline { display: block; }
  .player-bar[data-state="error"] .player-bar__statusline { color: var(--danger); }
}
@media (max-width: 22.4375em) { /* below 360px: keep the heart, drop the thumbs-down (still in the player sheet) */
  .player-bar__love .vote-nope { display: none; }
}
@media (max-width: 21.1875em) { /* below 340px */
  .player-bar__love { display: none; }
}
@media (pointer: coarse) {
  html.kb-open .player-bar { transform: translateY(115%); }
  html.kb-open body { padding-bottom: 0; }
}

/* Short viewports (a phone on its side, or 400% zoom: 1280×1024 becomes 320×256 CSS px). The header
   scrolls away with the page and the bar slims down to one line, so content keeps most of the screen
   (WCAG 1.4.10 Reflow). --header-h: 0 also releases the pages' sticky offsets. */
@media (max-height: 31.25em) { /* 500px at the default text size */
  :root { --header-h: 0px; --player-h: max(56px, 1.5rem + 16px); }
  .site-header { position: static; }
  .site-header__inner { padding-block: var(--space-2); }
  .player-bar__inner { gap: var(--space-3); padding-block: 0; }
  .player-bar__art .art { --art-size: 40px; }
  .player-bar__artist, .player-bar__love, .player-bar__center .status-pill { display: none; }
  .player-bar .play-btn { width: 44px; height: 44px; }
  .player-bar .play-btn .icon { width: 20px; height: 20px; }
}

/* Player options sheet: bottom sheet on phones, side panel on larger screens */
.player-sheet {
  inset: auto 0 0 0;
  width: 100%;
  max-height: 92dvh;
  border-top: 1px solid var(--border);
  border-radius: var(--radius-l) var(--radius-l) 0 0;
  background: var(--bg-raised);
}
@media (prefers-reduced-motion: no-preference) {
  .player-sheet[open] { animation-name: rj-sheet-up; }
}
@media (min-width: 45em) { /* 720px */
  .player-sheet { inset: 0 0 0 auto; width: min(460px, 92vw); height: 100%; max-height: 100%; border-top: 0; border-left: 1px solid var(--border); border-radius: 0; }
  .player-sheet[open] { animation-name: rj-sheet-in; }
}
.player-sheet__inner { display: grid; gap: var(--space-6); padding: var(--space-4) var(--space-5) calc(var(--space-6) + var(--safe-bottom)); }
.player-sheet__head { display: flex; align-items: center; justify-content: space-between; }
/* Cover, then Play/Pause right under it, then the song: the main control is on the first screen of the
   sheet on every phone. The cover gives way on short screens (34svh). */
.player-sheet__now { display: grid; gap: var(--space-4); justify-items: start; }
.player-sheet__art { position: relative; width: min(100%, 280px, 34vh); width: min(100%, 280px, 34svh); }
.player-sheet__art .art img:not([src]) { visibility: hidden; }
.player-sheet__art::before {
  /* ambient glow sampled from the cover (--glow) */
  content: "";
  position: absolute;
  inset: 12%;
  z-index: -1;
  border-radius: 50%;
  background: var(--glow);
  filter: blur(42px);
  opacity: 0.55;
  transition: background-color var(--dur-3) var(--ease);
}
.player-sheet__art .art { --art-size: 100%; border-radius: var(--radius-m); box-shadow: var(--shadow-3); }
.player-sheet__title { font-size: var(--step-3); line-height: 1.15; }
.player-sheet__artist { margin-top: var(--space-1); color: var(--text-2); font-size: var(--step-1); }
.player-sheet__album { color: var(--text-3); font-style: italic; }
.player-sheet__album:empty, .player-sheet__time:empty { display: none; }
.player-sheet__time { margin-top: var(--space-2); color: var(--text-3); font-size: var(--step--1); font-variant-numeric: tabular-nums; }
.player-sheet__actions { display: grid; gap: var(--space-3); }
.player-sheet__links { --cluster-gap: var(--space-2); }
.player-sheet__play { width: min(100%, 280px); min-width: min(100%, 12rem); }
.player-sheet__play .icon { width: 1.25em; height: 1.25em; }
@media (max-height: 31.25em) { /* short screens: Play/Pause goes beside a smaller cover */
  .player-sheet__inner { gap: var(--space-4); padding-top: var(--space-2); }
  .player-sheet__now { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: var(--space-4); }
  .player-sheet__art { width: min(96px, 28vw); }
  .player-sheet__play { width: 100%; min-width: 0; padding-inline: 1em; }
  .player-sheet__meta, .player-sheet__actions { grid-column: 1 / -1; }
}
.player-sheet__settings { display: grid; gap: var(--space-5); padding-top: var(--space-5); border-top: 1px solid var(--border); }
.player-sheet__sleep .select { flex: 1 1 100%; width: 100%; }
.player-sheet__countdown { color: var(--gold); font-variant-numeric: tabular-nums; font-weight: 500; }
.player-sheet__countdown:empty { display: none; }
.player-sheet__volume .cluster { flex-wrap: nowrap; }
.player-sheet__keys { padding-top: var(--space-2); }
.player-sheet__keys .field--switch { margin-bottom: var(--space-3); }
.keys { display: grid; gap: var(--space-2); margin: var(--space-2) 0 var(--space-3); }
.keys > div { display: flex; justify-content: space-between; gap: var(--space-4); }
.keys dd { color: var(--text-2); }

/* ============================================================== 13. Router + transitions ============ */
html.is-navigating::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 70;
  height: 2px;
  background: linear-gradient(90deg, var(--gold), var(--gold-2));
  transform-origin: left;
  animation: rj-nav 2.6s var(--ease) forwards;
}
@keyframes rj-nav { from { transform: scaleX(0); } to { transform: scaleX(0.85); } }
main[aria-busy="true"] { cursor: progress; }
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: rj-vt-out var(--dur-1) var(--ease) both; }
  ::view-transition-new(root) { animation: rj-vt-in var(--dur-2) var(--ease) both; }
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
@keyframes rj-vt-out { to { opacity: 0; } }
@keyframes rj-vt-in { from { opacity: 0; transform: translateY(8px); } }

/* ============================================================== 14. Motion + print ================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
@media (pointer: coarse) {
  .btn--sm, .chip, .icon-btn--sm, .love-btn--sm, .vote-nope, .site-footer__list a { min-height: 44px; }
  .icon-btn--sm { width: 44px; }
  .love-btn--sm, .vote-nope--sm { min-width: 44px; }   /* a count-less heart is only ~35px wide otherwise */
}
@media print {
  .site-header, .player-bar, .player-sheet, .nav-sheet, .toast, .skip-link, .site-footer__skyline { display: none !important; }
  body { padding: 0; background: #fff; color: #000; }
  body::before, body::after { display: none; }
  a { color: #000; }
}
