/* ── Invisible Network — design tokens ───────────────────── */
/* Cinematic and image-first: near-black surfaces, the artwork carries
   the colour, and the accent marks only what is active or focused.

   Colours are OKLCH, so equal steps in lightness look equal, and both
   themes live in one list: each token is light-dark(<light>, <dark>).
   Which side applies is the `color-scheme` in force: data-theme on
   <html> when set (base.html sets it before paint from the visitor's
   choice or the device's setting, app.js follows the device as it
   changes), the device's setting when it is not, and always dark inside
   .dark-surface. Every text token holds WCAG AA (4.5:1) on every
   surface in both themes; e2e/scripts/contrast.mjs checks it.        */

:root {
  color-scheme: dark light;

  /* Surfaces, from the page up. */
  --bg:         light-dark(oklch(0.985 0.002 265), oklch(0.145 0.004 265));
  --bg-raised:  light-dark(oklch(1 0 0), oklch(0.185 0.005 265));
  --bg-card:    light-dark(oklch(1 0 0), oklch(0.205 0.006 265));
  --bg-hover:   light-dark(oklch(0.95 0.004 265), oklch(0.255 0.007 265));
  --surface:    light-dark(oklch(0.955 0.004 265), oklch(0.235 0.006 265));
  /* Alias used by the music page's cards, so they follow the theme. */
  --card-bg:    var(--bg-card);

  /* Lines. --border separates; --border-strong outlines a control that
     must be seen on its own (3:1 against the page). */
  --border:        light-dark(oklch(0.9 0.005 265), oklch(0.3 0.008 265));
  --border-strong: light-dark(oklch(0.6 0.01 265), oklch(0.53 0.01 265));

  /* Text, three levels. */
  --text:       light-dark(oklch(0.2 0.01 265), oklch(0.96 0.003 265));
  --text-muted: light-dark(oklch(0.42 0.012 265), oklch(0.79 0.008 265));
  --text-dim:   light-dark(oklch(0.5 0.012 265), oklch(0.7 0.01 265));

  /* The accent has two jobs with opposite needs: as a fill it must be dark
     enough for white text on it, as text it must be light enough to read on
     the dark page. One value cannot do both, so text gets its own. */
  --accent:      light-dark(oklch(0.5 0.2 277), oklch(0.53 0.19 277));
  --accent-text: light-dark(oklch(0.48 0.2 277), oklch(0.78 0.105 277));
  --on-accent:   oklch(1 0 0);
  --accent-glow: color-mix(in oklab, var(--accent) 30%, transparent);
  --accent-tint: color-mix(in oklab, var(--accent) 16%, transparent);

  /* The primary action (Play, Watch) is the theme's inverse, a lit panel
     on a dark room, so the artwork beside it keeps the colour. */
  --action:       light-dark(oklch(0.2 0.01 265), oklch(0.97 0.002 265));
  --action-hover: light-dark(oklch(0.33 0.012 265), oklch(0.87 0.004 265));
  --on-action:    light-dark(oklch(1 0 0), oklch(0.17 0.005 265));

  --focus-ring: light-dark(oklch(0.5 0.2 277), oklch(0.76 0.115 277));

  /* States. Live is broadcast red; the others are for text and for tinted
     backgrounds (color-mix with transparent), so each must read as text. */
  --live:      oklch(0.56 0.21 27);
  --on-live:   oklch(1 0 0);
  --live-text: light-dark(oklch(0.52 0.2 27), oklch(0.74 0.15 25));
  --live-glow: color-mix(in oklab, var(--live) 35%, transparent);
  --success:   light-dark(oklch(0.5 0.13 150), oklch(0.78 0.15 150));
  --warning:   light-dark(oklch(0.52 0.11 65), oklch(0.83 0.13 80));
  --danger:    light-dark(oklch(0.52 0.2 27), oklch(0.74 0.15 25));
  /* Fills that carry white text (--on-accent): badges for kinds of thing. */
  --success-fill: oklch(0.5 0.13 150);
  --learn:     oklch(0.5 0.15 255);
  --faith:     oklch(0.5 0.16 300);
  /* The Classics Vault's gold, with dark text on it. */
  --classic:    oklch(0.8 0.13 85);
  --on-classic: oklch(0.22 0.03 85);

  /* Translucent layers that follow the theme: a hover wash, a stronger
     one for resting controls, and a divider. */
  --tint:        color-mix(in oklab, var(--text) 6%, transparent);
  --tint-strong: color-mix(in oklab, var(--text) 11%, transparent);
  --hairline:    color-mix(in oklab, var(--text) 9%, transparent);

  /* Over artwork and video the frame is dark whatever the theme, so these
     never change: text, a scrim to lift it off any image, and glass. */
  --media-bg:       oklch(0 0 0);
  --on-media:       oklch(1 0 0);
  --on-media-muted: oklch(0.88 0.004 265);
  --scrim-soft:     oklch(0.1 0.005 265 / 0.3);
  --scrim:          oklch(0.1 0.005 265 / 0.62);
  --scrim-strong:   oklch(0.1 0.005 265 / 0.86);
  --glass:          oklch(1 0 0 / 0.14);
  --glass-hover:    oklch(1 0 0 / 0.22);
  --glass-border:   oklch(1 0 0 / 0.2);

  /* A picture shown for its own sake (the Art section's hero, a work's
     page, zoom and gallery mode) sits on a neutral grey at 20% of the
     display's white, the same in both themes: what colour science asks,
     not what the theme does. ISO 3664 (§4.5.5 of the 2000 text) and
     ISO 12646:2008 §4.7.3 put the surround of an image on a display at no
     more than 20% of the white's luminance (preferably 3%, against flare),
     neutral, at the white's own chromaticity (R = G = B, D65). Within that
     range the lightest keeps a work's own contrast best: a darker surround
     makes a picture look lighter and flatter (Bartleson and Breneman 1967;
     Liu and Fairchild 2004), a coloured one tints it toward the opposite
     hue (simultaneous contrast), and 20% is sRGB's own reference surround
     (IEC 61966-2-1) and where CIECAM02's "average" surround, the one
     images are made for, begins. oklch(0.5828 0 0) is sRGB 123, relative
     luminance 0.198: the lightest 8-bit grey at or under 20%. White on it
     is 4.23:1, short of WCAG 2.2 AA, so its text is black (4.96:1) and its
     controls are outlined, never filled darker (black on a darker grey falls
     below 4.5:1); a hovered control lightens. .art-surround applies them. */
  --surround:       oklch(0.5828 0 0);
  --surround-hover: oklch(0.66 0 0);
  --on-surround:    oklch(0 0 0);

  /* Artwork not loaded (or none): a quiet panel, never a colour wash. */
  --placeholder: linear-gradient(160deg,
                   light-dark(oklch(0.93 0.008 265), oklch(0.27 0.014 265)),
                   light-dark(oklch(0.87 0.012 265), oklch(0.19 0.01 265)));
  /* Channel logos from other sites, white ones and dark ones alike: a
     mid-grey panel both read on, in either theme. */
  --logo-panel: radial-gradient(120% 100% at 50% 35%, oklch(0.84 0.005 265), oklch(0.64 0.01 265));
  /* Hero bands without an image. */
  --hero-band: linear-gradient(180deg,
                 light-dark(oklch(0.95 0.006 265), oklch(0.19 0.012 270)) 0%,
                 var(--bg) 100%);

  --shadow-1: 0 1px 2px light-dark(oklch(0 0 0 / 0.06), oklch(0 0 0 / 0.3)),
              0 4px 12px light-dark(oklch(0 0 0 / 0.06), oklch(0 0 0 / 0.25));
  --shadow-2: 0 18px 48px light-dark(oklch(0 0 0 / 0.14), oklch(0 0 0 / 0.5));

  /* ── Type ─────────────────────────────────────────────────── */
  /* The system's own UI face: nothing to download, so text paints with
     the first frame (LCP) and never reflows when a web font arrives. */
  --font:         system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono:    ui-monospace, "SF Mono", "Cascadia Code", "Fira Code", Menlo, monospace;
  /* For long reading and for book covers: the system's book faces. */
  --font-serif:   "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  /* Every search or find field is this shape: a pill. */
  --field-radius:   999px;
  /* Sections' titles (.page-title). */
  --title-face:     var(--font-display);
  --title-size:     var(--step-4);
  --title-weight:   800;
  --title-tracking: -0.03em;

  /* A fluid scale: each step grows smoothly from a 360px phone to a
     1440px desktop, about 1.2 apart on the phone and 1.25 on the desktop.
     The rem part keeps every step zoomable. */
  --step--2: clamp(0.72rem, 0.7rem + 0.1vw, 0.78rem);
  --step--1: clamp(0.82rem, 0.79rem + 0.15vw, 0.9rem);
  --step-0:  clamp(0.95rem, 0.92rem + 0.15vw, 1.05rem);
  --step-1:  clamp(1.1rem, 1.04rem + 0.3vw, 1.3rem);
  --step-2:  clamp(1.3rem, 1.18rem + 0.55vw, 1.65rem);
  --step-3:  clamp(1.6rem, 1.35rem + 1.1vw, 2.3rem);
  --step-4:  clamp(2rem, 1.55rem + 2vw, 3.2rem);
  --step-5:  clamp(2.4rem, 1.7rem + 3.2vw, 4.4rem);

  /* ── Space and shape ──────────────────────────────────────── */
  --gutter:     clamp(1rem, 3.4vw, 3rem);
  --radius:     8px;
  --radius-lg:  12px;
  --transition: 180ms ease;

  /* ── Motion system ─────────────────────────────────────── */
  --spring-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
  --spring-smooth: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out-smooth: cubic-bezier(0.65, 0, 0.35, 1);
  --duration-fast: 150ms;
  --duration-normal: 250ms;
  --duration-slow: 400ms;
  --duration-page: 500ms;

  /* ── find in a transcript (::highlight) ── every match, and the current one */
  --hit:            light-dark(oklch(0.9 0.12 95), oklch(0.86 0.13 92));
  --on-hit:         oklch(0.2 0.03 90);
  --hit-current:    light-dark(oklch(0.5 0.2 277), oklch(0.53 0.19 277));
  --on-hit-current: oklch(1 0 0);
}

/* data-theme, set by script from the visitor's choice or the device. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

/* Hero bands, overlays and bars drawn on a fixed dark background (artwork,
   video). Inside them every token takes its dark value. The players and the
   watch page are dark the same way, a screen in a dark room, and so are the
   game heroes, painted in each game's own deep colours. */
.dark-surface,
.inv-player,
.player-viewport,
.watch-cinema,
.games-hero,
.gd-hero {
  color-scheme: dark;
  color: var(--text);
}

/* Around a picture shown for its own sake: the surround above, and inside
   it every text token black, so the section's own rules (titles, links,
   buttons, the focus ring) keep 4.5:1 on it without knowing it is there.
   The secondary button's fill is the surround itself, outlined in black. */
.art-surround {
  color-scheme: light;
  background: var(--surround);
  color: var(--on-surround);
  --text:          var(--on-surround);
  --text-muted:    var(--on-surround);
  --text-dim:      var(--on-surround);
  --accent-text:   var(--on-surround);
  --focus-ring:    var(--on-surround);
  --tint-strong:   transparent;
  --hairline:      var(--on-surround);
  --border-strong: var(--on-surround);
}
.art-surround .btn--secondary:hover { background: var(--surround-hover); }
:root[data-tv] .art-surround {
  --tv-focus:      var(--on-surround);
  --tv-focus-halo: oklch(1 0 0 / 0.92);
}

/* Wide-gamut screens get a richer accent and red. The lightness stays the
   same, so contrast does too, and the chroma stops well short of the P3
   edge: on an HDR screen the interface should stay calm next to the art. */
@media (color-gamut: p3) {
  :root {
    --accent:      light-dark(oklch(0.5 0.23 277), oklch(0.53 0.22 277));
    --accent-text: light-dark(oklch(0.48 0.23 277), oklch(0.78 0.118 277));
    --focus-ring:  light-dark(oklch(0.5 0.23 277), oklch(0.76 0.13 277));
    --live:        oklch(0.56 0.24 27);
    --live-text:   light-dark(oklch(0.52 0.23 27), oklch(0.74 0.17 25));
  }
}

/* Browsers without light-dark() (Safari before 17.5, Chrome before 123)
   would drop every colour token. They get the dark theme as plain values,
   which contrast.mjs keeps identical to the dark side above. */
@supports not (color: light-dark(white, black)) {
  :root {
    --bg:            oklch(0.145 0.004 265);
    --bg-raised:     oklch(0.185 0.005 265);
    --bg-card:       oklch(0.205 0.006 265);
    --bg-hover:      oklch(0.255 0.007 265);
    --surface:       oklch(0.235 0.006 265);
    --border:        oklch(0.3 0.008 265);
    --border-strong: oklch(0.53 0.01 265);
    --text:          oklch(0.96 0.003 265);
    --text-muted:    oklch(0.79 0.008 265);
    --text-dim:      oklch(0.7 0.01 265);
    --accent:        oklch(0.53 0.19 277);
    --accent-text:   oklch(0.78 0.105 277);
    --action:        oklch(0.97 0.002 265);
    --action-hover:  oklch(0.87 0.004 265);
    --on-action:     oklch(0.17 0.005 265);
    --focus-ring:    oklch(0.76 0.115 277);
    --live-text:     oklch(0.74 0.15 25);
    --success:       oklch(0.78 0.15 150);
    --warning:       oklch(0.83 0.13 80);
    --danger:        oklch(0.74 0.15 25);
    --placeholder:   linear-gradient(160deg, oklch(0.27 0.014 265), oklch(0.19 0.01 265));
    --hero-band:     linear-gradient(180deg, oklch(0.19 0.012 270) 0%, var(--bg) 100%);
    --shadow-1:      0 1px 2px oklch(0 0 0 / 0.3), 0 4px 12px oklch(0 0 0 / 0.25);
    --shadow-2:      0 18px 48px oklch(0 0 0 / 0.5);
    --hit:           oklch(0.86 0.13 92);
    --hit-current:   oklch(0.53 0.19 277);
  }
  /* TV mode's ring (below), dark side. */
  :root[data-tv] {
    --tv-focus:      oklch(0.98 0.003 265);
    --tv-focus-halo: oklch(0.12 0.005 265 / 0.9);
  }
  /* Kids mode's own palette (further down), dark side. */
  body.kids-mode {
    --bg:          oklch(0.17 0.05 295);
    --bg-raised:   oklch(0.215 0.06 295);
    --bg-card:     oklch(0.235 0.065 295);
    --bg-hover:    oklch(0.285 0.07 295);
    --surface:     oklch(0.26 0.065 295);
    --border:      oklch(0.36 0.08 295);
    --accent-text: oklch(0.8 0.15 150);
    --focus-ring:  oklch(0.8 0.15 150);
  }
}

/* ── TV mode tokens (inv-tv) ─────────────────────────────────
   On <html data-tv> (base.html decides before paint). Seen from across a
   room, the focus ring is the one thing that must never be missed: a thick
   ring in the theme's text colour, at least 4.5:1 on every surface (text
   contrast, not the 3:1 for controls), inside a halo of the opposite colour
   so it stands out on any artwork too. The faintest text is lifted to the
   muted level. The edges keep clear of a TV's overscan: 5% each side, the
   title-safe area. contrast.mjs checks these pairs. */
:root[data-tv] {
  --tv-focus:      light-dark(oklch(0.2 0.01 265), oklch(0.98 0.003 265));
  --tv-focus-halo: light-dark(oklch(1 0 0 / 0.92), oklch(0.12 0.005 265 / 0.9));
  --text-dim:      var(--text-muted);
  --gutter:        max(5vw, 2rem);
  --tv-safe-y:     5vh;
}

/* On an HDR screen an image mastered for HDR can outshine the page's
   white. Posters and thumbnails are interface, so they keep to
   standard range; films in the player are left alone. */
img,
.home-hero-slide {
  dynamic-range-limit: standard;
}

/* ── Icons ────────────────────────────────────────────────── */
/* One set (Lucide, ISC licence: static/icons/LICENSE), drawn from the
   sprite static/icons.svg with <svg class="icon"><use href="…#name">.
   The icon is decoration (aria-hidden); the control it sits in carries
   the name, in its text or its aria-label. */

/* The sprite's symbols carry no fill or stroke of their own; these
   inherit into them, so a rule here or on a parent can change them. */
.icon {
  width: 1.25em;
  height: 1.25em;
  flex-shrink: 0;
  vertical-align: -0.25em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon--fill { fill: currentColor; }

/* Text for assistive technology only. */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Theme Toggle Button ─────────────────────────────────── */

.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 1rem;
  transition: background var(--transition), color var(--transition);
  flex-shrink: 0;
}

.theme-toggle:hover {
  background: var(--bg-hover);
  color: var(--text);
}

/* The icon shows the theme in force; before any script has run, the
   page simply follows the device, and says so. */
.theme-icon { display: none; width: 18px; height: 18px; vertical-align: 0; }
:root:not([data-theme]) .theme-icon--auto,
:root[data-theme="light"] .theme-icon--light,
:root[data-theme="dark"] .theme-icon--dark { display: block; }


*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { font-size: 16px; -webkit-font-smoothing: antialiased; text-size-adjust: 100%; }

body {
  font-family: var(--font);
  font-size: var(--step-0);
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  min-height: 100vh;
}

h1, h2, h3 {
  font-family: var(--font-display);
  line-height: 1.15;
  text-wrap: balance;
}

/* A section's title (TV, Radio drama, Art, a list of a section's works):
   one face, size and weight on every section's pages, so each reads as
   part of the same library. The serif is for reading and for a work's own
   title on its page, not for sections. */
.page-title {
  font-family: var(--title-face);
  font-size: var(--title-size);
  font-weight: var(--title-weight);
  letter-spacing: var(--title-tracking);
  line-height: 1.05;
}

p { text-wrap: pretty; }

a { color: inherit; text-decoration: none; }

/* Keyboard focus: one ring everywhere, in the accent, clear of the edge. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ── Navigation ───────────────────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 2rem;
  padding: 0 var(--gutter);
  height: 64px;
  background: color-mix(in oklab, var(--bg) 80%, transparent);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border-bottom: 1px solid var(--hairline);
}

.nav-logo {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.logo-mark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  color: var(--accent-text);
  letter-spacing: -0.03em;
}

.logo-text {
  font-weight: 500;
  font-size: 0.9rem;
  color: var(--text-muted);
  letter-spacing: 0.04em;
}

.nav-link {
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-muted);
  transition: color var(--transition), background var(--transition);
}

.nav-link:hover {
  color: var(--text);
  background: var(--tint);
}

.nav-search {
  margin-left: auto;
  position: relative;
}

.nav-search input {
  width: 240px;
  padding: 0.5rem 1rem;
  background: var(--tint);
  border: 1px solid var(--border-strong);
  border-radius: var(--field-radius);
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
  outline: none;
  transition: border-color var(--transition), width var(--transition), background var(--transition);
}

.nav-search input:focus {
  border-color: var(--focus-ring);
  background: var(--bg-raised);
  width: 320px;
}

.nav-search input::placeholder { color: var(--text-dim); }

.search-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 360px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}

.search-item {
  display: flex;
  flex-direction: column;
  padding: 0.75rem 1rem;
  transition: background var(--transition);
}

.search-item:hover { background: var(--bg-hover); }
.search-name { font-weight: 600; font-size: 0.9rem; }
.search-desc { font-size: 0.8rem; color: var(--text-muted); }
.search-live-tag { color: var(--live-text); }
.search-empty { color: var(--text-dim); text-align: center; }
.search-divider { height: 1px; background: var(--border); margin: 0.25rem 0; }

.nav-link--dim { opacity: 0.55; }
.nav-link--dim:hover { opacity: 1; }

/* ── Hero ─────────────────────────────────────────────────── */

.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 520px;
  padding: 4rem 3rem;
  background: var(--hero-band);
  overflow: hidden;
}

.hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--bg) 0%, transparent 60%);
}

.hero-content {
  position: relative;
  max-width: 700px;
}

.hero-badge-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.hero-type-badge {
  padding: 3px 10px;
  border-radius: 4px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  background: var(--accent);
  color: var(--on-accent);
}

.hero-meta-text {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.hero-title {
  font-size: var(--step-5);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin-bottom: 0.75rem;
}

.hero-subtitle {
  font-size: var(--step-1);
  color: var(--text-muted);
  margin-bottom: 1.5rem;
  line-height: 1.6;
}

.hero-stats {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 2rem;
  font-size: 0.9rem;
  color: var(--text-muted);
}

.hero-stats strong { color: var(--text); }

.stat-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--text-dim);
}

.hero-actions { display: flex; gap: 0.75rem; }

/* ── Buttons ──────────────────────────────────────────────── */
/* Primary: the theme's inverse (a lit panel, like Play on a TV). Secondary:
   a wash of the text colour, so it works on any surface, artwork included
   inside .dark-surface. Both class spellings are in use. */

.btn,
.btn--primary,
.btn--secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.7rem 1.4rem;
  border-radius: var(--radius);
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.2;
  transition: background var(--transition), color var(--transition), transform var(--transition);
  cursor: pointer;
  border: 1px solid transparent;
}

.btn .icon,
.btn--primary .icon,
.btn--secondary .icon { width: 1.15em; height: 1.15em; vertical-align: 0; }

.btn-primary,
.btn--primary {
  background: var(--action);
  color: var(--on-action);
}

/* A play triangle reads better solid. */
.btn-primary .icon,
.btn--primary .icon { fill: currentColor; }

.btn-primary:hover,
.btn--primary:hover { background: var(--action-hover); }

.btn-secondary,
.btn--secondary {
  background: var(--tint-strong);
  color: var(--text);
  border-color: var(--hairline);
}

.btn-secondary:hover,
.btn--secondary:hover { background: color-mix(in oklab, var(--text) 18%, transparent); }

/* ── Content Shelves ──────────────────────────────────────── */

.shelf {
  padding: 2rem 0 1rem;
}

.shelf-label {
  font-size: var(--step-2);
  font-weight: 700;
  padding: 0 var(--gutter);
  margin-bottom: 1rem;
  letter-spacing: -0.01em;
}

.shelf-rail {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  padding: 0.25rem var(--gutter) 1rem;
  scroll-behavior: smooth;
  cursor: grab;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.shelf-rail::-webkit-scrollbar { display: none; }

/* ── Cards ────────────────────────────────────────────────── */
/* Image first: the artwork is the card, the title sits under it on the
   page itself, with no box around it. */

.card {
  flex: 0 0 280px;
  min-width: 0;
  border-radius: var(--radius-lg);
  background: none;
}

.card--compact { flex: 0 0 200px; }

.card-visual {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--placeholder);
  border-radius: var(--radius-lg);
  display: flex;
  align-items: flex-end;
  gap: 0.4rem;
  padding: 0.6rem;
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--hairline) inset;
  transition: box-shadow var(--duration-normal) ease, transform var(--duration-normal) var(--spring-smooth);
}

/* Posters are 2:3. Rails of films and shows use them whole, uncropped. */
.card--poster { flex-basis: 184px; }
.card--poster .card-visual { aspect-ratio: 2 / 3; }

/* ── Card cover images ────────────────────────────────── */
.card-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
  transition: opacity 0.3s ease, transform var(--duration-slow) var(--spring-smooth);
}

/* Lift the artwork, not the whole card: the title stays put to be read. */
.card:hover .card-visual,
.card:focus-visible .card-visual {
  transform: translateY(-3px);
  box-shadow: var(--shadow-2), 0 0 0 1px color-mix(in oklab, var(--text) 30%, transparent) inset;
}

.card:hover .card-img { transform: scale(1.04); }

.card:focus-visible { outline: none; }
.card:focus-visible .card-visual { outline: 2px solid var(--focus-ring); outline-offset: 3px; }

