/* Continental Radio — brass, walnut and lamplight.

   Written mobile-first: the base rules are the phone, and the
   min-width blocks add the room a desk gets. Palette is polished
   brass and copper over deep walnut, parchment for anything you
   actually read at length, verdigris and oxblood for signals.
   Logo: Limelight (the wordmark, and NOTHING else — its capital G
   reads as a C). Display: Playfair Display. Body: Libre Caslon Text.
   Utility: Oswald. No images, no libraries — every rivet is a
   gradient. */

:root {
  /* --- the woods and the metals ---------------------------------- */
  --walnut-deep: #1e140d;
  --walnut: #2c1d13;
  --walnut-lit: #3f2a1a;
  --mahogany: #4a2c19;
  --brass: #d9b978;
  --brass-lit: #f7e5b6;
  --brass-dark: #8a6f3c;
  --copper: #c1743c;
  --copper-lit: #e39a5c;
  --verdigris: #4f8f80;
  --verdigris-lit: #7cc0ad;
  --oxblood: #7b2f2a;
  --oxblood-lit: #bb4d3f;
  --amber: #f5a93c;
  --filament: #ffd489;
  --ivory: #f7eeda;
  --ivory-dim: #ddcaa4;
  --parchment: #f2e5c6;
  --parchment-deep: #e0cda4;
  --ink: #33220f;

  /* --- the cabinet's geometry ------------------------------------
     Every panel on the station is cut from this one set of parts, so
     nothing reads as if it came out of a different workshop. The
     apparatus is the reference: its case, its panels, its keys. */
  --r-case: 10px;            /* an outer case (apparatus, dial, card) */
  --r-panel: 7px;            /* a panel screwed into a case */
  --r-key: 6px;              /* keys, chips, fields, tabs */
  --r-glass: 4px;            /* anything sitting behind glass */
  --edge-lit: #7d6435;       /* the lit edge of a brass panel */
  --edge-dark: #4b3a1c;      /* the shadowed edge of a fitting */
  --lip: inset 0 1px 0 rgba(255, 240, 200, 0.32);
  --floor: inset 0 -18px 30px rgba(0, 0, 0, 0.45);
  --lift: 0 12px 30px rgba(0, 0, 0, 0.6);
  --lift-low: 0 5px 14px rgba(0, 0, 0, 0.5);
  --recess: inset 0 2px 6px rgba(0, 0, 0, 0.6);
  --key-lift:
    0 3px 0 var(--edge-dark), 0 5px 9px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(255, 245, 215, 0.8);
  --lamp: 0 0 14px rgba(245, 169, 60, 0.4);

  /* --- shared decoration ----------------------------------------- */
  --rivet: radial-gradient(circle,
    var(--brass-lit) 0 1.2px, #b99a5e 1.3px 2.5px,
    #5f4a26 2.6px 3.3px, transparent 3.4px);
  --etch: repeating-linear-gradient(45deg,
    rgba(255, 236, 200, 0.022) 0 2px, transparent 2px 7px);
  --brass-face: linear-gradient(180deg,
    var(--brass-lit) 0%, var(--brass) 24%, #a98b4e 68%, #7a6132 100%);

  /* The wordmark's face, used by the wordmark alone. */
  --logo: "Limelight", "Georgia", serif;
  --display: "Playfair Display", "Libre Caslon Text", "Georgia", serif;
  --body: "Libre Caslon Text", "Georgia", serif;
  --utility: "Oswald", "Arial Narrow", sans-serif;
}

* { box-sizing: border-box; }

/* Controls do NOT inherit a font in any browser — left alone they fall
   back to the UA's Arial, which is the one face that has no business
   on this station. Every control starts in the house utility gothic
   and every field in the house text face; individual rules refine
   from there. */
button, select, ::file-selector-button {
  font-family: var(--utility);
}
input, textarea { font-family: var(--body); }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column;
  /* clip, not hidden: `hidden` would turn <body> into a scroll
     container, and the full-bleed stage needs the page to keep
     owning the scroll. */
  overflow-x: clip;
  background:
    radial-gradient(130% 70% at 50% -8%,
      rgba(193, 116, 60, 0.22) 0%, transparent 62%),
    radial-gradient(90% 60% at 100% 108%,
      rgba(79, 143, 128, 0.10) 0%, transparent 70%),
    linear-gradient(180deg, #33200f 0%, var(--walnut-deep) 46%, #130c08 100%);
  background-attachment: scroll;
  color: var(--ivory);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
}

a { color: var(--amber); text-decoration: none; }
a:hover { color: var(--copper-lit); }
:focus-visible {
  outline: 2px solid var(--filament);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Playfair carries every title unless a rule says otherwise (the
   utility gothic takes the small-caps legends, and Limelight is the
   wordmark's alone). A heading that forgets to ask still gets the
   right face. */
h1, h2, h3 {
  font-family: var(--display); font-weight: 400; margin: 0 0 0.4em;
}

/* Engraved plate lettering: cut into the metal, lit from above. */
h1, .hero-title, .plate-title, .wordmark-continental {
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7), 0 -1px 0 rgba(255, 226, 170, 0.10);
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

[hidden] { display: none !important; }

/* Parchment: the reading surfaces. Ink on paper, never ivory on wood.
   Same radius and brass edge as every other panel on the set — the
   difference is the material, not the joinery. */
.prose, .letter, .empty-state {
  background:
    repeating-linear-gradient(0deg,
      rgba(120, 90, 50, 0.035) 0 1px, transparent 1px 3px),
    linear-gradient(168deg, var(--parchment) 0%, var(--parchment-deep) 100%);
  color: var(--ink);
  border: 1px solid var(--brass-dark);
  border-radius: var(--r-key);
  padding: 1.1rem 1.15rem;
  box-shadow:
    var(--lift-low),
    inset 0 0 34px rgba(150, 110, 60, 0.20),
    inset 0 1px 0 rgba(255, 250, 235, 0.7);
}
.prose a, .letter a, .empty-state a {
  color: #8a3d16; text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px;
}
.prose a:hover, .letter a:hover { color: var(--oxblood); }

/* ------------------------------------------------------------ masthead */

/* The top rail of the cabinet: walnut, a machined brass edge, and the
   same rivets that hold the apparatus together. */
.masthead {
  position: relative;
  /* One rail normally; the smallest phones stack logo and keys. */
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: nowrap;
  padding: 0.6rem 0.7rem 0.7rem;
  border-bottom: 1px solid #120b06;
  background:
    var(--etch),
    linear-gradient(180deg, #4b3120 0%, var(--walnut) 78%, #241710 100%);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5), var(--lip);
}
/* The brass rail along the bottom edge, with a rivet at each end —
   the same joint as the stage's rule below the cabinet. */
.mast-rail {
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, var(--brass-dark), var(--brass) 18%,
    var(--brass-lit) 50%, var(--brass) 82%, var(--brass-dark));
}
.mast-rail::before, .mast-rail::after {
  content: ""; position: absolute; top: -4px; width: 8px; height: 8px;
  background-image: var(--rivet); background-size: 8px 8px;
}
.mast-rail::before { left: 0.55rem; }
.mast-rail::after { right: 0.55rem; }

.wordmark { display: flex; flex-direction: column; line-height: 1; flex: none; }
.wordmark-continental {
  font-family: var(--logo);
  font-size: 1.18rem;
  color: var(--ivory);
  letter-spacing: 0.03em;
}
.wordmark-radio {
  font-family: var(--utility);
  font-size: 0.78rem;
  letter-spacing: 0.52em;
  color: var(--brass);
  margin-top: 0.2rem;
  padding-left: 0.15em;
}
.wordmark:hover .wordmark-continental { color: var(--amber); }

.mast-nav {
  display: flex; gap: 0.4rem; align-items: center;
  flex-wrap: nowrap; white-space: nowrap;
  font-family: var(--utility);
  font-size: 0.8rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  margin-left: auto;
}
/* Text links in the share sheet keep the rail's lit-ivory treatment. */
.mast-nav a, .mast-nav .nav-plain {
  color: var(--ivory); padding: 0.35rem 0.3rem;
  display: inline-flex; align-items: center; min-height: 44px;
  box-shadow: inset 0 -1px 0 transparent;
}
/* The SHARE trigger is a <button>: strip the UA face, keep the type. */
button.nav-plain {
  background: none; border: none; cursor: pointer;
  font: inherit; letter-spacing: inherit; text-transform: inherit;
}
.mast-nav a:hover, .mast-nav a:focus-visible,
.mast-nav .nav-plain:hover, .mast-nav .nav-plain:focus-visible {
  color: var(--filament);
  text-shadow: 0 0 12px rgba(245, 169, 60, 0.5);
  box-shadow: inset 0 -2px 0 var(--amber);
}
/* With no brass face left to carry the state, the focus ring has to
   do the whole job — so it is drawn tight around the word rather than
   floating 3px off it. */
.mast-nav a:focus-visible, .mast-nav .nav-plain:focus-visible {
  outline: 2px solid var(--filament); outline-offset: 0;
  border-radius: 3px;
}
/* Masthead keys share the transport's brass face, lip and travel. */
.mast-nav .nav-key {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.35rem; flex: none;
  min-height: 44px; min-width: 44px; padding: 0 0.65rem;
  border: 1px solid #5d4a25; border-radius: var(--r-key);
  background: var(--brass-face);
  color: #221405;
  font-family: var(--utility); font-weight: 600; font-size: 0.8rem;
  letter-spacing: 0.09em; text-transform: uppercase;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.4);
  box-shadow: var(--key-lift);
  cursor: pointer;
}
.mast-nav .nav-key:hover, .mast-nav .nav-key:focus-visible {
  color: #221405; filter: brightness(1.07); text-shadow: none;
  box-shadow: var(--key-lift), var(--lamp);
}
.mast-nav .nav-key:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 var(--edge-dark),
    inset 0 2px 6px rgba(0, 0, 0, 0.45);
}
/* Subtle, not loud: a 2px edge and a shallow drop instead of the
   transport's 3px travel. It is a boundary around an icon, not a key
   competing with the words beside it. */
.nav-menu-key {
  position: relative; padding: 0 0.5rem;
  box-shadow:
    0 2px 0 var(--edge-dark), 0 3px 7px rgba(0, 0, 0, 0.45),
    inset 0 1px 0 rgba(255, 245, 215, 0.6);
}
.nav-menu-key:hover, .nav-menu-key:focus-visible {
  box-shadow:
    0 2px 0 var(--edge-dark), 0 3px 7px rgba(0, 0, 0, 0.45),
    0 0 12px rgba(245, 169, 60, 0.35),
    inset 0 1px 0 rgba(255, 245, 215, 0.6);
}
/* Three rules cut into the plate. */
.menu-rules {
  width: 22px; height: 17px; display: block; fill: currentColor;
  filter: drop-shadow(0 1px 0 rgba(255, 246, 216, 0.45));
}
/* Held down while the panel is out — a latching key, like the
   pressing switch. */
.nav-menu-key[aria-expanded="true"] {
  transform: translateY(2px);
  box-shadow: inset 0 2px 7px rgba(0, 0, 0, 0.5);
}
.nav-menu-key .unread-badge {
  position: absolute; top: -5px; right: -5px; margin: 0;
  vertical-align: baseline;
  border: 1px solid #3a1a15;
}

/* ------------------------------------------------ the masthead panel

   Everything with a name longer than one word drops out of the rail
   and into this machined plate: a drawer in the cabinet's top rail,
   not a second navigation bar. */
.mast-panel {
  position: absolute; top: 100%; right: 0.55rem; z-index: 90;
  width: min(18rem, calc(100vw - 1.1rem));
  margin-top: 7px; padding: 6px;
  border: 1px solid var(--edge-lit); border-radius: var(--r-panel);
  background:
    var(--etch),
    linear-gradient(180deg, var(--walnut-lit) 0%, #201510 100%);
  box-shadow: var(--lift), var(--lip);
}
/* The brass lug that ties the plate to the key above it. */
.mast-panel::before {
  content: ""; position: absolute; top: -6px; right: 16px;
  width: 12px; height: 6px;
  background: linear-gradient(180deg, var(--brass-lit), var(--brass-dark));
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.mast-panel-inner { display: flex; flex-direction: column; }
.panel-legend {
  margin: 0.1rem 0 0.35rem; padding: 0.35rem 0.7rem;
  border-radius: 3px;
  background: var(--brass-face);
  color: #221405;
  font-family: var(--utility); font-size: 0.82rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.45);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.panel-handle { font-weight: 500; opacity: 0.75; }
.panel-handle::before { content: "· "; }
.mast-panel a, .mast-panel .link-button {
  display: flex; align-items: center; gap: 0.5rem;
  width: 100%; min-height: 48px; padding: 0.5rem 0.7rem;
  color: var(--ivory); text-align: left;
  font-family: var(--utility); font-size: 0.92rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  border-bottom: 1px solid rgba(217, 185, 120, 0.14);
  box-shadow: none;
}
.mast-panel .inline-form { display: block; }
.mast-panel > .mast-panel-inner > :last-child a,
.mast-panel a:last-child { border-bottom: none; }
.mast-panel .inline-form:last-child .link-button { border-bottom: none; }
.mast-panel a:hover, .mast-panel a:focus-visible,
.mast-panel .link-button:hover, .mast-panel .link-button:focus-visible {
  color: var(--filament); box-shadow: none;
  background: rgba(245, 169, 60, 0.09);
  text-shadow: 0 0 12px rgba(245, 169, 60, 0.45);
}

.inline-form { display: inline-flex; }
.link-button {
  background: none; border: none; padding: 0.35rem 0; cursor: pointer;
  min-height: 44px;
  color: var(--ivory); font: inherit; letter-spacing: inherit;
  text-transform: inherit;
  box-shadow: inset 0 -1px 0 transparent;
}
.link-button:hover, .link-button:focus-visible {
  color: var(--filament); box-shadow: inset 0 -2px 0 var(--amber);
}

/* The masthead's ON AIR lamp is gone — it reported the state of a
   player that is not on most of the pages it hung over. The real
   illuminated sign is bolted into the apparatus, under the meter
   (`.on-air-lamp`, further down). */

/* The share sheet in the rail hangs from the RIGHT edge of its word:
   anchored left it would run off a narrow desk. */
.share-desk-mast .share-sheet { z-index: 95; }

/* The small phones (320-359): the rail holds SHARE, SIGN IN, SIGN UP
   and the menu plate on one line, so the wordmark and the type give
   up the room rather than any control doing so. */
@media (max-width: 359px) {
  .masthead { gap: 0.35rem; padding-left: 0.5rem; padding-right: 0.5rem; }
  .wordmark-continental { font-size: 0.95rem; }
  .wordmark-radio { font-size: 0.62rem; letter-spacing: 0.34em; }
  .mast-nav { gap: 0.1rem; font-size: 0.66rem; letter-spacing: 0.04em; }
  .mast-nav a, .mast-nav .nav-plain { padding: 0.35rem 0.2rem; }
  .mast-nav .nav-key { padding: 0 0.4rem; font-size: 0.66rem; }
}
/* 360-414: the same rail with a little more air in it. */
@media (min-width: 360px) and (max-width: 560px) {
  .mast-nav { gap: 0.15rem; font-size: 0.76rem; letter-spacing: 0.05em; }
  .mast-nav a, .mast-nav .nav-plain { padding: 0.35rem 0.22rem; }
}

/* ---------------------------------------------------------------- hero */

main {
  width: 100%; max-width: 1080px; margin: 0 auto; padding: 0 1rem 3rem;
  box-sizing: border-box; flex: 1 0 auto;
}
/* The programme window already consumes the honest viewport remainder.
   Extra page padding below the cabinet creates a second, useless scrollbar
   beside the programme's intentional one. */
.serial-page main { padding-bottom: 0; }

.hero { padding: 2.4rem 0 1.6rem; max-width: 46rem; }

/* THE HOME PAGE'S HERO IS A STATION IDENT, NOT A CURTAIN.

   Round six: it was running a three-line headline, a four-line lede
   and a triptych of explanation before the set came into view, which
   put the dial — the entire argument of the page — below the fold on
   a laptop. The triptych went to the About page; what is left is an
   ident, one headline of at most two lines, and one sentence. About a
   third of the height it had, and the tuner clears the fold. */
.hero-home { padding: 1rem 0 0.55rem; max-width: 42rem; }
.hero-home .eyebrow { margin-bottom: 0.45rem; font-size: 0.82rem; }
.hero-home .hero-title {
  font-size: clamp(1.65rem, 6.6vw, 2.5rem); line-height: 1.08;
  margin-bottom: 0.3rem;
}
.hero-home .hero-lede { font-size: 0.98rem; margin: 0; max-width: 34rem; }

.eyebrow {
  font-family: var(--utility);
  letter-spacing: 0.3em;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--brass-lit);
  margin: 0 0 0.9rem;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}

.hero-title {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2.1rem, 10vw, 4.6rem);
  line-height: 1.04;
  color: var(--ivory);
  text-shadow: 0 0 40px rgba(245, 169, 60, 0.22), 0 2px 0 rgba(0, 0, 0, 0.6);
}

.hero-lede { color: var(--ivory); max-width: 40rem; font-size: 1.05rem; }

/* =====================================================================
   THE GENRE TUNER

   The home page's dial is not a widget beside the radio — it is the
   radio's tuning section. It shares the apparatus's case, panel,
   rivets, tubes, engraved nameplate and glass by sharing its
   SELECTORS, so the two can never drift apart. Only the thing behind
   the glass differs: a band instead of a programme.
   ===================================================================== */

.tuner { margin: 1.1rem 0 1rem; }
.tuner-glass { padding: 0.5rem 0.9rem 0.4rem; }

.dial-band {
  position: relative;
  /* TWO TIERS OF ENGRAVING. Neighbouring carriers alternate between a
     short stem (name just under the scale) and a long one (name a rank
     lower), which is how a crowded band gets printed on a real set —
     and why nothing here has to hide to fit.

     Every offset below is measured FROM THE TOP OF THE BAND, because
     a station is no longer a small box parked at its tier: since round
     six it is a full-height column (see `.station`), and the stem, pip
     and name are placed inside it in band coordinates.

       --scale   where the scale line falls (bottom of the tick strip)
       --pip-a / --pip-b    top of a short / long stem's pip
       --name-a / --name-b  top of a short / long stem's engraving
       --hit     one carrier's share of the scale, set inline by the
                 server from the number of positions on the band  */
  --scale: 34px;
  --pip-a: 40px;
  --pip-b: 80px;
  --name-a: 57px;
  --name-b: 97px;
  --hit: 44px;
  height: 118px;
  /* A hair of margin so the outermost columns keep the glass's rounded
     corners clear. Carriers no longer sit hard against either end:
     every one is at the CENTRE of its equal share (app.py). */
  margin: 0 0.35rem;
  cursor: grab;
  touch-action: pan-y; /* horizontal drags tune; vertical still scrolls */
  user-select: none;
  -webkit-user-select: none;
  z-index: 1;
}
.dial-band.is-tuning { cursor: grabbing; }
.dial-band.is-tuning .station { pointer-events: none; }

.dial-ticks {
  position: absolute; inset: 0 0 auto 0; height: 34px;
  border-bottom: 1px solid var(--brass-dark);
}
.tick {
  position: absolute; bottom: 0; width: 1px; height: 9px;
  background: var(--brass-dark);
}
.tick-major { height: 17px; background: var(--brass); }
.tick-major i {
  position: absolute; bottom: 20px; left: 50%;
  transform: translateX(-50%);
  font-family: var(--utility); font-style: normal; font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.06em; color: var(--brass-lit);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9);
}
/* Eleven numerals across a phone is a smear: only the round hundreds
   are engraved until the set is wide enough for the rest. */
.tick-wide { display: none; }

/* A carrier: THE WHOLE VERTICAL COLUMN of its share of the scale.
   Round five made this a 44px square around the pip, which meant
   selecting a band was a game of hitting a 13px dot or a 9pt word.
   Now the target runs the full height of the band at that carrier's
   x-position and is exactly `--hit` wide — one slot, centred — so the
   columns TILE the scale: no gaps, and no overlap to make a click
   ambiguous. The boundary between two carriers is the midpoint
   between them, which is also where drag-to-tune switches allegiance.

   `--hit` is capped so a band with only two or three positions gets a
   generous column rather than an absurd one. Everything inside stays
   positioned in band coordinates, so a long name can still overhang
   the column without stealing its neighbour's touch area. */
.station {
  position: absolute; top: 0; bottom: 0;
  width: min(var(--hit), 108px);
  transform: translateX(-50%);
  touch-action: pan-y;
}
/* A column has to be legible as a target the moment you reach for it:
   a soft lamp-wash up the glass under the pointer, the focus ring, or
   the tuned carrier. Never a click target itself. */
.station::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  /* An oval of lamplight, not a lit rectangle: a hard-edged block
     would read as a UI element sitting on the glass rather than as
     the set's own light falling on the scale. */
  background: radial-gradient(66% 44% at 50% 62%,
    rgba(245, 169, 60, 0.19) 0%, rgba(245, 169, 60, 0.07) 52%,
    rgba(245, 169, 60, 0) 78%);
  opacity: 0; transition: opacity 0.18s ease;
}
.station:hover::before, .station:focus-visible::before { opacity: 1; }
.station.is-tuned::before { opacity: 0.62; }
.station-fav::before {
  background: radial-gradient(66% 44% at 50% 62%,
    rgba(124, 192, 173, 0.2) 0%, rgba(124, 192, 173, 0.07) 52%,
    rgba(124, 192, 173, 0) 78%);
}
/* The ring is drawn inside the column: the glass clips anything that
   floats off its edge. */