/* Labels on artwork: small glass chips that read on any image. */
.card-visual .badge {
  z-index: 3;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  background: var(--scrim);
  color: var(--on-media);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 3px 7px;
}

.card-visual .badge--live { background: var(--live); color: var(--on-live); }

.card-visual--sm { aspect-ratio: auto; height: 100px; }

.card-badge {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.2rem 0.5rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  border-radius: 4px;
  background: var(--live);
  color: var(--on-live);
}

.card-badge--learn { background: var(--learn); color: var(--on-accent); }
.card-badge--faith { background: var(--faith); color: var(--on-accent); }

.card-type-badge {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.2rem 0.5rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  border-radius: 4px;
  background: var(--scrim);
  color: var(--on-media);
  text-transform: uppercase;
}

.card-season-info {
  font-size: 0.75rem;
  color: var(--on-media-muted);
  font-weight: 600;
}

.card-now-playing {
  font-size: 0.8rem;
  color: var(--on-media-muted);
  text-transform: capitalize;
}

.card-body { padding: 0.65rem 0.15rem 0.25rem; }

.card-title {
  font-family: var(--font);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 0.15rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card-desc {
  font-size: 0.8rem;
  color: var(--text-muted);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-meta {
  display: flex;
  gap: 0.5rem;
  font-size: var(--step--2);
  color: var(--text-dim);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* ── Channel Detail ───────────────────────────────────────── */

.channel-hero {
  padding: 4rem 3rem 3rem;
  background: var(--hero-band);
}

.channel-hero-content { max-width: 700px; }

.channel-badge {
  display: inline-block;
  padding: 0.25rem 0.6rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-radius: 4px;
  background: var(--live);
  color: var(--on-live);
  margin-bottom: 1rem;
}

.channel-title {
  font-size: 2.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: 0.75rem;
}

.channel-desc {
  font-size: 1rem;
  color: var(--text-muted);
  line-height: 1.6;
  margin-bottom: 1rem;
}

.channel-meta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.85rem;
  color: var(--text-dim);
  margin-bottom: 1.5rem;
}

/* ── EPG Grid ─────────────────────────────────────────────── */

.epg { padding: 2rem 3rem; }

.epg .section-title {
  font-size: 1.1rem;
  margin-bottom: 1rem;
}

.epg-grid {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.epg-slot {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1rem;
  background: var(--bg-card);
  transition: background var(--transition);
}

.epg-slot:hover { background: var(--bg-hover); }

.epg-slot--current {
  background: var(--bg-hover);
  border-left: 3px solid var(--accent);
}

.epg-time {
  flex: 0 0 60px;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: var(--font-mono);
  color: var(--text-muted);
}

.epg-info { flex: 1; }

.epg-title {
  font-size: 0.9rem;
  font-weight: 500;
  text-transform: capitalize;
  display: block;
}

.epg-daypart {
  font-size: 0.75rem;
  color: var(--text-dim);
}

.epg-duration {
  flex: 0 0 40px;
  text-align: right;
  font-size: 0.8rem;
  color: var(--text-dim);
  font-family: var(--font-mono);
}

/* ── Browse Grid ──────────────────────────────────────────── */

.browse-header {
  padding: 3rem 3rem 1.5rem;
}

.browse-title { margin-bottom: 0.25rem; }

.browse-count {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-bottom: 1.5rem;
}

.browse-filters {
  display: flex;
  gap: 0.5rem;
}

.filter-pill {
  padding: 0.4rem 1rem;
  border-radius: 20px;
  font-size: 0.85rem;
  font-weight: 500;
  background: var(--surface);
  color: var(--text-muted);
  border: 1px solid var(--border);
  transition: all var(--transition);
}

.filter-pill:hover { background: var(--bg-hover); color: var(--text); }

.filter-pill--active {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
}

.browse-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.25rem;
  padding: 0 3rem 3rem;
}

.browse-card {
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  overflow: hidden;
  transition: transform var(--transition), box-shadow var(--transition);
}

.browse-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
}

.browse-card-visual {
  position: relative;
  height: 140px;
  background: var(--placeholder);
  display: flex;
  align-items: flex-end;
  padding: 1rem;
}

.browse-card-body { padding: 1rem; }

.browse-card-title {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.browse-card-desc {
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
}

/* ── Player ───────────────────────────────────────────────── */

.player { padding: 0; }

.player-viewport {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 70vh;
  background: var(--media-bg);
  display: flex;
  align-items: center;
  justify-content: center;
}

.player-placeholder {
  text-align: center;
}

.player-logo {
  font-size: 3rem;
  font-weight: 800;
  color: var(--accent-text);
  margin-bottom: 0.5rem;
}

.player-channel {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.player-now {
  font-size: 0.9rem;
  color: var(--text-muted);
  text-transform: capitalize;
}

.player-controls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  background: linear-gradient(to top, var(--scrim-strong), transparent);
}

.player-btn {
  background: none;
  border: none;
  color: var(--on-media);
  font-size: 1.25rem;
  cursor: pointer;
  padding: 0.25rem;
  opacity: 0.8;
  transition: opacity var(--transition);
}

.player-btn:hover { opacity: 1; }

.player-progress {
  flex: 1;
  height: 4px;
  background: var(--glass);
  border-radius: 2px;
  overflow: hidden;
}

.player-progress-fill {
  width: 35%;
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
}

.player-info {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 2rem;
  padding: 2rem 3rem;
}

.player-title {
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.player-desc {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.6;
  margin-bottom: 1rem;
}

.player-meta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.player-live-badge {
  padding: 0.15rem 0.5rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-radius: 4px;
  background: var(--live);
  color: var(--on-live);
}

.upnext-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
}

.upnext-time {
  flex: 0 0 50px;
  font-family: var(--font-mono);
  color: var(--text-dim);
}

.upnext-title {
  flex: 1;
  text-transform: capitalize;
}

.upnext-daypart {
  font-size: 0.75rem;
  color: var(--text-dim);
}

.player-back {
  display: flex;
  gap: 0.75rem;
  padding: 0 3rem 3rem;
}

/* ── Cinematic Watch Page ────────────────────────────────── */
.watch-cinema {
  display: grid;
  grid-template-columns: 1fr 360px;
  min-height: calc(100vh - 56px);
  background: var(--media-bg);
}

.watch-player-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 50vh;
  background: var(--media-bg);
}

.watch-player {
  width: 100%;
  height: 100%;
}

/* Play, over a live channel's place until it is pressed (watch.html,
   live.html, news.html): the player itself comes with the press. */
.player-start {
  position: absolute;
  inset: 0;
  margin: auto;
  width: max-content;
  height: max-content;
  z-index: 3;
}

.watch-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  padding: 2rem;
}

.watch-placeholder-logo {
  font-size: 4rem;
  font-weight: 900;
  color: var(--accent-text);
  margin-bottom: 1rem;
  opacity: 0.6;
}

.watch-placeholder-channel {
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.watch-placeholder-now {
  font-size: 1rem;
  color: var(--text-muted);
  text-transform: capitalize;
  margin-bottom: 1rem;
}

.watch-placeholder-status {
  font-size: 0.85rem;
  color: var(--text-dim);
  animation: pulse-text 2s ease-in-out infinite;
}

@keyframes pulse-text {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}

/* Info overlay */
.watch-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 1.5rem 2rem;
  opacity: 0;
  transition: opacity 0.4s;
  pointer-events: none;
  background: linear-gradient(180deg, var(--scrim) 0%, transparent 30%, transparent 60%, var(--scrim-strong) 100%);
}

.watch-player-wrap:hover .watch-overlay {
  opacity: 1;
  pointer-events: auto;
}

.watch-overlay-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.watch-back {
  color: var(--on-media);
  font-size: 0.85rem;
  text-decoration: none;
  opacity: 0.8;
  transition: opacity 0.2s;
}

.watch-back:hover { opacity: 1; }

.watch-live-badge {
  animation: live-pulse-anim 2s ease-in-out infinite;
}

/* Low latency: a two-state switch beside the LIVE badge. */
.watch-latency {
  margin-left: 0.5rem;
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--glass-border);
  border-radius: 999px;
  background: var(--scrim);
  color: var(--on-media);
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
}
.watch-latency[aria-pressed="true"] {
  background: var(--accent);
  border-color: transparent;
}
.watch-latency:focus-visible { outline: 2px solid var(--on-media); outline-offset: 2px; }

.watch-overlay-bottom {}

.watch-channel-name {
  font-size: 1.8rem;
  font-weight: 800;
  text-shadow: 0 2px 8px var(--scrim);
  margin-bottom: 0.25rem;
}

.watch-now-playing {
  font-size: 1rem;
  color: var(--on-media-muted);
  text-transform: capitalize;
  margin-bottom: 0.5rem;
}

.watch-meta {
  display: flex;
  gap: 0.75rem;
  align-items: center;
}

.watch-viewers {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.watch-category {
  font-size: 0.7rem;
  padding: 2px 10px;
  border-radius: 10px;
  background: var(--glass);
  color: var(--on-media-muted);
}

/* Sidebar */
.watch-sidebar {
  background: var(--bg-raised);
  border-left: 1px solid var(--hairline);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  overflow-y: auto;
  max-height: calc(100vh - 56px);
  transition: transform 0.3s;
}

.watch-sidebar.collapsed {
  transform: translateX(100%);
}

.watch-sidebar-header h2 {
  font-size: 1.1rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.watch-sidebar-desc {
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.6;
}

.watch-sidebar-title {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin-bottom: 0.75rem;
  font-weight: 700;
}

.watch-sidebar-section {
  border-top: 1px solid var(--hairline);
  padding-top: 1rem;
}

.watch-upnext-item {
  display: flex;
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--hairline);
}

.watch-upnext-time {
  font-size: 0.75rem;
  color: var(--text-dim);
  font-family: var(--font-mono);
  min-width: 44px;
}

.watch-upnext-name {
  font-size: 0.85rem;
  display: block;
  text-transform: capitalize;
}

.watch-upnext-daypart {
  font-size: 0.7rem;
  color: var(--text-dim);
}

.watch-related-card {
  display: flex;
  gap: 0.75rem;
  padding: 0.5rem;
  border-radius: 8px;
  transition: background 0.15s;
  text-decoration: none;
  color: inherit;
  align-items: center;
  margin-bottom: 0.25rem;
}

.watch-related-card:hover {
  background: var(--tint);
}

.watch-related-name {
  font-size: 0.85rem;
  font-weight: 600;
  display: block;
}

.watch-related-now {
  font-size: 0.72rem;
  color: var(--text-dim);
  text-transform: capitalize;
}

.badge--sm {
  font-size: 0.55rem;
  padding: 1px 6px;
}

.watch-sidebar-actions {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: auto;
}

.btn--full { width: 100%; text-align: center; }

@media (max-width: 1024px) {
  .watch-cinema {
    grid-template-columns: 1fr;
  }
  .watch-sidebar {
    max-height: none;
    border-left: none;
    border-top: 1px solid var(--hairline);
  }
}

/* ── Footer ───────────────────────────────────────────────── */

.footer {
  margin-top: 4rem;
  padding: 3rem var(--gutter);
  border-top: 1px solid var(--border);
}

.footer-inner { max-width: 600px; }

.footer-brand {
  font-weight: 700;
  margin-bottom: 0.25rem;
}

.footer-sub {
  font-size: 0.85rem;
  color: var(--text-dim);
  margin-bottom: 1rem;
}

.footer-links {
  display: flex;
  gap: 1.5rem;
  font-size: 0.85rem;
}

.footer-links a {
  color: var(--text-muted);
  transition: color var(--transition);
}

.footer-links a:hover { color: var(--text); }

/* ── Controller Focus Ring ────────────────────────────────── */
/* Visible when navigating with a gamepad or keyboard arrows. */

.controller-focus {
  outline: 2px solid var(--focus-ring) !important;
  outline-offset: 3px;
  box-shadow: 0 0 0 6px var(--accent-glow) !important;
  transition: outline var(--transition), box-shadow var(--transition);
}

/* ── Controller Indicator (nav bar) ───────────────────────── */

.controller-indicator {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: 0.5rem;
}

.ctrl-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 22px;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  border-radius: 4px;
  color: var(--on-accent);
}

/* Each controller in its maker's colour, so it is recognised at a glance. */
.ctrl-ps    { background: #2d5af0; }
.ctrl-nin   { background: #e60012; }
.ctrl-xbox  { background: #107c10; }
.ctrl-etee  { background: #7c3aed; }
.ctrl-samsung { background: #1428a0; }
.ctrl-generic { background: #55556a; }

/* ── Controllers Page ─────────────────────────────────────── */

.controllers-hero {
  padding: 3rem 3rem 1.5rem;
}

.controllers-title {
  font-size: 2rem;
  font-weight: 800;
  margin-bottom: 0.5rem;
}

.controllers-sub {
  font-size: 1rem;
  color: var(--text-muted);
  max-width: 600px;
}

.controllers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.25rem;
  padding: 0 3rem 2rem;
}

.controller-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
}

.controller-card h2 {
  font-size: 1.1rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.controller-card p {
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
  margin-bottom: 1rem;
}

.controller-card-icon {
  width: 40px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 800;
  border-radius: 6px;
  color: var(--on-accent);
  margin-bottom: 0.75rem;
}

.controller-status {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-dim);
  margin: 0.75rem 0;
}

.controller-mapping {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-dim);
}

.controller-mapping kbd {
  display: inline-block;
  padding: 0.15rem 0.4rem;
  border-radius: 3px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  margin-right: 0.15rem;
}

.joycon-pair-row {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.controllers-test {
  padding: 0 3rem 3rem;
}

.text-muted {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-bottom: 1rem;
}

.test-readout {
  display: flex;
  gap: 2rem;
  padding: 1rem;
  background: var(--bg-card);
  border-radius: var(--radius);
  border: 1px solid var(--border);
}

.test-item {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.test-label {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.test-item span:last-child {
  font-size: 1rem;
  font-weight: 600;
  font-family: var(--font-mono);
}

/* ── vSilicon Dashboard ───────────────────────────────────── */

.vs-section {
  padding: 0 3rem 2rem;
}

.section-title {
  font-size: var(--step-2);
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 0.85rem;
  color: var(--text);
}

/* In a page section, headings and their notes line up with the rail. */
.section > .section-title,
.section > .section-desc { padding-inline: var(--gutter); }

.section-subtitle {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-bottom: 1.25rem;
}

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.badge-shipping  { background: color-mix(in oklab, var(--success) 14%, transparent); color: var(--success); border: 1px solid color-mix(in oklab, var(--success) 30%, transparent); }
.badge-early     { background: var(--accent-tint); color: var(--accent-text); border: 1px solid color-mix(in oklab, var(--accent) 30%, transparent); }
.badge-lab       { background: color-mix(in oklab, var(--warning) 14%, transparent); color: var(--warning); border: 1px solid color-mix(in oklab, var(--warning) 30%, transparent); }
.badge-theoretical { background: var(--tint-strong); color: var(--text-muted); border: 1px solid var(--border); }

.strategy-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
}

.vs-card {
  flex: unset;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.vs-card:hover {
  transform: none;
  border-color: var(--accent);
  box-shadow: 0 0 20px var(--accent-glow);
}

.vs-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.vs-card-header .card-title {
  white-space: normal;
  font-size: 0.9rem;
}

.vs-workloads {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.75rem;
}

.workload-tag {
  display: inline-block;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 0.7rem;
  font-weight: 500;
  background: var(--surface);
  color: var(--text-muted);
  border: 1px solid var(--border);
}

.workload-tag--sm {
  font-size: 0.65rem;
  padding: 1px 5px;
}

.accelerator-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.75rem;
}

.vs-accel-card {
  flex: unset;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  text-align: center;
  transition: border-color var(--transition), box-shadow var(--transition);
}

.vs-accel-card:hover {
  transform: none;
  border-color: var(--accent);
  box-shadow: 0 0 16px var(--accent-glow);
}

.vs-accel-name {
  font-size: 1.1rem;
  font-weight: 800;
  color: var(--accent-text);
  margin-bottom: 0.35rem;
  letter-spacing: -0.02em;
}

.vs-accel-strategy {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}

.vs-accel-co {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem;
}

.tier-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

.tier-card {
  padding: 1.5rem;
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  border: 1px solid var(--border);
}

.tier-performance { border-left: 3px solid var(--warning); }
.tier-nextgen     { border-left: 3px solid var(--accent); }
.tier-standard    { border-left: 3px solid var(--success); }
.tier-economy     { border-left: 3px solid var(--border-strong); }

.tier-name {
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
}

.tier-multiplier {
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--accent-text);
  margin-bottom: 0.15rem;
}

.tier-sla {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 0.75rem;
}

.tier-features {
  list-style: none;
  padding: 0;
}

.tier-features li {
  font-size: 0.8rem;
  color: var(--text-muted);
  padding: 0.2rem 0;
  border-top: 1px solid var(--border);
}

.tier-features li:first-child { border-top: none; }

.bridge-viz {
  display: flex;
  align-items: stretch;
  gap: 0;
  margin: 0.5rem 0 1rem;
  background: var(--bg-card);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  overflow: hidden;
}

.bridge-step {
  flex: 1;
  text-align: center;
  padding: 1.25rem 0.75rem;
  border-right: 1px solid var(--border);
  transition: background var(--transition);
}

.bridge-step:last-child { border-right: none; }

.bridge-step:hover { background: var(--bg-hover); }

.bridge-name {
  font-size: 0.9rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
}

.bridge-step .latency {
  font-size: 1rem;
  font-weight: 700;
  color: var(--accent-text);
  font-family: var(--font-mono);
  margin-bottom: 0.35rem;
}

.bridge-desc {
  font-size: 0.75rem;
  color: var(--text-dim);
}

.vs-sovereignty {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}

.vs-map-placeholder {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  min-height: 200px;
}

.vs-map-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.vs-map-pin {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.6rem;
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--text-muted);
}

.vs-map-pin-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--live);
  box-shadow: 0 0 4px var(--live-glow);
}

.vs-jur-title {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.75rem;
}

.vs-jur-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.vs-table-wrap {
  overflow-x: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
}

.vs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.vs-table th {
  text-align: left;
  padding: 0.75rem 1rem;
  background: var(--bg-card);
  font-weight: 600;
  font-size: 0.8rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
}

.vs-table td {
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.vs-table tr:last-child td { border-bottom: none; }

.vs-table tr:hover td { background: var(--bg-hover); }

.vs-table-tier {
  font-family: var(--font) !important;
  font-weight: 600;
  color: var(--text) !important;
}

.vs-table-use {
  font-family: var(--font) !important;
  color: var(--text-muted) !important;
}

/* ── Adaptive HLS Player (inv-player.js) ─────────────────── */

.inv-player {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 80vh;
  background: var(--media-bg);
  overflow: hidden;
  cursor: pointer;
  user-select: none;
}

.inv-player-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* 360° video on a flat screen (inv-xr.js): a canvas over the video draws the
   picture around the viewer; drag, swipe or turn the phone to look around. */
.inv-xr-360 { touch-action: none; }
.inv-xr-360 .inv-player-video { opacity: 0; }
.inv-xr-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  cursor: grab;
}
.inv-xr-canvas:active { cursor: grabbing; }
.inv-xr-hint {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 1;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--scrim);
  color: var(--on-media);
  font-size: 0.75rem;
  font-weight: 600;
  pointer-events: none;
  transition: opacity 0.6s;
}
.inv-xr-hint-done { opacity: 0; }
.inv-xr-motion {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  z-index: 3;
  font-size: 0.75rem;
}

/* Buffering */
.inv-player-buffering {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s;
}

.inv-player.buffering .inv-player-buffering { opacity: 1; }

.inv-spinner {
  width: 48px;
  height: 48px;
  border: 3px solid var(--glass);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: inv-spin 0.8s linear infinite;
}

@keyframes inv-spin {
  to { transform: rotate(360deg); }
}

/* Controls overlay */
.inv-controls {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
}

.inv-player.controls-visible .inv-controls,
.inv-player.paused .inv-controls {
  opacity: 1;
  pointer-events: auto;
}

.inv-controls-gradient {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    var(--scrim-strong) 0%,
    var(--scrim-soft) 40%,
    transparent 70%
  );
  pointer-events: none;
}

/* Center play/seek */
.inv-controls-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: 2rem;
  z-index: 2;
}

/* Bottom bar */
.inv-controls-bar {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 1rem 0.75rem;
}

.inv-controls-left,
.inv-controls-right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.inv-btn {
  background: none;
  border: none;
  color: var(--on-media);
  cursor: pointer;
  padding: 6px;
  border-radius: 4px;
  transition: background 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.inv-btn:hover { background: var(--glass); }

/* Play/pause icon switching */
.inv-player.playing .inv-icon-play { display: none; }
.inv-player.playing .inv-icon-pause { display: block; }
.inv-player:not(.playing) .inv-icon-play { display: block; }
.inv-player:not(.playing) .inv-icon-pause { display: none; }

/* Volume */
.inv-volume-group { display: flex; align-items: center; gap: 0.25rem; }

.inv-volume-slider {
  width: 0;
  opacity: 0;
  transition: width 0.2s, opacity 0.2s;
  accent-color: var(--accent);
  height: 4px;
  cursor: pointer;
}

.inv-volume-group:hover .inv-volume-slider {
  width: 70px;
  opacity: 1;
}

.inv-player:not(.muted) .inv-icon-vol-off { display: none; }
.inv-player.muted .inv-icon-vol-on { display: none; }

/* Time */
.inv-time {
  font-size: 0.8rem;
  font-family: var(--font-mono, monospace);
  color: var(--on-media-muted);
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.inv-time-sep { color: var(--on-media-muted); }

.inv-live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--live);
  animation: inv-pulse 1.5s ease-in-out infinite;
}

@keyframes inv-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

.inv-live-label {
  font-weight: 700;
  color: var(--live-text);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
}

/* HDR: the badge, and how bright the picture may get. A film plays with the
   display's full HDR headroom; paused under the controls it is held to a
   little above SDR white, so the overlay stays legible beside it
   (dynamic-range-limit: Chrome and Edge 136+, Safari 26+; others ignore it). */
.inv-hdr-badge {
  font-size: 0.65rem;
  font-weight: 800;
  padding: 1px 6px;
  border-radius: 3px;
  border: 1px solid var(--glass-border);
  color: var(--on-media);
  letter-spacing: 0.04em;
}
.inv-hdr-badge[hidden] { display: none; }
.inv-player video { dynamic-range-limit: no-limit; transition: dynamic-range-limit 0.4s; }
.inv-player.paused video { dynamic-range-limit: constrained; }

/* Quality badge */
.inv-quality-badge {
  display: none;
  font-size: 0.65rem;
  font-weight: 800;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--glass);
  color: var(--on-media);
  letter-spacing: 0.04em;
}

/* Quality menu */
.inv-quality-menu-wrap { position: relative; }

.inv-quality-menu {
  position: absolute;
  bottom: 100%;
  right: 0;
  margin-bottom: 8px;
  background: color-mix(in oklab, var(--bg-raised) 94%, transparent);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 4px 0;
  min-width: 120px;
  /* Never taller than the picture it sits on (16:9, so 56.25% of the
     player's width), less the controls; the rest scrolls. */
  max-height: min(calc(56.25cqi - 72px), calc(100dvh - 120px));
  overflow-y: auto;
  overscroll-behavior: contain;
  backdrop-filter: blur(12px);
  z-index: 10;
}

.inv-quality-option {
  padding: 8px 16px;
  font-size: 0.8rem;
  color: var(--on-media-muted);
  cursor: pointer;
  transition: background 0.1s;
}

.inv-quality-option:hover { background: var(--tint); }
.inv-quality-option.active { color: var(--accent-text); font-weight: 700; }

/* Fullscreen icon switching */
.inv-player:fullscreen .inv-icon-fs-enter { display: none; }
.inv-player:fullscreen .inv-icon-fs-exit { display: block; }
.inv-player:not(:fullscreen) .inv-icon-fs-enter { display: block; }
.inv-player:not(:fullscreen) .inv-icon-fs-exit { display: none; }

/* Progress bar (VOD) */
.inv-progress-bar {
  position: relative;
  z-index: 2;
  height: 4px;
  background: var(--glass);
  cursor: pointer;
  transition: height 0.15s;
}

.inv-progress-bar:hover { height: 8px; }

.inv-progress-buffered {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: var(--glass-hover);
  border-radius: 2px;
  transition: width 0.3s;
}

.inv-progress-played {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
  transition: width 0.1s;
}

.inv-progress-thumb {
  position: absolute;
  top: 50%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, -50%) scale(0);
  transition: transform 0.15s;
}

.inv-progress-bar:hover .inv-progress-thumb {
  transform: translate(-50%, -50%) scale(1);
}

/* Picture enhancement (inv-enhance.js): the upscaled picture, laid over the
   video's own picture box by script; clicks go through to the video. */
.inv-enhance-canvas {
  position: absolute;
  display: block;
  pointer-events: none;
}
.inv-enhance-canvas[hidden], .inv-enhance-badge[hidden] { display: none; }
.inv-enhance-badge {
  font-size: 0.65rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--glass);
  color: var(--on-media);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.inv-menu-heading {
  padding: 8px 16px 4px;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--on-media-muted);
}
button.inv-quality-option {
  display: block;
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
}
/* The settings menu's link to this stream's hour on /energy. */
.inv-menu-link {
  display: block;
  padding: 6px 16px 10px;
  font-size: 0.75rem;
  color: var(--on-media-muted);
  text-decoration: underline;
}
.inv-menu-link:hover { color: var(--on-media); }

/* Captions. Who draws them is the viewer's (inv-caption-style.js): the
   browser, in the device's own caption style (data-cc-render="device"), or
   this overlay, in the settings chosen here, which inv-caption-style.js sets
   as the --cc-* properties (the site's own look without them). Sized to the
   player, not the window: readable in a small player and in fullscreen
   alike; --cc-scale is the viewer's size, 50% to 200%. The overlay is the
   caption window: as wide as its lines, in the window colour. */
.inv-player { container-type: inline-size; }
.inv-subtitle-overlay {
  position: absolute;
  left: 50%;
  bottom: 8%;
  z-index: 2;
  width: max-content;
  max-width: 90%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2em;
  padding: 0.15em 0.3em;
  border-radius: 0.25em;
  background: var(--cc-window, transparent);
  text-align: center;
  font-size: calc(clamp(14px, 3.4cqi, 40px) * var(--cc-scale, 1));
  font-family: var(--cc-font, inherit);
  font-variant: var(--cc-variant, normal);
  line-height: 1.3;
  pointer-events: none;
  transition: bottom 0.3s;
}
.inv-subtitle-overlay:empty { padding: 0; background: none; }
.inv-player.controls-visible .inv-subtitle-overlay { bottom: max(8%, 64px); }
.inv-cue {
  padding: 0.08em 0.4em;
  border-radius: 0.2em;
  background: var(--cc-bg, var(--scrim-strong));
  color: var(--cc-fg, var(--on-media));
  text-shadow: var(--cc-edge, none);
  white-space: pre-line;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
/* Where the system asks for less transparency, the site's own look is opaque;
   with forced colours, the system's colours (a viewer's own choice above
   either wins: the properties are set on the element). */
@media (prefers-reduced-transparency: reduce) {
  .inv-cue { background: var(--cc-bg, oklch(0.1 0.005 265)); }
}
@media (forced-colors: active) {
  .inv-cue { background: var(--cc-bg, Canvas); color: var(--cc-fg, CanvasText); forced-color-adjust: none; }
}
/* The site's style drawn by the browser, where only the video is on screen
   (iPhone full screen, the video's own picture-in-picture). */
.inv-player[data-cc-render="site"] .inv-player-video::cue {
  color: var(--cc-fg, oklch(1 0 0));
  background: var(--cc-bg, oklch(0.1 0.005 265 / 0.86));
  text-shadow: var(--cc-edge, none);
  font-family: var(--cc-font, inherit);
}
/* The device's style: the browser's own captions, lifted above the controls
   while they show (WebKit and Chromium; elsewhere they stay where they are). */
.inv-player.controls-visible .inv-player-video::-webkit-media-text-track-container {
  transform: translateY(-64px);
  transition: transform 0.3s;
}
/* The caption style's settings in the player's menu. */
.inv-cc-value { color: var(--on-media); font-size: 0.75rem; white-space: nowrap; }
.inv-menu-note {
  max-width: 22rem;
  margin: 4px 16px 8px;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--on-media-muted);
}

/* Seek preview: the frame and time under the pointer. */
.inv-seek-preview {
  position: absolute;
  bottom: 18px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  pointer-events: none;
  z-index: 3;
}
.inv-seek-preview[hidden], .inv-seek-preview-frame[hidden] { display: none; }
.inv-seek-preview-frame {
  border: 2px solid var(--on-media);
  border-radius: 6px;
  background-color: var(--media-bg);
  background-repeat: no-repeat;
  box-shadow: var(--shadow-2);
}
.inv-seek-preview-time {
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--scrim-strong);
  color: var(--on-media);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

/* Player offline message */
.player-offline {
  color: var(--text-dim);
  font-size: 0.85rem;
  margin-top: 0.5rem;
}

/* Player viewers */
.player-viewers {
  font-size: 0.85rem;
  color: var(--text-dim);
  margin-left: 0.5rem;
}

/* ── Home — 5-Section Landing ────────────────────────────── */

.home-sections {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.25rem;
  padding: 3rem;
}

.home-section-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 2rem 1.5rem;
  transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition);
}

.home-section-card:hover {
  transform: translateY(-4px);
  border-color: var(--accent);
  box-shadow: 0 8px 30px var(--accent-glow);
}

.home-section-icon {
  font-size: 2rem;
  margin-bottom: 0.75rem;
}

.home-section-card h2 {
  font-size: 1.25rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.home-section-card p {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.5;
}


/* ── TV Section ──────────────────────────────────────────── */

/* The featured channel, with a row of the library's posters beside it.
   Dark in both themes (.dark-surface), like the home hero. */
.tv-hero {
  position: relative;
  min-height: 420px;
  display: flex;
  align-items: flex-end;
  padding: 4rem var(--gutter) 3rem;
  background:
    radial-gradient(ellipse 70% 90% at 85% 40%, color-mix(in oklab, var(--live) 10%, transparent) 0%, transparent 70%),
    var(--hero-band);
}

.tv-hero-inner {
  position: relative;
  z-index: 1;
  max-width: 640px;
}

.tv-hero h1 { margin: 0.75rem 0 0.6rem; }

.tv-hero-desc {
  font-size: var(--step-0);
  color: var(--text-muted);
  max-width: 56ch;
  margin-bottom: 0.75rem;
}

.tv-hero-now {
  font-size: var(--step--1);
  color: var(--text-dim);
  margin-bottom: 1.5rem;
}

.tv-hero-actions {
  display: flex;
  gap: 0.75rem;
}

/* Posters fading in from the left, behind nothing: decoration only. */
.tv-hero-art {
  position: absolute;
  top: 50%;
  right: var(--gutter);
  transform: translateY(-50%);
  display: flex;
  gap: 0.9rem;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, black 45%);
  mask-image: linear-gradient(90deg, transparent 0%, black 45%);
}

.tv-hero-art img {
  width: clamp(110px, 10.5vw, 160px);
  height: auto;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2), 0 0 0 1px var(--glass-border);
}


@media (max-width: 900px) {
  .tv-hero-art { display: none; }
}

.tv-sub-nav {
  display: flex;
  gap: 0.5rem;
  padding: 1.5rem var(--gutter);
  border-bottom: 1px solid var(--border);
}

/* ── Music Section ───────────────────────────────────────── */

.music-hero {
  padding: 4rem 3rem 2rem;
  background: var(--hero-band);
}

.music-hero-inner { max-width: 600px; }

.music-hero h1 { margin-bottom: 0.5rem; }

.music-hero-desc {
  font-size: 1rem;
  color: var(--text-muted);
}

.music-genres {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 1.5rem 3rem;
  border-bottom: 1px solid var(--border);
}

/* ── Track list (Spotify-style table) ───────────────────────── */
.music-track-header {
  display: grid;
  grid-template-columns: 60px 1fr 1fr 80px 60px;
  gap: 1rem;
  padding: 0.5rem 3rem 0.5rem 4rem;
  font-size: 0.7rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  border-bottom: 1px solid var(--border);
}

.track-list {
  display: flex;
  flex-direction: column;
  padding: 0 3rem;
}

.track-row {
  display: grid;
  grid-template-columns: 28px 28px 1fr 1fr 80px 60px 28px;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border-bottom: 1px solid var(--hairline);
  border-radius: var(--radius);
  transition: background var(--transition);
}

.track-row:hover { background: var(--bg-hover); }

.track-row--active {
  background: var(--bg-hover);
  border-left: 3px solid var(--accent);
}

.track-row--active .track-title { color: var(--accent-text); }

.track-num {
  font-size: 0.8rem;
  color: var(--text-dim);
  text-align: center;
}

.track-row:hover .track-num { display: none; }
.track-play-btn { display: none; }
.track-row:hover .track-play-btn { display: flex; }
.track-row--active .track-play-btn { display: flex; }
.track-row--active .track-num { display: none; }

.track-play-btn {
  background: none;
  border: none;
  color: var(--text);
  cursor: pointer;
  padding: 0;
  align-items: center;
  justify-content: center;
}

.track-play-icon { display: block; }
.track-pause-icon { display: none; }
.track-row--active .track-play-icon { display: none; }
.track-row--active .track-pause-icon { display: block; }

.track-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.track-title {
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-artist {
  font-size: 0.75rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-album {
  font-size: 0.8rem;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-genre-tag {
  font-size: 0.7rem;
  color: var(--text-dim);
  padding: 2px 8px;
  background: var(--surface);
  border-radius: 10px;
  text-align: center;
}

.track-duration {
  font-size: 0.8rem;
  color: var(--text-dim);
  font-family: var(--font-mono);
  text-align: right;
}

.track-queue-btn {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 0.9rem;
  cursor: pointer;
  border-radius: 50%;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s, color 0.15s;
}

.track-row:hover .track-queue-btn { opacity: 1; }
.track-queue-btn:hover { color: var(--accent-text); border-color: var(--accent); }

/* ── Global Music Player Bar ────────────────────────────────── */
.music-player-global {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.6rem 1.5rem;
  background: color-mix(in oklab, var(--bg-raised) 94%, transparent);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border-top: 1px solid var(--border);
  z-index: 200;
  height: 72px;
}

.music-player-left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 200px;
  flex: 0 0 auto;
}

.music-player-art {
  width: 44px;
  height: 44px;
  border-radius: 6px;
  background: var(--placeholder);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  flex-shrink: 0;
}

.music-player-info {
  min-width: 0;
}

.music-player-title {
  font-size: 0.85rem;
  font-weight: 600;
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.music-player-artist {
  font-size: 0.72rem;
  color: var(--text-muted);
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.music-player-center {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  max-width: 600px;
  margin: 0 auto;
}

.music-player-controls {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.music-ctrl {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px;
  font-size: 1rem;
  transition: color 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.music-ctrl:hover { color: var(--text); }

.music-ctrl-play {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--action);
  color: var(--on-action);
  display: flex;
  align-items: center;
  justify-content: center;
}

.music-ctrl-play:hover { transform: scale(1.05); color: var(--on-action); }

.music-player-timeline {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}

.music-time {
  font-size: 0.65rem;
  color: var(--text-dim);
  font-family: var(--font-mono);
  min-width: 32px;
  text-align: center;
}

.music-progress-wrap {
  flex: 1;
  height: 4px;
  background: var(--tint-strong);
  border-radius: 2px;
  cursor: pointer;
  position: relative;
}

.music-progress-wrap:hover { height: 6px; }

.music-progress-bar {
  width: 0;
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
  transition: width 0.2s linear;
}

.music-player-right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 140px;
  justify-content: flex-end;
}

.music-player--loading .music-player-title::after {
  content: ' Loading…';
  opacity: 0.5;
  animation: skeleton-shimmer 1.2s ease-in-out infinite;
}

.music-volume-wrap {
  display: flex;
  align-items: center;
  gap: 4px;
}

.music-vol-slider {
  width: 80px;
  height: 4px;
  accent-color: var(--accent);
}

/* ── Queue Panel ────────────────────────────────────────────── */
.music-queue-panel {
  position: fixed;
  bottom: 72px;
  right: 1rem;
  width: 320px;
  max-height: 400px;
  background: color-mix(in oklab, var(--bg-raised) 96%, transparent);
  backdrop-filter: blur(20px);
  border: 1px solid var(--border);
  border-radius: 12px;
  z-index: 201;
  overflow: hidden;
}

.music-queue-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
}

.music-queue-header h3 { font-size: 0.9rem; font-weight: 700; margin: 0; }
.music-queue-header button {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 0.75rem;
}

.music-queue-list {
  max-height: 340px;
  overflow-y: auto;
}

.music-queue-item {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
  transition: background 0.15s;
  align-items: center;
}

.music-queue-item:hover { background: var(--tint); }
.music-queue-item.active { background: var(--accent-tint); }
.music-queue-item.active .queue-title { color: var(--accent-text); }

.queue-num { font-size: 0.75rem; color: var(--text-dim); text-align: center; }
.queue-title { font-size: 0.82rem; font-weight: 500; }
.queue-artist { font-size: 0.72rem; color: var(--text-muted); }

/* ── Music Responsive ───────────────────────────────────────── */
@media (max-width: 768px) {
  .music-track-header { display: none; }
  .track-row {
    grid-template-columns: 28px 28px 1fr 50px;
    padding: 0.5rem 0.5rem;
  }
  .track-album, .track-genre-tag, .track-queue-btn { display: none; }
  .music-player-global { padding: 0.5rem 1rem; gap: 0.75rem; }
  .music-player-left { min-width: 120px; }
  .music-player-right { display: none; }
  .music-queue-panel { width: calc(100vw - 2rem); right: 1rem; left: 1rem; }
}

/* ── Books Section ───────────────────────────────────────── */

.books-hero {
  padding: 4rem 3rem 2rem;
  background: var(--hero-band);
}

.books-hero-inner { max-width: 600px; }

.books-hero h1 {
  font-size: 3rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  margin-bottom: 0.5rem;
}

.books-hero-desc {
  font-size: 1rem;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}

.books-hero-stat {
  font-size: 0.85rem;
  color: var(--text-dim);
}

.book-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1rem;
  padding: 0 3rem 2rem;
}

.book-card {
  display: flex;
  gap: 1rem;
  padding: 1rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: transform var(--transition), border-color var(--transition);
}

.book-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
}

.book-cover {
  flex: 0 0 60px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  border-radius: var(--radius);
}

.book-icon { font-size: 1.5rem; }

.book-info { flex: 1; min-width: 0; }

.book-title {
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.2rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.book-author {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 0.25rem;
}

.book-meta {
  font-size: 0.75rem;
  color: var(--text-dim);
}

/* ── Games ───────────────────────────────────────────────── */

.games-hero {
  padding: 5rem 3rem 2.5rem;
  background:
    radial-gradient(120% 140% at 100% 0%, oklch(0.42 0.12 290 / 0.55) 0%, transparent 60%),
    oklch(0.2 0.04 280);
}

.games-hero-inner { max-width: 60ch; }

.games-hero-desc {
  font-size: var(--step-0);
  color: var(--text-muted);
  margin-top: 0.5rem;
}

.pill--active {
  background: var(--action);
  color: var(--on-action);
}

/* The section keeps the page gutter; its heading lines up with its cards. */
.games-section > .section-title,
.games-section > .section-desc { padding-inline: 0; }
.games-grid {
  padding: 0;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.games-grid .card { min-width: 0; }

/* Games not played here are facts, set as a directory rather than as tiles. */
.games-facts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 0.6rem 1rem;
}

.game-fact {
  display: flex;
  gap: 0.75rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  color: var(--text);
  text-decoration: none;
  transition: background var(--transition), border-color var(--transition);
}

.game-fact:hover { background: var(--bg-hover); border-color: color-mix(in oklab, var(--text) 25%, transparent); }

.game-fact-mark {
  flex: 0 0 4px;
  border-radius: 2px;
}

.game-fact-text {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}

.game-fact-title {
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1.3;
}

.game-fact-makers,
.game-fact-meta {
  font-size: var(--step--2);
  color: var(--text-dim);
}

.game-fact-makers {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A game's page: its name over its colours, then the game. */
.gd-hero {
  padding: 5rem 3rem 2.5rem;
}

.gd-hero-inner { max-width: 70ch; }

.gd-hero-title {
  font-size: var(--step-4);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-bottom: 0.5rem;
}

.gd-hero-dev {
  color: var(--on-media-muted);
  margin-bottom: 0.75rem;
}

.gd-hero-about {
  color: var(--text);
  margin-bottom: 1.25rem;
}

.gd-hero-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

/* The game: a dark stage that waits to be started, then holds the frame. */
.gd-play { padding: 1.5rem 3rem 0; }

.game-stage {
  position: relative;
  aspect-ratio: 16 / 9;
  max-height: calc(100dvh - 8rem);
  max-width: calc((100dvh - 8rem) * 16 / 9);
  margin-inline: auto;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: oklch(0.12 0.02 280);
  color-scheme: dark;
  color: var(--text);
  display: grid;
  place-items: center;
}

/* A hosted game the law does not allow to be served here: the reason, in
   place of the stage (jurisdiction, Activity::Games). */
.game-refused { max-width: 72ch; margin-inline: auto; padding: 1.25rem 1.5rem; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-raised); }
.game-refused p { margin: 0 0 0.5rem; }
.game-refused-title { font-size: var(--step-1); font-weight: 700; }
.game-refused a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.15em; }

.game-stage:fullscreen {
  max-height: none;
  max-width: none;
  border-radius: 0;
  aspect-ratio: auto;
}

.game-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  background: #000;
}

.game-start {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  padding: 1.5rem 2rem;
  font: inherit;
  font-size: var(--step-1);
  font-weight: 700;
  color: inherit;
  background: none;
  border: 0;
  border-radius: var(--radius-lg);
  cursor: pointer;
}

.game-start-icon {
  display: grid;
  place-items: center;
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 50%;
  background: var(--action);
  color: var(--on-action);
  transition: transform var(--transition);
}

.game-start-icon .icon { width: 2rem; height: 2rem; }
.game-start:hover .game-start-icon { transform: scale(1.06); }

.game-stage-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

.game-note {
  margin-right: auto;
  font-size: var(--step--1);
  color: var(--text-dim);
}

.gd-body { padding: 2rem 3rem; }

.gd-body-inner { max-width: 70ch; }

.gd-body-inner h2 {
  font-size: var(--step-1);
  font-weight: 700;
  margin-bottom: 1rem;
}

.gd-dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.6rem 1.25rem;
}

.gd-dl dt {
  color: var(--text-dim);
  font-weight: 500;
}

.gd-dl dd { color: var(--text); overflow-wrap: anywhere; }
.gd-dl a, .gd-source a { color: var(--accent-text); text-decoration: underline; }

.gd-source {
  margin-top: 1.5rem;
  font-size: var(--step--1);
  color: var(--text-dim);
}

.gd-back { padding: 0 3rem 3rem; }


/* ── News Section ────────────────────────────────────────── */

/* Breaking News Ticker */
.news-ticker {
  display: flex;
  align-items: stretch;
  background: color-mix(in oklab, var(--live) 12%, var(--bg));
  border-bottom: 2px solid var(--live);
  overflow: hidden;
  height: 36px;
}

.news-ticker-label {
  background: var(--live);
  color: var(--on-live);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  padding: 0 1rem;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.news-ticker-track {
  flex: 1;
  overflow: hidden;
  position: relative;
}

.news-ticker-scroll {
  display: flex;
  gap: 3rem;
  white-space: nowrap;
  animation: ticker-scroll 60s linear infinite;
  padding: 0 1rem;
  align-items: center;
  height: 100%;
}

.news-ticker-item {
  font-size: 0.8rem;
  color: var(--text);
  text-decoration: none;
  flex-shrink: 0;
}
.news-ticker-item:hover { text-decoration: underline; }
/* Reading a headline, or tabbing to one, holds the ticker still. */
.news-ticker-scroll:hover,
.news-ticker-scroll:focus-within { animation-play-state: paused; }
.news-ticker-scroll > [aria-hidden] { display: contents; }

.ticker-source {
  font-weight: 700;
  color: var(--live-text);
  margin-right: 0.5rem;
  font-size: 0.7rem;
}

@keyframes ticker-scroll {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

.news-hero {
  padding: 3rem 3rem 1.5rem;
}

.news-hero h1 { margin-bottom: 0.5rem; }

.news-hero-desc {
  font-size: 1rem;
  color: var(--text-muted);
}

.news-primary {
  display: grid;
  grid-template-columns: 1fr 380px;
  gap: 2rem;
  padding: 0 3rem 2rem;
}

.news-primary-player { width: 100%; }

.news-primary-info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 0.75rem;
}

.news-primary-info h2 {
  font-size: 1.4rem;
  font-weight: 700;
}

.news-primary-desc {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.6;
}

.news-primary-meta {
  display: flex;
  gap: 0.75rem;
  align-items: center;
}

.news-viewers {
  font-size: 0.8rem;
  color: var(--text-dim);
}

.news-category-tag {
  font-size: 0.7rem;
  padding: 2px 10px;
  border-radius: 10px;
  background: var(--accent-tint);
  color: var(--accent-text);
  font-weight: 600;
}

.news-primary-actions {
  display: flex;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.news-live-badge {
  animation: live-pulse-anim 2s ease-in-out infinite;
}

.news-categories {
  display: flex;
  gap: 0.5rem;
  padding: 0 3rem 1rem;
  flex-wrap: wrap;
}

.news-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1rem;
  padding: 0 3rem 2rem;
}

.news-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition);
  text-decoration: none;
}

.news-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in oklab, var(--live) 40%, transparent);
  box-shadow: var(--shadow-2);
}

.news-card-visual {
  height: 100px;
  background: var(--placeholder);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 0.75rem;
}

.news-card-viewers {
  font-size: 0.7rem;
  color: var(--text-muted);
  background: var(--scrim);
  padding: 2px 8px;
  border-radius: 4px;
}

.news-card-info { padding: 0.75rem 1rem 1rem; }

.news-card-info h3 {
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.2rem;
}