.station:focus-visible { outline: 2px solid var(--filament);
  outline-offset: -2px; border-radius: 3px; }

/* The leader line from the scale down to the pip. On tier A it is a
   stub; on tier B it reaches down a whole rank, which is what tells
   you which name belongs to which carrier. */
.station-stem {
  position: absolute; left: 50%; width: 1px; margin-left: -0.5px;
  top: var(--scale);
  background: linear-gradient(180deg, var(--brass), var(--brass-dark));
  pointer-events: none;
}
.station-tier-a .station-stem { height: calc(var(--pip-a) - var(--scale)); }
.station-tier-b .station-stem { height: calc(var(--pip-b) - var(--scale)); }

.station-pip {
  position: absolute; left: 50%; transform: translateX(-50%);
  width: 13px; height: 13px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #7d6535, #3a2c14);
  border: 1px solid var(--brass);
  box-shadow: var(--recess);
  pointer-events: none;
}
.station-tier-a .station-pip { top: var(--pip-a); }
.station-tier-b .station-pip { top: var(--pip-b); }

.station-name {
  position: absolute; left: 50%; transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--utility); font-size: 0.66rem; font-weight: 600;
  letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--ivory);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.95), 0 0 4px rgba(0, 0, 0, 0.9);
  line-height: 1.1;
  pointer-events: none;
}
.station-tier-a .station-name { top: var(--name-a); }
.station-tier-b .station-name { top: var(--name-b); }

.station.status-on_air .station-pip {
  background: radial-gradient(circle at 35% 30%, var(--filament), var(--amber));
  box-shadow: 0 0 12px 3px rgba(245, 169, 60, 0.75);
}
/* The listener's own frequency is verdigris, not brass: it is the one
   position on the band that isn't the station's. */
.station-fav .station-pip {
  background: radial-gradient(circle at 35% 30%, var(--verdigris-lit),
    #23473f);
  border-color: var(--verdigris-lit);
}
.station-fav.is-tuned .station-pip {
  box-shadow: 0 0 12px 3px rgba(124, 192, 173, 0.6);
}
/* The tuned carrier wears the brass collar the current chapter wears
   in the cabinet window. */
.station.is-tuned .station-pip {
  outline: 2px solid var(--brass-lit); outline-offset: 2px;
}
.station:hover .station-name, .station:focus-visible .station-name {
  color: var(--filament);
}
.station.is-tuned .station-name {
  color: var(--filament);
  text-shadow: 0 0 12px rgba(245, 169, 60, 0.55), 0 1px 2px rgba(0, 0, 0, 0.9);
}
.station-fav.is-tuned .station-name {
  color: var(--verdigris-lit);
  text-shadow: 0 0 12px rgba(124, 192, 173, 0.5), 0 1px 2px rgba(0, 0, 0, 0.9);
}

.dial-band.is-tuning .dial-needle { transition: none; }
.dial-needle {
  position: absolute; top: 0; bottom: 10px; width: 2px; left: 0;
  background: linear-gradient(180deg, var(--filament), var(--oxblood-lit));
  box-shadow: 0 0 14px 2px rgba(187, 77, 63, 0.9);
  transition: left 1.1s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

.dial-caption {
  margin: 0.15rem 0 0;
  font-family: var(--utility);
  letter-spacing: 0.14em; font-size: 0.8rem; font-weight: 500;
  color: #e9d7ab;
  text-align: center; text-transform: uppercase;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.85);
  position: relative; z-index: 1;
}
.dial-caption a { color: var(--filament); text-decoration: underline; }

/* ----------------------------------------------------------- the bill

   (Round five retired the home page's "tonight's programme" bill and
   its running order — a second front page left over from before the
   apparatus. The bill's type survives here because the SERIAL page
   still uses it.) */

.stage-cover { position: relative; align-self: start; }
.stage-cover img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--brass-dark);
  border-radius: 2px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.6);
}
.bill-byline {
  font-family: var(--utility); letter-spacing: 0.16em;
  text-transform: uppercase; font-size: 0.88rem; color: var(--brass);
  margin-top: 0;
}
.bill-desc { color: var(--ivory); max-width: 44rem; font-size: 1rem; }
.bill-config {
  font-style: italic; color: var(--ivory-dim); font-size: 0.92rem;
}

/* ------------------------------------------------------- the programme

   The listener's own shelves. Every row is a link into the apparatus
   on the serial page (?ep=N), never a player of its own. Built like
   the cabinet window's chapter rows so the whole station reads as one
   piece of joinery. */