.news-card-info p {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.news-card-category {
  display: inline-block;
  font-size: 0.65rem;
  padding: 1px 8px;
  border-radius: 8px;
  background: var(--tint);
  color: var(--text-dim);
  margin-top: 0.4rem;
}

/* ── Shared: Section + Pills ─────────────────────────────── */

.section {
  padding: 1.75rem 0 0.75rem;
}

/* Sections that hold their own grids keep the page gutter themselves. */
.section.games-section { padding-inline: var(--gutter); }
.energy-page .section > .section-title,
.energy-page .section > .section-desc { padding-inline: 0; }

.pill {
  display: inline-block;
  padding: 0.4rem 1rem;
  border-radius: 20px;
  font-size: 0.85rem;
  font-weight: 500;
  background: var(--surface);
  color: var(--text-muted);
  border: 1px solid var(--border);
  transition: all var(--transition);
}

.pill:hover { background: var(--bg-hover); color: var(--text); }

/* The chosen filter is lit like the primary button, not tinted. */
.pill--active,
.pill--active:hover {
  background: var(--action);
  color: var(--on-action);
  border-color: var(--action);
}

.badge--live {
  background: var(--live);
  color: var(--on-live);
}

.badge--price {
  background: var(--accent);
  color: var(--on-accent);
}

/* "Plays here": a small solid disc with the play mark. */
.badge--play,
.card-visual .badge--play {
  width: 24px;
  height: 24px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
  background: var(--on-media);
  color: var(--media-bg);
}
.badge--play .icon { width: 12px; height: 12px; fill: currentColor; margin-left: 1px; }
.badge--kids {
  background: var(--faith);
  color: var(--on-accent);
}
.badge--classic,
.card-visual .badge--classic {
  background: var(--classic);
  color: var(--on-classic);
  font-weight: 700;
}
.section--classics {
  border-top: 1px solid color-mix(in oklab, var(--classic) 40%, transparent);
  padding-top: 2rem;
}
.section-desc {
  color: var(--text-dim);
  font-size: var(--step--1);
  margin: -0.4rem 0 1rem;
  max-width: calc(60ch + 2 * var(--gutter));
}
/* The vault's cards carry a thin gold edge. */
.card--classic .card-visual {
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--classic) 45%, transparent) inset;
}

.count {
  font-size: 0.8em;
  color: var(--text-dim);
  font-weight: 400;
}

/* ── Card variants for TV ────────────────────────────────── */

/* Tiles without artwork (channels, games, books) carry their name, set
   large. A channel's tile is a dark screen in both themes, with a faint
   on-air glow in the corner. */
.card--channel .card-visual {
  color-scheme: dark;
  color: var(--text);
  background:
    radial-gradient(120% 120% at 100% 0%, color-mix(in oklab, var(--live) 16%, transparent) 0%, transparent 60%),
    var(--placeholder);
}

/* A game's tile is painted in the game's own deep colours (inline); its
   name stops short of the rating in the corner. */
.card--game .card-visual { color-scheme: dark; color: var(--text); }
.card--game .card-tile-title { right: 4.5rem; }

.card-tile-title {
  position: absolute;
  top: 0.8rem;
  left: 0.9rem;
  right: 0.9rem;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--text);
}

.card-now {
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* ── Responsive ───────────────────────────────────────────── */

@media (max-width: 768px) {
  .nav { padding: 0 1rem; gap: 1rem; }
  .hero { min-height: 400px; padding: 3rem 1.5rem; }
  .hero-title { font-size: 2rem; }
  .hero-stats { flex-wrap: wrap; }
  .card { flex: 0 0 240px; }
  .card.card--poster { flex-basis: 150px; }
  .channel-hero { padding: 2rem 1.5rem; }
  .channel-title { font-size: 1.75rem; }
  .epg { padding: 1.5rem; }
  .browse-header { padding: 2rem 1.5rem 1rem; }
  .browse-grid { padding: 0 1.5rem 2rem; grid-template-columns: 1fr; }
  .player-info { grid-template-columns: 1fr; padding: 1.5rem; }
  .player-back { padding: 0 1.5rem 2rem; }
  .vs-section { padding: 0 1.5rem 2rem; }
  .tier-row { grid-template-columns: repeat(2, 1fr); }
  .bridge-viz { flex-direction: column; }
  .bridge-step { border-right: none; border-bottom: 1px solid var(--border); }
  .bridge-step:last-child { border-bottom: none; }
  .vs-sovereignty { grid-template-columns: 1fr; }
  .home-sections { padding: 1.5rem; }
  .tv-hero { padding: 2rem 1.5rem; min-height: 300px; }
  .tv-sub-nav { padding: 1rem 1.5rem; }
  .music-hero { padding: 2rem 1.5rem; }
  .music-genres { padding: 1rem 1.5rem; }
  .track-list { padding: 0 1.5rem; }
  .books-hero { padding: 2rem 1.5rem; }
  .book-grid { padding: 0 1.5rem 1.5rem; }
  .games-hero, .gd-hero { padding: 3.5rem var(--gutter) 2rem; }
  .gd-play, .gd-body { padding-inline: var(--gutter); }
  .gd-back { padding: 0 var(--gutter) 2rem; }
  .gd-hero-title { font-size: var(--step-3); }
  .news-hero { padding: 2rem 1.5rem; }
  .news-primary { grid-template-columns: 1fr; padding: 0 1.5rem 1.5rem; }
  .news-grid { padding: 0 1.5rem 1.5rem; }
}

@media (max-width: 480px) {
  .card { flex: 0 0 200px; }
  .card.card--poster { flex-basis: 132px; }
  .hero-actions { flex-direction: column; }
  .profiles-grid { gap: 1.25rem; }
  .profile-avatar { width: 80px; height: 80px; font-size: 1.75rem; }
}

/* ── Profile Selector ("Who's Watching?") ───────────────── */

.profiles-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 64px - 80px);
  padding: 3rem 2rem;
}

.profiles-title {
  font-size: 2.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 3rem;
  text-align: center;
}

.profiles-grid {
  display: flex;
  gap: 2rem;
  flex-wrap: wrap;
  justify-content: center;
  max-width: 800px;
}

.profile-card-form { display: contents; }

.profile-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 1.5rem;
  background: transparent;
  border: 2px solid transparent;
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: transform var(--transition), border-color var(--transition);
  color: var(--text);
  font-family: inherit;
  min-width: 120px;
}

.profile-card:hover {
  transform: translateY(-4px);
  border-color: var(--accent);
}

.profile-card--kids {
  position: relative;
}

.profile-card--kids::after {
  content: "KIDS";
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 0.15rem 0.4rem;
  background: var(--success-fill);
  color: var(--on-accent);
  border-radius: var(--radius);
}

.profile-avatar {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.25rem;
  font-weight: 700;
  color: var(--on-accent);
  text-transform: uppercase;
  border: 3px solid var(--glass-border);
  transition: border-color var(--transition);
}

.profile-card:hover .profile-avatar {
  border-color: var(--accent);
}

.profile-avatar-icon {
  pointer-events: none;
}

.profile-name {
  font-size: 1rem;
  font-weight: 600;
}

.profile-tier {
  font-size: 0.7rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.profile-lock {
  font-size: 0.8rem;
  opacity: 0.6;
}

.profiles-hint {
  margin-top: 3rem;
  font-size: 0.85rem;
  color: var(--text-dim);
  text-align: center;
}
.profiles-hint + .profiles-hint { margin-top: 0.75rem; }
.profiles-hint a, .home-privacy-note a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.15em; }
.home-privacy-note { color: var(--text-muted); font-size: 0.9rem; }

/* ── PIN Entry Page ─────────────────────────────────────── */

.pin-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 64px - 80px);
  padding: 3rem 2rem;
}

.pin-title {
  font-size: 1.75rem;
  font-weight: 700;
  margin-bottom: 2rem;
  text-align: center;
}

.pin-error {
  color: var(--danger);
  font-size: 0.9rem;
  margin-bottom: 1rem;
}

.pin-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
}

.pin-input-row {
  display: flex;
  gap: 0.5rem;
}

.pin-input {
  width: 200px;
  padding: 0.75rem 1rem;
  font-size: 1.5rem;
  text-align: center;
  letter-spacing: 0.5em;
  background: var(--bg-card);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-family: inherit;
  transition: border-color var(--transition);
}

.pin-input:focus {
  outline: none;
  border-color: var(--accent);
}

.pin-cancel {
  margin-top: 0.5rem;
  text-decoration: none;
}

/* ── Kids Mode UI Transformation ────────────────────────── */
/* Shapes only; the kids palette is with the rest of kids mode below. */

body.kids-mode .card,
body.kids-mode .card-visual {
  border-radius: 1rem;
}


/* Active profile indicator in nav */
.nav-profile-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.6rem;
  border-radius: 2rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--text);
  transition: opacity var(--transition);
}

.nav-profile-badge:hover { opacity: 0.8; }

.nav-profile-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  animation: nav-dot-breathe 3s ease-in-out infinite;
}

@keyframes nav-dot-breathe {
  0%, 100% { box-shadow: 0 0 4px currentColor; }
  50% { box-shadow: 0 0 12px currentColor, 0 0 20px currentColor; }
}

/* ══════════════════════════════════════════════════════════════
   PROFILE SELECTOR — The Gateway
   ══════════════════════════════════════════════════════════════ */

/* Ambient background for profiles page: one still pool of accent light. */
.profiles-ambient {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse 60% 50% at 50% 45%, var(--accent-tint) 0%, transparent 70%);
  pointer-events: none;
}

.profiles-page {
  position: relative;
  overflow: hidden;
}

/* Staggered entrance animation for profile cards */
.profile-card {
  opacity: 0;
  transform: translateY(24px) scale(0.95);
  animation: profile-entrance 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
  animation-delay: calc(var(--i, 0) * 0.1s + 0.2s);
}

@keyframes profile-entrance {
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* Avatar emoji — large, centered */
.profile-avatar {
  position: relative;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s ease;
}

.profile-avatar-emoji {
  font-size: 2.5rem;
  line-height: 1;
  filter: drop-shadow(0 2px 8px var(--scrim-soft));
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

/* Avatar ring — glows on hover */
.profile-avatar-ring {
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid transparent;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
  pointer-events: none;
}

.profile-card:hover .profile-avatar {
  transform: scale(1.08);
  box-shadow: 0 0 30px color-mix(in oklab, var(--profile-color, var(--accent)) 40%, transparent);
}

.profile-card:hover .profile-avatar-ring {
  border-color: var(--profile-color, var(--accent));
  box-shadow: 0 0 20px var(--profile-color, var(--accent-glow));
}

.profile-card:hover .profile-avatar-emoji {
  transform: scale(1.1);
}

/* Lock icon for PIN-protected profiles */
.profile-lock-icon {
  position: absolute;
  bottom: 0.5rem;
  right: 0.5rem;
  width: 20px;
  height: 20px;
  background: var(--scrim);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(4px);
  color: var(--on-media);
}

.profile-lock-icon .icon { width: 12px; height: 12px; }

/* Kids badge — playful green pill */
.profile-kids-badge {
  position: absolute;
  top: 0.4rem;
  right: 0.2rem;
  font-size: 0.5rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  padding: 0.15rem 0.45rem;
  background: var(--success-fill);
  color: var(--on-accent);
  border-radius: 2rem;
  box-shadow: 0 2px 8px color-mix(in oklab, var(--success-fill) 30%, transparent);
}

/* Remove old KIDS ::after since we use a real element now */
.profile-card--kids::after { display: none; }

/* ══════════════════════════════════════════════════════════════
   NO ENTRANCE FADES
   Rows, cards and heroes used to start transparent and fade in as script
   saw them scroll into view. Whatever is on screen at load is now there in
   the first frame: nothing to wait for, and the browser can measure the
   page's largest paint (LCP) at all, which it skips for invisible content.
   ══════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════
   KIDS MODE — Full UI transformation
   When a Kids or LittleOnes profile is active, the platform turns warm
   and playful: a plum page, green for what is chosen, rounder and
   bouncier cards. Same rules as the main palette: light-dark() pairs,
   and contrast.mjs checks them.
   ══════════════════════════════════════════════════════════════ */

body.kids-mode {
  --bg:          light-dark(oklch(0.975 0.012 300), oklch(0.17 0.05 295));
  --bg-raised:   light-dark(oklch(1 0 0), oklch(0.215 0.06 295));
  --bg-card:     light-dark(oklch(1 0 0), oklch(0.235 0.065 295));
  --bg-hover:    light-dark(oklch(0.94 0.02 300), oklch(0.285 0.07 295));
  --surface:     light-dark(oklch(0.95 0.018 300), oklch(0.26 0.065 295));
  --border:      light-dark(oklch(0.88 0.03 300), oklch(0.36 0.08 295));
  --accent:      oklch(0.5 0.13 150);
  --accent-text: light-dark(oklch(0.47 0.12 150), oklch(0.8 0.15 150));
  --focus-ring:  light-dark(oklch(0.47 0.12 150), oklch(0.8 0.15 150));
}

body.kids-mode .nav-logo .logo-mark { color: var(--accent-text); }

/* Kids cards — bouncy, rounded, playful */
body.kids-mode .card-visual {
  border-radius: 1.25rem;
  transition: transform 0.4s var(--spring-bounce), box-shadow 0.3s ease, border-color 0.3s ease;
}

body.kids-mode .card:hover .card-visual {
  transform: translateY(-6px) rotate(-1deg);
  border-color: var(--accent);
  box-shadow: 0 16px 40px color-mix(in oklab, var(--accent) 25%, transparent);
}

body.kids-mode .section-title {
  font-size: calc(var(--step-2) * 1.1);
  font-weight: 800;
}

body.kids-mode .pill { color: var(--text-muted); }

body.kids-mode .pill:hover,
body.kids-mode .pill--active {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}

/* ══════════════════════════════════════════════════════════════
   CONTENT RESTRICTION PAGE
   ══════════════════════════════════════════════════════════════ */

.restrict-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 64px);
  padding: 3rem 2rem;
  text-align: center;
}

.restrict-icon {
  font-size: 4rem;
  margin-bottom: 1.5rem;
  opacity: 0.6;
  animation: restrict-breathe 3s ease-in-out infinite;
}

@keyframes restrict-breathe {
  0%, 100% { transform: scale(1); opacity: 0.6; }
  50% { transform: scale(1.05); opacity: 0.8; }
}

.restrict-title {
  font-size: 1.75rem;
  font-weight: 700;
  margin-bottom: 0.75rem;
}

.restrict-message {
  color: var(--text-muted);
  font-size: 1rem;
  margin-bottom: 2rem;
  max-width: 400px;
}

.restrict-back {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  background: var(--action);
  color: var(--on-action);
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.9rem;
  transition: background 0.2s ease, transform 0.2s ease;
}

.restrict-back:hover {
  background: var(--action-hover);
  transform: translateY(-2px);
}

/* ══════════════════════════════════════════════════════════════
   PIN PAGE — Polish
   ══════════════════════════════════════════════════════════════ */

.pin-page {
  position: relative;
}

.pin-input {
  transition: border-color var(--transition), box-shadow var(--transition);
}

.pin-input:focus {
  box-shadow: 0 0 16px var(--accent-glow);
}

.pin-error {
  animation: pin-shake 0.4s ease-in-out;
}

@keyframes pin-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-8px); }
  50% { transform: translateX(8px); }
  75% { transform: translateX(-4px); }
}

/* ══════════════════════════════════════════════════════════════
   BOOK CARDS — Enhanced with descriptions
   ══════════════════════════════════════════════════════════════ */

.book-desc {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.book-card {
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
              border-color 0.3s ease,
              box-shadow 0.3s ease;
}

.book-card:hover {
  transform: translateY(-4px);
  border-color: var(--accent);
  box-shadow: var(--shadow-2);
}

.book-icon {
  font-size: 2rem;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.book-card:hover .book-icon {
  transform: scale(1.15);
}

/* ══════════════════════════════════════════════════════════════
   IN-APP BOOK READER
   Clean, focused reading experience. Three themes:
   default (dark), sepia (warm), light (paper white).
   ══════════════════════════════════════════════════════════════ */

.reader-header {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 1rem 2rem;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.reader-back {
  font-size: 0.85rem;
  color: var(--text-muted);
  text-decoration: none;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: color var(--transition), border-color var(--transition);
  flex-shrink: 0;
}

.reader-back:hover {
  color: var(--text);
  border-color: var(--accent);
}

.reader-meta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
}

.reader-icon {
  font-size: 1.5rem;
  flex-shrink: 0;
}

.reader-title {
  font-size: 1rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reader-author {
  font-size: 0.75rem;
  color: var(--text-muted);
}

.reader-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.reader-btn {
  padding: 0.35rem 0.65rem;
  font-size: 0.8rem;
  font-weight: 600;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
  font-family: inherit;
}

.reader-btn:hover {
  color: var(--text);
  border-color: var(--accent);
}

.reader-progress {
  font-size: 0.75rem;
  color: var(--text-dim);
  font-family: var(--font-mono);
  min-width: 2.5rem;
  text-align: right;
}

/* Reader content area */
.reader-content {
  max-width: 720px;
  margin: 0 auto;
  padding: 2rem 2rem 6rem;
  min-height: calc(100vh - 64px - 80px);
}

.reader-text {
  font-size: 18px;
  line-height: 1.8;
  color: var(--text);
  font-family: var(--font-serif);
}

.reader-text p {
  margin-bottom: 1.25em;
  text-indent: 0;
}

/* Reader themes: paper the reader picks for the page, whatever the site's
   theme, so these are the paper's own colours, not tokens. */
.reader-sepia {
  background: #f4ecd8;
}

.reader-sepia .reader-text {
  color: #3c3122;
}

.reader-light {
  background: #ffffff;
}

.reader-light .reader-text {
  color: #1a1a1a;
}

/* Loading state */
.reader-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding: 4rem 0;
  color: var(--text-muted);
}

.reader-loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: inv-spin 0.8s linear infinite;
}

.reader-error {
  text-align: center;
  padding: 3rem;
  color: var(--text-muted);
}

.reader-error button {
  margin-top: 0.5rem;
  padding: 0.5rem 1rem;
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  font-family: inherit;
  font-weight: 600;
}

/* Responsive */
@media (max-width: 768px) {
  .reader-header { padding: 0.75rem 1rem; gap: 0.75rem; }
  .reader-content { padding: 1.5rem 1rem 4rem; }
  .reader-text { font-size: 16px; }
  .reader-title { font-size: 0.85rem; }
}

/* ══════════════════════════════════════════════════════════════
   HOME PAGE — Cinematic Hero + Content Discovery
   ══════════════════════════════════════════════════════════════ */

/* ── Hero Carousel ──────────────────────────────────────────── */
/* One work from each of several parts of the library. A film of the site's
   own shows a still from its master across the whole band; any other work
   (a poster, a cover, a painting, an archive's thumbnail) stands whole and
   sharp beside the words, in its own shape, over a field made of the same
   picture blurred into its colours, since stretched across the band it
   would blur. The band is .dark-surface in both themes, like the artwork it
   frames. */
.home-hero {
  position: relative;
  height: min(74vh, 680px);
  min-height: 460px;
  overflow: hidden;
  background: var(--bg);
}

.home-hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.2s var(--ease-in-out-smooth);
  display: flex;
  align-items: flex-end;
  isolation: isolate;
  background-color: var(--bg);
}

.home-hero-slide.active { opacity: 1; z-index: 1; }
.home-hero-slide--plain { background: var(--hero-band); }

/* A backdrop cut from the title's master, sized by the browser from its
   srcset; the blurred placeholder shows until the image arrives. */
.home-hero-art,
.home-hero-art img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.home-hero-art img {
  object-fit: cover;
  object-position: center 35%;
  background-size: cover;
  background-position: center;
}

/* The field behind a framed picture: the picture itself, blurred. */
.home-hero-backdrop {
  position: absolute;
  z-index: -1;
  inset: -64px;
  width: calc(100% + 128px);
  height: calc(100% + 128px);
  object-fit: cover;
  filter: blur(56px) saturate(1.25) brightness(0.5);
}

/* The picture, whole, at the right; its shape is --ar (width / height). */
.home-hero-frame {
  position: absolute;
  z-index: 2;
  top: 46%;
  right: calc(var(--gutter) + 2vw);
  height: min(78%, calc(42vw / var(--ar, 0.6667)));
  aspect-ratio: var(--ar, 0.6667);
  translate: 0 -50%;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--placeholder);
  box-shadow: 0 30px 80px var(--scrim-strong), 0 0 0 1px var(--glass-border);
}
.home-hero-frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* A picture its host could not send is removed (app.js): no empty frame. */
.home-hero-frame:not(:has(img)) { display: none; }

.home-hero-gradient {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, var(--scrim-strong) 0%, var(--scrim) 38%, transparent 68%),
    linear-gradient(0deg, var(--bg) 0%, transparent 32%);
  z-index: 1;
}

.home-hero-content {
  position: relative;
  z-index: 2;
  max-width: min(620px, 54%);
  padding: 0 var(--gutter) clamp(2.5rem, 6vh, 4rem);
}

.home-hero-meta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.9rem;
}

.home-hero-rating,
.home-hero-year {
  font-size: var(--step--1);
  color: var(--on-media-muted);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.home-hero-rating {
  padding: 1px 6px;
  border: 1px solid var(--glass-border);
  border-radius: 4px;
  font-size: var(--step--2);
  letter-spacing: 0.04em;
}

.home-hero-title {
  font-size: var(--step-5);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.02;
  margin-bottom: 0.9rem;
  color: var(--on-media);
}

.home-hero-synopsis {
  font-size: var(--step-0);
  color: var(--on-media-muted);
  line-height: 1.6;
  max-width: 52ch;
  margin-bottom: 0.9rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Genres as a quiet line of words, not a row of chips. */
.home-hero-genres {
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
  font-size: var(--step--1);
  color: var(--on-media-muted);
}

.home-hero-genre + .home-hero-genre::before {
  content: '·';
  margin: 0 0.5em;
  color: var(--text-dim);
}

.home-hero-actions {
  display: flex;
  gap: 0.75rem;
}

.btn--lg {
  padding: 0.85rem 1.9rem;
  font-size: 1rem;
  font-weight: 700;
}

/* A secondary action laid over artwork: frosted, in the text colour. */
.btn--glass {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.7rem 1.4rem;
  border-radius: var(--radius);
  background: var(--tint-strong);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--hairline);
  color: var(--text);
  font-weight: 600;
  font-size: 0.95rem;
  cursor: pointer;
  transition: background var(--transition);
  text-decoration: none;
}

.btn--glass .icon { width: 1.15em; height: 1.15em; vertical-align: 0; }
.btn--lg + .btn--glass { padding: 0.85rem 1.6rem; font-size: 1rem; }

.btn--glass:hover {
  background: color-mix(in oklab, var(--text) 20%, transparent);
}

/* Hero indicators */
.home-hero-indicators {
  position: absolute;
  bottom: 1.5rem;
  right: var(--gutter);
  z-index: 3;
  display: flex;
  gap: 8px;
}

.home-hero-dot {
  width: 24px;
  height: 3px;
  border-radius: 2px;
  border: none;
  background: var(--glass-hover);
  cursor: pointer;
  transition: width 0.4s, background 0.4s;
  padding: 0;
}

.home-hero-dot.active {
  background: var(--on-media);
  width: 40px;
}

/* ── Every section, under the hero ──────────────────────────────
   The header's own list (crate::nav). On a wide screen they wrap, all in
   view; on a phone they are one row that scrolls, as rails do. */
.home-nav-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 1.5rem var(--gutter) 0.5rem;
}
@media (max-width: 640px) {
  .home-nav-strip { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
}

.home-nav-strip::-webkit-scrollbar { display: none; }

.home-nav-pill {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1.1rem;
  border-radius: 100px;
  background: var(--tint);
  border: 1px solid var(--hairline);
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--step--1);
  text-decoration: none;
  transition: background var(--transition), color var(--transition);
}

.home-nav-pill:hover {
  background: var(--tint-strong);
  color: var(--text);
}

.home-nav-pill .icon { width: 1.1em; height: 1.1em; vertical-align: 0; }

/* ── Card Extras ────────────────────────────────────────────── */
.card--live-glow .card-visual {
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--live) 22%, transparent) inset;
}

.card-rating-star {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--on-media);
  background: var(--scrim);
  padding: 2px 8px;
  border-radius: 4px;
}

.card-rating-star .icon { width: 12px; height: 12px; color: var(--classic); fill: currentColor; }

/* Books get covers: cloth in a deep colour, the title set in a book face,
   the emblem at the foot, a shadow for the spine. The colours are the
   covers' own (art, not interface), in turn along the row. */
.card-visual--book {
  --cover-hue: 265;
  color-scheme: dark;
  color: var(--text);
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  padding: 1rem 0.9rem 0.9rem 1.1rem;
  background: linear-gradient(165deg, oklch(0.42 0.07 var(--cover-hue)), oklch(0.23 0.045 var(--cover-hue)));
  box-shadow: inset 5px 0 0 oklch(0 0 0 / 0.22), 0 0 0 1px var(--hairline) inset;
}

.card--book:nth-child(6n+1) .card-visual--book { --cover-hue: 25; }
.card--book:nth-child(6n+2) .card-visual--book { --cover-hue: 160; }
.card--book:nth-child(6n+3) .card-visual--book { --cover-hue: 255; }
.card--book:nth-child(6n+4) .card-visual--book { --cover-hue: 75; }
.card--book:nth-child(6n+5) .card-visual--book { --cover-hue: 320; }
.card--book:nth-child(6n+6) .card-visual--book { --cover-hue: 205; }

.card-visual--book .card-tile-title {
  position: static;
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: var(--step-0);
  letter-spacing: 0;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.book-icon-lg { color: var(--text-muted); }
.book-icon-lg .icon { width: 1.75rem; height: 1.75rem; stroke-width: 1.5; }

.badge--accent {
  background: var(--accent);
  color: var(--on-accent);
}

.badge--game,
.card-visual .badge--game {
  background: var(--success-fill);
  color: var(--on-accent);
}

.badge--game .icon { width: 14px; height: 14px; }

/* ── Live pulse indicator ───────────────────────────────────── */
.live-pulse {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--live);
  margin-left: 0.5rem;
  vertical-align: middle;
  animation: live-pulse-anim 2s ease-in-out infinite;
}

/* Pulses the glow only: fading the badge itself took its text below
   readable contrast twice a second. */
@keyframes live-pulse-anim {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--live) 60%, transparent); }
  50% { box-shadow: 0 0 0 6px transparent; }
}

/* ── Personal rows and genre rows (inv-personal) ────────────────
   "Continue watching" and "Because you watched …" are reserved before paint
   with cards of the real size (the skeleton) and filled without moving
   anything: the cards keep the poster card's size at every width. */
.personal-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.personal-card {
  position: relative;
  flex: 0 0 184px;
  min-width: 0;
}
.personal-card > .card { display: block; width: 100%; }
@media (max-width: 768px) { .personal-card { flex-basis: 150px; } }
@media (max-width: 480px) { .personal-card { flex-basis: 132px; } }

.card--skeleton .card-visual {
  background: linear-gradient(90deg, var(--bg-card) 25%, var(--bg-hover) 50%, var(--bg-card) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
}
.card--skeleton .card-title,
.card--skeleton .card-meta {
  width: 70%;
  border-radius: 4px;
  background: var(--tint);
}
.card--skeleton .card-meta { width: 45%; }
.personal-card--note .card-visual { background: var(--tint); }

.personal-card .continue-progress {
  position: absolute;
  inset: auto 0 0;
  z-index: 3;
  height: 4px;
  background: var(--glass);
}
.personal-card .continue-progress-fill {
  display: block;
  height: 100%;
  background: var(--accent);
}

/* Remove from Continue watching: a small disc on the poster's corner. */
.personal-remove {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  z-index: 4;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  border: 1px solid var(--glass-border);
  background: var(--scrim-strong);
  color: var(--on-media);
  cursor: pointer;
}
.personal-remove .icon { width: 1rem; height: 1rem; }
.personal-remove:hover,
.personal-remove:focus-visible { background: var(--on-media); color: var(--media-bg); }

/* Why these rows, and the switches for them: a disclosure menu. */
.personal-menu { padding: 0 var(--gutter) 0.5rem; }
.personal-menu-summary {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: var(--step--1);
  cursor: pointer;
  list-style: none;
}
.personal-menu-summary::-webkit-details-marker { display: none; }
.personal-menu-summary:hover { color: var(--text); background: var(--tint); }
/* :open where the browser has it; the attribute where it does not (:is()
   drops the selector it cannot read and keeps the other). */
.personal-menu:is(:open, [open]) .personal-menu-summary { color: var(--text); background: var(--tint); }
.personal-menu-body {
  max-width: 60ch;
  padding: 0.6rem 0.6rem 0.25rem;
  color: var(--text-muted);
  font-size: var(--step--1);
}
.personal-menu-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }

.genre-rows-head { padding: 1.75rem var(--gutter) 0; }
.genre-rows-head .section-title { margin-bottom: 0.1rem; }
.genre-rows-note { color: var(--text-muted); font-size: var(--step--1); }
.genre-row { padding-top: 1rem; }

/* Keyboard and D-pad moves along a rail keep the page's gutter in view. */
.shelf-rail { scroll-padding-inline: var(--gutter); }

/* ── Labels on posters in the poster's colour (contrast-color()) ─────
   A card's badge takes its poster's hue (InvAmbient sets --ambient-color
   once the image is in): a dark chip on a dark poster, a light one on a
   light poster, and contrast-color() picks the text, white or black, for
   whichever it is. Lightness is pushed to 0.3 or 0.9, never a mid-tone, so
   the pick always clears 4.5:1 (over 12:1 either way). Elsewhere, and
   until the poster has loaded, the glass chip with white text stays. */
@supports (color: contrast-color(red)) and (color: oklch(from red l c h)) {
  .card.ambient-active .card-visual .badge:not(.badge--play, .badge--live, .badge--classic) {
    --chip: oklch(from var(--ambient-color) calc(0.3 + 0.6 * round(down, l + 0.4, 1)) min(c, 0.08) h);
    background: var(--chip);
    color: contrast-color(var(--chip));
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* ── The hero recedes as the page scrolls (scroll-driven animation) ──
   The artwork drifts down and dims a little while the rows come up over
   it, on the compositor, no script. Not for visitors who asked for less
   motion, and not where the browser has no scroll timelines. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    .home-hero-art,
    .home-hero-backdrop {
      animation: hero-recede linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 min(74vh, 680px);
    }
  }
}
@keyframes hero-recede {
  to { transform: translateY(14%) scale(1.04); opacity: 0.55; }
}

/* ── TV mode (inv-tv) ───────────────────────────────────────────
   Bigger type (about 24px body text on a 1920px-wide screen, the 10-foot
   minimum), bigger cards, the ring from the TV tokens, room around the
   rails for the ring and the lift, and nothing in the overscan margins. */
:root[data-tv] { font-size: clamp(18px, 1.25vw, 40px); scroll-padding-block: 20vh; }
:root[data-tv] body { padding-bottom: var(--tv-safe-y); }
:root[data-tv] .nav { height: auto; min-height: 64px; padding-block: max(2.5vh, 0.6rem) 0.6rem; }
/* Thirteen sections in the bar at TV size: the links a little closer, and
   the search field (a remote's last resort) gives more way; what still does
   not fit is in the More menu, as on any screen. */
:root[data-tv] .nav-link,
:root[data-tv] .nav-more { padding-inline: 0.6rem; }
@media (min-width: 769px) {
  :root[data-tv] .nav-search { min-width: 6rem; }
}
:root[data-tv] .home-nav-strip { display: none; }
:root[data-tv] .card { flex-basis: clamp(280px, 18vw, 640px); }
:root[data-tv] .card.card--poster,
:root[data-tv] .personal-card { flex-basis: clamp(184px, 11.5vw, 420px); }
:root[data-tv] .shelf-rail { gap: 1.25rem; padding-block: 1.25rem 1.5rem; }
:root[data-tv] .card-title { font-size: var(--step-0); }
:root[data-tv] .card-meta { font-size: var(--step--1); }
/* The hero leaves the first row in view, as a TV home does. */
:root[data-tv] .home-hero { height: min(58vh, 820px); min-height: 0; }
:root[data-tv] .home-hero-content { max-width: min(48rem, 56%); }
:root[data-tv] .home-hero-title {
  font-size: var(--step-4);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
:root[data-tv] .home-hero-synopsis { -webkit-line-clamp: 2; }
:root[data-tv] .footer { padding-bottom: calc(2rem + var(--tv-safe-y)); }
:root[data-tv] .global-player { padding-bottom: calc(0.5rem + 3.5vh); }

:root[data-tv] :focus-visible,
:root[data-tv] .controller-focus {
  outline: 0.25rem solid var(--tv-focus) !important;
  outline-offset: 0.2rem;
  box-shadow: 0 0 0 0.85rem var(--tv-focus-halo) !important;
  animation: none !important;
}
/* On a card the ring goes round the artwork, which lifts; the title under it stays put to be read. */
:root[data-tv] .card:is(:focus-visible, .controller-focus) {
  outline: none !important;
  box-shadow: none !important;
  position: relative;
  z-index: 2;
}
:root[data-tv] .card:is(:focus-visible, .controller-focus) .card-visual {
  outline: 0.25rem solid var(--tv-focus);
  outline-offset: 0.2rem;
  box-shadow: 0 0 0 0.85rem var(--tv-focus-halo), var(--shadow-2);
}
@media (prefers-reduced-motion: no-preference) {
  :root[data-tv] .card:is(:focus-visible, .controller-focus) .card-visual { transform: scale(1.05); }
}
:root[data-tv] .personal-remove { width: 2rem; height: 2rem; }

/* ── Settings kept in this browser (TV mode, personalisation) ── */
.settings-help { color: var(--text-muted); font-size: var(--step--1); margin: 0.4rem 0 0.8rem; }
.settings-local { border: 0; margin: 1.25rem 0 0; padding: 0; }
.settings-local .settings-radio-group { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; margin-top: 0.5rem; }
.settings-local input[type="radio"] { accent-color: var(--accent); }
.settings-kept { display: grid; gap: 0.35rem; margin: 0.5rem 0 1rem; }
.settings-kept dt { font-weight: 600; margin-top: 0.6rem; }
.settings-kept dd { color: var(--text-muted); font-size: var(--step--1); line-height: 1.55; }
/* A select whose list is open keeps its ring (on a TV the list covers it). */
.settings-select:open { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ── Responsive Home ────────────────────────────────────────── */
@media (max-width: 768px) {
  .home-hero-synopsis { -webkit-line-clamp: 2; }
  .home-hero-indicators { bottom: 1rem; }
}

/* On a phone the hero leaves the first row of choices in view (half the
   screen, at most 480px): the words sit at the foot of the band, a framed
   picture small at its top, and the synopsis, the genres and a long title
   give way to the actions. */
@media (max-width: 640px) {
  .home-hero { height: clamp(360px, 50svh, 480px); min-height: 0; padding: 0; }
  .home-hero-frame {
    top: 0.75rem;
    right: auto;
    left: var(--gutter);
    height: min(7.5rem, 30%);
    translate: none;
    border-radius: var(--radius);
  }
  .home-hero-gradient {
    background: linear-gradient(0deg, var(--bg) 0%, var(--scrim-strong) 38%, var(--scrim-soft) 58%, transparent 72%);
  }
  .home-hero-content { max-width: none; padding-bottom: 2.25rem; }
  .home-hero-meta { margin-bottom: 0.5rem; flex-wrap: wrap; row-gap: 0.25rem; }
  .home-hero-title {
    font-size: var(--step-4);
    margin-bottom: 0.5rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .home-hero-synopsis { -webkit-line-clamp: 2; margin-bottom: 0.75rem; font-size: var(--step--1); }
  .home-hero-genres { display: none; }
  .home-hero-indicators { left: 0; right: 0; bottom: 0.75rem; justify-content: center; }
  .home-nav-strip { padding-top: 1rem; }
}

/* ══════════════════════════════════════════════════════════════
   ABOUT / LEGAL / AI DISCLOSURE PAGE
   ══════════════════════════════════════════════════════════════ */

.about-page {
  max-width: 900px;
  margin: 0 auto;
  padding-bottom: 4rem;
}

/* Hero */
.about-hero {
  padding: 5rem 2rem 3rem;
  text-align: center;
}

.about-hero-inner { max-width: 650px; margin: 0 auto; }

.about-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 4px 14px;
  border-radius: 100px;
  background: var(--accent-tint);
  color: var(--accent-text);
  border: 1px solid color-mix(in oklab, var(--accent) 25%, transparent);
  margin-bottom: 1.25rem;
}

.about-hero h1 {
  font-size: 3rem;
  font-weight: 900;
  letter-spacing: -0.03em;
  margin-bottom: 0.5rem;
}

.about-hero-subtitle {
  font-size: 1.1rem;
  color: var(--text-muted);
  font-style: italic;
  margin-bottom: 0.5rem;
}

.about-hero-tagline {
  font-size: 0.95rem;
  color: var(--text-dim);
}

/* Sections */
.about-section {
  padding: 2.5rem 2rem;
  border-top: 1px solid var(--border);
}

.about-content h2 {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: 1.25rem;
}

.about-content p {
  font-size: 0.95rem;
  line-height: 1.8;
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.about-content ul {
  margin: 0.75rem 0 1rem 1.5rem;
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1.8;
}

.about-content li { margin-bottom: 0.3rem; }

/* Book Section */
.about-book {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 2.5rem;
  align-items: start;
}

.about-book-mockup {
  width: 180px;
  height: 260px;
  background: linear-gradient(135deg, #0d2818 0%, #1a4d2e 40%, #0a3d1c 100%);
  border-radius: 4px;
  border: 1px solid var(--glass-border);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  box-shadow: var(--shadow-2);
}

.about-book-emoji { font-size: 2.5rem; }

.about-book-title-sm {
  font-size: 0.85rem;
  font-weight: 700;
  text-align: center;
  color: var(--classic);
  line-height: 1.3;
  padding: 0 1rem;
}

.about-book-info h2 {
  font-size: 1.4rem;
  font-weight: 800;
  margin-bottom: 0.25rem;
}

.about-book-subtitle {
  font-size: 0.9rem;
  color: var(--text-dim);
  font-style: italic;
  margin-bottom: 0.25rem;
}

.about-book-author {
  font-size: 0.85rem;
  color: var(--accent-text);
  font-weight: 600;
  margin-bottom: 1rem;
}

.about-book-meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.about-book-detail {
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.5;
}

.about-label {
  display: block;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  font-weight: 700;
  margin-bottom: 2px;
}

/* AI Disclosure */
.ai-badge, .ai-badge-inline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--accent);
  color: var(--on-accent);
  vertical-align: middle;
}

.ai-badge-inline {
  margin-right: 0.5rem;
  font-size: 0.7rem;
  padding: 4px 10px;
}

.ai-badge-sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.5rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--accent);
  color: var(--on-accent);
  vertical-align: middle;
}

.about-disclosure-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin: 1.5rem 0;
}

.about-disclosure-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.25rem;
}

.about-disclosure-icon {
  margin-bottom: 0.75rem;
}

.about-disclosure-card h3 {
  font-size: 0.9rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.about-disclosure-card p {
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: 0;
}

/* Where a visitor sees the use said, beside the thing itself. */
.about-disclosure-card p.about-disclosure-label {
  margin-top: 0.6rem;
  color: var(--text);
}

.about-disclosure-heading {
  font-size: 1rem;
  font-weight: 700;
  margin: 1.75rem 0 0;
}

.about-notice {
  background: color-mix(in oklab, var(--accent) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--accent) 20%, transparent);
  border-radius: 12px;
  padding: 1.5rem;
  margin-top: 1.5rem;
}

.about-notice h3 {
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 0.75rem;
}

.about-notice p, .about-notice li {
  font-size: 0.85rem;
}

/* Attribution */
.about-attribution-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-top: 1rem;
}

.about-attr-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.25rem;
}

.about-attr-card h3 {
  font-size: 0.9rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.about-attr-card p {
  font-size: 0.82rem;
  line-height: 1.6;
  margin-bottom: 0;
}

/* Legal */
.about-legal-block {
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--border);
}

.about-legal-block:last-child { border-bottom: none; }

.about-legal-block h3 {
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.about-legal-block p, .about-legal-block li {
  font-size: 0.85rem;
  line-height: 1.7;
}

/* A key fingerprint is one long word: it wraps rather than widen a phone's page. */
.about-legal-block code { overflow-wrap: anywhere; }

/* Footer */
.about-copyright {
  text-align: center;
  padding: 1rem 0;
}

.about-copyright p {
  font-size: 0.82rem;
  color: var(--text-dim);
  margin-bottom: 0.25rem;
}

.about-updated {
  font-size: 0.72rem;
  color: var(--text-dim);
  margin-top: 0.5rem;
}

/* Responsive About */
@media (max-width: 768px) {
  .about-hero { padding: 3rem 1.5rem 2rem; }
  .about-hero h1 { font-size: 2rem; }
  .about-section { padding: 2rem 1.5rem; }
  .about-book { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .about-book-meta { grid-template-columns: 1fr; }
  .about-disclosure-grid { grid-template-columns: 1fr; }
  .about-attribution-grid { grid-template-columns: 1fr; }
}


/* ══════════════════════════════════════════════════════════════
   POLISH — Loading skeletons, page transitions, micro-interactions
   ══════════════════════════════════════════════════════════════ */

/* Skeleton loading shimmer */
.skeleton {
  background: linear-gradient(90deg, var(--surface) 25%, var(--bg-hover) 50%, var(--surface) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
  border-radius: var(--radius);
}

@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.skeleton-card {
  background: var(--bg-card);
  border-radius: var(--radius-lg);
  overflow: hidden;
  min-height: 180px;
  animation: skeleton-pulse 1.8s ease-in-out infinite;
}

.skeleton-card .skeleton-visual {
  aspect-ratio: 16/9;
  background: linear-gradient(90deg, var(--bg-card) 25%, var(--bg-hover) 50%, var(--bg-card) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
}

.skeleton-card .skeleton-line {
  height: 12px;
  border-radius: 6px;
  background: var(--bg-hover);
  margin: 8px 12px;
}

.skeleton-card .skeleton-line--short {
  width: 60%;
}

@keyframes skeleton-pulse {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}

.skeleton-text {
  height: 14px;
  margin-bottom: 8px;
  border-radius: 4px;
}

.skeleton-text--short { width: 60%; }
.skeleton-text--medium { width: 80%; }

/* Page enter animation */
main {
  animation: page-enter var(--duration-page) var(--ease-out-expo) both;
}

@keyframes page-enter {
  from {
    opacity: 0;
    transform: translateY(12px);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* Card active press feedback */
.card:active {
  transform: scale(0.97);
  transition-duration: var(--duration-fast);
}

/* Button press feedback */
.btn {
  transition: transform var(--duration-normal) var(--spring-bounce),
              background-color var(--duration-normal) ease,
              box-shadow var(--duration-normal) ease;
}

.btn:hover {
  transform: scale(1.02);
}

.btn:active, .pill:active, .music-ctrl:active {
  transform: scale(0.97);
  transition-duration: var(--duration-fast);
}

/* Focus visible ring for accessibility (cards ring their artwork instead) */
.btn:focus-visible, .pill:focus-visible, .nav-link:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Smooth scroll behavior */
html {
  scroll-behavior: smooth;
}

/* Hide scrollbar on shelves but keep scrollable */
.shelf-rail::-webkit-scrollbar {
  height: 0;
}

/* Responsive news ticker */
@media (max-width: 768px) {
  .news-primary { grid-template-columns: 1fr; padding: 0 1.5rem 1.5rem; }
  .news-grid { padding: 0 1.5rem 1.5rem; grid-template-columns: 1fr 1fr; }
  .news-hero { padding: 2rem 1.5rem; }
  .news-categories { padding: 0 1.5rem 1rem; }
}

@media (max-width: 480px) {
  .news-grid { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════
   REDUCED MOTION — Respect user preferences
   ══════════════════════════════════════════════════════════════ */

/* ── Stations ────────────────────────────────────────────── */

.stations-hero {
  background: var(--hero-band);
  padding: 4rem 2rem 3rem;
  text-align: center;
}
.stations-hero-inner { max-width: 720px; margin: 0 auto; }
.stations-hero h1 { margin: 0 0 0.75rem; }
.stations-hero-desc { color: var(--text-dim); font-size: 1.1rem; margin: 0 0 1.5rem; }
.stations-hero-stats { display: flex; gap: 0.75rem; justify-content: center; flex-wrap: wrap; }
.stat-chip {
  background: var(--surface);
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--text-dim);
  border: 1px solid var(--border);
}
.stat-chip--queries { border-color: var(--live); color: var(--live-text); }

.stations-nav {
  display: flex;
  gap: 0.5rem;
  padding: 1rem 2rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: sticky;
  top: 56px;
  z-index: 90;
}

.stations-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.25rem;
  padding: 0 0 1rem;
}

.station-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.25rem;
  text-decoration: none;
  color: var(--text);
  transition: var(--transition);
  cursor: pointer;
}
.station-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
}

.station-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}
.station-card-name { font-size: 1.15rem; font-weight: 600; margin: 0; }
.station-card-tagline { color: var(--text-dim); font-size: 0.85rem; font-style: italic; margin: 0 0 0.75rem; }
.station-card-genres { font-size: 0.75rem; color: var(--text-dim); }
.station-card-meta { margin-bottom: 0.75rem; }

.station-card-vpe { margin-bottom: 0.75rem; display: flex; flex-direction: column; gap: 0.4rem; }
.vpe-bar { display: flex; align-items: center; gap: 0.5rem; }
.vpe-bar-label { font-size: 0.7rem; color: var(--text-dim); width: 3rem; text-align: right; }
.vpe-bar-track { flex: 1; height: 6px; background: var(--bg); border-radius: 3px; overflow: hidden; }
.vpe-bar-fill { height: 100%; border-radius: 3px; transition: width 0.3s ease; }
.vpe-bar-fill--intensity { background: linear-gradient(90deg, var(--success), var(--warning), var(--danger)); }
.vpe-bar-fill--lightness { background: linear-gradient(90deg, var(--media-bg), var(--accent), var(--on-media)); }

.station-card-footer {
  margin-top: auto;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--text-dim);
}

/* Station detail page */
.station-detail-hero {
  padding: 4rem 2rem 3rem;
  background: var(--hero-band);
}
.station-detail-hero-inner { max-width: 720px; }
.station-back {
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.85rem;
  margin-bottom: 1rem;
  display: inline-block;
}
.station-back:hover { color: var(--accent-text); }
.station-detail-header { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.5rem; }
.station-detail-header h1 { font-size: 2.4rem; margin: 0; }
.station-detail-tagline { font-size: 1.2rem; font-style: italic; color: var(--text-dim); margin: 0 0 1rem; }
.station-detail-desc { color: var(--text-dim); margin: 0 0 1.25rem; max-width: 60ch; }
.station-detail-meta { display: flex; gap: 0.5rem; flex-wrap: wrap; }

.vpe-profile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-top: 1rem;
}
.vpe-profile-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.25rem;
}
.vpe-profile-card h4 { margin: 0 0 0.75rem; font-size: 0.9rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.05em; }
.vpe-meter { height: 8px; background: var(--bg); border-radius: 4px; overflow: hidden; margin-bottom: 0.5rem; }
.vpe-meter-fill { height: 100%; border-radius: 4px; }
.vpe-meter-fill--intensity { background: linear-gradient(90deg, var(--success), var(--warning), var(--danger)); }
.vpe-meter-fill--lightness { background: linear-gradient(90deg, var(--media-bg), var(--accent), var(--on-media)); }
.vpe-value { font-size: 1.4rem; font-weight: 700; color: var(--text); }
.vpe-value--large { font-size: 2rem; display: block; margin-bottom: 0.5rem; }
.vpe-explain { font-size: 0.78rem; color: var(--text-dim); margin: 0.5rem 0 0; }
.vpe-note { color: var(--text-dim); font-size: 0.9rem; margin-top: 1.5rem; padding: 1rem; background: var(--surface); border-radius: 8px; border-left: 3px solid var(--accent); }