.programme {
  width: 100%; border-collapse: collapse; margin-top: 0.9rem;
  border-radius: var(--r-glass); overflow: hidden;
  border: 1px solid #241708;
  background: linear-gradient(180deg, #0d0805 0%, #1b1109 60%, #100a06 100%);
}
.programme tr { border-bottom: 1px solid rgba(217, 185, 120, 0.16); }
.programme tr:last-child { border-bottom: none; }
.programme td { padding: 0.7rem 0.55rem; vertical-align: middle; }
.prog-no {
  font-family: var(--utility); font-size: 1.05rem; font-weight: 600;
  color: var(--brass-lit);
  letter-spacing: 0.08em; white-space: nowrap;
}
.prog-title { font-size: 1.05rem; color: var(--ivory); display: block; }
/* The title is the row's affordance, so it takes the row's height. */
a.prog-title { font-family: var(--display); padding: 0.35rem 0; }
a.prog-title:hover { color: var(--filament); }
.prog-teaser {
  display: block; font-style: italic; color: #e6d5b0;
  font-size: 0.92rem;
}
.prog-len {
  font-family: var(--utility); color: #ecdcb8; font-weight: 500;
  letter-spacing: 0.08em; white-space: nowrap; text-align: right;
}

/* -------------------------------------------------------------- buttons */

/* A chip is a small unlit key: recessed brass-edged slot, lit
   lettering. The apparatus's keys are the lit ones; these are the
   secondary controls on the same panel. */
.chip-button {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--utility); letter-spacing: 0.13em; font-weight: 500;
  text-transform: uppercase; font-size: 0.9rem;
  color: var(--ivory);
  background: linear-gradient(180deg, #33240f, #1c1209);
  border: 1px solid var(--edge-dark); border-radius: var(--r-key);
  padding: 0.5rem 0.9rem; cursor: pointer; min-height: 44px;
  box-shadow: var(--recess), var(--lip);
}
.chip-button:hover {
  color: var(--filament); border-color: var(--brass-dark);
  box-shadow: var(--recess), var(--lamp);
}
.chip-button:active { transform: translateY(1px); }

.like-button {
  background: linear-gradient(180deg, #33240f, #1c1209);
  border: 1px solid var(--edge-dark); border-radius: var(--r-key);
  color: var(--brass); cursor: pointer;
  min-width: 40px; min-height: 40px; font-size: 1rem;
  box-shadow: var(--recess);
}
.like-button.liked, .like-button:hover {
  color: #ff9a86; border-color: var(--oxblood-lit);
  text-shadow: 0 0 10px rgba(187, 77, 63, 0.7);
}

/* The marquee key: the biggest lit control the station has. Utility
   gothic like every other control on the set — the display face is
   for titles, not for keys. */
.marquee-button {
  font-family: var(--utility); font-weight: 600; font-size: 1.05rem;
  text-transform: uppercase; letter-spacing: 0.16em;
  color: #2b1c10;
  background: linear-gradient(180deg, var(--filament), var(--amber) 40%,
    var(--copper) 100%);
  border: 1px solid var(--brass); border-radius: var(--r-key);
  padding: 0.8rem 1.6rem; cursor: pointer; min-height: 48px;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.45);
  box-shadow: 0 4px 0 #6b3b16, 0 8px 18px rgba(0, 0, 0, 0.5),
    inset 0 1px 0 rgba(255, 246, 220, 0.85);
}
.marquee-button:hover { filter: brightness(1.08); }
.marquee-button:active { transform: translateY(2px); box-shadow: 0 2px 0 #6b3b16; }

/* ------------------------------------------------------------------ how */

/* FROM PAGE TO AIR. The triptych lives on the ABOUT page since round
   six — on the home page it stood between a listener and the dial
   they came to turn. Here it is the visual answer to "how does this
   work", ahead of the prose that gives the detail. */
.how { margin: 1.7rem 0 1.3rem; }
.how-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }
/* Three brass-topped plates screwed to the walnut. */
.how-step {
  position: relative;
  border: 1px solid var(--edge-dark); border-top: 2px solid var(--brass);
  border-radius: var(--r-key);
  padding: 1rem 1rem 0.9rem;
  background: linear-gradient(180deg, rgba(217, 185, 120, 0.08),
    rgba(0, 0, 0, 0.2));
  box-shadow: var(--lip), var(--lift-low);
}
.how-step::before {
  content: ""; position: absolute; top: 6px; left: 6px;
  width: 8px; height: 8px; background-image: var(--rivet);
  background-size: 8px 8px;
}
.how-step::after {
  content: ""; position: absolute; top: 6px; right: 6px;
  width: 8px; height: 8px; background-image: var(--rivet);
  background-size: 8px 8px;
}
.how-step h3 {
  font-family: var(--utility); letter-spacing: 0.18em; font-weight: 600;
  text-transform: uppercase; font-size: 0.98rem; color: var(--filament);
  margin-top: 0.35rem;
}
.how-step p { color: var(--ivory); font-size: 1rem; margin-bottom: 0; }

/* ------------------------------------------------------------ catalogue */

/* A page's title plate: an engraved legend, the title, and the brass
   rule that separates it from the works below. */
.page-head { padding: 2rem 0 1rem; position: relative; }
.page-head h1 {
  font-family: var(--display); font-weight: 700; font-size: 1.9rem;
  margin-bottom: 0.55rem;
}
.page-head::after {
  content: ""; display: block; height: 2px; margin-top: 0.9rem;
  background: linear-gradient(90deg, var(--brass) 0%, var(--brass-dark) 42%,
    transparent 96%);
}

/* The genre rail is a row of machined tabs, not a line of links. */
.genre-rail {
  display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1rem;
  font-family: var(--utility); letter-spacing: 0.12em; font-weight: 500;
  text-transform: uppercase; font-size: 0.84rem;
}
.genre-rail a {
  color: var(--ivory); padding: 0.4rem 0.75rem; min-height: 40px;
  display: inline-flex; align-items: center;
  border: 1px solid var(--edge-dark); border-radius: var(--r-key);
  background: linear-gradient(180deg, #33240f, #1c1209);
  box-shadow: var(--recess);
}
.genre-rail a:hover {
  color: var(--filament); border-color: var(--brass-dark);
}
.genre-rail a.active {
  color: #221405; font-weight: 600;
  background: var(--brass-face);
  border-color: var(--edge-dark);
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.4);
  box-shadow:
    0 2px 0 var(--edge-dark), inset 0 1px 0 rgba(255, 245, 215, 0.8);
}

/* ------------------------------------------------- the programme guide

   The shelf of shows, shared by the home page (under the tuner) and
   the Shows page. Real book proportions, binding and page edges on a
   wooden table; the radio's brass stays on the radio. */

.guide { margin: 0.6rem 0 2rem; }
.guide-bezel {
  position: relative;
  padding: 1.9rem 12px 18px;
  border-radius: var(--r-panel);
  border: 1px solid #624329;
  background:
    radial-gradient(ellipse at 35% 10%, #c1853b24, transparent 75%),
    repeating-linear-gradient(2deg, #d5a46706 0 1px, transparent 1px 5px),
    repeating-linear-gradient(90deg, transparent 0 213px, #170d0755 214px 216px, #b8884330 217px, transparent 219px),
    linear-gradient(110deg, #382215, #54371f 48%, #322014);
  box-shadow: inset 0 1px 0 #b4885055, inset 0 -3px 0 #170e08aa, 0 10px 25px #0005;
}
.guide-legend {
  position: absolute; top: 0.38rem; left: 0; right: 0;
  text-align: center;
  font-family: var(--utility); font-size: 0.86rem; font-weight: 700;
  letter-spacing: 0.3em; text-indent: 0.3em;
  color: #f6e5bd;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.9);
}
/* The count rides in the bezel's right shoulder, like a meter reading. */
.guide-count {
  position: absolute; top: 0.42rem; right: 0.85rem;
  font-family: var(--utility); font-size: 0.74rem; font-weight: 600;
  letter-spacing: 0.14em; color: var(--ivory-dim);
  background: transparent;
  border: 0; border-radius: 0;
  padding: 0.02rem 0.4rem;
  display: none;                  /* the shoulder needs a wider set */
}
.guide-glass { padding: 0.7rem; }
.guide-empty {
  margin: 0.4rem 0.2rem; color: #ecdcb8; font-style: italic;
}
.guide-empty a { color: var(--filament); }

.cover-wall {
  display: grid; position: relative; isolation: isolate;
  padding: 18px 8px 8px;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 1.8rem 1.4rem;
}
.cover-wall-small {
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
/* The guide's book holds a link (the whole cover)
   and a star key side by side — nesting a button inside an anchor is
   invalid and unusable, so the two are siblings on one plate. The
   studio's shelf still uses a bare <a class="cover-card">, and both
   shapes take these rules. */
.cover-card {
  --book-angle: -0.5deg;
  --book-outline: polygon(0.3% 0.4%, 22% 0%, 23% 0.3%, 25% 0%,
    73% 0.2%, 98.8% 0%, 99.8% 0.8%, 100% 32%, 99.6% 33%,
    100% 35%, 99.8% 78%, 100% 98.8%, 99.2% 99.8%, 70% 100%,
    69% 99.6%, 67% 100%, 31% 99.8%, 1% 100%, 0% 99.1%,
    0.2% 65%, 0.5% 64%, 0% 62%, 0.1% 19%);
  display: block; position: relative;
  padding: 0; border: 0; border-radius: 2px 3px 3px 2px;
  isolation: isolate; overflow: visible;
  background: transparent;
  box-shadow: 4px 5px 4px -2px #0006, 9px 11px 9px -5px #0004;
  transform: rotate(var(--book-angle));
  transition: transform 0.25s ease, box-shadow 0.25s ease,
    border-color 0.25s ease;
}
.cover-card:nth-child(3n) { --book-angle: 0.7deg; }
.cover-card:nth-child(4n) { --book-angle: -0.9deg; }
.cover-card::before {
  /* Worn cover stock seen straight down, not a projecting page block. */
  content: ""; position: absolute; z-index: 2; inset: 0;
  pointer-events: none; clip-path: var(--book-outline);
  background:
    radial-gradient(ellipse 9px 2px at 23% 0%, #decba35c, transparent),
    radial-gradient(ellipse 2px 10px at 100% 33%, #decba352, transparent),
    radial-gradient(ellipse 11px 2px at 69% 100%, #decba366, transparent),
    radial-gradient(ellipse 2px 8px at 0% 64%, #decba34d, transparent),
    radial-gradient(circle 5px at 100% 100%, #decba366, transparent),
    radial-gradient(circle 4px at 0% 0%, #decba34d, transparent);
  box-shadow: inset 0 0 0 1px #c9b58c26;
}
.cover-plate { display: block; overflow: hidden; border-radius: 2px; clip-path: var(--book-outline); }
.cover-card > img { clip-path: var(--book-outline); }
.cover-plate::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 13px;
  background: linear-gradient(90deg, #0008, #0001 25%, #fff2 45%, #0005 65%, transparent);
  pointer-events: none;
}
.cover-card.is-off { position: absolute; pointer-events: none; }
.cover-card.is-off .cover-overlays { visibility: hidden; }
.cover-wall.is-empty .cover-card.is-off { visibility: hidden; }
.empty-stack {
  position: relative; pointer-events: none; transform: rotate(-0.5deg);
  box-shadow: 4px 5px 4px -2px #0006, 9px 11px 9px -5px #0004;
  border-radius: 2px 3px 3px 2px;
}
.empty-stack img {
  display: block; width: 100%; height: auto; aspect-ratio: 552 / 752;
  border-radius: inherit;
}
.cover-card img { width: 100%; height: auto; aspect-ratio: 552 / 752; display: block; border-radius: 2px; }
.cover-card:hover, .cover-card:focus-within,
.cover-card:focus-visible {
  transform: translateY(-3px) rotate(var(--book-angle));
  box-shadow: 6px 8px 6px -3px #0006, 12px 15px 12px -6px #0004;
}
.cover-plate:focus-visible { outline: 2px solid var(--filament); outline-offset: -3px; }
.cover-overlays {
  position: absolute; top: -8px; left: 5px; right: 5px;
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 2px; pointer-events: none;
  padding: 1px 2px 9px;
}
.cover-status { min-width: 0; padding: 10px 0 0 7px; }

/* Transient cover lift/hinge. Never contains controls or the audio element. */
.book-transition {
  position: fixed; inset: 0; z-index: 1000; overflow: hidden;
  pointer-events: none; contain: paint;
}
.book-opening {
  position: absolute; pointer-events: none;
  perspective: 1100px; transform-origin: center;
  background: linear-gradient(90deg, #8a7352, #efe0bd 5%, #e2cca1 96%, #9d8157);
  border: 1px solid #6a5030; border-radius: 2px 5px 5px 2px;
  box-shadow: 7px 14px 35px #0009;
}
.book-opening-cover {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transform-origin: left center;
}
.book-opening img {
  width: 100%; height: 100%; display: block; object-fit: fill;
  backface-visibility: hidden;
  box-shadow: 4px 0 10px #0006;
}
.book-opening-endpaper {
  position: absolute; inset: 0; backface-visibility: hidden;
  transform: rotateY(180deg);
  background: linear-gradient(90deg, #cbb58b, #e6d5ae 85%, #9b8058);
  border: 5px solid #463321; box-shadow: inset 0 0 15px #80643b55;
}

/* ------------------------------------------------------- the star key

   The station's one favorites affordance: on the bill of a serial and
   on every plate in the guide. A brass key like the transport's, 44px
   square; `aria-pressed` is the state and the mark fills with amber
   when it is set. */
.fav-key {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem; flex: none;
  min-width: 44px; min-height: 44px; padding: 0 0.5rem;
  border: 1px solid #5d4a25; border-radius: var(--r-key);
  background: var(--brass-face);
  color: #3a2a12; cursor: pointer;
  box-shadow: var(--key-lift);
}
.fav-key-capped { padding: 0 0.75rem; }
.fav-star {
  width: 22px; height: 22px; display: block; flex: none;
  fill: none;
  filter: drop-shadow(0 1px 0 rgba(255, 246, 216, 0.4));
  transition: fill 0.18s ease;
}
.fav-cap {
  font-family: var(--utility); font-size: 0.8rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: #221405; text-shadow: 0 1px 0 rgba(255, 246, 216, 0.4);
  padding-top: 2px;
}
.fav-key:hover { filter: brightness(1.07); }
.fav-key:active { transform: translateY(2px); box-shadow: 0 1px 0 #4b3a1c; }
.fav-key[aria-pressed="true"] { color: #6b3b16; }
.fav-key[aria-pressed="true"] .fav-star {
  fill: var(--amber);
  filter: drop-shadow(0 0 7px rgba(245, 169, 60, 0.85));
}

/* On a plate the key rides in the top-left corner, clear of the title
   lettering and easy to find in the same place on every poster. */
.stage-cover .fav-key {
  position: absolute; top: 4px; left: 4px; z-index: 2;
  min-width: 44px; min-height: 44px; padding: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, rgba(30, 20, 12, 0.86),
    rgba(12, 8, 5, 0.9));
  border: 1px solid rgba(217, 185, 120, 0.55);
  color: var(--brass-lit);
  box-shadow: 0 2px 7px rgba(0, 0, 0, 0.6);
}
.stage-cover .fav-key:hover { filter: none; color: var(--filament); }
.stage-cover .fav-key:active { transform: translateY(1px); }
.stage-cover .fav-key[aria-pressed="true"] {
  color: var(--amber); border-color: var(--amber);
}
.cover-card .fav-star, .stage-cover .fav-star { width: 20px; height: 20px; }
.cover-card .fav-key {
  --glyph-color: #fff1ca; --glyph-halo: #000b;
  position: relative; top: auto; left: auto; pointer-events: auto;
  width: 44px; height: 44px; min-width: 44px; padding: 0;
  border: 1px solid transparent; border-radius: 50%;
  background: transparent; box-shadow: none;
}
.cover-card .fav-key .fav-star { stroke-width: 1.8; filter: drop-shadow(0 1px 2px #000); }
.cover-card .fav-key:hover, .cover-card .fav-key:focus-visible {
  background: #1e160bbd; border-color: #efd7a58c; outline: none;
}
.cover-card .fav-key[aria-pressed="true"] {
  --glyph-color: #ffd783; --glyph-halo: #e4a44570;
  background: transparent; box-shadow: none; border-color: transparent;
}
/* On a small top-lettered painting, keep the full touch target off the art. */
.stage-cover.cover-lettered-top { padding-bottom: 48px; }
.stage-cover.cover-lettered-top .fav-key {
  top: auto; bottom: 0; left: calc(50% - 22px);
}
.cover-card-production {
  color: #f1dfbd; font-family: var(--utility); font-size: 0.66rem;
  letter-spacing: 0.1em; line-height: 1.2; display: block;
  text-shadow: 0 1px 3px #000, 0 0 5px #000;
}
.status-on_air { color: var(--amber); }
.status-in_production { color: var(--ivory-dim); }
.status-auditioning { color: var(--ivory-dim); font-style: italic; }
.status-inline.status-on_air { color: var(--oxblood-lit); }

/* ====================================================================
   THE SERIAL PAGE
   ==================================================================== */

/* The stage is the cabinet: bill, apparatus and the programme window
   under the glass. It has exactly ONE shape — nothing here condenses,
   folds away or restyles on scroll, because the chapter list scrolls
   inside its own window rather than moving the set. */
.stage {
  position: relative;                  /* the brass rule below hangs off it */
  margin: 0 -1rem; padding: 0.6rem 1rem 0.6rem;
  background:
    linear-gradient(180deg, var(--walnut-deep) 0%, #1a110c 88%,
      rgba(19, 12, 8, 0.97) 100%);
}
.stage::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--brass) 12%,
    var(--brass-lit) 50%, var(--brass) 88%, transparent);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.75);
}

.stage-bill {
  display: grid; grid-template-columns: 78px 1fr; gap: 0.8rem;
  align-items: start;
}
.stage-text { min-width: 0; }
.stage-text h1 {
  font-family: var(--display); font-weight: 700;
  font-size: 1.35rem; line-height: 1.12;
}
.stage .eyebrow {
  font-size: 0.84rem; letter-spacing: 0.14em; margin-bottom: 0.3rem;
}
.stage .bill-byline { font-size: 0.88rem; }
/* On a phone the abridgement line is the first thing to go: the
   programme below it is what the listener came for. */
.stage .bill-config { display: none; }
.stage .bill-byline { margin-bottom: 0.25rem; }
.stage h1 { margin-bottom: 0.2rem; }
.stage .bill-desc { margin: 0.2rem 0 0; }

/* Two lines is the whole budget: the cabinet below is what the
   listener came for. */
.stage-desc {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

.rating-readout {
  font-family: var(--utility); letter-spacing: 0.08em;
  color: var(--amber); font-size: 0.9rem;
}

/* ------------------------------------------------------- the share desk */

.share-desk { position: relative; }

.megaphone {
  display: inline-flex; align-items: center; gap: 0.5rem;
  min-height: 44px; padding: 0.5rem 0.75rem;
  border: 1px solid #5d4a25; border-radius: 6px; cursor: pointer;
  background: var(--brass-face);
  color: #1a0f04;
  font-family: var(--utility); letter-spacing: 0.12em; font-size: 0.95rem;
  font-weight: 700;
  box-shadow:
    0 3px 0 #4b3a1c, 0 6px 14px rgba(0, 0, 0, 0.5),
    inset 0 1px 0 rgba(255, 245, 215, 0.85);
}
.megaphone:hover {
  filter: brightness(1.07);
  box-shadow:
    0 3px 0 #4b3a1c, 0 6px 14px rgba(0, 0, 0, 0.5),
    0 0 18px rgba(245, 169, 60, 0.45),
    inset 0 1px 0 rgba(255, 245, 215, 0.9);
}
.megaphone:active { transform: translateY(2px); box-shadow: 0 1px 0 #4b3a1c; }
.megaphone-glyph { width: 23px; height: 20px; flex: none; }
.megaphone-cap { padding-top: 2px; }

/* Phone: a bottom sheet, thumb-high. Desk: a popover under the horn. */
.share-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
  padding: 1rem 1.1rem calc(1rem + env(safe-area-inset-bottom, 0px));
  border-top: 2px solid var(--brass);
  border-radius: 12px 12px 0 0;
  background:
    var(--etch),
    linear-gradient(180deg, var(--walnut-lit), #201510);
  box-shadow: 0 -16px 44px rgba(0, 0, 0, 0.75);
}
.share-eyebrow {
  font-family: var(--utility); letter-spacing: 0.28em; font-size: 0.74rem;
  color: var(--brass); margin: 0 0 0.7rem;
}
.share-copy {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  width: 100%; min-height: 48px; cursor: pointer;
  border: 1px solid var(--brass); border-radius: 5px;
  background: linear-gradient(180deg, var(--filament), var(--amber) 45%,
    var(--copper));
  color: #2b1c10;
  font-family: var(--utility); font-size: 1rem; letter-spacing: 0.16em;
  text-transform: uppercase;
  box-shadow: 0 3px 0 #6b3b16, 0 6px 14px rgba(0, 0, 0, 0.5);
}
.share-copy:hover { filter: brightness(1.07); }
.share-copy:active { transform: translateY(2px); box-shadow: 0 1px 0 #6b3b16; }
.share-said {
  min-height: 1.3em; margin: 0.45rem 0 0.7rem;
  font-size: 0.84rem; font-style: italic; color: var(--verdigris-lit);
  word-break: break-all;
}
.share-targets { display: grid; grid-template-columns: 1fr 1fr; gap: 0.45rem; }
.share-target {
  display: flex; align-items: center; gap: 0.5rem;
  min-height: 46px; padding: 0.4rem 0.6rem;
  border: 1px solid var(--brass-dark); border-radius: 4px;
  color: var(--ivory); font-size: 0.9rem;
}
.share-target:hover {
  color: var(--filament); border-color: var(--amber);
  background: rgba(245, 169, 60, 0.08);
}
.share-icon { width: 20px; height: 20px; flex: none; }

/* ------------------------------------------------ the wireless apparatus */

/* THE CASE and THE PANEL. The genre tuner on the home page is the same
   cabinet as the player here, so it shares these selectors outright —
   change one and both change, which is the point. */
.apparatus, .tuner-case {
  margin-top: 0.6rem;
  padding: 6px;
  border-radius: var(--r-case);
  background:
    repeating-linear-gradient(96deg,
      rgba(0, 0, 0, 0.16) 0 3px, transparent 3px 9px),
    linear-gradient(158deg, var(--mahogany), #2a1a10 62%, #3d2717);
  box-shadow:
    var(--lift),
    inset 0 0 0 1px rgba(217, 185, 120, 0.28);
}

.apparatus-panel, .tuner-panel {
  position: relative;
  display: grid; gap: 0.5rem;
  padding: 0.65rem 0.75rem 0.6rem;
  border: 1px solid var(--edge-lit); border-radius: var(--r-panel);
  background:
    var(--etch),
    linear-gradient(180deg, rgba(109, 89, 49, 0.9) 0%,
      rgba(82, 65, 35, 0.55) 26%, rgba(58, 47, 25, 0.95) 100%),
    linear-gradient(180deg, #5f4d2a, #2f2614);
  box-shadow: var(--lip), var(--floor);
}
.apparatus-panel::before, .tuner-panel::before {
  content: ""; position: absolute; inset: 5px; pointer-events: none;
  background-image: var(--rivet), var(--rivet), var(--rivet), var(--rivet);
  background-size: 8px 8px; background-repeat: no-repeat;
  background-position: left top, right top, left bottom, right bottom;
}

/* Three tubes, warm even on stand-by, alive on the air. */
.app-tubes {
  display: flex; gap: 0.5rem; justify-content: center;
}
.tube {
  --filament-level: 0.17;
  width: 14px; height: 26px; border-radius: 7px 7px 3px 3px;
  position: relative;
  background: linear-gradient(180deg,
    rgba(255, 226, 170, 0.30), rgba(255, 170, 60, 0.10) 58%,
    rgba(0, 0, 0, 0.4));
  border: 1px solid rgba(217, 185, 120, 0.5);
  box-shadow: inset 0 -7px 11px -5px var(--amber);
}
.tube::before {
  content: ""; position: absolute; inset: 4px 1px 3px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(ellipse, #f7a73570, transparent 75%);
  opacity: var(--filament-level);
  transition: opacity 0.6s ease;
}
.tube::after {
  content: ""; position: absolute; inset: 6px 2px 5px;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 24'%3E%3Cpath d='M4 23V5Q4 1 7 5L13 19Q16 23 16 19V1' fill='none' stroke='%23ffd489' stroke-width='1.2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
  filter: drop-shadow(0 0 2px #ffb442) drop-shadow(0 0 4px #ef8d2860);
  opacity: var(--filament-level);
  animation: filament 7.3s ease-in-out infinite;
}
/* Any live set warms its tubes — the player when it is running, the
   tuner when it is parked on a carrier that is on the air. */
.is-live .tube {
  --filament-level: 0.9;
}
.tube:nth-child(2)::after { animation-delay: -2.6s; }
.tube:nth-child(3)::after { animation-delay: -5.1s; }
/* A small, irregular filament flutter, never a full-screen flash. */
@keyframes filament {
  0%, 22%, 28%, 61%, 68%, 100% { opacity: var(--filament-level); }
  24%, 65% { opacity: calc(var(--filament-level) * 0.90); }
  48%, 86% { opacity: calc(var(--filament-level) * 0.96); }
}

/* The engraved nameplate. Brightest brass on the set, so the
   lettering is cut deep and dark: near-espresso on polished metal. */
.app-plate {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 0.5rem 0.7rem 0.55rem; border-radius: 4px; text-align: center;
  min-width: 0;
  background: linear-gradient(180deg, #e2cb99, #c2a469 52%, #9d8146);
  border: 1px solid #6d5730;
  box-shadow:
    inset 0 1px 0 rgba(255, 246, 216, 0.75),
    inset 0 -6px 12px rgba(0, 0, 0, 0.22),
    0 3px 8px rgba(0, 0, 0, 0.5);
}
.plate-eyebrow {
  font-family: var(--utility); font-size: 0.95rem; letter-spacing: 0.3em;
  font-weight: 700; line-height: 1.1;
  color: #221405;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.45);
}
.plate-title {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(1.3rem, 5.6vw, 1.62rem); line-height: 1.14;
  color: #170c02;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.55);
}
.plate-sub {
  font-size: 0.88rem; font-weight: 600; font-style: italic; color: #33200a;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
}

/* The position gauge: a VU face whose needle is also the seek bar. */
.app-meter { display: grid; gap: 0.5rem; justify-items: center; }
.meter-face {
  width: min(164px, 47vw); height: auto; display: block;
  filter: drop-shadow(0 3px 7px rgba(0, 0, 0, 0.55));
  transition: filter 0.4s ease;
}
/* The glass warms while the set is on the air. */
.apparatus.is-live .meter-face {
  filter: drop-shadow(0 3px 7px rgba(0, 0, 0, 0.55))
          drop-shadow(0 0 13px rgba(245, 169, 60, 0.5));
}
/* The face's engraved capitals take the sheet's utility gothic like
   every other label on the set. */
.meter-cap { font-family: var(--utility); fill: #c9a96a; }
/* The meter loop drives the needle every frame; a CSS transition
   would only smear it. */
.apparatus.is-metering #ap-needle { transition: none; }
.app-scale { width: 100%; }

/* A thumb-high trough: the track is a hairline of filament but the
   control itself is 44px of grab. */
.seek {
  --pct: 0%;
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; height: 44px; margin: 0;
  background: transparent; cursor: pointer;
}
.seek::-webkit-slider-runnable-track {
  height: 13px; border-radius: 7px;
  border: 1px solid #5d4a25;
  background:
    linear-gradient(90deg, var(--filament) 0 var(--pct),
      rgba(0, 0, 0, 0) var(--pct)),
    linear-gradient(180deg, #150e08, #33230f);
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.85),
    0 0 10px -3px var(--amber);
}
.seek::-moz-range-track {
  height: 13px; border-radius: 7px;
  border: 1px solid #5d4a25;
  background:
    linear-gradient(90deg, var(--filament) 0 var(--pct),
      rgba(0, 0, 0, 0) var(--pct)),
    linear-gradient(180deg, #150e08, #33230f);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.85);
}
.seek::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 24px; height: 24px; margin-top: -7px; border-radius: 50%;
  background:
    repeating-conic-gradient(from 0deg,
      rgba(0, 0, 0, 0.22) 0 6deg, transparent 6deg 18deg),
    radial-gradient(circle at 34% 30%, var(--brass-lit),
      var(--brass) 52%, #765d2c);
  border: 1px solid #4b3a1c;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.65);
}
.seek::-moz-range-thumb {
  width: 24px; height: 24px; border-radius: 50%; border: 1px solid #4b3a1c;
  background: radial-gradient(circle at 34% 30%, var(--brass-lit),
    var(--brass) 52%, #765d2c);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.65);
}
.seek:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px rgba(245, 169, 60, 0.75);
}
.seek:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 3px rgba(245, 169, 60, 0.75);
}

.app-times {
  display: flex; justify-content: space-between; align-items: center;
  gap: 0.5rem;
  font-family: var(--utility); font-size: 1.05rem; letter-spacing: 0.1em;
  font-weight: 600;
  color: #fff0cd;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}
.app-tag {
  font-family: var(--utility); font-size: 0.82rem; letter-spacing: 0.16em;
  font-weight: 600;
  color: #b6ecdc; border: 1px solid rgba(124, 192, 173, 0.6);
  background: rgba(79, 143, 128, 0.2);
  border-radius: 2px; padding: 0.1rem 0.45rem;
}

/* ------------------------------------------------- the ON AIR sign

   The studio lamp, bolted to the panel under the meter: brass bezel
   with its four rivets, a glazed face, and the legend cut into the
   glass. Cold and dark on stand-by — the lettering is the brown of
   unlit paint; the moment audio runs the filament warms, the glass
   takes an amber cast and the whole sign throws light onto the panel
   around it. `.apparatus.is-live` is the only switch.

   Both legends are stacked in one grid cell so the sign never changes
   width when it lights: only which of them is visible changes. */
.app-lamp { display: flex; justify-content: center; }

.on-air-lamp {
  position: relative;
  display: grid; place-items: center;
  min-width: 10.5rem; max-width: 100%; padding: 6px;
  border: 1px solid #5d4a25; border-radius: 7px;
  background: var(--brass-face);
  box-shadow:
    0 3px 0 var(--edge-dark), 0 5px 10px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(255, 245, 215, 0.8);
  transition: box-shadow 0.45s ease;
}
.on-air-lamp::before {
  content: ""; position: absolute; inset: 3px; pointer-events: none;
  background-image: var(--rivet), var(--rivet), var(--rivet), var(--rivet);
  background-size: 7px 7px; background-repeat: no-repeat;
  background-position: left top, right top, left bottom, right bottom;
}
.lamp-glass {
  --filament-level: 0.17;
  position: relative;
  display: grid; place-items: center;
  width: 100%; padding: 0.35rem 0.9rem 0.65rem;
  border: 1px solid #241708; border-radius: var(--r-glass);
  background:
    radial-gradient(120% 150% at 50% 130%, #3a2412 0%, #150d07 72%);
  box-shadow:
    inset 0 2px 7px rgba(0, 0, 0, 0.9),
    inset 0 -1px 0 rgba(255, 240, 200, 0.10);
  transition: background 0.45s ease, box-shadow 0.45s ease;
}
.lamp-word {
  grid-area: 1 / 1; white-space: nowrap;
  font-family: var(--utility); font-weight: 700; font-size: 0.92rem;
  letter-spacing: 0.34em; text-indent: 0.34em; line-height: 1.5;
  transition: opacity 0.35s ease;
}
/* Unlit paint on dark glass, cut rather than printed. */
.lamp-off {
  color: #ac8b55;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.9),
    0 0 5px #e19a3030;
}
.lamp-on {
  opacity: 0; color: var(--filament);
  text-shadow:
    0 0 9px rgba(245, 169, 60, 0.95), 0 0 26px rgba(245, 169, 60, 0.6),
    0 1px 0 rgba(0, 0, 0, 0.55);
}
.apparatus.is-live .lamp-off { opacity: 0; }
.apparatus.is-live .lamp-on {
  opacity: 1;
  animation: lamp-warm 0.9s ease-out 1, lamp-breathe 4.2s ease-in-out 0.9s infinite;
}
.apparatus.is-live .lamp-glass {
  --filament-level: 0.86;
  background:
    radial-gradient(120% 150% at 50% 132%, #a4611a 0%, #6a3d10 44%,
      #2e1c0a 82%);
  box-shadow:
    inset 0 2px 7px rgba(0, 0, 0, 0.55),
    inset 0 0 22px rgba(245, 169, 60, 0.5);
}
.apparatus.is-live .on-air-lamp {
  box-shadow:
    0 3px 0 var(--edge-dark), 0 5px 10px rgba(0, 0, 0, 0.55),
    0 0 22px rgba(245, 169, 60, 0.4),
    inset 0 1px 0 rgba(255, 245, 215, 0.85);
}
/* A tube takes a beat to come up to temperature, and a working lamp
   never sits perfectly still afterwards. */
@keyframes lamp-warm {
  0% { opacity: 0; filter: brightness(0.25) saturate(0.4); }
  55% { opacity: 1; filter: brightness(1.05); }
  100% { opacity: 1; filter: none; }
}
@keyframes lamp-breathe { 50% { opacity: 0.94; } }

/* Transport and speed share one bank of engraved, thumb-sized keys. */
.app-transport {
  display: grid; grid-template-columns: repeat(7, minmax(44px, 1fr)); gap: 5px;
}
.brass-key {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 2px;
  min-height: 56px; padding: 0.4rem 0.1rem;
  border: 1px solid #5d4a25; border-radius: 7px; cursor: pointer;
  background: var(--brass-face);
  color: #1a0f04;
  box-shadow:
    0 3px 0 #4b3a1c, 0 5px 9px rgba(0, 0, 0, 0.55),
    inset 0 1px 0 rgba(255, 245, 215, 0.8);
}
.brass-key:hover:not(:disabled) {
  filter: brightness(1.06);
  box-shadow:
    0 3px 0 #4b3a1c, 0 5px 9px rgba(0, 0, 0, 0.55),
    0 0 14px rgba(245, 169, 60, 0.4),
    inset 0 1px 0 rgba(255, 245, 215, 0.85);
}
.brass-key:active:not(:disabled) {
  transform: translateY(2px);
  box-shadow: 0 1px 0 #4b3a1c, inset 0 2px 6px rgba(0, 0, 0, 0.45);
}
.brass-key:disabled { opacity: 0.38; cursor: default; box-shadow: none; }
/* Captionless: the glyph IS the key. It gets the whole face. */
.key-glyph {
  font-size: clamp(1.75rem, 7.4vw, 2.25rem); line-height: 1;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.4);
}
.key-glyph-svg {
  width: 1em; height: 1em; display: block;
  filter: drop-shadow(0 1px 0 rgba(255, 246, 216, 0.4));
}
/* Every transport mark is a currentColor fill on the same grid, so
   the six keys carry one ink weight. */
.key-glyph-svg { fill: currentColor; }

/* Both marks sit in the play key's SVG from the start and exactly one
   shows. `.apparatus.is-live` is the ONLY switch — app.js derives it
   from `audio.paused` in one place and never rewrites the key's
   markup. No transition or animation on either group: a cross-fading
   swap is precisely what reads as a flicker. */
.glyph-play, .glyph-pause { transition: none; animation: none; }
.glyph-pause { display: none; }
.apparatus.is-live .glyph-play { display: none; }
.apparatus.is-live .glyph-pause { display: block; }

/* The switchboard: pressing lever. */
.app-switchboard {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.4rem; flex-wrap: nowrap;
  padding-top: 0.4rem;
  border-top: 1px solid rgba(0, 0, 0, 0.35);
  box-shadow: 0 -1px 0 rgba(255, 240, 200, 0.12);
}
.pressing { display: flex; align-items: center; gap: 0.3rem; min-width: 0; }
/* These ride on the dark lower panel, so they go LIGHT, not brown. */
.press-label {
  font-family: var(--utility); font-size: 0.8rem; letter-spacing: 0.06em;
  font-weight: 600; line-height: 1.1;
  color: #e4d1a4;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}
.press-label.is-on {
  color: var(--filament); text-shadow: 0 0 10px rgba(245, 169, 60, 0.6),
    0 1px 2px rgba(0, 0, 0, 0.8);
}
.brass-switch {
  position: relative; width: 58px; height: 44px; flex: none;
  background: none; border: none; padding: 0; cursor: pointer;
}
.brass-switch::before {
  content: ""; position: absolute; inset: 7px 0; border-radius: 15px;
  border: 1px solid #4b3a1c;
  background: linear-gradient(180deg, #1c1209, #3a2818);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.85);
}
.switch-lever {
  position: absolute; top: 9px; left: 29px; width: 26px; height: 26px;
  border-radius: 50%;
  background:
    repeating-conic-gradient(from 0deg,
      rgba(0, 0, 0, 0.18) 0 5deg, transparent 5deg 16deg),
    radial-gradient(circle at 35% 30%, var(--brass-lit),
      var(--brass) 50%, #765d2c);
  border: 1px solid #4b3a1c;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.7);
  transition: left 0.18s ease;
}
.brass-switch.is-rehearsal .switch-lever { left: 4px; }
.brass-switch:disabled { cursor: default; }
.brass-switch.is-locked { opacity: 0.78; }
.brass-switch.is-locked .switch-lever {
  filter: saturate(0.72);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.75);
}
.apparatus.is-rehearsal .app-plate {
  background: linear-gradient(180deg, #cfd9c6, #a9bdac 52%, #85998b);
}

/* ------------------------------------------- the cabinet window

   The programme is not a list on a page — it is the schedule seen
   through a glazed opening in the lower part of the cabinet. Brass
   bezel, rivets, glare across the top of the glass, and the list
   itself scrolling BEHIND it. The set never moves while you read. */

.cabinet-window { margin-top: 0.55rem; }

.window-bezel {
  position: relative;
  padding: 1.5rem 8px 8px;
  border-radius: 8px;
  border: 1px solid #7d6435;
  background:
    var(--etch),
    linear-gradient(180deg, #7a6435 0%, #4c3d20 42%, #6b5730 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 240, 200, 0.34),
    inset 0 -2px 7px rgba(0, 0, 0, 0.45),
    0 5px 14px rgba(0, 0, 0, 0.5);
}
.window-bezel::before {
  content: ""; position: absolute; inset: 6px; pointer-events: none;
  background-image: var(--rivet), var(--rivet), var(--rivet), var(--rivet);
  background-size: 8px 8px; background-repeat: no-repeat;
  background-position: left top, right top, left bottom, right bottom;
}
.window-legend {
  position: absolute; top: 0.36rem; left: 0; right: 0;
  text-align: center;
  font-family: var(--utility); font-size: 0.92rem; font-weight: 700;
  letter-spacing: 0.34em; text-indent: 0.34em;
  color: #f6e5bd;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.9);
}

/* The same pane glazes the programme in the cabinet window, the band
   in the tuner and the shelf in the programme guide. */
.window-glass, .tuner-glass {
  position: relative;
  border-radius: var(--r-glass);
  overflow: hidden;
  border: 1px solid #241708;
  background: linear-gradient(180deg, #0d0805 0%, #1b1109 60%, #100a06 100%);
}
/* The glaze: an inner shadow that puts the list behind the pane, and
   a bright hairline along the top edge where the glass catches the
   room. Overlay, never a click target. */
.window-glass::after, .tuner-glass::after {
  content: ""; position: absolute; inset: 0; z-index: 3;
  pointer-events: none; border-radius: var(--r-glass);
  box-shadow:
    inset 0 9px 20px -7px rgba(0, 0, 0, 0.95),
    inset 0 -9px 18px -7px rgba(0, 0, 0, 0.85),
    inset 0 1px 0 rgba(255, 240, 200, 0.16),
    inset 0 0 0 1px rgba(0, 0, 0, 0.55);
}
/* ...and the reflection lying across the upper pane. */
.window-glare {
  position: absolute; inset: 0 0 auto 0; height: 48%;
  z-index: 4; pointer-events: none;
  border-radius: 4px 4px 46% 14%;
  background: linear-gradient(166deg,
    rgba(255, 245, 216, 0.125) 0%,
    rgba(255, 245, 216, 0.055) 27%,
    rgba(255, 245, 216, 0.016) 49%,
    rgba(255, 245, 216, 0) 68%);
}

/* A tiny tab on the glass makes the cabinet's internal scroll plain
   on touch screens, where the brass scrollbar is normally hidden.
   Script withdraws it at the last chapter. */
.window-more {
  position: absolute; z-index: 5; left: 50%; bottom: 0.42rem;
  transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 0.38rem;
  min-height: 34px; padding: 0.28rem 0.7rem;
  border: 1px solid #8e743b; border-radius: 3px;
  background: linear-gradient(180deg, rgba(61, 45, 23, 0.97),
    rgba(24, 15, 8, 0.98));
  color: #f4dfb1; cursor: pointer;
  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.65),
    inset 0 1px 0 rgba(255, 239, 195, 0.18);
  font-family: var(--utility); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.16em; white-space: nowrap;
}
.window-more[hidden] { display: none; }
.window-more svg {
  width: 12px; height: 7px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.window-more:hover { color: var(--filament); border-color: var(--brass-lit); }
.window-more:focus-visible { outline-offset: 2px; }

.window-scroll {
  /* THE PART THAT GIVES. When the viewport gets shorter, the glass
     absorbs the loss and everything above it keeps its size —
     `--windowh` is measured from the space actually left below the
     cabinet chrome (app.js `fitWindow`), floored at the measured height of
     two complete chapter rows and capped by the measured whole programme,
     after which the page simply scrolls. The clamp is the pre-script
     and no-script fallback; dvh so mobile browser chrome can't lie. */
  height: var(--windowh, clamp(260px, 35dvh, 420px));
  min-height: 180px; /* no-script fallback; script measures two real rows */
  overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0.1rem 0.55rem 0.35rem;
  /* Firefox: a thin brass bar instead of the system one. */
  /* A brass thumb you can actually grab on a phone (operator, Sep 1
     2026: "the scrollbar thumb on the right is too skinny"). */
  scrollbar-width: auto;
  scrollbar-color: #a2833f rgba(0, 0, 0, 0.55);
}
.window-scroll:focus-visible { outline-offset: -3px; }
.window-scroll::-webkit-scrollbar { width: 36px; }
.window-scroll::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.55); border-radius: 5px; margin: 5px 0;
}
.window-scroll::-webkit-scrollbar-thumb {
  border-radius: 5px; border: 1px solid rgba(0, 0, 0, 0.6);
  background: linear-gradient(180deg, var(--brass-lit),
    var(--brass) 42%, #8a6f3c);
}
.window-scroll::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, #fff3d4, var(--brass-lit) 45%,
    var(--brass));
}

.programme-list { list-style: none; margin: 0; padding: 0; }

.chapter-row {
  position: relative;
  display: flex; align-items: stretch;
  border-bottom: 1px solid rgba(217, 185, 120, 0.16);
}
.chapter-row:first-child { border-top: none; }
.chapter-row:last-child { border-bottom: none; }
.chapter-progress {
  display: block; grid-column: 2 / -1; height: 7px; margin: 0.1rem 0 0.2rem;
  border: 1px solid #81643b; border-radius: 5px; pointer-events: none;
  background: linear-gradient(90deg, #c69b54 var(--chapter-progress, 0%), transparent var(--chapter-progress, 0%)),
    linear-gradient(#130d08, #382817);
  box-shadow: inset 0 1px 3px #000c, 0 1px 0 #efd7a326;
}

.chapter {
  flex: 1 1 auto; min-width: 0;
  display: grid; grid-template-columns: 14px 2.1rem 1fr auto;
  align-items: center; gap: 0.5rem;
  padding: 0.8rem 0.25rem;
  color: var(--ivory);
}
/* The whole row is the link; the aside rides above it. */
.chapter::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.chapter:hover { background: rgba(245, 169, 60, 0.06); }

.chapter-mark {
  width: 0; height: 0; justify-self: center;
  border-top: 6px solid transparent; border-bottom: 6px solid transparent;
  border-left: 9px solid var(--amber);
  filter: drop-shadow(0 0 6px rgba(245, 169, 60, 0.85));
  opacity: 0; transition: opacity 0.2s ease;
}
.chapter-no {
  font-family: var(--utility); font-size: 1.2rem; font-weight: 600;
  color: var(--brass-lit); letter-spacing: 0.08em;
}
.chapter-art { display: none; }
.chapter-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.chapter-title {
  font-family: var(--display); font-size: 1.08rem; font-weight: 600;
  line-height: 1.28;
}
.chapter-teaser {
  font-style: italic; color: #f0e3c6; font-size: 0.95rem;
  line-height: 1.38;
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; overflow: hidden;
}
.chapter-tags { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.chapter-tags:empty { display: none; }
.tag {
  font-family: var(--utility); font-size: 0.78rem; letter-spacing: 0.14em;
  font-weight: 600;
  text-transform: uppercase; padding: 0.08rem 0.45rem;
  border: 1px solid; border-radius: 2px; margin-top: 0.2rem;
}
.tag-rehearsal {
  color: #b6ecdc; border-color: rgba(124, 192, 173, 0.6);
  background: rgba(79, 143, 128, 0.2);
}
.tag-pending {
  color: #ecdcb8; border-color: var(--brass-dark);
  font-style: italic;
}
.chapter-len {
  font-family: var(--utility); color: #ecdcb8; font-weight: 600;
  letter-spacing: 0.06em; white-space: nowrap; font-size: 0.98rem;
}

.chapter-aside {
  position: relative; z-index: 2; flex: none;
  display: flex; align-items: center; gap: 0.25rem;
  padding-left: 0.3rem;
}

.chapter-row.is-current {
  background: linear-gradient(90deg, rgba(245, 169, 60, 0.17),
    rgba(245, 169, 60, 0.04) 55%, transparent);
}
.chapter-row.is-current::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, var(--brass-lit), var(--amber));
  box-shadow: 0 0 12px rgba(245, 169, 60, 0.7);
}
.is-current .chapter-mark { opacity: 1; }
.is-current .chapter-title {
  color: var(--filament);
  text-shadow: 0 0 14px rgba(245, 169, 60, 0.5), 0 1px 0 rgba(0, 0, 0, 0.8);
}
.is-current .chapter-no { color: var(--filament); }
.chapter-row.is-silent .chapter-title { color: #e3d2ae; }
.chapter-row.is-silent .chapter { cursor: default; }

.rating-desk { margin-top: 2rem; }
.rate-form {
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
}
.star-picker {
  border: none; padding: 0; margin: 0; display: inline-flex;
  flex-direction: row-reverse;
}
.star-picker input { position: absolute; opacity: 0; width: 1px; }
.star-picker label {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px;
  font-size: 1.7rem; color: #a2833f; cursor: pointer;
  line-height: 1;
}
.star-picker input:checked ~ label,
.star-picker label:hover,
.star-picker label:hover ~ label {
  color: var(--amber); text-shadow: 0 0 12px rgba(245, 169, 60, 0.5);
}
.star-picker input:focus-visible + label {
  outline: 2px solid var(--amber); outline-offset: 2px;
}

.notice {
  border: 1px solid var(--brass-dark); border-left: 4px solid var(--amber);
  border-radius: var(--r-key);
  padding: 0.8rem 1rem;
  color: var(--filament); font-style: italic; margin-top: 1.2rem;
  background: rgba(245, 169, 60, 0.09);
  box-shadow: var(--recess);
}

.empty-state { margin-top: 1.6rem; }

/* -------------------------------------------------------------- mailbag

   A brass drawer, shut by default: the serial page belongs to the
   cabinet, and the letters open only when someone asks. */

.mailbag-desk {
  margin-top: 1.4rem; max-width: 46rem;
  border: 1px solid var(--edge-lit); border-radius: var(--r-panel);
  background:
    var(--etch),
    linear-gradient(180deg, rgba(217, 185, 120, 0.10),
      rgba(0, 0, 0, 0.22));
  box-shadow: var(--lip), var(--lift-low);
}
.mailbag-summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.8rem; cursor: pointer;
  min-height: 48px; padding: 0.6rem 0.9rem;
  list-style: none;
}
.mailbag-summary::-webkit-details-marker { display: none; }
.mailbag-summary:hover { background: rgba(245, 169, 60, 0.07); }
.mailbag-summary:focus-visible { outline-offset: -3px; }
.mailbag-legend {
  font-family: var(--utility); font-size: 0.92rem; font-weight: 600;
  letter-spacing: 0.3em; color: var(--brass-lit);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}
.mailbag-count {
  display: flex; align-items: center; gap: 0.5rem;
  font-family: var(--utility); font-size: 0.86rem; font-weight: 600;
  letter-spacing: 0.08em; color: var(--ivory-dim); white-space: nowrap;
}
/* A brass pull that turns as the drawer opens. */
.mailbag-count::after {
  content: ""; width: 0; height: 0; flex: none;
  border-left: 6px solid transparent; border-right: 6px solid transparent;
  border-top: 7px solid var(--brass);
  transition: transform 0.2s ease;
}
.mailbag-desk[open] .mailbag-count::after { transform: rotate(180deg); }

.mailbag { padding: 0 0.9rem 1rem; max-width: 46rem; }
.letter { margin: 1rem 0; border-left: 4px solid var(--brass-dark); }
.letter-body { margin: 0 0 0.35rem; }
.letter-body a { display: inline-block; padding: 0.35rem 0.15rem; }
.letter-sig {
  margin: 0; font-family: var(--utility);
  letter-spacing: 0.1em; font-size: 0.9rem; color: #6d4a1c;
}
.letter-handle { color: #8a6a3c; }
.letter-form textarea { resize: vertical; }
.letter-form button { margin-top: 0.6rem; }
.empty-line { color: #e6d5b0; font-style: italic; font-size: 1rem; }

/* ------------------------------------------------------------ work order */

/* The work order is a run of panels bolted to the same case, with the
   fields recessed into them like the pressing switch's trough. */
.work-order { max-width: 46rem; }
.order-block {
  position: relative;
  border: 1px solid var(--edge-lit); border-radius: var(--r-panel);
  padding: 0.9rem 1rem 1.2rem;
  margin: 0 0 1.4rem;
  background:
    var(--etch),
    linear-gradient(180deg, rgba(217, 185, 120, 0.10),
      rgba(0, 0, 0, 0.22));
  box-shadow: var(--lip), var(--lift-low);
}
.order-block legend {
  font-family: var(--utility); letter-spacing: 0.22em; font-weight: 600;
  text-transform: uppercase; color: #221405;
  background: var(--brass-face);
  border: 1px solid var(--edge-dark); border-radius: 2px;
  padding: 0.15rem 0.7rem; font-size: 0.84rem;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.45);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
}
.order-field { margin-bottom: 1rem; }
.order-field label {
  display: block; font-family: var(--utility);
  letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500;
  font-size: 0.82rem; color: var(--brass-lit); margin-bottom: 0.35rem;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}
.order-field input[type="text"], .order-field input[type="password"],
.order-field select, .letter-form textarea {
  width: 100%; background: linear-gradient(180deg, #150e08, #241810);
  color: var(--ivory);
  border: 1px solid var(--edge-dark); border-radius: var(--r-key);
  padding: 0.7rem; min-height: 46px;
  font-family: var(--body); font-size: 1rem;
  box-shadow: var(--recess);
}
.order-field input:focus, .order-field select:focus,
.letter-form textarea:focus {
  border-color: var(--amber); outline: none;
  box-shadow: var(--recess), var(--lamp);
}
/* The file slot is a recessed trough with a brass key in it, like
   everything else that takes a press. */
.order-field input[type="file"] {
  color: var(--ivory); width: 100%;
  min-height: 46px; padding: 0.5rem;
  border: 1px solid var(--edge-dark); border-radius: var(--r-key);
  background: linear-gradient(180deg, #150e08, #241810);
  box-shadow: var(--recess);
}
.order-field input[type="file"]::file-selector-button {
  margin-right: 0.7rem; cursor: pointer;
  min-height: 34px; padding: 0.25rem 0.8rem;
  border: 1px solid var(--edge-dark); border-radius: var(--r-key);
  background: var(--brass-face); color: #221405;
  font-family: var(--utility); font-size: 0.84rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  text-shadow: 0 1px 0 rgba(255, 246, 216, 0.4);
  box-shadow: 0 2px 0 var(--edge-dark),
    inset 0 1px 0 rgba(255, 245, 215, 0.8);
}
.order-field input[type="file"]::file-selector-button:hover {
  filter: brightness(1.07);
}
.order-or {
  text-align: center; font-style: italic; color: #e0cda4;
  margin: 0.6rem 0 1rem;
}
.field-note { font-size: 0.95rem; color: #e6d5b0; font-style: italic; }

.order-choices { display: grid; grid-template-columns: 1fr; gap: 0.6rem; }
/* A selector plate: unlit until chosen, then it lights like a key. */
.choice-card {
  display: block; border: 1px solid var(--edge-dark);
  border-radius: var(--r-key);
  padding: 0.8rem 0.9rem; cursor: pointer; min-height: 44px;
  background: linear-gradient(180deg, #33240f, #1c1209);
  box-shadow: var(--recess);
}
.choice-card:hover { border-color: var(--brass-dark); }
.choice-card input { margin-right: 0.5rem; accent-color: var(--amber); }
.choice-card:has(input:checked) {
  border-color: var(--amber);
  background: linear-gradient(180deg, rgba(245, 169, 60, 0.16),
    rgba(0, 0, 0, 0.22));
  box-shadow: var(--recess), var(--lamp);
}
.choice-title {
  font-family: var(--utility); letter-spacing: 0.1em; font-weight: 500;
  text-transform: uppercase; color: var(--ivory);
}
.choice-card:has(input:checked) .choice-title { color: var(--filament); }
.choice-note {
  display: block; font-size: 0.88rem; color: #e6d5b0;
  margin-top: 0.3rem;
}

/* -------------------------------------------------------- studio & auth */

.studio-block { margin: 2rem 0; }
/* The studio's section legends are the same engraved plate the guide
   and the cabinet window wear. */
.studio-block > .eyebrow {
  border-bottom: 2px solid var(--brass-dark);
  padding-bottom: 0.4rem; margin-bottom: 0.2rem;
}

/* The listener's QSL card: the station's most formal panel. */
.qsl-card {
  max-width: 30rem; margin: 2.2rem auto;
  border: 1px solid var(--edge-lit);
  outline: 1px solid var(--brass-dark);
  outline-offset: 5px; border-radius: var(--r-case);
  padding: 1.5rem 1.3rem;
  position: relative;
  background:
    var(--etch),
    linear-gradient(160deg, var(--walnut-lit), var(--walnut));
  box-shadow: var(--lift), var(--lip);
}
.qsl-card::before {
  content: ""; position: absolute; inset: 7px; pointer-events: none;
  background-image: var(--rivet), var(--rivet), var(--rivet), var(--rivet);
  background-size: 8px 8px; background-repeat: no-repeat;
  background-position: left top, right top, left bottom, right bottom;
}
.qsl-card h1 {
  font-family: var(--display); font-weight: 700; font-size: 1.7rem;
}
.qsl-card .empty-line { color: var(--ivory); }
.auth-form { margin-top: 1.3rem; }
.auth-form .marquee-button { width: 100%; }
.form-error {
  color: #ffc9bd; border: 1px solid var(--oxblood-lit);
  border-left: 4px solid var(--oxblood-lit);
  border-radius: var(--r-key);
  padding: 0.6rem 0.9rem; font-style: italic;
  background: rgba(123, 47, 42, 0.3);
}

/* ------------------------------------------------------ the patch panel

   Third-party sign-in. A switchboard operator patched a caller in on
   somebody else's line; that is exactly what this is, so it is drawn
   as a row of patch cords rather than as a row of brand chips. NONE OF
   IT RENDERS unless the operator has configured that provider — see
   templates/_providers.html and docs/OIDC-SETUP.md. */

.patch-panel {
  margin-top: 1.6rem; padding-top: 1.2rem;
  border-top: 1px solid var(--brass-dark);
}
.patch-legend {
  font-family: var(--utility); font-size: 0.76rem; font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--brass); margin: 0 0 0.8rem; text-align: center;
}
.patch-keys { display: grid; gap: 0.55rem; }
.patch-key {
  display: flex; align-items: center; gap: 0.7rem;
  min-height: 48px; padding: 0.5rem 0.9rem;
  border: 1px solid var(--edge-dark); border-radius: var(--r-key);
  background: linear-gradient(180deg, #33240f, #1c1209);
  color: var(--ivory);
  box-shadow: var(--recess), var(--lip);
}
.patch-key:hover, .patch-key:focus-visible {
  color: var(--filament); border-color: var(--brass-dark);
  box-shadow: var(--recess), var(--lamp);
}
/* The plug: a brass jack tip in its socket. */
.patch-jack {
  width: 15px; height: 15px; border-radius: 50%; flex: none;
  background: radial-gradient(circle at 34% 30%, var(--brass-lit),
    var(--brass) 52%, #5f4a26);
  border: 1px solid #4b3a1c;
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.45),
    0 0 0 4px rgba(217, 185, 120, 0.3);
}
.patch-key:hover .patch-jack {
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.45),
    0 0 0 4px rgba(245, 169, 60, 0.55);
}
.patch-name {
  font-family: var(--utility); font-size: 0.94rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
}

/* The old native-audio bottom console is retired. The compact cabinet bar
   below controls the apparatus's same persistent audio, never a second player. */

.empty-line a, .guide-empty a {
  display: inline-block; padding: 0.4rem 0;
}

.prose { max-width: 44rem; padding: 1.4rem 1.3rem; }
.prose h2 {
  font-family: var(--utility); letter-spacing: 0.18em; font-weight: 600;
  text-transform: uppercase; font-size: 1.02rem;
  color: #6b2520; margin-top: 2rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid rgba(107, 37, 32, 0.35);
}
.prose h2:first-child { margin-top: 0; }
.prose li { margin-bottom: 0.6rem; }
.prose strong { color: #4a2a10; }

/* ------------------------------------------------------------ messages */

.unread-badge {
  display: inline-block; min-width: 1.2em; text-align: center;
  background: var(--oxblood-lit); color: var(--ivory);
  border-radius: 50%; font-size: 0.75rem; padding: 0.05em 0.3em;
  margin-left: 0.25em; vertical-align: super;
}
.letter-unread { border-left-color: var(--amber); }

/* NOTHING ON THE DIAL HIDES. Round four decluttered a crowded band by
   dropping colliding labels, which read as arbitrary — the fix is one
   word per band and two tiers of engraving (above), not fewer names.
   The tuned carrier rides on top so its lit name is never overprinted
   by a neighbour's. */
.station { z-index: 1; }
.station.is-tuned { z-index: 2; }
.station:hover, .station:focus { z-index: 3; }

/* Hero covers swap to the compact plate (no small print) on phones —
   at half scale, small print is just noise. The `img` qualifier is
   load-bearing: it has to outrank `.stage-cover img`. */
img.cover-when-full { display: none; }
img.cover-when-small { display: block; }

/* -------------------------------------------------- the pocket wireless

   A phone is not a narrow desk. Keep every part of the radio, but compose the
   controls as a portable set: meter and scale share a row; tubes and lamp
   share another. Touch targets stay at least 44px while ornamental air gives
   way to the programme. The desk composition begins again at 561px. */
@media (max-width: 560px) {
  .stage { padding-top: 0.45rem; }
  .stage-bill { grid-template-columns: 68px 1fr; gap: 0.65rem; }
  .stage .eyebrow {
    font-size: 0.72rem; letter-spacing: 0.1em; margin-bottom: 0.18rem;
  }
  .stage-text h1 { font-size: 1.24rem; }
  .stage .bill-byline { font-size: 0.76rem; letter-spacing: 0.12em; }
  .stage .bill-desc {
    font-size: 0.88rem; line-height: 1.3; -webkit-line-clamp: 1;
  }
  .apparatus { margin-top: 0.45rem; padding: 5px; }
  .apparatus-panel {
    grid-template-columns: minmax(92px, 0.72fr) minmax(150px, 1.28fr);
    grid-template-areas:
      "tubes lamp"
      "plate plate"
      "meter meter"
      "transport transport"
      "switches switches";
    gap: 0.38rem 0.65rem;
    padding: 0.5rem 0.62rem 0.48rem;
  }
  .apparatus-panel .app-tubes {
    grid-area: tubes; align-self: center; justify-self: center;
  }
  .apparatus-panel .app-lamp { grid-area: lamp; width: 100%; }
  .apparatus-panel .on-air-lamp {
    min-width: 0; width: 100%; padding: 4px;
  }
  .apparatus-panel .lamp-glass { padding: 0.18rem 0.35rem; }
  .apparatus-panel .lamp-word {
    font-size: 0.76rem; letter-spacing: 0.26em; text-indent: 0.26em;
  }
  .apparatus-panel .app-plate {
    grid-area: plate; padding: 0.38rem 0.6rem 0.42rem;
  }
  .apparatus-panel .plate-eyebrow { font-size: 0.82rem; }
  .apparatus-panel .plate-title {
    font-size: clamp(1.12rem, 5.2vw, 1.38rem);
  }
  .apparatus-panel .plate-sub { font-size: 0.76rem; }

  .apparatus-panel .app-meter {
    grid-area: meter;
    grid-template-columns: minmax(100px, 128px) minmax(0, 1fr);
    gap: 0.65rem; align-items: center; justify-items: stretch;
  }
  .apparatus-panel .meter-face {
    width: 100%; max-width: 128px; justify-self: center;
  }
  .apparatus-panel .app-scale { min-width: 0; }
  .apparatus-panel .seek { height: 44px; }
  .apparatus-panel .app-times { font-size: 0.9rem; }
  .apparatus-panel .app-tag {
    font-size: 0.68rem; letter-spacing: 0.08em; padding-inline: 0.25rem;
  }

  .apparatus-panel .app-transport { grid-area: transport; gap: 5px; }
  .apparatus-panel .brass-key { min-height: 48px; padding-block: 0.25rem; }
  .apparatus-panel .key-glyph { font-size: clamp(1.65rem, 7vw, 2rem); }
  .apparatus-panel .app-switchboard {
    grid-area: switches; padding-top: 0.12rem;
  }
  .apparatus-panel .press-label { font-size: 0.72rem; }

  .cabinet-window { margin-top: 0.42rem; }
  .window-bezel { padding-top: 1.38rem; }
  .chapter { padding-block: 0.62rem; }
  .chapter-title { font-size: 1.02rem; }
  .chapter-teaser { -webkit-line-clamp: 1; font-size: 0.9rem; }
}

/* ====================================================================
   ROOM TO BREATHE — tablets and desks
   ==================================================================== */

@media (min-width: 561px) {
  body { font-size: 18px; }
  main { padding: 0 1.5rem 3rem; }
  .masthead { padding: 0.9rem 1.2rem 0.85rem; gap: 1rem; }
  .wordmark-continental { font-size: 1.35rem; }
  .wordmark-radio { font-size: 0.9rem; letter-spacing: 0.6em; }
  .mast-nav { gap: 0.75rem; font-size: 0.9rem; letter-spacing: 0.11em; }
  .mast-nav .nav-key { font-size: 0.86rem; padding: 0 0.85rem; }
  .stage .eyebrow { letter-spacing: 0.26em; }
  .megaphone { letter-spacing: 0.2em; font-size: 1rem;
    padding: 0.5rem 0.95rem; }
  .meter-face { width: min(190px, 52vw); }

  .stage { margin: 0 -1.5rem; padding: 0.8rem 1.5rem 0.7rem; }
  .stage-bill { grid-template-columns: 108px 1fr; gap: 1.1rem; }
  .stage-text h1 { font-size: 1.7rem; }

  img.cover-when-full { display: block; }
  img.cover-when-small { display: none; }

  /* The room engraves bigger: the tiers spread and the names grow.
     The click columns grow on their own — they are a share of the
     scale, and the scale just got wider. */
  .station-name { font-size: 0.82rem; letter-spacing: 0.06em; }
  .tick-wide { display: block; }
  .dial-band {
    --pip-a: 42px; --pip-b: 92px;
    --name-a: 61px; --name-b: 111px;
    height: 140px; margin: 0 0.6rem;
  }
  .tuner-glass { padding: 0.7rem 1.1rem 0.5rem; }
  .dial-caption { font-size: 0.86rem; letter-spacing: 0.18em; }

  .guide-count { display: block; }
  .guide-glass { padding: 1rem; }
  .cover-wall { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }

  .hero { padding: 3.4rem 0 2rem; }
  .hero-home { padding: 1.3rem 0 0.7rem; }
  .hero-home .eyebrow { font-size: 0.86rem; }
  .hero-home .hero-lede { font-size: 1.02rem; }
  .page-head { padding: 3rem 0 1.5rem; }
  .page-head h1 { font-size: 2.4rem; }

  .stage .bill-config { display: block; }
  .chapter { grid-template-columns: 14px 2.4rem 46px 1fr auto; }
  .chapter-art {
    display: block; width: 46px; border: 1px solid var(--brass-dark);
    border-radius: 2px;
  }
  .chapter-title { font-size: 1.14rem; }
  .chapter-teaser { font-size: 1rem; -webkit-line-clamp: 2; }

  .window-scroll { height: var(--windowh, clamp(280px, 40dvh, 560px)); }
  .window-legend { font-size: 1rem; }
  .window-bezel { padding: 1.7rem 11px 11px; }

  .order-choices { grid-template-columns: repeat(2, 1fr); }
  .cover-wall-small {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }
  .qsl-card { padding: 2.2rem 2.4rem; margin: 3.4rem auto; }
  .how-grid { gap: 1.2rem; }

  .app-transport { gap: 8px; }
  .brass-key { min-height: 62px; }
  .key-glyph { font-size: 2.4rem; }
  .plate-eyebrow { font-size: 1.05rem; }
  .plate-title { font-size: 1.85rem; }
  .plate-sub { font-size: 0.95rem; }
  .app-times { font-size: 1.15rem; }
  .press-label { font-size: 0.92rem; letter-spacing: 0.1em; }

  .share-sheet {
    position: absolute; left: 0; right: auto; bottom: auto;
    top: calc(100% + 0.6rem);
    width: 21rem; max-width: 88vw;
    border: 1px solid var(--brass); border-radius: 6px;
    padding: 1rem 1.1rem 1.1rem;
    box-shadow: 0 20px 44px rgba(0, 0, 0, 0.7);
  }
  /* The rail's desk drops out of the MASTHEAD, not out of its word —
     the same joint the menu plate uses, and for the same reason:
     anchored to a word sitting mid-rail, a 21rem sheet runs off one
     end of a narrow desk or the other (it did: 52px of overflow at
     640px, 7px of clipped sheet at 561px). Going static hands the
     sheet to `.masthead`, which is the positioned ancestor. */
  .share-desk-mast { position: static; }
  .share-desk-mast .share-sheet {
    left: auto; right: 0.55rem; top: calc(100% + 7px);
    max-width: calc(100vw - 1.1rem);
  }
}

@media (min-width: 821px) {
  .how-grid { grid-template-columns: repeat(3, 1fr); gap: 2rem; }
  .hero-lede { font-size: 1.12rem; }

  .stage { padding: 0.9rem 1.5rem 0.8rem; }
  .stage-bill { grid-template-columns: 132px 1fr; gap: 1.5rem; }
  .stage-text h1 { font-size: 2.05rem; }
}

@media (min-width: 700px) {
  /* Portrait tablets have room for the same set as a desk. Keeping
     the gauge beside the scale leaves more chapters above the fold.
     The gauge takes the left
     bay with the ON AIR sign directly beneath it, and the seek scale
     gets the full width of the right one — a fifteen-minute chapter
     needs room to scrub. */
  .apparatus-panel {
    grid-template-columns: 216px 1fr;
    grid-template-areas:
      "tubes  plate"
      "meter  scale"
      "meter  transport"
      "lamp   switches";
    align-items: center;
    gap: 0.45rem 1.2rem;
    padding: 0.75rem 1.1rem;
  }
  /* Scoped to the PLAYER's panel: the tuner shares .app-tubes and
     .app-plate, and an unscoped `grid-area` here lands those parts in
     a grid that has no such areas — which pulls the tuner to pieces.
     (It did, on the first pass.) */
  .apparatus-panel .app-tubes { grid-area: tubes; }
  .apparatus-panel .app-plate { grid-area: plate; }
  .apparatus-panel .app-meter { display: contents; }
  .apparatus-panel .meter-face {
    grid-area: meter; justify-self: center; align-self: center;
    width: 100%; max-width: 216px;
  }
  .apparatus-panel .app-scale { grid-area: scale; }
  .apparatus-panel .app-transport { grid-area: transport; }
  .apparatus-panel .app-switchboard { grid-area: switches; }
  .apparatus-panel .app-lamp { grid-area: lamp; }
  .apparatus-panel .on-air-lamp { min-width: 0; width: 100%; }
  .plate-title { font-size: 2.05rem; }
  .plate-eyebrow { font-size: 1.1rem; }
  .tube { width: 17px; height: 32px; }
  .app-switchboard { border-top: none; box-shadow: none; padding-top: 0; }
}

@media (min-width: 821px) {
  /* On a desk the tuner spreads the same way the player does: the
     nameplate takes the left bay and the band gets the width it needs
     to be swept with a thumb or a mouse. */
  .tuner-panel {
    grid-template-columns: 216px 1fr;
    grid-template-areas:
      "tubes  glass"
      "plate  glass"
      "plate  caption";
    align-items: center;
    gap: 0.5rem 1.2rem;
    padding: 0.85rem 1.1rem;
  }
  .tuner-panel .app-tubes { grid-area: tubes; }
  .tuner-panel .app-plate { grid-area: plate; align-self: start; }
  .tuner-glass { grid-area: glass; }
  .tuner-panel .dial-caption {
    grid-area: caption; text-align: left; margin: 0;
  }
  .dial-band { --pip-b: 102px; --name-b: 121px; height: 152px; }
}

/* A real desk: the masthead spreads out. At every width below this
   the rail still has to hold its four words and the menu plate on one
   line — the type condenses, nothing folds away but ABOUT. */
@media (min-width: 1000px) {
  .masthead { padding: 1.1rem 2rem 1rem; gap: 1.6rem; }
  .wordmark-continental { font-size: 1.55rem; }
  .mast-nav { gap: 1.2rem; font-size: 1.02rem; }
}

/* Short screens and landscape phones, before the script measures:
   the window is already the thing that gives. */
@media (max-height: 620px) {
  .window-scroll { height: var(--windowh, clamp(140px, 30dvh, 300px)); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .dial-needle, .cover-card, .switch-lever,
  .meter-face, .mailbag-count::after, .fav-star,
  .station::before, .lamp-word, .lamp-glass, .on-air-lamp {
    transition: none;
  }
  .tube::after { animation: none; }
  /* The sign still lights — it just does not warm up or breathe. */
  .apparatus.is-live .lamp-on { animation: none; }
}

.release-badge {
  display: inline-flex; align-items: center; gap: 5px;
  margin: -4px 0 0 -9px; padding: 6px 16px 7px 12px;
  color: #fff0cc; background: linear-gradient(110deg, #70251f, #ba4936);
  font-family: var(--utility); font-size: 0.76rem; font-weight: 600;
  letter-spacing: 0.16em; line-height: 1.2;
  clip-path: polygon(0 0, 100% 0, calc(100% - 8px) 50%, 100% 100%, 0 100%);
  text-shadow: 0 1px 1px #43140d; pointer-events: none;
}
.cover-plate { position: relative; }
.app-transport, .stage-text, .app-scale { min-width: 0; }
/* Notch-safe landscape and a visible focus mark on dark brass. */
main {
  padding-left: max(1rem, env(safe-area-inset-left, 0px));
  padding-right: max(1rem, env(safe-area-inset-right, 0px));
}
@media (min-width: 561px) {
  main {
    padding-left: max(1.5rem, env(safe-area-inset-left, 0px));
    padding-right: max(1.5rem, env(safe-area-inset-right, 0px));
  }
}
:focus-visible { outline: 2px solid var(--filament); outline-offset: 3px; }

/* The salon's controls: softly worn brass, ink-cut icons, a quiet enamel
   accent. Decoration must never cost a tap target or a line of programme. */
.mast-nav { gap: 6px; }
.mast-nav .nav-key { border-radius: 8px; min-width: 44px; }
.nav-icon {
  width: 21px; height: 21px; flex: none; fill: none;
  stroke: currentColor; stroke-width: 2.3; stroke-linecap: round;
  stroke-linejoin: round;
}
.nav-caption { display: none; }
.mast-nav .share-sheet .share-target { white-space: normal; }
.speed-key .knob-read, .speed-key .knob-cap {
  font-family: var(--utility); font-weight: 600; line-height: 1.1;
  color: #281b0d; text-shadow: 0 1px 0 #fff4ce70;
}
.speed-key .knob-read { font-size: 1.1rem; }
.speed-key .knob-cap { font-size: 0.65rem; letter-spacing: 0.06em; }
/* Latched keys sink into their sockets; brass does not turn blue to mean on.
   Existing ARIA/audio state owns the effect, with no second JS state machine. */
.brass-key, .mast-nav .nav-key { position: relative; background: var(--brass-face); }
.brass-key[aria-pressed], .mast-nav .nav-key[aria-expanded], .fav-key {
  --filament-level: 0.15;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.lamp-glass::after {
  content: ""; position: absolute; pointer-events: none;
  width: 18px; height: 5px; left: calc(50% - 9px); bottom: 4px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 8'%3E%3Cpath d='M1 7L5 1L10 7L15 1L20 7L23 1' fill='none' stroke='%23ffd489' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  filter: drop-shadow(0 0 2px #ffb442) drop-shadow(0 0 5px #ef8d2860);
  opacity: var(--filament-level);
  animation: filament 7.3s ease-in-out infinite;
}
.brass-key[aria-pressed="true"],
.mast-nav .nav-key[aria-expanded="true"],
.fav-key[aria-pressed="true"] {
  --filament-level: 0.86;
  transform: translateY(2px);
  background: linear-gradient(180deg, #856333, #bd985b 35%, #d0ae70);
  border-color: #624823;
  box-shadow: inset 0 3px 6px #261706aa, inset 0 -1px 0 #ffe6ac55,
    0 1px 0 #e6c38460;
  filter: none;
}
.stage-cover .fav-key[aria-pressed="true"] {
  background: radial-gradient(circle at 50% 80%, #3f2813, #130d08);
}
@media (prefers-reduced-motion: reduce) {
  .brass-key[aria-pressed], .mast-nav .nav-key[aria-expanded], .fav-key,
  .tube::before { transition: none; }
  .lamp-glass::after { animation: none; }
}

/* Light belongs to the engraved glyph, not an extra lamp below the button. */
.brass-key, .mast-nav .nav-key, .fav-key { --glyph-color: #68421d; --glyph-halo: #efac4938; }
.brass-key .key-glyph, .mast-nav .nav-icon, .mast-nav .menu-rules,
.fav-key .fav-star, .speed-key .knob-read {
  color: var(--glyph-color);
  /* Pale bevels washed out small/outline marks despite identical ink colors. */
  filter: drop-shadow(0 1px 0 #2c180830) drop-shadow(0 0 2px var(--glyph-halo));
  text-shadow: none;
  animation: glyph-shimmer 7.3s ease-in-out infinite;
}
.brass-key[aria-pressed="true"], .mast-nav .nav-key[aria-expanded="true"],
.fav-key[aria-pressed="true"] { --glyph-color: #fff0c5; --glyph-halo: #ffbd60d0; }
.brass-key[aria-pressed="true"] .key-glyph,
.mast-nav .nav-key[aria-expanded="true"] svg,
.fav-key[aria-pressed="true"] .fav-star {
  filter: drop-shadow(0 1px 1px #41260c) drop-shadow(0 0 3px var(--glyph-halo));
}
.fav-key[aria-pressed="true"] .fav-star { fill: var(--glyph-color); }
@keyframes glyph-shimmer { 0%, 28%, 68%, 100% { opacity: 1; } 24%, 65% { opacity: .92; } }
.mini-player.is-live .glyph-play { display: none; }
.mini-player.is-live .glyph-pause { display: block; }
.mini-player {
  position: fixed; z-index: 40; bottom: 0; left: 0; right: 0;
  padding: 6px max(12px, env(safe-area-inset-right)) max(6px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  background: var(--etch), linear-gradient(#49371f, #251b10);
  border-top: 1px solid var(--brass); box-shadow: 0 -3px 12px #0008, inset 0 1px 0 #fbe2a530;
}
.mini-cabinet { max-width: 1100px; margin: auto; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 2px 12px; }
#mini-book { min-width: 0; color: var(--ivory); min-height: 48px; display: flex; align-items: center; gap: 10px; }
#mini-cover { flex: none; width: 36px; height: 48px; object-fit: cover; border: 1px solid var(--brass-dark); box-shadow: 0 2px 5px #000a; }
.mini-bill { display: flex; flex-direction: column; min-width: 0; }
.mini-open { color: var(--brass-lit); font-size: 1.1rem; margin-left: auto; }
.mini-transport { display: flex; gap: 5px; }
#mini-title, #mini-chapter { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
#mini-title { font-family: var(--display); font-size: .98rem; }
#mini-chapter { font-size: .75rem; color: var(--brass-lit); }
.mini-player .brass-key { width: 44px; min-height: 44px; flex: none; padding: 4px; }
.mini-player .key-glyph { font-size: 1.4rem; }
.mini-timeline { grid-column: 1 / -1; display: flex; align-items: center; gap: 9px; color: var(--brass-lit); font-family: var(--utility); font-size: .7rem; font-variant-numeric: tabular-nums; line-height: 18px; }
#mini-status { font-size: .65rem; letter-spacing: .12em; min-width: 4.5em; color: #c8ad78; }
.mini-player.is-live #mini-status { color: #ffe4a9; text-shadow: 0 0 5px #e9aa5b90; }
#mini-progress { --progress: 0%; height: 6px; flex: 1; overflow: hidden; border: 1px solid #82683b; border-radius: 4px; background: linear-gradient(#110d08, #302417); box-shadow: inset 0 2px 3px #000a, 0 1px 0 #efd39b20; }
#mini-progress > span { display: block; height: 100%; width: var(--progress); background: linear-gradient(#f4d994, #a77d3a); box-shadow: 1px 0 5px #f8d99b80; }
.has-mini-player main { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
@media (min-width: 760px) {
  .mini-cabinet { grid-template-columns: minmax(220px, 1fr) minmax(160px, .8fr) auto; column-gap: 24px; }
  .mini-timeline { grid-column: 2; grid-row: 1; flex-wrap: wrap; gap: 4px 9px; }
  #mini-status { flex-basis: 100%; }
  .mini-transport { grid-column: 3; grid-row: 1; }
  .has-mini-player main { padding-bottom: calc(80px + env(safe-area-inset-bottom)); }
}
@media (max-width: 359px) {
  .mini-player { padding-left: max(8px, env(safe-area-inset-left)); padding-right: max(8px, env(safe-area-inset-right)); }
  .mini-cabinet { column-gap: 6px; }
  #mini-book { gap: 6px; }
  #mini-cover { width: 30px; height: 40px; }
  .mini-open { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .brass-key .key-glyph, .mast-nav .nav-icon, .mast-nav .menu-rules,
  .fav-key .fav-star, .speed-key .knob-read { animation: none; }
}

/* The station's back rooms use the same cabinet joinery as its receiver.
   Long copy stays ink on parchment; headings are engraved brass plates. */
.page-head {
  margin: 1.4rem 0; padding: 1.3rem 1.4rem;
  border: 1px solid var(--brass-dark); border-radius: var(--r-panel);
  background: var(--brass-face); color: var(--ink);
  box-shadow: var(--lip), var(--lift-low);
}
.page-head h1 {
  color: #281b0d; font-size: clamp(1.75rem, 3.5vw, 2.65rem);
  text-shadow: 0 1px 0 #fff0cf80; overflow-wrap: anywhere;
}
.page-head .eyebrow { color: #624421; text-shadow: 0 1px 0 #fff0cf50; }
.page-head::after {
  position: absolute; inset: 5px; height: auto; margin: 0; pointer-events: none;
  background-image: var(--rivet), var(--rivet), var(--rivet), var(--rivet);
  background-size: 7px 7px; background-repeat: no-repeat;
  background-position: left top, right top, left bottom, right bottom;
}
.page-deck { margin: 0.3rem 0 0; color: #4d341b; font-style: italic; }
.about-page { max-width: 70rem; margin-inline: auto; }
.about-body { display: grid; grid-template-columns: minmax(0, 1fr) 15rem; gap: 1.4rem; align-items: start; }
.about-body .prose { grid-column: 1; grid-row: 1; max-width: none; padding: clamp(1.2rem, 3vw, 2rem); }
.about-body .prose h2 { scroll-margin-top: 1rem; }
.about-body .prose p, .about-body .prose ul { max-width: 65ch; }
.station-index {
  grid-column: 2; padding: 1rem; min-width: 0;
  border: 1px solid var(--brass-dark); border-radius: var(--r-panel);
  background: var(--etch), linear-gradient(160deg, #42311b, #20170f);
  box-shadow: var(--lip), var(--lift-low);
}
.station-index .eyebrow { margin: 0 0 0.5rem; font-size: 0.85rem; }
.station-index > a {
  display: flex; align-items: center; min-height: 44px;
  padding: 0.5rem 0; color: var(--ivory); border-bottom: 1px solid #b88f4b40;
}
.station-index > a:hover { color: var(--filament); }
.station-index > .marquee-button {
  justify-content: center; margin-top: 1rem; padding: 0.65rem;
  color: #281b0d; font-size: 0.9rem;
}
.station-index > .marquee-button:hover { color: #281b0d; }
.qsl-card h1 {
  padding: 0.7rem 0.85rem; background: var(--brass-face); color: #281b0d;
  border: 1px solid var(--brass-dark); border-radius: var(--r-key);
  text-shadow: 0 1px 0 #fff0cf80; box-shadow: var(--lip);
}
.genre-rail a { min-height: 44px; }
.genre-rail a.active { transform: translateY(1px); box-shadow: inset 0 2px 5px #26170680, 0 1px 0 #ffe6ac60; }
@media (max-width: 760px) {
  .page-head { padding: 1rem; margin-block: 1rem; }
  .about-body { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .about-body .prose { grid-row: 2; }
  .station-index { grid-column: 1; grid-row: 1; display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; }
  .station-index .eyebrow { width: 100%; }
  .station-index > .marquee-button { margin-top: 0; }
}
.guide-bezel { border-top-color: #b99a5e; }
.hero-home .hero-title { color: #f1dfb6; }
@media (min-width: 800px) {
  .nav-caption { display: inline; }
  .mast-nav .nav-key { padding-inline: 0.8rem; gap: 0.5rem; }
}
@media (max-width: 560px) {
  .masthead { padding: 0.6rem 0.65rem; gap: 0.4rem; }
  .mast-nav { gap: 4px; }
  .mast-nav .nav-key { padding-inline: 0; width: 44px; }
  .wordmark-continental { font-size: 1.1rem; }
  .wordmark-radio { font-size: 0.62rem; }
  .home-page .hero-home, .home-page .dial-caption,
  .home-page .plate-eyebrow, .home-page .plate-sub { display: none; }
  .home-page .tuner { margin-top: 0.65rem; }
  .home-page .tuner-panel .app-plate { margin-bottom: 0.5rem; }
  .apparatus-panel { padding-inline: 6px; }
  .apparatus-panel .app-transport { gap: 2px; }
  .stage-bill { grid-template-columns: 84px 1fr; }
}
/* Seven keys use two ranks on narrow phones without shrinking targets. */
@media (max-width: 389px) {
  .apparatus-panel .app-transport { grid-template-columns: repeat(4, 1fr); gap: 5px; }
  .apparatus-panel .speed-key { grid-column: span 2; }
  .masthead { flex-wrap: wrap; justify-content: center; }
  .mast-nav { margin-left: 0; }
}
@media (max-height: 500px) and (max-width: 950px) {
  .home-page .hero-home, .home-page .dial-caption,
  .home-page .plate-eyebrow, .home-page .plate-sub { display: none; }
  .home-page .tuner { margin-top: 0.65rem; }
}