.query-list { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 1rem; }
.query-item {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem;
}
.query-index {
  background: var(--accent);
  color: var(--on-accent);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  font-weight: 600;
  flex-shrink: 0;
}
.query-body { display: flex; flex-direction: column; gap: 0.25rem; }
.query-source { font-size: 0.8rem; color: var(--accent-text); font-weight: 600; }
.query-label { font-size: 1rem; color: var(--text); }
.query-meta { font-size: 0.78rem; color: var(--text-dim); }

/* ── Station content cards ───────────────────────────────── */

.content-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.25rem;
  padding: 0 0 1rem;
}

.content-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  color: var(--text);
  transition: var(--transition);
}
.content-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
}

.content-card-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--bg);
  overflow: hidden;
}
.content-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.content-card-duration {
  position: absolute;
  bottom: 6px;
  right: 6px;
  background: var(--scrim-strong);
  color: var(--on-media);
  font-size: 0.72rem;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 500;
}

.content-card-body {
  padding: 0.75rem 1rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 1;
}
.content-card-title {
  font-size: 0.95rem;
  font-weight: 600;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.content-card-year {
  font-size: 0.78rem;
  color: var(--text-dim);
}
.content-card-desc {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin: 0.25rem 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: 1;
}
.content-card-meta {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--text-dim);
}
.content-card-source {
  font-weight: 500;
  color: var(--accent-text);
}
.content-card-license {
  opacity: 0.7;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  html { scroll-behavior: auto; }
  main { animation: none; }
  .profile-card { opacity: 1; transform: none; }
  .home-hero-slide { transition: none; }
  .news-ticker-scroll { animation: none; }
  .hero-content > * {
    opacity: 1;
    transform: none;
  }
}

/* ── Global Music Player Bar ────────────────────────────────── */
.global-player {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  background: color-mix(in oklab, var(--bg-raised) 94%, transparent);
  border-top: 1px solid var(--border);
  padding: 0.5rem 1rem;
  backdrop-filter: blur(12px);
}
.global-player-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 1200px;
  margin: 0 auto;
}
.global-player-info {
  flex: 0 0 200px;
  overflow: hidden;
  /* A button (it opens the now-playing view) that reads as the title. */
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
  border-radius: var(--radius);
}
.global-player-info:hover .gp-title { text-decoration: underline; }
.gp-title {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gp-artist {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.global-player-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.gp-btn {
  background: none;
  border: none;
  color: var(--text);
  cursor: pointer;
  font-size: 1rem;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  transition: background 0.15s;
}
.gp-btn:hover {
  background: var(--tint-strong);
}
.gp-btn-play {
  font-size: 1.2rem;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--action);
  color: var(--on-action);
}
.gp-btn-play:hover {
  background: var(--action-hover);
}
.global-player-progress {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.gp-time {
  font-size: 0.75rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 3em;
}
.gp-bar {
  flex: 1;
  height: 4px;
  background: var(--tint-strong);
  border-radius: 2px;
  cursor: pointer;
  position: relative;
}
.gp-bar-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
  width: 0;
  transition: width 0.1s linear;
}
/* A live stream (world radio): no previous or next track, no position. */
.global-player--live #gp-prev,
.global-player--live #gp-next,
.global-player--live .gp-time,
.global-player--live .gp-bar { display: none; }
.global-player--live .global-player-progress::before {
  content: "LIVE";
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--live);
  color: var(--on-live);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.05em;
}
.gp-btn-close {
  font-size: 1.2rem;
  opacity: 0.6;
}
.gp-btn-close:hover {
  opacity: 1;
}

/* ══════════════════════════════════════════════════════════════
   SOTA ANIMATION SYSTEM — Staggered reveals, glow, parallax
   ══════════════════════════════════════════════════════════════ */

/* ── Hero Section Polish ───────────────────────────────────── */

.hero {
  background-attachment: fixed;
}

.hero-content > * {
  opacity: 0;
  transform: translateY(16px);
  animation: hero-stagger-in var(--duration-page) var(--ease-out-expo) forwards;
}

.hero-content > *:nth-child(1) { animation-delay: 0ms; }
.hero-content > *:nth-child(2) { animation-delay: 100ms; }
.hero-content > *:nth-child(3) { animation-delay: 200ms; }
.hero-content > *:nth-child(4) { animation-delay: 300ms; }
.hero-content > *:nth-child(5) { animation-delay: 400ms; }

@keyframes hero-stagger-in {
  from {
    opacity: 0;
    transform: translateY(16px);
    filter: blur(2px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* Hero carousel crossfade with blur */
.home-hero-slide {
  transition: opacity 1.2s var(--ease-in-out-smooth), filter 1.2s var(--ease-in-out-smooth);
  filter: blur(0);
}

.home-hero-slide:not(.active) {
  filter: blur(4px);
}

/* ── Glow Effects ──────────────────────────────────────────── */

.music-track--playing,
.track-row--playing {
  box-shadow: inset 0 0 24px var(--accent-glow);
}

/* Rails below the first two are rendered only as they come near the screen
   (content-visibility): on a page of fifteen or twenty rails most of the
   style, layout and paint at load, and at every page swapped in place, is
   skipped. Until a rail has been rendered it holds about a rail's height;
   after, the height it had (auto). The remote's moves (inv-controller.js)
   read places as before: the browser lays out a skipped rail when asked, and
   focus inside it makes it rendered. Older engines ignore the property and
   render every rail, as before. */
.section:has(> .shelf-rail) ~ .section:has(> .shelf-rail) ~ .section:has(> .shelf-rail) {
  content-visibility: auto;
  contain-intrinsic-block-size: auto 22rem;
}
html[data-tv] .section:has(> .shelf-rail) ~ .section:has(> .shelf-rail) ~ .section:has(> .shelf-rail) {
  contain-intrinsic-block-size: auto 34rem;
}

/* ── Scroll Progress Indicator ─────────────────────────────── */
/* The reading-progress bar: a full-width line scaled to how far the page is
   read. Where the browser has scroll-driven animations the scale follows the
   page's own scroll position on the compositor, with no script; elsewhere
   (older TV engines) app.js sets it once per frame. A transform, not a
   width: no layout either way. It follows the reader's own scrolling, so it
   is not motion to reduce. */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--accent);
  z-index: 10000;
  pointer-events: none;
  transform-origin: 0 50%;
  transform: scaleX(0);
}
/* On the timeline the individual `scale` property is animated, not
   transform: scaleX(): from a scale of 0, WebKit 27.2 drew a transform at the
   square of the progress (0.25 at half the page). */
@supports (animation-timeline: scroll()) {
  .scroll-progress {
    transform: none;
    scale: 0 1;
    animation: scroll-progress linear both;
    animation-duration: auto !important;
    animation-timeline: scroll(root block);
  }
}
@keyframes scroll-progress {
  from { scale: 0 1; }
  to { scale: 1 1; }
}

/* ═══════════════════════════════════════════════════════════
   SKELETON LOADERS
   ═══════════════════════════════════════════════════════════ */

.skeleton-card {
  background: var(--bg-card);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  overflow: hidden;
  min-width: 200px;
}

.skeleton-card .skeleton-visual {
  aspect-ratio: 16 / 9;
  background: linear-gradient(
    90deg,
    var(--bg-card) 0%,
    var(--bg-hover) 40%,
    var(--bg-card) 80%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.8s ease-in-out infinite;
}

.skeleton-card .skeleton-body {
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.skeleton-line {
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    var(--bg-hover) 0%,
    color-mix(in srgb, var(--bg-hover) 70%, var(--border)) 40%,
    var(--bg-hover) 80%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.8s ease-in-out infinite;
}

.skeleton-line--title {
  width: 75%;
  height: 14px;
}

.skeleton-line--meta {
  width: 50%;
  height: 10px;
}

/* Skeleton shelf — shows 6 placeholder cards */
.skeleton-shelf {
  display: flex;
  gap: 1rem;
  padding: 0 3rem;
  overflow: hidden;
}

.skeleton-shelf .skeleton-card {
  flex: 0 0 220px;
}

/* ═══════════════════════════════════════════════════════════
   ERROR & EMPTY STATES
   ═══════════════════════════════════════════════════════════ */

.empty-state {
  text-align: center;
  padding: 3rem 2rem;
  color: var(--text-muted);
}

.empty-state-icon {
  font-size: 3rem;
  margin-bottom: 1rem;
  opacity: 0.4;
}

.empty-state-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.5rem;
}

.empty-state-desc {
  font-size: 0.9rem;
  max-width: 400px;
  margin: 0 auto 1.5rem;
  line-height: 1.6;
}

.empty-state .btn {
  display: inline-flex;
}

.error-state {
  text-align: center;
  padding: 2rem;
  background: color-mix(in oklab, var(--danger) 6%, transparent);
  border: 1px solid color-mix(in oklab, var(--danger) 25%, transparent);
  border-radius: var(--radius);
  margin: 1rem 0;
}

.error-state-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--danger);
  margin-bottom: 0.5rem;
}

.error-state-desc {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 1rem;
}

.error-state .btn--retry {
  background: color-mix(in oklab, var(--danger) 12%, transparent);
  color: var(--danger);
  border: 1px solid color-mix(in oklab, var(--danger) 35%, transparent);
  padding: 0.5rem 1.25rem;
  border-radius: var(--radius);
  cursor: pointer;
  font-weight: 500;
  transition: background 200ms ease;
}

.error-state .btn--retry:hover {
  background: color-mix(in oklab, var(--danger) 20%, transparent);
}

/* Image fallback for missing cover art */
.card-img {
  background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-hover) 100%);
}

.card-img[src=""] {
  display: none;
}

.card-visual:has(.card-img[src=""]) {
  background: linear-gradient(135deg, var(--surface) 0%, var(--bg-card) 100%);
}

/* ── Skip-to-main link ────────────────────────────────────── */

.skip-link {
  position: fixed;
  top: -100px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: var(--on-accent);
  padding: 0.75rem 1.5rem;
  border-radius: var(--radius);
  z-index: 100000;
  font-weight: 600;
  transition: top 0.2s ease;
}
.skip-link:focus {
  top: 1rem;
}

/* ── Active nav indicator ─────────────────────────────────── */

/* The current section: full-strength text, marked by a short accent bar. */
.nav-active {
  color: var(--text) !important;
  position: relative;
}
.nav-logo.nav-active::after { content: none; }
.nav-active::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0.75rem;
  right: 0.75rem;
  height: 2px;
  background: var(--accent-text);
  border-radius: 1px;
}

/* ── Keyboard focus visible ───────────────────────────────── */

.keyboard-nav *:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 4px;
}
.keyboard-nav .card:focus-visible { outline: none; }

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE — COMPREHENSIVE BREAKPOINTS
   ═══════════════════════════════════════════════════════════ */

/* Side padding everywhere is --gutter, which already narrows with the
   screen; type sizes are fluid too (the --step tokens). */

/* ── Extra large desktop (1440px+) ──────────────────── */
@media (min-width: 1440px) {
  .tv-hero-inner { max-width: 50%; }
}

/* ── Tablet landscape (960-1024px) ──────────────────── */
@media (max-width: 960px) {
  .shelf-rail .card:not(.card--poster) { min-width: 180px; }
}

/* ── Tablet portrait (640-768px) ────────────────────── */
@media (max-width: 640px) {
  /* Hero sections compact */
  .tv-hero {
    min-height: 50vh;
    padding: 2rem var(--gutter);
  }

  .tv-hero-desc {
    font-size: 0.9rem;
  }

  .section { padding: 1.5rem 0 0.75rem; }
  .shelf-rail { gap: 0.75rem; }

  /* Card sizing */
  .shelf-rail .card:not(.card--poster) { min-width: 160px; }

  /* Sub-nav scrolls */
  .tv-sub-nav, .genre-bar {
    padding: 0.75rem 1rem;
    gap: 0.5rem;
  }

  .pill { font-size: 0.8rem; padding: 0.5rem 1rem; }
}

/* ── Small phone (max-width: 480px) — enhanced ──────── */
@media (max-width: 480px) {
  .shelf-rail .card:not(.card--poster) { min-width: 140px; }

  .section-desc { font-size: 0.8rem; }

  .btn { padding: 0.75rem 1.25rem; font-size: 0.85rem; }

  /* Hero buttons share the width, side by side. */
  .tv-hero-actions .btn, .home-hero-actions .btn {
    flex: 1;
    text-align: center;
  }
}

/* ═══════════════════════════════════════════════════════════
   PHONES — TOUCH TARGETS AND SEARCH
   ═══════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  /* Ensure all touch targets are 44px+ */
  .btn, .pill, a.card, button, input, select {
    min-height: 44px;
  }

  .pill {
    padding: 0.625rem 1.25rem;
  }

  /* Search goes full width on mobile */
  .search-container {
    position: static;
  }

  #search-input {
    width: 100%;
  }

  .search-dropdown {
    left: 0;
    right: 0;
    width: 100%;
  }
}

/* ═══════════════════════════════════════════════════════════
   TOUCH-FRIENDLY SHELF SCROLLING
   ═══════════════════════════════════════════════════════════ */

.shelf-rail {
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  /* Snap cards to the page gutter, where the first one starts. */
  scroll-padding-inline: var(--gutter);
}

.shelf-rail .card {
  scroll-snap-align: start;
}

/* Hide scrollbar but keep functionality */
.shelf-rail::-webkit-scrollbar {
  height: 0;
  display: none;
}

.shelf-rail {
  scrollbar-width: none;
}

/* ═══════════════════════════════════════════════════════════
   SAFE AREA INSETS — NOTCH / DYNAMIC ISLAND PHONES
   ═══════════════════════════════════════════════════════════ */

@supports (padding: env(safe-area-inset-top)) {
  nav {
    padding-top: env(safe-area-inset-top);
  }

  .music-global-player {
    padding-bottom: env(safe-area-inset-bottom);
  }

  body {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }
}

/* ── Search Results (templates/search.html) ─────────────────── */
/* In the frame every section page has: the title in its band and gutter,
   each group's matches inside the page's gutters, on the site's surfaces. */
.search-results-hero { padding: 2rem var(--gutter) 1.25rem; background: var(--hero-band); }
.search-results-count { margin: 0.4rem 0 0; color: var(--text-muted); }
.search-results-grid,
.search-results-empty-inner { padding-inline: var(--gutter); }
.search-results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
  gap: 0.75rem;
}
.search-result-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color var(--transition), background var(--transition);
}
.search-result-card:hover { border-color: var(--border-strong); background: var(--bg-hover); }
.search-result-badge {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.search-result-badge--live { color: var(--live-text); }
.search-result-name { margin: 0; font-size: var(--step-0); font-weight: 600; }
.search-result-desc {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--step--1);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.search-results-empty-msg { margin: 0 0 0.25rem; font-weight: 600; }
.search-results-empty-hint { margin: 0; color: var(--text-muted); }
/* The type-ahead's "nothing found" line (app.js). */
.search-empty {
  text-align: center;
  padding: 4rem 2rem;
  color: var(--text-muted);
}
.search-empty h2 { font-size: 1.3rem; color: var(--text-muted); margin-bottom: 0.5rem; }

/* ── Settings Page ───────────────────────────────────────────── */
.settings-page { padding: 2rem 3rem; max-width: 720px; }
.settings-section {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 1.5rem;
  margin-bottom: 1.5rem;
}
.settings-section h2 {
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent-text);
  margin-bottom: 1rem;
}
.settings-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--hairline);
}
.settings-row:last-child { border-bottom: none; }
.settings-row label { color: var(--text); }
.settings-row select, .settings-row input[type="radio"] { accent-color: var(--accent); }
.settings-row select {
  background: var(--tint);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  color: var(--text);
  padding: 0.4rem 0.8rem;
}
.settings-toggle {
  position: relative;
  width: 48px; height: 26px;
  background: var(--tint-strong);
  border-radius: 13px;
  cursor: pointer;
  transition: background 0.2s;
}
.settings-toggle.active { background: var(--accent); }
.settings-toggle::after {
  content: '';
  position: absolute;
  top: 3px; left: 3px;
  width: 20px; height: 20px;
  background: var(--on-accent);
  border-radius: 50%;
  transition: transform 0.2s;
}
.settings-toggle.active::after { transform: translateX(22px); }
.btn--danger {
  background: color-mix(in oklab, var(--danger) 14%, transparent);
  color: var(--danger);
  border: 1px solid color-mix(in oklab, var(--danger) 30%, transparent);
  border-radius: 8px;
  padding: 0.5rem 1rem;
  cursor: pointer;
  transition: background 0.2s;
}
.btn--danger:hover { background: color-mix(in oklab, var(--danger) 24%, transparent); }
.settings-toast {
  position: fixed;
  bottom: 2rem; right: 2rem;
  background: var(--success-fill);
  color: var(--on-accent);
  padding: 0.75rem 1.5rem;
  border-radius: 10px;
  opacity: 0;
  transform: translateY(10px);
  transition: all 0.3s;
  z-index: 9999;
}
.settings-toast.show { opacity: 1; transform: translateY(0); }

/* ── Energy ──────────────────────────────────────────────────── */
.energy-page { padding: 2rem 3rem; }
.energy-hero { padding: 2rem 0 1rem; max-width: 65ch; }
.energy-hero h1 { font-size: var(--step-4); margin-bottom: 0.5rem; }
.energy-hero-sub { color: var(--text-muted); line-height: 1.6; }
.energy-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
}
.energy-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
}
.energy-card-title { font-size: var(--step--1); font-weight: 600; color: var(--text-muted); margin-bottom: 0.75rem; }
.energy-stat-number {
  font-size: var(--step-3);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.energy-stat-note { margin-top: 0.5rem; font-size: var(--step--2); color: var(--text-dim); }
.energy-stat-note a { color: var(--accent-text); text-decoration: underline; }
.energy-philosophy-inner { max-width: 70ch; }
.energy-practices { display: grid; gap: 0.9rem; padding-left: 1.2rem; line-height: 1.6; color: var(--text-muted); }
.energy-practices strong { color: var(--text); }
.energy-hero-sub + .energy-hero-sub { margin-top: 0.75rem; }
.energy-hero-sub a, .energy-page .section-desc a, .energy-hop a, .energy-sources a, .energy-practices a { color: var(--accent-text); text-decoration: underline; }
.energy-classes { display: grid; gap: 0.5rem; margin: 0.5rem 0 1rem; }
.energy-classes > div { display: flex; flex-wrap: wrap; gap: 0.25rem 0.6rem; align-items: baseline; }
.energy-classes dd { margin: 0; color: var(--text-muted); }
.energy-class {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.4;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  color: var(--text);
  background: var(--tint);
  overflow-wrap: anywhere;
}
.energy-class[data-class="OnChipCounter"], .energy-class[data-class="CalibratedInstrument"] { border-color: var(--success); }
.energy-class[data-class="Unmetered"] { border-style: dashed; }
.energy-form { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; align-items: end; margin: 1rem 0 1.25rem; }
.energy-field { display: grid; gap: 0.25rem; font-size: var(--step--1); color: var(--text-muted); min-width: 0; }
.energy-field select, .energy-field input {
  min-width: 0;
  max-width: 100%;
  font: inherit;
  color: var(--text);
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius, 0.5rem);
  padding: 0.4rem 0.6rem;
}
.energy-field input[type="number"] { width: 7.5rem; }
.energy-check { display: flex; gap: 0.4rem; align-items: center; font-size: var(--step--1); color: var(--text-muted); }
.energy-hops { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 1rem; }
.energy-hop {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.1rem 1.25rem;
  display: grid;
  gap: 0.5rem;
  align-content: start;
  min-width: 0;
}
.energy-hop--part { border-style: dashed; }
.energy-hop-title { font-size: var(--step-0); font-weight: 700; display: grid; gap: 0.15rem; }
.energy-hop-what { font-size: var(--step--1); font-weight: 400; color: var(--text-muted); }
.energy-hop-wh .energy-stat-number { font-size: var(--step-2); }
.energy-hop-unit { color: var(--text-muted); font-size: var(--step--1); }
.energy-hop-class, .energy-hop-method { font-size: var(--step--1); color: var(--text-muted); line-height: 1.55; overflow-wrap: anywhere; }
.energy-sub { font-size: var(--step-0); font-weight: 700; margin: 1.25rem 0 0.5rem; }
.energy-totals { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; padding: 0; list-style: none; }
.energy-eco { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 1rem; }
.energy-eco-list { display: grid; gap: 0.3rem; font-size: var(--step--1); }
.energy-eco-list dt { color: var(--text-muted); }
.energy-eco-list dd { margin: 0 0 0.4rem; color: var(--text); }
.energy-fleet { display: grid; gap: 0.6rem; max-width: 80ch; }
.energy-fleet > div { display: grid; gap: 0.2rem; }
.energy-fleet dt { font-weight: 600; }
.energy-fleet dd { margin: 0; color: var(--text-muted); line-height: 1.55; overflow-wrap: anywhere; }
.energy-sources { display: grid; gap: 0.4rem; padding-left: 1.4rem; font-size: var(--step--1); color: var(--text-muted); max-width: 90ch; overflow-wrap: anywhere; }
.energy-sources li:target { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.home-credit-text { color: var(--text-muted); line-height: 1.6; }
.home-credit-text a { color: var(--accent-text); text-decoration: underline; }
@media (max-width: 768px) { .energy-page { padding: 1rem var(--gutter); } }

/* ── Error Pages ─────────────────────────────────────────────── */
.error-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 60vh;
  text-align: center;
  padding: 2rem;
}
.error-code {
  font-size: 8rem;
  font-weight: 800;
  line-height: 1;
  color: var(--accent-text);
  margin-bottom: 1rem;
}
.error-page h1 { font-size: 2rem; margin-bottom: 0.75rem; }
.error-page p { color: var(--text-muted); margin-bottom: 2rem; max-width: 400px; }
.error-actions { display: flex; gap: 1rem; }

/* ── Micro-interactions ──────────────────────────────────────── */
.nav-link { position: relative; }

/* Ambient color glow on cards */
.ambient-active .card-visual {
  box-shadow: 0 8px 32px rgba(var(--ambient-r, 99), var(--ambient-g, 102), var(--ambient-b, 241), 0.15);
}

/* Button ripple effect */
.btn { position: relative; overflow: hidden; }
.btn::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 0; height: 0;
  background: color-mix(in oklab, currentColor 18%, transparent);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  transition: width 0.4s, height 0.4s, opacity 0.4s;
  opacity: 0;
}
.btn:active::after { width: 200px; height: 200px; opacity: 1; transition: 0s; }

/* Tooltip on hover */
[data-tooltip] { position: relative; }
[data-tooltip]:hover::before {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--scrim-strong);
  color: var(--on-media);
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 0.75rem;
  white-space: nowrap;
  pointer-events: none;
  z-index: 1000;
}

/* Focus ring animation */
@keyframes focus-pulse {
  0%, 100% { box-shadow: 0 0 0 2px color-mix(in oklab, var(--focus-ring) 50%, transparent); }
  50% { box-shadow: 0 0 0 4px color-mix(in oklab, var(--focus-ring) 30%, transparent); }
}
.keyboard-nav *:focus-visible { animation: focus-pulse 1.5s ease infinite; }

/* Card hover lift with spring */
.card {
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease;
}

/* Live badge pulse */
.badge--live {
  animation: live-pulse-anim 2s ease-in-out infinite;
}

/* Smooth page transitions */
main { animation: page-fade-in 0.25s ease-out; }
@keyframes page-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── Site shell: header landmark, search form ─────────────── */

/* The primary <nav> sits inside the header bar and lays out as part of it:
   the logo, the sections, and the menu of those that do not fit. It takes
   the room the bar has left; the logo and the menu button never shrink. */
.nav-primary {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  height: 100%;
  flex: 1 1 auto;
  min-width: 0;
}
.nav-logo { margin-right: 1.75rem; }
@media (max-width: 768px) {
  .nav-logo { margin-right: 0.75rem; }
  /* TV mode's larger type leaves no room below a desktop's width for the
     name beside the mark, the menu, and a field kept in a section. */
  :root[data-tv] .nav .logo-text { display: none; }
}

/* ── The header's sections: as many as fit, then "More" ─────
   Thirteen sections do not fit beside the logo and the search field below
   about 1,350px (1,420px in TV mode). The bar keeps them in one row in
   their order; inv-page.js measures which fit (whenever the room changes: a
   window resized, TV mode's larger type, the search field widening while
   it is used), hides the rest from the bar and shows them in the More menu.
   Until it has measured, and without script, the row wraps and only its
   first line shows, so nothing ever runs past the edge; the menu then
   lists every section. */
.nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  /* As wide as its links want, less what the bar does not have (the search
     field gives way first), one row high. */
  flex: 0 1 auto;
  min-width: 0;
  height: 2.4rem;
  overflow: hidden;
}
/* Measured: only the links that fit are left, the button sits right after
   the last one, and focus rings are not clipped. The bar then keeps the
   width it was measured with (the search field takes any shortfall), since
   a fraction of a pixel less would wrap its last link. */
.nav-links[data-fit] { height: auto; overflow: visible; }
.nav-primary:has(> .nav-links[data-fit]) { flex-shrink: 0; }
/* Measured in one go, so nothing here may be mid-transition: with reduced
   motion every element is given a tiny transition, of all properties. */
.nav-primary,
.nav-links,
.nav-search { transition-property: none; }
.nav-link { white-space: nowrap; }
.nav-link--out { display: none; }

.nav-more {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.75rem;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: color var(--transition), background var(--transition);
}
.nav-more:hover,
.nav-more:has(+ :popover-open) { color: var(--text); background: var(--tint); }
.nav-more[hidden] { display: none; }
.nav-more .icon { width: 1.15em; height: 1.15em; vertical-align: 0; }
/* "More" beside links; "Menu" when every section is in it (a phone). */
.nav-more-label--all,
.nav[data-fit="none"] .nav-more-label--some { display: none; }
.nav[data-fit="none"] .nav-more-label--all { display: inline; }

/* The menu: one of the site's popovers (the reader's, the player's
   settings), a raised panel under its button. Light dismiss, Escape and a
   remote's Back close it; focus goes back to the button. */
.nav-more-menu {
  position: fixed;
  inset: auto;
  /* Where anchor positioning is missing (older TV browsers), under the
     header, whose height app.js gives as --nav-bottom when it opens. */
  top: calc(var(--nav-bottom, 64px) + 0.25rem);
  right: max(var(--gutter), env(safe-area-inset-right));
  margin: 0;
  min-width: 13rem;
  max-height: calc(100dvh - var(--nav-bottom, 64px) - 1rem);
  overflow: auto;
  padding: 0.4rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  color: var(--text);
  box-shadow: var(--shadow-2);
}
@supports (anchor-name: --a) {
  .nav-more { anchor-name: --nav-more; }
  .nav-more-menu {
    position-anchor: --nav-more;
    top: calc(anchor(bottom) + 0.4rem);
    left: anchor(left);
    right: auto;
    max-height: calc(100dvh - anchor(bottom) - 1rem);
    position-try-fallbacks: flip-inline;
  }
}
.nav-more-menu ul { list-style: none; display: grid; gap: 2px; }
.nav-more-menu li[hidden] { display: none; }
.nav-more-menu a {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 44px;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  color: var(--text);
  font-weight: 500;
}
.nav-more-menu a:hover,
.nav-more-menu a:focus-visible { background: var(--bg-hover); }
.nav-more-menu a.nav-active { color: var(--accent-text); }
.nav-more-menu a.nav-active::after { content: none; }
.nav-more-menu .icon { color: var(--text-muted); }
/* On a phone the menu spans the screen under the header, in two columns,
   so all thirteen sections are in reach of a thumb without scrolling. */
@media (max-width: 600px) {
  .nav-more-menu {
    top: calc(var(--nav-bottom, 64px) + 0.25rem);
    left: 0.5rem;
    right: 0.5rem;
    min-width: 0;
    max-height: calc(100dvh - var(--nav-bottom, 64px) - 1rem);
  }
  .nav-more-menu ul { grid-template-columns: 1fr 1fr; }
}

.nav-search form { margin: 0; }

/* ── One search field, kept in a section where it has its own ─
   On such a section the field carries a chip naming it
   (search_scope.html): ticked, the query stays there; unticked, struck
   through, it covers the whole site. Field and chip are one pill. */
.search-scope:empty { display: none; }
.search-scope { display: contents; }
.nav-search form:has(.search-scope-chip) {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  padding-left: 0.3rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--field-radius);
  background: var(--tint);
  transition: border-color var(--transition), background var(--transition);
}
.nav-search form:has(.search-scope-chip):focus-within { border-color: var(--focus-ring); background: var(--bg-raised); }
.nav-search form:has(.search-scope-chip) input[type="search"] {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  padding-left: 0.35rem;
}
.search-scope-chip {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.25rem;
  max-width: 9rem;
  padding: 0.2rem 0.45rem 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--accent-tint);
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
}
/* The box itself is for keyboards, remotes and screen readers; the chip
   shows its state, and its ring. */
.search-scope-chip input {
  position: absolute;
  width: 1px;
  height: 1px;
  min-height: 0;
  margin: 0;
  clip-path: inset(50%);
}
.search-scope-chip:has(input:focus-visible),
.search-scope-chip:has(input.controller-focus) { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
:root[data-tv] .search-scope-chip:has(input.controller-focus) { outline: 4px solid var(--tv-focus); }
.search-scope-chip .icon { width: 0.95em; height: 0.95em; vertical-align: 0; transition: rotate var(--transition); }
.search-scope-chip:has(input:not(:checked)) { background: none; color: var(--text-dim); text-decoration: line-through; }
.search-scope-chip:has(input:not(:checked)) > .icon { rotate: 45deg; }
/* The smallest phones (any phone, in TV mode's larger type) have no room
   for the section's name beside the field's own word: the chip shows the
   section's icon (the menu's) in its place, and the name is still read out. */
.search-scope-icon { display: none; }
@media (max-width: 389px) {
  .search-scope-icon { display: inline-flex; }
  .search-scope-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@media (max-width: 480px) {
  :root[data-tv] .search-scope-icon { display: inline-flex; }
  :root[data-tv] .search-scope-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
/* And TV mode's type on the narrowest window: less space between the
   header's parts and round the chip's icon, so the word still reads in full
   beside it and the microphone. */
@media (max-width: 359px) {
  :root[data-tv] .nav { gap: 0.4rem; }
  :root[data-tv] .search-scope-chip { padding-inline: 0.35rem 0.3rem; }
}
/* On /ask the page's own field is the one: a request in plain words, with
   its microphone, at the top of the page. The header's would ask the same
   library a second way, so it gives way there (a page swapped in place
   included, since this follows the page, not the header). */
body:has(main .ask-form) .nav-search { display: none; }

/* Asking aloud (app.js, inv-speech.js): a microphone at the end of the
   search field, shown only where the browser can hear, and the note under
   the field that says where what is said goes (beside the form, in
   .nav-search, which it is placed against). */
.nav-search form { position: relative; }
/* The field keeps its width (the header has no more to give): the empty
   field's word "Search" reads in full beside the small microphone, and
   what is typed stops short of it. */
.nav-search form:has(.nav-search-voice:not([hidden])) input:is(:focus, :not(:placeholder-shown)) { padding-right: 2.25rem; }
.nav-search-voice {
  position: absolute;
  top: 50%;
  right: 0.3rem;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.nav-search-voice[hidden] { display: none; }
.nav-search-voice:hover { color: var(--text); background: var(--tint); }
.nav-search-voice:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.nav-search-voice[aria-pressed="true"] { color: var(--on-live); background: var(--live); }
.nav-search-voice .icon { width: 1rem; height: 1rem; }
.voice-note {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 60;
  width: min(22rem, calc(100vw - 2rem));
  padding: 0.75rem 0.9rem;
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px color-mix(in oklab, black 30%, transparent);
  font-size: 0.875rem;
  line-height: 1.45;
}
.voice-note[hidden] { display: none; }
.voice-note p { margin: 0 0 0.5rem; }
.voice-note .btn { margin: 0.25rem 0.4rem 0 0; padding: 0.45rem 0.9rem; }
@media (max-width: 480px) {
  /* On a phone the field is narrow: the note spans the window less its
     margins (the field ends at the right one), still under the field
     however tall the header is (TV mode's is taller). */
  .voice-note { width: calc(100vw - 2rem); }
}

.search-item[aria-selected="true"] { background: var(--bg-hover); }

/* Room for the music bar, so it never covers the end of the page. */
body.has-global-player { padding-bottom: 72px; }

/* ── Player: error and unmute overlays ────────────────────── */

.inv-player-error {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1.5rem;
  text-align: center;
  background: var(--scrim-strong);
  color: var(--on-media);
}
.inv-player-error[hidden] { display: none; }
.inv-player-error-text { max-width: 32rem; font-size: 1rem; line-height: 1.5; }

.inv-player-unmute {
  position: absolute;
  top: 1rem;
  left: 1rem;
  z-index: 4;
  display: none;
}
.inv-player.auto-muted .inv-player-unmute { display: inline-flex; }

/* ── Motion ───────────────────────────────────────────────── */

/* Navigations between pages cross-fade instead of flashing, in browsers
   that support cross-document view transitions. The header and the music
   bar are named so they hold still while the content changes. */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: no-preference) {
  .nav { view-transition-name: site-header; }
  .global-player { view-transition-name: music-bar; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation-duration: 0.18s; }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
  main { animation: none; }
  .keyboard-nav *:focus-visible,
  .badge--live { animation: none; }
}

/* With a view transition running, the old fade-in would play twice. */
@supports (view-transition-name: none) {
  main { animation: none; }
}

/* ── Small-screen and light-theme corrections ─────────────── */

/* The search field gives way first, from its 240px (200px on a tablet)
   down to 9rem (7rem), so the sections keep as much of the bar as they can;
   then they move into the menu. While it is used (typed in, or its
   microphone's note open) it widens into the room the bar has spare, up to
   320px: the sections stay where they are, and nothing is pushed past the
   window's edge. */
@media (min-width: 481px) {
  /* Shrinking that much faster than the bar, it takes all of any shortfall
     until it is at its least: the bar loses nothing while it is measured. */
  .nav-search { flex: 0 100000 240px; min-width: 9rem; }
  .nav-search:focus-within { flex-basis: 320px; }
  .nav-search input,
  .nav-search input:focus { width: 100%; }
  /* With a section's chip in it, still room for a word or two. */
  .nav-search:has(.search-scope-chip),
  :root[data-tv] .nav-search:has(.search-scope-chip) { min-width: 15rem; }
}
@media (min-width: 481px) and (max-width: 768px) {
  .nav-search { flex-basis: 200px; min-width: 7rem; }
}

@media (max-width: 480px) {
  /* On a phone the mark alone identifies the site, search gets the room,
     and every section is in the menu, whose button shows its icon (its name
     is still there for screen readers). */
  .nav .logo-text { display: none; }
  .nav-more { padding-inline: 0.6rem; }
  .nav-more-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .nav-primary { flex: none; }
  .nav-links { display: none; }
  .nav-search { flex: 1; min-width: 0; margin-left: 0; }
  .nav-search input,
  .nav-search input:focus { width: 100%; }
  .search-dropdown { position: fixed; top: 64px; left: 0.5rem; right: 0.5rem; width: auto; }
}

/* Carousel indicators are thin bars. The blanket 44px touch-target rule for
   buttons turned them into blocks on phones; keep the bar and widen the
   area that responds to a tap instead. */
.home-hero-dot { position: relative; min-height: 0; }
.home-hero-dot::after { content: ""; position: absolute; inset: -20px -4px; }


/* ── Layout corrections found by testing at phone width ───── */

/* The footer's links ran off the right edge on every page, which made the
   whole site scroll sideways on a phone. */
.footer-links { flex-wrap: wrap; row-gap: 0.75rem; }

/* Grid and flex children default to min-width:auto and so refuse to shrink
   below their content; a video's intrinsic size then widens the page. */
.watch-player-wrap,
.watch-sidebar { min-width: 0; }

@media (max-width: 1024px) {
  /* Stacked layout: the player takes its height from its 16:9 ratio. With a
     fixed height the ratio worked backwards and made it 750px wide. */
  .watch-player-wrap { height: auto; min-height: 0; }
  .watch-player { height: auto; }
}

/* Rows of filter pills scroll within themselves instead of widening the page. */
.browse-filters,
.tv-sub-nav {
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.browse-filters::-webkit-scrollbar,
.tv-sub-nav::-webkit-scrollbar { display: none; }
.browse-filters > *,
.tv-sub-nav > * { flex-shrink: 0; }

/* The hero's decorative orb is positioned 50px past the right edge, which
   widened the page. Clip decoration to the section it decorates. */
.hero,
.tv-hero { overflow-x: clip; }

/* Poster inside a library card: fills the visual, under the type badge. */
.browse-card-visual { position: relative; overflow: hidden; }
.browse-card-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Badges stay above the poster (flex items and positioned boxes both honour z-index). */
.browse-card-visual > :not(.browse-card-img) { z-index: 1; }

/* Player buttons that do not apply here (no cast target, no picture-in-picture)
   are hidden with the attribute; `display` on .inv-btn would otherwise win. */
.inv-btn[hidden] { display: none; }

/* A page swapped in place while music plays: show that the click registered. */
html.inv-navigating { cursor: progress; }
html.inv-navigating #main-content { opacity: 0.6; transition: opacity 0.2s 0.15s; }
#main-content:focus { outline: none; }

/* ── Transcript page ──────────────────────────────────────── */
.transcript-page { max-width: 760px; margin: 0 auto; padding: 2.5rem 1.25rem 4rem; }
.transcript-back a { color: var(--text-muted); }
.transcript-title { font-size: 2rem; margin: 0.75rem 0 0.5rem; }
.transcript-note { color: var(--text-muted); margin-bottom: 1.75rem; }
.transcript { list-style: none; padding: 0; margin: 0; }
.transcript li { display: flex; gap: 1rem; padding: 0.45rem 0; border-bottom: 1px solid var(--border); line-height: 1.55; }
.transcript-time { flex: 0 0 4.5rem; font-family: var(--font-mono); font-size: 0.85rem; color: var(--accent-text); padding-top: 0.1rem; }
.transcript li:target { background: var(--bg-hover); }

/* ── Find in a transcript (CSS Custom Highlight API) ─────────── */
.transcript-find {
  position: sticky;
  top: 64px;
  z-index: 5;
  margin: 0 0 1.25rem;
  padding: 0.75rem 0;
  background: var(--bg);
}
.transcript-find label { display: block; font-weight: 600; margin-bottom: 0.35rem; }
.transcript-find-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.transcript-find input {
  flex: 1 1 14rem;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--field-radius);
  padding: 0.45rem 0.9rem;
}
.transcript-find .btn--glass { padding: 0.45rem 0.6rem; }
.transcript-find-count { min-width: 7ch; color: var(--text-muted); font-variant-numeric: tabular-nums; }
::highlight(transcript-hit) { background-color: var(--hit); color: var(--on-hit); }
::highlight(transcript-current) { background-color: var(--hit-current); color: var(--on-hit-current); }
/* Without the API (and for text it cannot paint), the lines that match. */
.transcript li.transcript-hit { background: color-mix(in oklab, var(--hit) 22%, transparent); }
.transcript li.transcript-current { box-shadow: inset 4px 0 0 var(--hit-current); }

/* ── "More like this" on title pages ──────────────────────── */
.related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; }
.related-card { display: flex; flex-direction: column; gap: 0.35rem; color: var(--text); text-decoration: none; }
.related-card-art { aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden; background: linear-gradient(135deg, var(--surface), var(--bg-hover)); }
.related-card-art img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.25s ease; }
.related-card:hover .related-card-art img, .related-card:focus-visible .related-card-art img { transform: scale(1.04); }
.related-card-name { font-weight: 600; font-size: 0.9rem; line-height: 1.3; }
.related-card-meta { color: var(--text-muted); font-size: 0.8rem; }

/* ════════════════════════════════════════════════════════════
   Native components (look-and-feel track): the poster-to-title view
   transition, the player's settings menu as a popover, and the mini player
   (Document Picture-in-Picture). Kept together here, after everything else,
   and coloured only through the tokens above.
   ════════════════════════════════════════════════════════════ */

/* ── Poster to title page ─────────────────────────────────── */
/* The followed card's poster and the title page's backdrop share a name
   (inv-page.js, title.html) and a class, so one grows into the other. Both
   pictures fill the moving box and are cropped rather than stretched while
   its shape goes from poster to backdrop. With reduced motion nothing is
   named, and the rules under "Motion" stop every transition animation. */
.title-hero-art { view-transition-class: title-art; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-group(*.title-art) {
    animation-duration: 0.35s;
    animation-timing-function: cubic-bezier(0.2, 0, 0, 1);
  }
  ::view-transition-old(*.title-art),
  ::view-transition-new(*.title-art) {
    height: 100%;
    object-fit: cover;
  }
}

/* ── Player settings menu as a popover ────────────────────── */
/* Where the browser has popovers and anchor positioning (inv-player.js,
   POPOVER_MENU) the menu is in the top layer, where the player's overflow
   cannot clip it. It sits above its button, right edges aligned.
   Its height is held as above, to the picture less the controls, from the
   player's width (the player is the menu's container in the top layer too),
   and not by anchor-size(): in WebKit 27.2 a box whose height anchor-size()
   caps loses its scroll position, back to the top, each time it is placed
   again (the page scrolls, the video pauses), so a choice low in the menu
   jumped away as it was scrolled to and could not be pressed.
   Its left edge is held 8px inside the player's, and not by a cap on its
   width: the button is not at the player's right edge (the subtitle, speed,
   cast, picture-in-picture and full-screen buttons are to its right, as many
   as the browser offers), so a long menu reached past the player where more
   of them showed (WebKit, whose cast button shows while AirPlay has a screen
   to play on: 9.5px past a 485px player). Between that edge and the button
   the menu is as wide as its longest line, at the button's end; a longer
   line wraps. */
@supports (anchor-name: --a) {
  .inv-player { anchor-name: --inv-player; }
  .inv-btn-quality { anchor-name: --inv-settings; }
  .inv-quality-menu[popover] {
    position: fixed;
    position-anchor: --inv-settings;
    inset: auto;
    left: calc(anchor(--inv-player left) + 8px);
    right: anchor(right);
    bottom: anchor(top);
    justify-self: end;
    margin: 0 0 8px;
    position-try-fallbacks: flip-inline;
    color: #fff;
    pointer-events: auto;
  }
}
/* The controls stay up while the menu is open. */
.inv-player.menu-open .inv-controls { opacity: 1; pointer-events: auto; }

/* ── Mini player (Document Picture-in-Picture) ────────────── */
/* The window inv-player.js opens: the video and its captions above a bar of
   controls. Dark in both themes, like the player. */
.inv-mini {
  display: flex;
  flex-direction: column;
  height: 100vh;
  min-height: 0;
  overflow: hidden;
  background: #000;
  color: #fff;
}
.inv-mini-stage { position: relative; flex: 1; min-height: 0; container-type: inline-size; }
.inv-mini-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
  background: var(--bg-card);
}
.inv-mini-seek { flex: 1; min-width: 0; accent-color: var(--accent); }
.inv-mini-bar .inv-live-label { flex: 1; }
.inv-mini-time { font-family: var(--font-mono); font-size: 0.75rem; white-space: nowrap; }
.inv-mini.playing .inv-icon-play,
.inv-mini:not(.playing) .inv-icon-pause { display: none; }

/* In the page, where the video was; under the controls bar, which still works. */
.inv-mini-note {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  background: #000;
  color: #fff;
  text-align: center;
}
.inv-player.in-mini .inv-controls-center { display: none; }

/* ── Catch me up (inv-recap.js) ───────────────────────────────── */
.title-recap { max-width: 700px; margin: 0 0 1.25rem; padding: 1rem 1.25rem; border-radius: 12px; border: 1px solid var(--border); background: var(--surface); }
.title-recap h2 { font-size: var(--step-0); margin: 0 0 0.5rem; }
.title-recap ul { margin: 0; padding-left: 1.2rem; display: grid; gap: 0.35rem; }
.title-recap-note { margin: 0.75rem 0 0; font-size: var(--step--2); color: var(--text-muted); }

/* ════════════════════════════════════════════════════════════
   Access services: which titles have subtitles, audio description and
   a transcript (cards, title pages, the library's filter), and the
   player's audio description shown as text. Coloured only through the
   tokens above.
   ════════════════════════════════════════════════════════════ */

/* "CC 25", "AD", "Transcript": outlined, so they read as labels and not as
   buttons. The words they stand for are in the markup for screen readers.
   Positioned, so those words (absolutely placed, .visually-hidden) stay in
   the box: in a scrolled shelf they would otherwise widen the whole page. */
.access-badges { position: relative; display: inline-flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.35rem; }
.title-meta .access-badges { margin-top: 0; }
.access-badge {
  padding: 0 0.35em;
  border: 1px solid var(--border-strong);
  border-radius: 3px;
  font-size: var(--step--2);
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The library's filter: a checkbox and a language, sent as a plain form. */
.access-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  margin-top: 0.9rem;
  font-size: var(--step--1);
  color: var(--text-muted);
}
.access-filter label { display: inline-flex; align-items: center; gap: 0.45rem; }
.access-filter input[type="checkbox"] { width: 1.1rem; height: 1.1rem; accent-color: var(--accent); }
.access-filter select {
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 0.3rem 0.5rem;
  max-width: 16rem;
}
.access-filter button { font: inherit; cursor: pointer; }
.access-filter-clear { color: var(--text-muted); text-decoration: underline; }
.browse-empty { color: var(--text-muted); }
.browse-empty a { color: var(--accent-text); text-decoration: underline; }

/* Transcript lines that describe the picture, from the audio description. */
.transcript-described .transcript-text { font-style: italic; color: var(--text-muted); }
.transcript-mark {
  font-style: normal;
  font-size: var(--step--2);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-text);
  margin-right: 0.35em;
}

/* Audio description as text (inv-describe.js): at the top of the picture,
   clear of the subtitles at the bottom. The region is always there, empty
   between descriptions, so screen readers and braille displays hear of each
   new one. */
.inv-description {
  position: absolute;
  top: 5%;
  left: 5%;
  right: 5%;
  z-index: 2;
  display: flex;
  justify-content: center;
  text-align: center;
  font-size: clamp(13px, 2.8cqi, 32px);
  line-height: 1.35;
  pointer-events: none;
}
.inv-description-text {
  padding: 0.15em 0.5em;
  border-radius: 0.2em;
  background: var(--scrim-strong);
  color: var(--on-media);
  font-style: italic;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* ── Chapters (chapters.rs, inv-chapters.js) ──────────────── */
/* Where each chapter starts: a thin gap cut into the seek bar. */
.inv-chapter-marks { position: absolute; inset: 0; pointer-events: none; }
.inv-chapter-mark {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  transform: translateX(-1px);
  background: var(--media-bg);
  opacity: 0.85;
}
/* The chapter's name above the time in the seek preview. */
.inv-seek-preview-chapter {
  max-width: 240px;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--scrim-strong);
  color: var(--on-media);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inv-seek-preview-chapter[hidden] { display: none; }
/* In the settings menu: the chapter playing, which opens the list of all. */
button.inv-chapter-entry { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.inv-chapter-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 16rem; }
.inv-chapter-more { color: var(--on-media-muted); }
button.inv-chapter-option { display: flex; gap: 0.75rem; max-width: 22rem; white-space: normal; }
.inv-chapter-time { flex: 0 0 auto; min-width: 3.2em; font-variant-numeric: tabular-nums; }

/* The transcript in chapters: their list first, then a heading over each. */
.transcript-chapters { margin: 0 0 2rem; padding: 1rem 1.25rem; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); }
.transcript-chapters-heading { font-size: var(--step-1); margin: 0 0 0.5rem; }
.transcript-chapters ol { list-style: none; margin: 0; padding: 0; columns: 15rem auto; column-gap: 1.5rem; }
.transcript-chapters li { break-inside: avoid; padding: 0.2rem 0; }
.transcript-chapters a { color: var(--text); text-decoration: none; }
.transcript-chapters a:hover { text-decoration: underline; }
.transcript-chapter-time { display: inline-block; min-width: 3.5em; font-family: var(--font-mono); font-size: 0.85rem; color: var(--accent-text); }
.transcript-chapter { display: flex; gap: 1rem; align-items: baseline; margin: 2rem 0 0.5rem; font-size: var(--step-1); scroll-margin-top: 5rem; }
.transcript-quiet { padding: 0.45rem 0; border-bottom: 1px solid var(--border); color: var(--text-muted); font-style: italic; }

/* ── Offline downloads (inv-download.js) ──────────────────── */
/* A message any page can show without moving what is on it. */
.inv-download-toast {
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  z-index: 1000;
  transform: translateX(-50%);
  max-width: min(36rem, calc(100vw - 2rem));
  margin: 0;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  background: var(--action);
  color: var(--on-action);
  box-shadow: var(--shadow-2);
  font-size: var(--step--1);
}
.inv-download-toast[hidden] { display: none; }

/* /downloads. Tall enough from the start that the list, read from the
   browser's storage after the first paint, never moves the footer. */
.downloads-page { max-width: 860px; min-height: 70vh; margin: 0 auto; padding: 2.5rem var(--gutter) 4rem; }
.downloads-title { margin-bottom: 0.5rem; font-size: var(--step-4); font-weight: 800; letter-spacing: -0.03em; }
.downloads-intro { max-width: 62ch; margin-bottom: 1.25rem; color: var(--text-muted); line-height: 1.6; }
.downloads-storage { min-height: 1.5em; margin-bottom: 1rem; color: var(--text-muted); font-size: var(--step--1); }
.downloads-list { display: grid; gap: 0.75rem; margin: 0; padding: 0; list-style: none; }
.downloads-item { display: grid; grid-template-columns: 64px 1fr auto; gap: 1rem; align-items: center; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-card); }
.downloads-art { display: block; width: 64px; aspect-ratio: 2 / 3; border-radius: var(--radius); overflow: hidden; background: var(--placeholder); }
.downloads-art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.downloads-info { display: grid; gap: 0.2rem; min-width: 0; }
.downloads-name { color: var(--text); font-weight: 700; text-decoration: none; }
.downloads-name:hover { text-decoration: underline; }
.downloads-what, .downloads-state { color: var(--text-muted); font-size: var(--step--1); }
.downloads-progress { width: 100%; max-width: 20rem; accent-color: var(--accent); }
.downloads-progress[hidden] { display: none; }
.downloads-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem; }
.downloads-actions .icon { width: 1em; height: 1em; vertical-align: -0.125em; }
.downloads-empty { color: var(--text-muted); }
.downloads-unsupported { padding: 0.75rem 1rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
/* What this browser can do is known in the page's head, before the first paint. */
:root:not(.can-download) .downloads-supported { display: none; }
:root.can-download .downloads-unsupported { display: none; }
@media (max-width: 560px) {
  .downloads-item { grid-template-columns: 48px 1fr; }
  .downloads-art { width: 48px; }
  .downloads-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

/* ── Live TV around the world (/tv/world, /live/<id>) ─────── */
/* A channel's logo (from iptv-org) covers its name on the card; when the
   logo fails to load, app.js removes it and the name is there, in the same
   place. */
.card-visual .card-logo,
.news-card-visual .card-logo {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  padding: 12% 18% 20%;
  object-fit: contain;
  background: var(--logo-panel);
}
.news-card-visual { position: relative; overflow: hidden; }
.news-card-visual .card-logo { padding: 10% 22% 14%; }
.news-card-visual > :not(.card-logo) { position: relative; z-index: 2; }
.world-hero { padding: 2rem var(--gutter) 1.25rem; background: var(--hero-band); }
.world-hero h1 { margin-bottom: 0.4rem; }
.world-lede { max-width: 62ch; margin-bottom: 1rem; color: var(--text-muted); }
.world-crumbs { margin-bottom: 0.5rem; color: var(--text-dim); font-size: var(--step--1); }
.world-crumbs a, .world-note a, .world-credit a, .live-facts a, .world-more { color: var(--accent-text); }
/* Links within a sentence are underlined, not told apart by colour alone. */
.world-note a, .world-credit a { text-decoration: underline; text-underline-offset: 0.15em; }
.world-section { padding-bottom: 1rem; }
.world-section > .section-title, .world-section > .section-desc,
.world-section > .world-note, .world-section > .world-credit { padding-inline: var(--gutter); }
.world-on-tv, .world-news { padding-top: 2rem; }
.world-rail-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 1rem; padding-inline: var(--gutter); }
.world-rail-head .section-title { margin-bottom: 0.6rem; padding-inline: 0; }
.world-rail-head .section-title a { color: inherit; }
.world-rail-head .section-title a:hover { text-decoration: underline; }
.world-rail.section { padding-block: 0.75rem 0; }
.world-more { font-size: var(--step--1); white-space: nowrap; }
.world-more:hover { text-decoration: underline; }
.world-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1rem; padding: 0 var(--gutter); list-style: none; }
.world-chips .filter-pill { display: inline-flex; align-items: center; gap: 0.35em; }
.world-hero .world-chips { margin-top: 0.25rem; padding-inline: 0; }
.world-browse-title { margin: 0.75rem 0 0.5rem; padding-inline: var(--gutter); color: var(--text-muted); font-size: var(--step-0); }
.world-browse .world-note { padding-inline: var(--gutter); }
.world-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1.25rem 1rem; padding: 0 var(--gutter); }
.world-grid .card { flex: none; }
.world-pager { display: flex; gap: 0.75rem; padding: 1.5rem var(--gutter) 0; }
.world-quiet { margin: 1.5rem var(--gutter) 0; }
.world-quiet summary { cursor: pointer; font-weight: 600; }
.world-quiet > p { margin: 0.5rem 0; }
.world-quiet ul { margin: 0.75rem 0 0; padding: 0; list-style: none; columns: 20rem; column-gap: 2rem; }
.world-quiet li { padding: 0.2rem 0; break-inside: avoid; }
.world-note, .world-credit { color: var(--text-dim); font-size: var(--step--1); }
.world-note--search { margin-top: 0.75rem; padding-inline: var(--gutter); }
.world-credit { max-width: calc(72ch + 2 * var(--gutter)); line-height: 1.6; }

.live-page { display: grid; grid-template-columns: minmax(0, 2fr) minmax(18rem, 1fr); gap: 1.5rem 2rem; padding: 1.5rem var(--gutter) 0; }
.live-player { position: relative; overflow: hidden; aspect-ratio: 16 / 9; border-radius: var(--radius-lg); background: var(--media-bg); }
.live-notice {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1.5rem;
  color: var(--on-media);
  text-align: center;
}
.live-notice-title { font-size: var(--step-2); font-weight: 700; }
.live-notice p:not(.live-notice-title) { max-width: 46ch; color: var(--on-media-muted); }
/* A channel the law keeps from this visitor: the reason and its texts, as
   long as they need, in place of the player (jurisdiction::media). */
.live-player--withheld { aspect-ratio: auto; min-height: 14rem; }
.live-notice--law { position: static; min-height: inherit; }
.live-notice--law a { color: var(--on-media); text-decoration: underline; text-underline-offset: 0.15em; }
.live-notice-law { font-size: var(--step--1); overflow-wrap: anywhere; }
.live-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.25rem; }
.live-logo { flex: none; width: 120px; height: 68px; padding: 0.4rem; border-radius: var(--radius); background: var(--logo-panel); object-fit: contain; }
.live-head h1 { font-size: var(--step-3); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; }
.live-head h1 .badge { vertical-align: middle; font-size: var(--step--2); }
.live-alt { color: var(--text-muted); font-size: var(--step--1); }
.live-facts { display: grid; grid-template-columns: auto 1fr; gap: 0.45rem 1rem; margin: 1.25rem 0; }
.live-facts dt { color: var(--text-dim); }
.live-facts dd { margin: 0; overflow-wrap: anywhere; }
.live-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
@media (max-width: 900px) {
  .live-page { grid-template-columns: 1fr; }
  .world-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
}

/* ── Podcasts and free music (/podcasts, /podcast/…, /music/free) ── */
/* Square artwork. A show or a release with no artwork, or artwork that does
   not load (app.js removes it), shows its initial on a colour of its own. */
.card--square { flex: 0 0 176px; }
.card--square .card-visual { aspect-ratio: 1; padding: 0; }
.card-initial {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: clamp(2.2rem, 4vw, 3.2rem);
  font-weight: 800;
  color: oklch(0.97 0.02 var(--hue, 270));
  background: linear-gradient(160deg, oklch(0.5 0.1 var(--hue, 270)), oklch(0.3 0.07 calc(var(--hue, 270) + 40)));
}
.card-initial .icon { width: 2.5rem; height: 2.5rem; }
.card--square .card-img { z-index: 1; background: none; }
.card--more .card-visual { background: var(--surface); }
.card-more-label { position: absolute; inset: 0; display: grid; place-items: center; font-weight: 700; color: var(--accent-text); }
.audio-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.audio-group-title { padding: 1.5rem var(--gutter) 0; font-size: var(--step-3); }
.audio-hero h1 .icon { width: 0.85em; height: 0.85em; vertical-align: -0.08em; }
.audio-status { min-height: 1.4em; margin: 0.25rem 0 0; padding-inline: var(--gutter); color: var(--text-muted); font-size: var(--step--1); }
.audio-section-note { margin: -0.25rem 0 0.75rem; }
.audio-rail-about { margin: -0.35rem 0 0.5rem; padding-inline: var(--gutter); max-width: calc(72ch + 2 * var(--gutter)); }
.audio-stations { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0 var(--gutter) 0.5rem; }
.audio-station { display: inline-flex; align-items: center; gap: 0.4em; cursor: pointer; font: inherit; }
.audio-station .icon { width: 0.95em; height: 0.95em; fill: currentColor; }
.audio-station[aria-busy="true"] { opacity: 0.6; }
.badge-explicit {
  display: inline-block;
  padding: 0 0.4em;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-size: 0.78em;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--text-muted);
}

/* A show, an episode or a release: the artwork beside what it is. */
.show-head { display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr); gap: 1.5rem 2rem; padding: 1.75rem var(--gutter) 0.5rem; align-items: start; }
.show-art { position: relative; aspect-ratio: 1; overflow: hidden; border-radius: var(--radius-lg); box-shadow: var(--shadow-1); }
.show-art img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: cover; display: block; }
.show-info h1 { margin: 0.2rem 0 0.25rem; font-size: var(--step-4); font-weight: 800; letter-spacing: -0.02em; line-height: 1.08; overflow-wrap: anywhere; }
.episode-page .show-info h1 { font-size: var(--step-3); }
.show-artist { margin: 0; color: var(--text-muted); font-size: var(--step-1); }
.show-facts { margin: 0.4rem 0 0.9rem; color: var(--text-dim); font-size: var(--step--1); }
.show-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.5rem; }
.show-about { max-width: 70ch; margin-top: 0.75rem; color: var(--text-muted); }
.show-about summary { cursor: pointer; color: var(--accent-text); margin-top: 0.4rem; }
.show-links { display: flex; flex-wrap: wrap; gap: 0.4rem 1.25rem; margin: 1rem 0 0; padding: 0; list-style: none; font-size: var(--step--1); }
.show-links a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.15em; }
.show-episodes > .section-title, .show-episodes > .world-note, .release-about > * { padding-inline: var(--gutter); }
.release-about p { max-width: 72ch; color: var(--text-muted); }
.release-credits { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 1rem; margin: 1rem 0 0.5rem; font-size: var(--step--1); }
.release-credits dt { color: var(--text-dim); }
.release-credits dd { margin: 0; overflow-wrap: anywhere; }
.release-credits a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.15em; }
.release-credits > div { display: contents; }

/* Episodes and tracks: play, what it is, then play next and add to queue. */
.episode-list { margin: 0; padding: 0 var(--gutter); list-style: none; }
.episode { display: grid; grid-template-columns: 2.75rem minmax(0, 1fr) auto; gap: 0.25rem 0.9rem; align-items: start; padding: 0.85rem 0; border-top: 1px solid var(--hairline); }
.episode-play {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 0;
  border-radius: 50%;
  background: var(--action);
  color: var(--on-action);
  cursor: pointer;
}
.episode-play .icon { width: 1.1rem; height: 1.1rem; fill: currentColor; }
.episode-play:hover { background: var(--action-hover); }
.episode-play:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; }
.episode-title { margin: 0; font-size: var(--step-0); font-weight: 650; line-height: 1.3; }
.episode-title a { color: inherit; }
.episode-title a:hover { text-decoration: underline; }
.track-n { display: inline-block; min-width: 1.6em; color: var(--text-dim); font-variant-numeric: tabular-nums; font-weight: 500; }
.episode-meta { margin: 0.15rem 0 0; color: var(--text-dim); font-size: var(--step--1); }
.episode-notes { margin: 0.35rem 0 0; color: var(--text-muted); font-size: var(--step--1); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.episode-actions { display: flex; gap: 0.25rem; }
.audio-small {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
}
.audio-small:hover { background: var(--tint-strong); color: var(--text); }
.audio-small:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.audio-small .icon { width: 1.15rem; height: 1.15rem; }
/* How far into an episode this browser has listened. */
.audio-progress { display: block; height: 3px; margin-top: 0.45rem; border-radius: 2px; background: var(--hairline); overflow: hidden; max-width: 22rem; }
.audio-progress[hidden] { display: none; }
.audio-progress::before { content: ""; display: block; height: 100%; width: var(--progress, 0%); background: var(--accent); }
.audio-card-play { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; text-align: start; font: inherit; cursor: pointer; }
.audio-card-play:focus-visible { outline: none; }
.audio-card-play:focus-visible .card-visual { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.audio-card .card-title, .audio-card .card-now { display: block; }
.audio-card .audio-progress { max-width: none; margin-top: 0.4rem; }

/* The episode page: the audiobook player (css/books.css), its chapters and transcript. */
.show-info .audio-player { max-width: 40rem; margin: 0.5rem 0 1rem; }
.episode-body { max-width: 70ch; color: var(--text-muted); }
.episode-links summary { cursor: pointer; color: var(--accent-text); }
.episode-links ul { margin: 0.5rem 0; padding-inline-start: 1.25rem; overflow-wrap: anywhere; }
.episode-links a { color: var(--accent-text); }
.audio-panel--page .audio-lines { max-height: min(70vh, 40rem); overflow-y: auto; overscroll-behavior: contain; }
.audio-panel--page > .lib-note, .audio-panel--page > .audio-find { padding-inline: var(--gutter); }
.audio-lines .lib-chapter[disabled] { cursor: default; }
.audio-lines .lib-chapter { grid-template-columns: 4.25rem minmax(0, 1fr); align-items: baseline; }
.audio-lines .lib-chapter-n { font-size: var(--step--1); }
.audio-who { font-weight: 650; color: var(--text); }
.audio-find { display: flex; align-items: center; gap: 0.75rem; margin: 0 0 0.75rem; }
.audio-find input { flex: 1; max-width: 26rem; padding: 0.55rem 0.8rem; border: 1px solid var(--border-strong); border-radius: var(--field-radius); background: var(--bg-raised); color: var(--text); font: inherit; }
.audio-found { color: var(--text-dim); font-size: var(--step--1); }
.episode-nav { flex-wrap: wrap; }

/* The now-playing view: over the whole page, from the bar's title. */
.audio-now {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: max(1rem, env(safe-area-inset-top)) var(--gutter) 1.5rem;
  border: 0;
  overflow-y: auto;
  background: var(--bg);
  color: var(--text);
}
.audio-now::backdrop { background: var(--scrim); }
.audio-now-inner { position: relative; max-width: 58rem; margin: 0 auto; }
.audio-now .audio-now-close { position: absolute; top: 0; right: 0; z-index: 1; }
.audio-now .audio-player { max-width: none; }
.audio-now .lib-chapter-list { padding: 0; }
.audio-now-head { display: flex; align-items: center; gap: 1rem; padding-right: 3.5rem; margin-bottom: 1rem; }
.audio-now-art { flex: none; width: 6rem; height: 6rem; border-radius: var(--radius); overflow: hidden; background: var(--placeholder); }
.audio-now-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.audio-now-kind { margin: 0; font-size: var(--step-2); font-weight: 750; line-height: 1.2; overflow-wrap: anywhere; }
.audio-now-artist { margin: 0.2rem 0 0; color: var(--text-muted); }
.audio-now-panels { display: grid; gap: 1.25rem; margin-top: 1.25rem; }
.audio-now .audio-lines, .audio-now .audio-queue { max-height: 40vh; overflow-y: auto; overscroll-behavior: contain; margin: 0; padding: 0; list-style: none; }
.audio-panel-title { margin: 0 0 0.5rem; font-size: var(--step-1); }
.audio-queue-item { display: flex; align-items: center; gap: 0.25rem; }
.audio-queue-item .lib-chapter { flex: 1; }
.audio-drop { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border: 0; border-radius: 50%; background: none; color: var(--text-muted); cursor: pointer; }
.audio-drop:hover { background: var(--tint-strong); }
.audio-drop .icon { width: 1rem; height: 1rem; }
.audio-player--live [data-audio-act="prev"],
.audio-player--live [data-audio-act="next"],
.audio-player--live [data-audio-act="back"],
.audio-player--live [data-audio-act="forward"],
.audio-player--live .lib-scrub { visibility: hidden; }

@media (max-width: 720px) {
  .show-head { grid-template-columns: minmax(0, 1fr); }
  .show-art { width: min(100%, 15rem); }
  .card--square { flex-basis: 140px; }
  .audio-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
  .episode { grid-template-columns: 2.5rem minmax(0, 1fr); }
  .episode-actions { grid-column: 2; }
  .audio-now-art { width: 4.5rem; height: 4.5rem; }
}
@media (min-width: 1000px) {
  .audio-now-panels { grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); }
}

/* TV: bigger artwork, rows of episodes as the remote moves along them. */
:root[data-tv] .card--square { flex-basis: clamp(200px, 12vw, 400px); }
:root[data-tv] .audio-grid { grid-template-columns: repeat(auto-fill, minmax(clamp(200px, 12vw, 400px), 1fr)); }
:root[data-tv] .episode { grid-template-columns: 3.5rem minmax(0, 1fr) auto; padding: 1.1rem 0; }
:root[data-tv] .episode-play { width: 3.5rem; height: 3.5rem; }
:root[data-tv] .episode-play:is(:focus-visible, .controller-focus),
:root[data-tv] .audio-station:is(:focus-visible, .controller-focus) { outline: 4px solid var(--focus-ring); outline-offset: 4px; }
:root[data-tv] .audio-now-art { width: 10rem; height: 10rem; }
:root[data-tv] .audio-now-kind { font-size: var(--step-3); }
/* Hidden controls keep their place (no shift when chapters arrive); hidden options go. */
[data-audio-player] .lib-transport [hidden] { display: grid; visibility: hidden; }
[data-audio-player] .lib-options [hidden] { display: none; }

/* ── Grids on a phone: two across ─────────────────────────────
   A phone's single column made the Films list 12,600px tall (one big card a
   screen), Games and News 7,600-10,000px: every item stays, two to a row,
   the longer descriptions left to each item's own page. */
@media (max-width: 640px) {
  /* (Under main: the sections' own stylesheets come after this one.) */
  main :is(.browse-grid, .games-grid, .news-grid, .stations-grid, .games-facts, .art-grid, .learn-grid) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
    padding-inline: var(--gutter);
  }
  main :is(.games-grid, .games-facts) { padding-inline: 0; }
  .browse-card-visual { height: 104px; padding: 0.6rem; }
  .browse-card-body { padding: 0.6rem 0.7rem 0.75rem; }
  .browse-card-desc { display: none; }
}

/* ── Permanence: a source not answering, a work gone from it ──────────
   (crate::permanence, templates/permanence.html). Said in words; the
   colour only marks the line. */
.perm-note {
  margin: 0.9rem 0 0;
  max-width: 62ch;
  padding: 0.55rem 0.8rem;
  border-left: 3px solid var(--warning);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: color-mix(in oklab, var(--warning) 9%, transparent);
  color: var(--text);
  font-size: var(--step--1);
  line-height: 1.5;
}
.perm-gone {
  margin: 1rem 0 0;
  max-width: 62ch;
  padding: 0.8rem 0.95rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: var(--step--1);
  line-height: 1.55;
}
.perm-gone-title { margin: 0 0 0.4rem; font-size: var(--step-0); font-weight: 700; line-height: 1.3; }
.perm-gone p { margin: 0 0 0.45rem; }
.perm-gone a { color: var(--accent-text); text-decoration: underline; }
.perm-copies { margin: 0.4rem 0 0; padding-left: 1.1rem; }
.perm-copies li + li { margin-top: 0.4rem; }
.card-note { display: block; margin: 0.2rem 0 0; font-size: var(--step--2); color: var(--text-muted); }
.home-pd > .section-desc { max-width: 72ch; }
.perm-kept { max-width: 760px; margin: 0 auto; padding: clamp(1.5rem, 4vw, 3rem) var(--gutter) 3rem; }
.perm-kept-crumbs, .perm-kept-kind { margin: 0 0 0.5rem; color: var(--text-muted); font-size: var(--step--1); }
.perm-kept-crumbs a { color: var(--accent-text); text-decoration: underline; }
.perm-kept-by { margin: 0.25rem 0 0; color: var(--text-muted); }
.perm-kept-about { margin: 1.25rem 0 0; max-width: 68ch; line-height: 1.65; color: var(--text-muted); }
.perm-kept-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0.5rem 1.25rem; margin: 1.5rem 0 0; font-size: var(--step--1); }
.perm-kept-facts dt { color: var(--text-dim); font-weight: 600; }
.perm-kept-facts dd { margin: 0; color: var(--text-muted); overflow-wrap: anywhere; }
.perm-kept-url { font-family: var(--font-mono, ui-monospace, monospace); }
@media (max-width: 640px) { .perm-kept-facts { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; } .perm-kept-facts dd { margin-bottom: 0.6rem; } }

/* ── Caption style on /settings (inv-caption-style.js) ──────── */
.cc-style-grid { display: grid; gap: 1rem 1.5rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); align-items: start; margin: 0.75rem 0; }
.cc-style-fields { display: grid; gap: 0.5rem; }
.cc-preview-wrap { margin: 0; }
/* A bright picture and a dark one side by side, so the preview shows how the
   captions read over both. */
.cc-preview {
  position: relative;
  container-type: inline-size;
  aspect-ratio: 16 / 9;
  max-width: 560px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  overflow: hidden;
  background: linear-gradient(90deg, var(--on-media) 0 50%, var(--media-bg) 50% 100%);
}
.cc-preview .inv-subtitle-overlay { bottom: 10%; transition: none; }
.cc-note { margin-top: 0.5rem; }
.cc-note--low { color: var(--warning); font-weight: 600; }
