/* ── The other two routes ─────────────────────────────────────
   Not numbered alongside the player: the player is the offer, and
   these are what somebody reaches for when they would rather listen
   elsewhere or wants the files themselves. */
.offer {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding-top: var(--stack-sm);
  border-top: 1px solid var(--hairline);
}
.offer__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 26;
  font-size: clamp(1.25rem, 2.2vw, 1.625rem);
  line-height: 1.15;
}
.offer__link {
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 2px;
  transition: border-color var(--dur-fast) var(--ease-soft);
}
.offer__link:hover { border-color: var(--ink); }
.offer__note {
  max-width: 46ch;
  font-size: var(--fs-small);
  line-height: 1.7;
  color: var(--ink-dim);
}
.offer__note em { font-family: var(--font-display); font-style: italic; color: var(--ink); }
/* ══════════════════════════════════════════════════════════════
   ONE LUNAR DAY — site styles
   ══════════════════════════════════════════════════════════════ */

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

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

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 300;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, picture, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible {
  outline: 1px solid var(--signal);
  outline-offset: 4px;
}

/* A container given tabindex="-1" purely so focus can be handed to it —
   the skip link's destination, and where the label kit's intro leaves
   you — is not something anybody tabbed to, and ringing the entire page
   to say so is noise rather than an affordance. */
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible { outline: none; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* Hidden by being clipped to nothing rather than parked above the
   viewport. Parking it there worked until somebody rubber-banded the
   page downward past its own top edge, at which point a bright bar
   nobody asked for slid into view — the area above the document is
   still painted, so translating out of the page does not translate out
   of sight. Clipping has no such edge case. */
.skip {
  position: absolute; top: 0; left: 0; z-index: 999;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  background: var(--ink); color: var(--ground);
  font-size: var(--fs-caption); letter-spacing: var(--tr-caption);
  text-transform: uppercase;
}
.skip:focus {
  width: auto; height: auto;
  overflow: visible;
  clip-path: none;
  padding: 1rem 1.5rem;
}

/* ── shared type ─────────────────────────────────────────────
   Bodoni Moda is variable on two axes: weight (400-900) and opsz
   (optical size, 6-96). opsz sets stroke contrast — high values give
   the fine display hairlines, low values thicken them for text sizes.
   Every rule below sets opsz to roughly the size it actually renders
   at, and grades weight upward as size comes down. Light strokes on a
   black ground lose far more to anti-aliasing than dark-on-white does,
   so small type here needs more stroke than it would on paper.        */
.label {
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  text-transform: uppercase;
  color: var(--ink-dim);
}
.label--faint { color: var(--ink-faint); }

.lede {
  max-width: var(--measure);
  font-size: var(--fs-lead);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--ink-dim);
}

/* ── film grain ────────────────────────────────────────────
   The photographs carry heavy grain; flat black does not. This
   unifies them so ground and image read as one surface.          */
.grain {
  position: fixed;
  inset: -50%;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ══════════════════════════════════════════════════════════════
   NAVIGATION — absent on load, arrives after the cover
   ══════════════════════════════════════════════════════════════ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 1.25rem var(--gutter);
  background: linear-gradient(to bottom, rgb(5 5 5 / 0.92), rgb(5 5 5 / 0));
  opacity: 0;
  visibility: hidden;
  transition:
    opacity    var(--dur-slow) var(--ease),
    visibility 0s linear var(--dur-slow);
}
/* An open panel keeps the bar with it, whatever the observer thinks
   about where the page is scrolled to — the panel lives inside .nav,
   so a hidden bar would take the menu down with it. */
.nav[data-visible="true"],
[data-menu="open"] .nav {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

/* The slide-down lives on the contents, not on .nav itself. A
   transform makes its element the containing block for any fixed
   descendant, and the mobile menu below is a fixed descendant that
   needs the viewport — with the transform up here it would have sized
   itself to the height of the bar. */
.nav__bar {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  transform: translateY(-140%);
  transition: transform var(--dur-slow) var(--ease);
}
.nav[data-visible="true"] .nav__bar,
[data-menu="open"] .nav__bar { transform: none; }

.nav__mark {
  display: block;
  /* The logo's letterforms have strokes deliberately removed, so it needs
     real width to stay legible. Below ~180px it reads as noise. */
  width: clamp(180px, 19vw, 260px);
}
.nav__mark img { width: 100%; height: auto; }

.nav__links {
  display: flex;
  gap: clamp(1.25rem, 2.6vw, 2.75rem);
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-nav);
  text-transform: uppercase;
  color: var(--ink-dim);
}
.nav__links a { transition: color var(--dur-fast) var(--ease-soft); }
.nav__links a:hover { color: var(--ink); }

@media (min-width: 761px) {
  /* Wide enough for the links to ride the bar, so they slide with it. */
  .nav__links {
    transform: translateY(-140%);
    transition: transform var(--dur-mid) var(--ease);
  }
  .nav[data-visible="true"] .nav__links { transform: none; }
}

/* ── The bar's own control ─────────────────────────────────────
   A word and two hairlines. It shows only once js/main.js has
   confirmed it can open and close the panel, and only on the widths
   where the panel exists. */
.nav__toggle {
  display: none;
  align-items: center;
  gap: 0.7rem;
  /* 44px of tappable height, which is the smallest a thumb should be
     asked to find. */
  padding: 0.75rem 0;
  color: var(--ink-dim);
  transition: color var(--dur-fast) var(--ease-soft);
}
.nav__toggle-word {
  position: relative;
  display: grid;
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-nav);
  text-transform: uppercase;
}
/* Both words occupy the same cell, so the bar never changes width
   when one replaces the other. */
.nav__toggle-word > span {
  grid-area: 1 / 1;
  transition: opacity var(--dur-fast) var(--ease-soft);
}
.nav__toggle-word > [data-menu-word="close"] { opacity: 0; }
[data-menu="open"] .nav__toggle-word > [data-menu-word="open"] { opacity: 0; }
[data-menu="open"] .nav__toggle-word > [data-menu-word="close"] { opacity: 1; }

.nav__toggle-rules {
  display: grid;
  width: 22px;
  height: 9px;
}
.nav__toggle-rules i {
  grid-area: 1 / 1;
  width: 100%;
  height: 1px;
  background: currentColor;
  transition: transform var(--dur-mid) var(--ease);
}
.nav__toggle-rules i:first-child { transform: translateY(-4px); }
.nav__toggle-rules i:last-child  { transform: translateY(4px); }
[data-menu="open"] .nav__toggle-rules i:first-child { transform: rotate(45deg); }
[data-menu="open"] .nav__toggle-rules i:last-child  { transform: rotate(-45deg); }

@media (max-width: 760px) {
  .nav { padding-block: 1rem; }
  .nav__bar { flex: 1; justify-content: space-between; }
  .nav__mark { width: 150px; }
  .js-nav .nav__toggle { display: inline-flex; }

  /* ── The panel ──
     Full bleed, the links set as display type rather than as the
     ten-pixel row they used to be. */
  .js-nav .nav__links {
    position: fixed;
    inset: 0;
    z-index: 1;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0;
    padding: 0 var(--gutter);
    background: var(--ground);
    font-size: inherit;
    letter-spacing: normal;
    text-transform: none;
    opacity: 0;
    visibility: hidden;
    transition:
      opacity    var(--dur-mid) var(--ease),
      visibility 0s linear var(--dur-mid);
  }
  [data-menu="open"] .nav__links {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
  }

  .js-nav .nav__links a {
    font-family: var(--font-display);
    font-weight: 600;
    font-variation-settings: "opsz" 40;
    font-size: clamp(2rem, 9vw, 2.75rem);
    line-height: 1;
    letter-spacing: 0.004em;
    text-transform: none;
    color: var(--ink);
    padding-block: 0.42em;
    /* Each one arrives just after the one above it. */
    opacity: 0;
    transform: translateY(0.5rem);
    transition:
      opacity   var(--dur-mid) var(--ease),
      transform var(--dur-mid) var(--ease);
  }
  [data-menu="open"] .nav__links a { opacity: 1; transform: none; }
  [data-menu="open"] .nav__links a:nth-child(1) { transition-delay: 60ms; }
  [data-menu="open"] .nav__links a:nth-child(2) { transition-delay: 100ms; }
  [data-menu="open"] .nav__links a:nth-child(3) { transition-delay: 140ms; }
  [data-menu="open"] .nav__links a:nth-child(4) { transition-delay: 180ms; }
  [data-menu="open"] .nav__links a:nth-child(5) { transition-delay: 220ms; }
  [data-menu="open"] .nav__links a:nth-child(6) { transition-delay: 260ms; }
  [data-menu="open"] .nav__links a:nth-child(7) { transition-delay: 300ms; }
}

/* Nothing scrolls behind an open panel. */
[data-menu="open"] body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .nav__bar,
  .nav__links,
  .nav__links a,
  .nav__toggle-rules i { transition: none !important; }
  [data-menu="open"] .nav__links a { transition-delay: 0s !important; }
}

/* ══════════════════════════════════════════════════════════════
   COVER
   Split composition: type holds the left, photograph runs full-bleed
   to the right viewport edge. Below 900px the photograph moves behind
   the type under a scrim.
   ══════════════════════════════════════════════════════════════ */
.cover {
  position: relative;
  min-height: 100svh;
  display: grid;
  /* minmax(0, …) removes the min-content floor — without it the display
     type distorts both tracks and leaves dead space at the right. */
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: stretch;
  isolation: isolate;
}

.cover__type {
  position: relative;
  z-index: 2;
  display: flex;
  padding: clamp(1.75rem, 4vh, 3rem) 0 clamp(1.75rem, 4vh, 3rem) var(--gutter);
  padding-right: clamp(1rem, 3vw, 3rem);
}

/* The container query lives on a padding-free box, so 1cqi is exactly
   1% of the width the type can actually occupy. */
.cover__type-inner {
  container-type: inline-size;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
/* The eyebrow sits directly above the title, and the two float a
   little below the middle of the column; the release line keeps the
   foot. The auto margins centre the pair, the offset drops it. */
.cover__eyebrow { margin-top: auto; margin-bottom: 1.5rem; }
.cover__title { margin-bottom: auto; }
.cover__eyebrow, .cover__title { position: relative; top: 9vh; }

.cover__eyebrow { display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; }

.cover__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 80;
  /* Set from the type column, not the viewport: 11cqi keeps the sentence
     to four lines beside the photograph and clear of the foot at 100svh. */
  font-size: clamp(2rem, 11cqi, 6rem);
  line-height: 1.24;
  letter-spacing: 0.002em;
  max-width: 17ch;
  text-wrap: balance;
}
.cover__title em { font-style: italic; font-weight: 400; }

.cover__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 2rem;
}

.cover__release { display: flex; flex-direction: column; gap: 0.6rem; }
.cover__release-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 22;
  font-size: clamp(1.125rem, 1.9vw, 1.75rem);
  line-height: 1.2;
}

.cover__figure {
  position: relative;
  z-index: 1;
  overflow: hidden;
}
.cover__figure picture {
  display: block;
  width: 100%;
  height: 100%;
}
.cover__figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 28%;
  filter: grayscale(1) contrast(1.04);
}
/* Scrim element exists at all widths but only carries a gradient when the
   photograph sits behind the type. */
.cover__figure::after { content: ""; position: absolute; inset: 0; }

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

  .cover__type {
    grid-area: 1 / 1;
    padding-right: var(--gutter);
    min-height: 100svh;
  }

  .cover__figure { grid-area: 1 / 1; }
  .cover__figure img { object-position: 50% 22%; }

  /* Dark enough that the small labels clear WCAG AA over the bright
     upper part of the photograph. */
  .cover__figure::after {
    background: linear-gradient(to bottom,
      rgb(5 5 5 / 0.90) 0%,
      rgb(5 5 5 / 0.55) 38%,
      rgb(5 5 5 / 0.96) 100%);
  }

  /* The faintest grey is unreadable over photography. */
  .cover__eyebrow .label--faint { color: var(--ink-dim); }
}

/* ══════════════════════════════════════════════════════════════
   SCROLL REVEALS
   ══════════════════════════════════════════════════════════════ */
/* Hidden only once main.js has confirmed it is running and will reveal
   them again. If the script fails to load, nothing is ever hidden. */
.js-reveal .reveal:not([data-shown="true"]) {
  opacity: 0;
  transform: translateY(32px);
}
/* The cover's pace, so the page breathes the way its opening does.
   --stagger is set by js/main.js when several reveals enter together,
   so a row arrives one after another rather than as a block. */
.reveal {
  transition:
    opacity   var(--dur-cover) var(--ease) var(--stagger, 0ms),
    transform var(--dur-cover) var(--ease) var(--stagger, 0ms);
}
/* In a section head the small label follows the title by a beat. */
.js-reveal .section-head.reveal:not([data-shown="true"]) > .label {
  opacity: 0;
  transform: translateY(10px);
}
.section-head.reveal > .label {
  transition:
    opacity   var(--dur-cover) var(--ease) calc(var(--stagger, 0ms) + 220ms),
    transform var(--dur-cover) var(--ease) calc(var(--stagger, 0ms) + 220ms);
}

/* ── portraits settle as they enter ─────────────────────────────
   Each member photograph arrives slightly enlarged and eases to size,
   staggered across the row with the reveal. The animation only fills
   backwards, so once it has played the hover scale below takes over
   again without a fight. */
.js-reveal .member.reveal:not([data-shown="true"]) .member__figure img { transform: scale(1.06); }
.member.reveal[data-shown="true"] .member__figure img {
  animation: settle var(--dur-cover) var(--ease) var(--stagger, 0ms) backwards;
}

/* ── cover arrival sequence ────────────────────────────────────
   The type waits below the fold of its own box until the visitor has
   actually reached the cover — js/main.js sets data-arrived on the
   section the first time the prelude is fully dissolved — and then
   rises into place. Played at page load it would run unseen behind
   the held frame. */
.cover__type-inner > * {
  opacity: 0;
  transform: translateY(2.5rem);
}
.cover[data-arrived="true"] .cover__type-inner > * {
  animation: rise var(--dur-cover) var(--ease) forwards;
}
.cover[data-arrived="true"] .cover__eyebrow { animation-delay: 120ms; }
.cover[data-arrived="true"] .cover__title   { animation-delay: 280ms; }
.cover[data-arrived="true"] .cover__foot    { animation-delay: 600ms; }

/* The photograph waits slightly enlarged, so it is already at the
   animation's first frame while the held frame dissolves over it —
   starting the settle from a plain scale(1) made it jump outward the
   moment the type began to rise. */
.js-ready .cover__figure img { transform: scale(1.06); }
.cover[data-arrived="true"] .cover__figure img { animation: settle 2400ms var(--ease) forwards; }

@keyframes rise   { to   { opacity: 1; transform: none; } }
@keyframes settle { from { transform: scale(1.06); } to { transform: scale(1); } }

/* No JS: nothing stays hidden. */
.no-js .cover__type-inner > *,
.no-js .reveal { opacity: 1; transform: none; }
.no-js .cover__figure img { transform: none; }

/* ══════════════════════════════════════════════════════════════
   REDUCED MOTION — everything arrives, nothing moves.
   ══════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .cover__type-inner > *,
  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }

  .cover__figure img { transform: none !important; }
  .member__quote { transform: none !important; }
}

/* ══════════════════════════════════════════════════════════════
   SHARED SECTION FURNITURE
   ══════════════════════════════════════════════════════════════ */
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  padding-bottom: var(--stack-sm);
  border-bottom: 1px solid var(--hairline);
  margin-bottom: var(--stack-lg);
}
.section-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 56;
  font-size: var(--fs-title);
  line-height: 1.05;
  letter-spacing: 0.004em;
}

.inline-link {
  color: var(--ink);
  border-bottom: 1px solid var(--hairline);
  transition: border-color var(--dur-fast) var(--ease-soft);
}
.inline-link:hover { border-color: var(--ink); }

.linklist { list-style: none; display: flex; flex-wrap: wrap; gap: 0.6rem 2rem; }
.linklist a {
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-nav);
  text-transform: uppercase;
  color: var(--ink-dim);
  padding-block: 0.35rem;
  border-bottom: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft);
}
.linklist a:hover { color: var(--ink); border-bottom-color: var(--hairline); }

.btn {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  padding: 1rem 2rem;
  border: 1px solid var(--hairline);
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  text-transform: uppercase;
  color: var(--ink);
  transition: background-color var(--dur-fast) var(--ease-soft),
              color            var(--dur-fast) var(--ease-soft),
              border-color     var(--dur-fast) var(--ease-soft);
}
.btn:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ground);
}

/* ══════════════════════════════════════════════════════════════
   PRELUDE
   The first screen. One frame — artwork, mark, one line — held for a
   viewport and then dissolved into the cover.

   The stage is sticky, not fixed, and that is the whole reason this
   degrades. Sticky needs no script: it pins while .prelude is in view
   and leaves with it, so a visitor without JavaScript gets a hero that
   holds for one screen and then scrolls away. The cross-dissolve is
   the enhancement — js/main.js drives --prelude-out from 0 to 1 across
   that same screen, and everything below reads from it.
   ══════════════════════════════════════════════════════════════ */
.prelude {
  --prelude-out: 0;
  position: relative;
  height: 100vh;
  height: 100svh;
}

/* Sticky is the floor, not the effect. Without script the frame simply
   scrolls away like any other section — nothing pins, nothing hides,
   and the site below is one flick away. */
.prelude__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: grid;
  place-items: center;
  overflow: hidden;
  opacity: calc(1 - var(--prelude-out));
}

/* With script, the frame is held against the viewport instead, and the
   cover rises into place behind it while it dissolves. Fixed and faded
   arrive together, on the same class, so there is no state where the
   frame is pinned but nothing is left to unpin it.

   Below --z-lunar, so the moon light falls across the prelude the way
   it falls across every other page, and above the cover, which is in
   normal flow and would otherwise paint over it. */
.js-prelude .prelude__stage {
  position: fixed;
  inset: 0;
  height: auto;
  z-index: 75;
}

.prelude__art { position: absolute; inset: 0; }
/* <picture> is an inline wrapper with no height of its own, so the
   image's height: 100% resolved against nothing and it fell back to
   its intrinsic square — filling the width and overflowing the frame
   instead of covering it. The same trap the cover image hit. */
.prelude__art picture { display: block; width: 100%; height: 100%; }

/* The artwork's right side is nearly white, and white type on it is a
   guess rather than a reading. A scrim darkens the middle, where the
   mark sits, and both edges, where the bar and the cue sit — without
   touching the bright field that makes the picture. */
.prelude__art::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(64% 52% at 50% 44%, rgb(5 5 5 / 0.44), transparent 72%),
    linear-gradient(to bottom,
      rgb(5 5 5 / 0.42) 0%,
      transparent 20%,
      transparent 68%,
      rgb(5 5 5 / 0.5) 100%);
}
.prelude__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  /* Drifts in a little as it goes, so the dissolve has somewhere to
     travel rather than simply thinning out. */
  transform: scale(calc(1 + 0.07 * var(--prelude-out)));
}

.prelude__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.75rem, 4vh, 3rem);
  padding-inline: var(--gutter);
  text-align: center;
  transform: translateY(calc(var(--prelude-out) * -2.5vh));
}

.prelude__mark {
  width: min(38rem, 62vw);
  height: auto;
}

/* Jost rather than the mark's own face — that exists here only as
   outlines, and Jost was chosen for this site because it echoes the
   same monoline construction. */
.prelude__line {
  font-family: var(--font-ui);
  font-weight: 300;
  font-size: clamp(0.75rem, 1.5vw, 0.9375rem);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink);
  text-wrap: balance;
}
/* The album's name keeps its own lower case inside the tracked capitals. */
.prelude__line em { font-style: normal; text-transform: none; letter-spacing: 0; }

.prelude__cue {
  position: absolute;
  z-index: 1;
  bottom: clamp(2rem, 6vh, 3.5rem);
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  color: var(--ink-dim);
  transition: color var(--dur-fast) var(--ease-soft);
}
.prelude__cue:hover,
.prelude__cue:focus-visible { color: var(--ink); }
.prelude__cue-line {
  display: block;
  width: 46px;
  height: 1px;
  background: currentColor;
  transition: width var(--dur-mid) var(--ease);
}
.prelude__cue:hover .prelude__cue-line,
.prelude__cue:focus-visible .prelude__cue-line { width: 72px; }

@media (max-width: 600px) {
  .prelude__mark { width: 74vw; }
}

/* The drift is decoration; the dissolve is the mechanism, and fading
   is not what motion sensitivity is about. So the fade stays and the
   movement goes. */
@media (prefers-reduced-motion: reduce) {
  .prelude__art img,
  .prelude__inner { transform: none; }
}

/* ══════════════════════════════════════════════════════════════
   THE SINGLE
   ══════════════════════════════════════════════════════════════ */
.single {
  padding: var(--section-y) var(--gutter);
  border-top: 1px solid var(--hairline-soft);
}
.single__grid {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  max-width: 1600px;
  margin-inline: auto;
}
@media (min-width: 861px) {
  .single__grid {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 6rem);
    align-items: center;
  }
}

.single__art { display: flex; flex-direction: column; gap: 0.9rem; }
.single__art img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
}

.single__body { display: flex; flex-direction: column; gap: var(--stack-sm); }

.single__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 72;
  font-size: clamp(2.5rem, 6vw, 5.5rem);
  line-height: 1.02;
  letter-spacing: 0.004em;
}

.single__state { display: flex; flex-direction: column; gap: var(--stack-sm); }
.single__state[hidden] { display: none; }

/* On a phone the artwork, the title and the countdown all run the full
   width, so a button pinned to the left edge under them reads as
   leftover rather than as the thing to press. Centred, it sits under
   the countdown it belongs to. */
@media (max-width: 860px) {
  .single__state .btn {
    align-self: center;
    justify-content: center;
    min-width: min(20rem, 100%);
  }
}

.single__date {
  font-family: var(--font-ui);
  font-weight: 300;
  font-size: clamp(1.125rem, 1.8vw, 1.5rem);
  color: var(--ink-dim);
}

.countdown {
  display: flex;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding-block: var(--stack-sm);
  border-block: 1px solid var(--hairline);
}
.countdown__unit { display: flex; flex-direction: column; gap: 0.4rem; }
.countdown__n {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 48;
  font-size: clamp(2rem, 4.4vw, 3.5rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* ══════════════════════════════════════════════════════════════
   INTERSTITIAL ARTWORK
   ══════════════════════════════════════════════════════════════ */
.interstitial {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 6;
  overflow: hidden;
}
/* Never so short it reads as a stripe on a narrow screen. */
@media (max-width: 700px) {
  .interstitial { aspect-ratio: auto; height: clamp(220px, 34svh, 340px); }
}
.interstitial picture { display: block; width: 100%; height: 100%; }
.interstitial img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.06);
}

/* ── parallax: the dividers move slower than the page ──────────
   js/main.js writes --parallax from 1 (just below the viewport) to -1
   (just above it). The image is taller than its frame and slides the
   other way as the frame travels, so it lags the page like a view
   through a window. The overshoot is 20% each side; the travel stays
   inside it, so no edge ever shows. Without script the variable is
   unset and the image simply fills the frame. */
[data-parallax] img {
  position: absolute;
  left: 0;
  top: -20%;
  height: 140%;
  transform: translate3d(0, calc(var(--parallax, 0) * -14%), 0);
  will-change: transform;
}
/* The soft form: no overshoot, the whole picture scaled a touch and
   drifting a few percent — for the single's artwork, which has text
   beside it rather than a page above and below. The transform rides
   on <picture> so it never meets the unveiling's own transform on the
   image inside. */
[data-parallax="soft"] img { position: static; height: auto; transform: none; will-change: auto; }
[data-parallax="soft"] picture {
  display: block;
  transform: scale(1.08) translate3d(0, calc(var(--parallax, 0) * -3%), 0);
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  [data-parallax] img { position: static; height: 100%; transform: none; }
  [data-parallax="soft"] picture { transform: none; }
}

/* ══════════════════════════════════════════════════════════════
   THE ALBUM
   ══════════════════════════════════════════════════════════════ */
.album {
  padding: var(--section-y) var(--gutter);
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  max-width: 1600px;
  margin-inline: auto;
}
@media (min-width: 1000px) {
  .album {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(3rem, 8vw, 8rem);
    align-items: start;
  }
}
.album__head { display: flex; flex-direction: column; gap: var(--stack-sm); container-type: inline-size; }
.album__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 88;
  /* Never wider than its column: one word, and in a wide face it runs
     under the paragraph beside it. 21cqw holds "leave." at 4.6em. */
  font-size: min(clamp(3.5rem, 11vw, 10rem), 21cqw);
  line-height: 0.9;
  letter-spacing: 0.002em;
}
.album__body { display: flex; flex-direction: column; gap: var(--stack-sm); }
.album__body em { font-family: var(--font-display); font-style: italic; }
/* The album's name, wherever it is mentioned, is em.upright — styled at
   the end of the file so it wins over every "em in this block" rule. */
/* Sized to its own type rather than stretched across the column, so the
   hover target is the words and the rule, not the whole width. */
.album__go { align-self: start; }

/* ── artefacts: the door, not the object ──────────────────────
   The edition lives on its own page. This keeps the section rhythm and
   says the prints exist, in the space one link needs. */
.artefacts {
  padding: var(--section-y) var(--gutter);
  border-top: 1px solid var(--hairline-soft);
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: var(--stack-sm);
}
/* .section-head's own margin is sized to introduce a block of content.
   Here it introduces a single line, and that much air reads as a gap
   rather than as spacing. */
.artefacts .section-head { margin-bottom: 0; }

/* ══════════════════════════════════════════════════════════════
   WATCH
   Sized to the still we actually have (1280px) rather than blown up
   to full width, and the play affordance uses the same hairline-and-
   label language as the rest of the site instead of a play badge.
   ══════════════════════════════════════════════════════════════ */
.watch { padding: var(--section-y) var(--gutter); }

.watch__grid {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  max-width: 1500px;
  margin-inline: auto;
}
@media (min-width: 901px) {
  .watch__grid {
    grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 6rem);
    align-items: center;
  }
}
.watch__text { display: flex; flex-direction: column; gap: var(--stack-sm); }

.video { width: 100%; }
.video__trigger {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 100%;
  text-align: left;
  cursor: pointer;
}
.video__frame {
  display: block;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--hairline);
}
.video__frame img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  filter: grayscale(1) contrast(1.24) brightness(1.32);
  transition: filter var(--dur-mid) var(--ease-soft),
              transform var(--dur-slow) var(--ease);
}
.video__trigger:hover .video__frame img,
.video__trigger:focus-visible .video__frame img {
  filter: grayscale(1) contrast(1.28) brightness(1.5);
  transform: scale(1.02);
}

.video__cue { display: inline-flex; align-items: center; gap: 0.85rem; color: var(--ink-dim); }
.video__rule {
  display: block;
  width: 44px; height: 1px;
  background: currentColor;
  transition: width var(--dur-mid) var(--ease), background-color var(--dur-fast) var(--ease-soft);
}
.video__trigger:hover .video__cue,
.video__trigger:focus-visible .video__cue { color: var(--ink); }
.video__trigger:hover .video__rule,
.video__trigger:focus-visible .video__rule { width: 76px; }

.video iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  display: block;
}

/* ══════════════════════════════════════════════════════════════
   THE SIX
   ══════════════════════════════════════════════════════════════ */
.band { padding: var(--section-y) var(--gutter); }

.members {
  list-style: none;
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 2.5rem) clamp(1rem, 2vw, 2rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 1600px;
  margin-inline: auto;
}
@media (min-width: 1001px) {
  .members { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.member { display: flex; flex-direction: column; gap: 0.9rem; }
.member__figure { position: relative; display: block; overflow: hidden; }
.member__figure img {
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  filter: grayscale(1) contrast(1.04);
  transition: transform var(--dur-slow) var(--ease),
              filter    var(--dur-mid)  var(--ease-soft);
}
.member__trigger:hover .member__figure img,
.member__trigger:focus-visible .member__figure img {
  transform: scale(1.03);
  filter: grayscale(1) contrast(1.08) brightness(1.06);
}

.member__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--hairline);
}
.member__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 20;
  font-size: clamp(1.125rem, 2vw, 1.75rem);
  line-height: 1.1;
}

/* ══════════════════════════════════════════════════════════════
   LIVE
   ══════════════════════════════════════════════════════════════ */
.live { padding: var(--section-y) var(--gutter); }
/* Both are off the page for now — see index.html. */
.live[hidden], .artefacts[hidden], .wayout[hidden], .cover__foot[hidden] { display: none; }
.live__grid {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  max-width: 1600px;
  margin-inline: auto;
}
@media (min-width: 900px) {
  .live__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: clamp(2.5rem, 7vw, 7rem);
    align-items: start;
  }
}
.live__upcoming, .live__past { display: flex; flex-direction: column; gap: var(--stack-sm); }

/* A composed absence, not a blank grid. */
.live__empty {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 44;
  font-size: clamp(1.75rem, 4vw, 3.25rem);
  line-height: 1.1;
  color: var(--ink);
}

.datelist { list-style: none; display: flex; flex-direction: column; }
.datelist__row {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 0.25rem 1.5rem;
  padding-block: clamp(0.9rem, 2vh, 1.4rem);
  border-bottom: 1px solid var(--hairline);
}
.datelist__row:first-child { border-top: 1px solid var(--hairline); }
.datelist__year {
  grid-row: span 2;
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  padding-top: 0.35rem;
}
.datelist__what {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 20;
  font-size: clamp(1.125rem, 2vw, 1.625rem);
  line-height: 1.15;
}

/* ══════════════════════════════════════════════════════════════
   SUBSCRIBE
   ══════════════════════════════════════════════════════════════ */
.subscribe {
  padding: var(--section-y) var(--gutter);
  border-top: 1px solid var(--hairline-soft);
}
.subscribe__inner {
  display: flex;
  flex-direction: column;
  gap: var(--stack-sm);
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
  align-items: center;
}
.subscribe__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 72;
  font-size: clamp(2.25rem, 6vw, 5rem);
  line-height: 1.02;
}

/* ── the flicker ─────────────────────────────────────────────
   A bulb with a loose contact: every so often the line stutters for
   well under a second, then holds steady again. js/main.js adds
   data-flickering at random intervals while the line is on screen and
   removes it when the animation ends; two patterns so it never reads
   as a loop. The glow is a bulb's, not a screen's — faint, and only
   while it misbehaves. */
[data-flicker] { will-change: opacity; }
[data-flickering="a"] { animation: flicker-a 720ms steps(1, end) both; }
[data-flickering="b"] { animation: flicker-b 560ms steps(1, end) both; }
@keyframes flicker-a {
  0%   { opacity: 1; }
  6%   { opacity: 0.28; }
  10%  { opacity: 1;    text-shadow: 0 0 28px rgb(237 234 228 / 0.28); }
  16%  { opacity: 0.62; }
  21%  { opacity: 1; }
  52%  { opacity: 1; }
  55%  { opacity: 0.18; }
  59%  { opacity: 0.9; }
  64%  { opacity: 0.45; }
  70%  { opacity: 1;    text-shadow: 0 0 28px rgb(237 234 228 / 0.22); }
  100% { opacity: 1;    text-shadow: none; }
}
@keyframes flicker-b {
  0%   { opacity: 1; }
  12%  { opacity: 0.4; }
  18%  { opacity: 1;    text-shadow: 0 0 28px rgb(237 234 228 / 0.26); }
  26%  { opacity: 0.74; }
  31%  { opacity: 1; }
  78%  { opacity: 1; }
  82%  { opacity: 0.25; }
  88%  { opacity: 1; }
  100% { opacity: 1;    text-shadow: none; }
}
.subscribe .lede { text-align: center; }

.signup {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  width: 100%;
  max-width: 34rem;
  margin-top: var(--stack-sm);
}
.signup__input {
  flex: 1 1 16rem;
  min-width: 0;
  padding: 1rem 1.25rem;
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 300;
  font-size: var(--fs-small);
}
.signup__input::placeholder { color: var(--ink-faint); }
.signup__input:disabled { cursor: not-allowed; }
.signup__submit {
  padding: 1rem 2rem;
  border: 1px solid var(--hairline);
  transition: background-color var(--dur-fast) var(--ease-soft),
              color var(--dur-fast) var(--ease-soft);
}
.signup__submit:not(:disabled):hover { background: var(--ink); }
.signup__submit:not(:disabled):hover .label { color: var(--ground); }
.signup__submit:disabled { cursor: not-allowed; opacity: 0.5; }

/* ══════════════════════════════════════════════════════════════
   FOOTER
   ══════════════════════════════════════════════════════════════ */
.footer {
  padding: var(--stack-lg) var(--gutter) var(--stack-md);
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: var(--stack-lg);
}
.footer__top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--stack-md);
}
.footer__contact { display: flex; flex-direction: column; gap: 0.6rem; }
.footer__email {
  font-family: var(--font-ui);
  font-weight: 300;
  /* And never wider than the page: the address is one unbreakable
     word, twenty characters that run to about 19em in a wide face, so
     on a phone it is sized to fit between the gutters. */
  font-size: min(clamp(1.25rem, 3.2vw, 2.5rem), calc((100vw - 2 * var(--gutter)) / 19.5));
  line-height: 1.05;
  letter-spacing: 0.004em;
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) var(--ease-soft);
  overflow-wrap: break-word;
}
.footer__email:hover { border-bottom-color: var(--ink); }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--stack-sm) var(--stack-md);
  padding-top: var(--stack-md);
  border-top: 1px solid var(--hairline-soft);
}
.footer__mark { width: clamp(150px, 18vw, 230px); height: auto; opacity: 0.55; }
.footer__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.75rem;
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-nav);
  text-transform: uppercase;
  color: var(--ink-faint);
}
.footer__legal a { transition: color var(--dur-fast) var(--ease-soft); }
.footer__legal a:hover { color: var(--ink); }

/* ══════════════════════════════════════════════════════════════
   SUBPAGES — press kit and legal
   Same visual world as the homepage, but efficient rather than
   cinematic. A promoter is here to get something and leave.
   ══════════════════════════════════════════════════════════════ */
.pagenav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 1.5rem var(--gutter);
  border-bottom: 1px solid var(--hairline-soft);
}
.pagenav a.label { transition: color var(--dur-fast) var(--ease-soft); }
.pagenav a.label:hover { color: var(--ink); }

.page__main {
  padding: var(--stack-lg) var(--gutter) var(--section-y);
  max-width: 1500px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--stack-lg);
}
.page__main--prose { max-width: 68ch; }
/* Followed by a section that carries its own padding and rule, so
   this column closes at its own baseline instead of laying a
   second one on top of it. */
.page__main--head { padding-bottom: var(--stack-lg); }

.page__head { display: flex; flex-direction: column; gap: var(--stack-sm); }
.page__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 72;
  font-size: clamp(2.25rem, 6vw, 5rem);
  line-height: 1.02;
  letter-spacing: 0.004em;
  text-wrap: balance;
}

.press__block { display: flex; flex-direction: column; gap: var(--stack-sm); }
.press__note { margin-top: 0.5rem; }

/* ── services: a platform each, with its own mark ── */
.services {
  list-style: none;
  display: grid;
  gap: 0.6rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
}
.service {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.95rem 1.1rem;
  border: 1px solid var(--hairline);
  color: var(--ink-dim);
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-soft),
              border-color     var(--dur-fast) var(--ease-soft),
              color            var(--dur-fast) var(--ease-soft);
}
.service:hover,
.service:focus-visible { background: var(--ink); border-color: var(--ink); color: var(--ground); }
.service__icon { width: 1.25rem; height: 1.25rem; flex: none; fill: currentColor; }
.service__name {
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  text-transform: uppercase;
}

/* ── facts ── */
.factlist { display: flex; flex-direction: column; }
.factlist__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.15rem 2rem;
  padding-block: 0.9rem;
  border-bottom: 1px solid var(--hairline-soft);
}
@media (min-width: 640px) {
  .factlist__row { grid-template-columns: 14rem 1fr; align-items: baseline; }
}
.factlist dd {
  font-family: var(--font-ui);
  font-weight: 300;
  font-size: clamp(1.0625rem, 1.7vw, 1.375rem);
}
.factlist dd em { font-style: italic; }

/* ── biography ── */
.press__bios {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .press__bios { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); gap: clamp(2rem, 5vw, 4.5rem); }
  /* Short and medium stack on the left; the long one takes the right
     column for both rows, so the page reads short to long. */
  .bio--long { grid-column: 2; grid-row: 1 / span 2; }
}
.bio { display: flex; flex-direction: column; gap: 0.9rem; }
.bio__text {
  max-width: 62ch;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-dim);
}
.bio__text + .bio__text { margin-top: 0.75rem; }
.bio__text em { font-family: var(--font-display); font-style: italic; color: var(--ink); }

/* ── downloadable assets ── */
.assetgrid {
  display: grid;
  gap: var(--stack-sm);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
}
.asset { display: flex; flex-direction: column; gap: 0.75rem; }
.asset img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  filter: grayscale(1);
  border: 1px solid var(--hairline-soft);
}
.asset figcaption { display: flex; flex-direction: column; gap: 0.35rem; }
.asset__name { font-size: var(--fs-small); color: var(--ink); }
.asset__dl {
  color: var(--ink-dim);
  border-bottom: 1px solid var(--hairline);
  align-self: flex-start;
  padding-bottom: 2px;
  transition: color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft);
}
.asset__dl:hover { color: var(--ink); border-color: var(--ink); }
/* The same row, without a link under it — used by the self-contained
   copy, where a download the page starts is blocked by the sandbox
   anyway. It should read as a note, not as a button that does nothing. */
.asset__dl--flat { border-bottom: 0; color: var(--ink-faint); }

.assetgrid--logos .asset img {
  aspect-ratio: 16 / 6;
  object-fit: contain;
  padding: 1.25rem;
  background: var(--ground-raised);
}
/* Black logo files need a light ground to be visible at all. */
.assetgrid--logos .asset--onlight img { background: var(--ink); }

/* ── legal prose ── */
.prose { display: flex; flex-direction: column; gap: 1.75rem; }
/* The legal pages carry both languages, English first; a rule and a
   label mark where the German begins. */
.prose + .prose {
  margin-top: var(--stack-md);
  padding-top: var(--stack-md);
  border-top: 1px solid var(--hairline-soft);
}
.prose > .label { margin-bottom: -0.5rem; }
.prose h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 22;
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  line-height: 1.2;
  margin-bottom: -0.75rem;
}
.prose p {
  color: var(--ink-dim);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  max-width: 62ch;
}

/* ══════════════════════════════════════════════════════════════
   MEMBER QUOTE
   Hidden until the portrait is pressed, then it surfaces over the
   image and fades out on its own. Nothing to dismiss.
   ══════════════════════════════════════════════════════════════ */
.member__trigger {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  width: 100%;
  text-align: left;
  cursor: pointer;
}

.member__flash {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 3vw, 2rem);
  background: rgb(5 5 5 / 0.72);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity    440ms var(--ease),
    visibility 0s linear 440ms;
}
.member[data-flash="true"] .member__flash {
  opacity: 1;
  visibility: visible;
  transition:
    opacity    340ms var(--ease),
    visibility 0s linear 0s;
}

.member__quote {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-variation-settings: "opsz" 24;
  font-size: clamp(0.9375rem, 1.5vw, 1.1875rem);
  line-height: 1.45;
  color: var(--ink);
  text-align: center;
  text-wrap: pretty;
  transform: translateY(8px);
  transition: transform 520ms var(--ease);
}
.member[data-flash="true"] .member__quote { transform: none; }

/* Without JS the portraits are not controls, so do not dress them as one. */
.no-js .member__trigger { cursor: default; }

/* ══════════════════════════════════════════════════════════════
   LIMITED EDITION
   One object, presented like an object. The counter and the closing
   line do the work that a shop grid would otherwise do badly.
   ══════════════════════════════════════════════════════════════ */
.edition {
  padding: var(--section-y) var(--gutter);
  border-top: 1px solid var(--hairline-soft);
  background:
    radial-gradient(120% 90% at 50% 0%, rgb(237 234 228 / 0.045), transparent 62%),
    var(--ground);
}
.edition__grid {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  max-width: 1500px;
  margin-inline: auto;
}
@media (min-width: 901px) {
  .edition__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 6rem);
    align-items: center;
  }
}

.edition__art img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  filter: grayscale(1);
  border: 1px solid var(--hairline);
}

.edition__body { display: flex; flex-direction: column; gap: var(--stack-sm); }

.edition__mark {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--hairline);
}
.edition__count { display: inline-flex; align-items: baseline; gap: 0.5rem; }
.edition__n {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 28;
  font-size: clamp(1.375rem, 2.4vw, 2rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.edition__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 72;
  font-size: clamp(2.5rem, 6vw, 5rem);
  line-height: 1;
}
.edition__kind {
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-variation-settings: "opsz" 22;
  font-size: clamp(1.0625rem, 1.7vw, 1.375rem);
  color: var(--ink-dim);
  margin-top: -0.35rem;
}

.spec { display: flex; flex-direction: column; margin-top: var(--stack-sm); }
.spec__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.1rem 2rem;
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--hairline-soft);
}
@media (min-width: 520px) {
  .spec__row { grid-template-columns: 9rem 1fr; align-items: baseline; }
}
.spec dd { font-size: var(--fs-small); color: var(--ink); }

.edition__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
  margin-top: var(--stack-sm);
}
.edition__price {
  white-space: nowrap;
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 40;
  font-size: clamp(1.5rem, 2.8vw, 2.25rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.btn--solid {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ground);
}
.btn--solid:hover { background: transparent; color: var(--ink); border-color: var(--ink); }

.edition__note { margin-top: 0.25rem; }


/* ══════════════════════════════════════════════════════════════
   MOON PHASE
   The band is named after a unit of time; the footer keeps it.
   ══════════════════════════════════════════════════════════════ */
.footer__moon {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding-bottom: var(--stack-sm);
}
.footer__moon[hidden] { display: none; }
.moon { width: 22px; height: 22px; overflow: visible; }
.moon__disc { fill: none; stroke: var(--ink-faint); stroke-width: 1; }
.moon__lit  { fill: var(--ink-dim); }
.footer__moon-text { display: inline-flex; gap: 0.6rem; }

/* ══════════════════════════════════════════════════════════════
   SMART LINK  (/veil)
   One screen, one decision. Built for a link in a bio, so it is
   designed mobile-first and never scrolls more than it must.
   ══════════════════════════════════════════════════════════════ */
.smartlink { min-height: 100svh; display: flex; }

.sl {
  width: 100%;
  max-width: 34rem;
  margin-inline: auto;
  padding: clamp(2rem, 6vh, 4rem) var(--gutter) clamp(2.5rem, 8vh, 5rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.25rem, 3vh, 2rem);
  text-align: center;
}

.sl__mark { width: clamp(150px, 44vw, 210px); }
.sl__mark img { width: 100%; height: auto; }

.sl__art { width: min(78vw, 380px); }
.sl__art img {
  width: 100%; height: auto;
  aspect-ratio: 1; object-fit: cover;
  border: 1px solid var(--hairline);
}

.sl__head { display: flex; flex-direction: column; gap: 0.5rem; }
.sl__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 72;
  font-size: clamp(2.75rem, 13vw, 4.5rem);
  line-height: 1;
}

.sl__state { width: 100%; align-items: center; gap: var(--stack-sm); }
.sl__state[hidden] { display: none; }
.sl__out {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 30;
  font-size: 1.25rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

.countdown--tight {
  justify-content: center;
  gap: clamp(1rem, 6vw, 2rem);
  width: 100%;
}
.countdown--tight .countdown__unit { align-items: center; }
.countdown--tight .countdown__n { font-size: clamp(1.5rem, 7vw, 2.25rem); }

.platforms {
  list-style: none;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.platform {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--hairline);
  transition: background-color var(--dur-fast) var(--ease-soft),
              border-color     var(--dur-fast) var(--ease-soft),
              color            var(--dur-fast) var(--ease-soft);
}
.platform:hover { background: var(--ink); border-color: var(--ink); color: var(--ground); }
.platform:hover .platform__do { color: var(--ground); }
.platform__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 24;
  font-size: 1.125rem;
}
.platform__do { color: var(--ink-dim); }

.sl__signup { width: 100%; display: flex; flex-direction: column; gap: 0.75rem; align-items: center; }
.sl__signup .signup { margin-top: 0; }
.sl__back { margin-top: 0.5rem; transition: color var(--dur-fast) var(--ease-soft); }
.sl__back:hover { color: var(--ink); }

/* ══════════════════════════════════════════════════════════════
   CONSENT BAR
   ══════════════════════════════════════════════════════════════ */
.consent {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 200;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding: 1.1rem var(--gutter);
  background: var(--ground-raised);
  border-top: 1px solid var(--hairline);
}
.consent[hidden] { display: none; }
.consent__text {
  max-width: 62ch;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--ink-dim);
}
.consent__actions { display: flex; gap: 0.75rem; flex-shrink: 0; }
.consent__btn {
  padding: 0.65rem 1.4rem;
  border: 1px solid var(--hairline);
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft);
}
.consent__btn:hover { color: var(--ink); border-color: var(--ink); }
.consent__btn--yes { background: var(--ink); border-color: var(--ink); color: var(--ground); }
.consent__btn--yes:hover { background: transparent; color: var(--ink); }

/* ══════════════════════════════════════════════════════════════
   THE RECORD  (/leave)
   A tracklist where nine of ten titles do not exist publicly yet.
   Sealed rows show a veiled bar rather than an invented title — no
   fake song names in the markup for anyone to find.
   ══════════════════════════════════════════════════════════════ */
.record {
  padding: var(--stack-lg) var(--gutter) var(--section-y);
  max-width: 1500px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--stack-lg);
}

.record__head { display: flex; flex-direction: column; gap: var(--stack-sm); }
.record__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 88;
  font-size: clamp(4rem, 16vw, 13rem);
  line-height: 0.86;
  letter-spacing: 0.002em;
  margin-left: -0.03em;
}
.record__line {
  font-family: var(--font-ui);
  font-weight: 300;
  font-size: clamp(1.125rem, 2.2vw, 1.75rem);
  color: var(--ink-dim);
}

.record__body {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
}
@media (min-width: 1000px) {
  .record__body {
    grid-template-columns: minmax(0, 0.72fr) minmax(0, 1fr);
    gap: clamp(3rem, 7vw, 7rem);
    align-items: start;
  }
}
.record__note { display: flex; flex-direction: column; gap: var(--stack-sm); }
.record__foot { padding-top: var(--stack-sm); border-top: 1px solid var(--hairline-soft); }

/* ── The artwork ──────────────────────────────────────────────
   A credit with a picture in it, because the picture is the point.
   Wide enough to read as a section rather than a footnote, which is
   what it was while it sat at the end of the twenty-nine fragments. */
.artwork {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  align-items: center;
  padding-block: var(--stack-md);
  border-block: 1px solid var(--hairline);
}
@media (min-width: 941px) {
  .artwork {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    gap: clamp(2.5rem, 6vw, 6rem);
  }
}
.artwork__img { overflow: hidden; }
.artwork__img img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  filter: grayscale(1) contrast(1.06);
  transform: scale(1.001);
  transition: transform 1200ms var(--ease-soft);
}
.artwork:hover .artwork__img img { transform: scale(1.03); }

.artwork__body { display: flex; flex-direction: column; gap: var(--stack-sm); }
.artwork__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 60;
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1;
  letter-spacing: 0.004em;
}
.artwork__text {
  max-width: 44ch;
  font-size: var(--fs-lead);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--ink-dim);
}
.artwork__link { margin-top: 0; padding-top: 0; }

@media (prefers-reduced-motion: reduce) {
  .artwork__img img { transition: none; }
  .artwork:hover .artwork__img img { transform: none; }
}

/* ── The way out ──────────────────────────────────────────────
   The cycle used to be a clause inside the sentence about
   unannounced titles, which made the one genuine door off this page
   read as an aside. It is a panel of its own now — the same .gateway__go
   marker the home page uses, given a whole block to carry it. */
.wayout {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: clamp(1.75rem, 4vw, 3rem) 0;
  /* Ruled top and bottom so it holds as a block on its own, rather
     than depending on whatever happens to sit above it. */
  border-block: 1px solid var(--hairline);
  transition: border-color var(--dur-mid) var(--ease-soft);
}
.wayout:hover,
.wayout:focus-visible { border-color: var(--ink-faint); }
.wayout__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 48;
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  line-height: 1;
  letter-spacing: 0.004em;
}
.wayout__note {
  max-width: 44ch;
  font-size: var(--fs-small);
  line-height: 1.75;
  color: var(--ink-dim);
}

/* ── the list ── */
.tracks { list-style: none; display: flex; flex-direction: column; }

.track,
.track__link {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.35rem 1.5rem;
  padding-block: clamp(1rem, 2.4vh, 1.6rem);
}
.track { border-bottom: 1px solid var(--hairline); }
.track:first-child { border-top: 1px solid var(--hairline); }

/* An open track carries its grid on the anchor, not the list item —
   otherwise the link becomes a single grid child and collapses into
   the first column. */
.track--open { display: block; padding-block: 0; }
/* Four children on the link — number, title, meta, arrow — so it needs a
   fourth track or the arrow wraps beneath the number. */
.track__link { width: 100%; grid-template-columns: 2.75rem minmax(0, 1fr) auto auto; }

.track__n {
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.track__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 32;
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  line-height: 1.05;
}
.track__meta { justify-self: end; text-align: right; }

/* Available track */
.track--open { transition: background-color var(--dur-fast) var(--ease-soft); }
.track--open .track__n,
.track--open .track__meta { transition: color var(--dur-fast) var(--ease-soft); }
.track--open:hover { background: rgb(237 234 228 / 0.035); }
.track--open:hover .track__meta { color: var(--ink-dim); }

.track__go {
  justify-self: end;
  width: 26px; height: 1px;
  background: var(--ink-faint);
  position: relative;
  transition: width var(--dur-mid) var(--ease), background-color var(--dur-fast) var(--ease-soft);
}
.track__go::after {
  content: "";
  position: absolute; right: 0; top: 0;
  width: 7px; height: 7px;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  color: var(--ink-faint);
  transform: translateY(-50%) rotate(45deg);
  transition: color var(--dur-fast) var(--ease-soft);
}
.track--open:hover .track__go { width: 40px; background: var(--ink); }
.track--open:hover .track__go::after { color: var(--ink); }

@media (max-width: 620px) {
  .track { grid-template-columns: 2.25rem minmax(0, 1fr); }
  .track__link { grid-template-columns: 2.25rem minmax(0, 1fr); }
  .track__meta { grid-column: 2; justify-self: start; text-align: left; }
  .track__go { display: none; }
}

/* Sealed track — a veiled bar, not a title */
/* Varied bar widths hint at title length without inventing one.
   Set here rather than inline so style-src can stay strict. */
.tracks .track:nth-child(1) .track__veiled { width: 46%; }
.tracks .track:nth-child(3) .track__veiled { width: 62%; }
.tracks .track:nth-child(4) .track__veiled { width: 38%; }
.tracks .track:nth-child(5) .track__veiled { width: 71%; }
.tracks .track:nth-child(6) .track__veiled { width: 52%; }
.tracks .track:nth-child(7) .track__veiled { width: 44%; }
.tracks .track:nth-child(8) .track__veiled { width: 66%; }
.tracks .track:nth-child(9) .track__veiled { width: 35%; }
.tracks .track:nth-child(10) .track__veiled { width: 58%; }

.track__veiled {
  display: block;
  width: 50%;
  height: clamp(1.1rem, 2.4vw, 1.9rem);
  border-radius: 1px;
  background: linear-gradient(
    100deg,
    rgb(237 234 228 / 0.16) 0%,
    rgb(237 234 228 / 0.07) 42%,
    rgb(237 234 228 / 0.13) 100%);
  filter: blur(3px);
}
.track--sealed .track__n,
.track--sealed .track__meta { color: var(--ink-faint); }

/* ══════════════════════════════════════════════════════════════
   A SONG  (/leave/veil)
   ══════════════════════════════════════════════════════════════ */
.song {
  padding: var(--stack-lg) var(--gutter) var(--section-y);
  max-width: 96rem;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--stack-lg);
}

.song__head { display: flex; flex-direction: column; gap: 0.5rem; }
.song__n {
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.song__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 88;
  font-size: clamp(3.5rem, 13vw, 9rem);
  line-height: 0.9;
  margin-left: -0.03em;
  /* The tight leading leaves no room below the baseline, so a title
     with descenders — places — ran its p into the line beneath. */
  padding-bottom: 0.14em;
  margin-bottom: 0.1em;
}
.song__head em { font-family: var(--font-display); font-style: italic; }

/* ── Spotify ──────────────────────────────────────────────── */
/* The page stacks its parts a long gap apart; the player sits closer
   to the title than that, so it pulls most of the gap back. */
.spotify { max-width: 36rem; margin-top: calc(var(--stack-sm) - var(--stack-lg)); }
.spotify iframe { display: block; border: 0; border-radius: 12px; }

/* ── the lyric ── */
.lyrics { display: flex; flex-direction: column; gap: clamp(2.25rem, 6vh, 4rem); }

/* The section marking sits out in the margin like a score direction,
   present for anyone following the structure, quiet enough to ignore. */
.stanza { display: grid; grid-template-columns: 1fr; gap: 0.55rem; }
@media (min-width: 900px) {
  .stanza {
    grid-template-columns: 6.5rem minmax(0, 1fr);
    gap: 0 clamp(1.25rem, 2.2vw, 2.25rem);
    align-items: start;
  }
  .stanza__mark { padding-top: 0.85em; }
}
.stanza__lines { display: flex; flex-direction: column; gap: 0.1rem; }

.line {
  font-family: var(--font-ui);
  font-weight: 300;
  font-size: clamp(1.5rem, 3.8vw, 3.25rem);
  line-height: 1.26;
  letter-spacing: 0.002em;
  /* Hanging indent: if a long line does wrap, the continuation is
     indented, so it can never be mistaken for the next lyric line. */
  padding-left: 1.3em;
  text-indent: -1.3em;
}

/* Backing vocal answering the lead. */
.line--echo {
  font-style: italic;
  font-size: clamp(1.05rem, 2.4vw, 1.95rem);
  color: var(--ink-dim);
  padding-left: 2.6em;
}

/* Repeat of the chorus opening, set apart without a new heading. */
.line--gap { margin-top: 1.1em; }

/* ── annotation marker ── */
.annot__toggle {
  display: none;                      /* revealed only when JS is running */
  position: relative;
  width: 0.4em; height: 0.4em;
  margin-left: 0.5em;
  vertical-align: 0.3em;
  border-radius: 50%;
  background: var(--signal);
  opacity: 0.7;
  transition: opacity var(--dur-fast) var(--ease-soft),
              transform var(--dur-fast) var(--ease-soft);
}
.js-annot .annot__toggle { display: inline-block; }
.annot__toggle:hover,
.annot__toggle:focus-visible { opacity: 1; transform: scale(1.2); }
.annot__toggle[aria-expanded="true"] { opacity: 1; transform: scale(1.2); }

/* A ring travelling outward from the marker, so it reads as something
   waiting to be opened rather than a full stop. */
.annot__toggle::after {
  content: "";
  position: absolute;
  inset: -0.28em;
  border-radius: 50%;
  border: 1px solid var(--signal);
  opacity: 0;
  pointer-events: none;
}
.annot__toggle:hover::after,
.annot__toggle:focus-visible::after {
  animation: annot-ring 1600ms var(--ease-soft) infinite;
}
.annot__toggle[aria-expanded="true"]::after { animation: none; opacity: 0; }

@keyframes annot-ring {
  0%   { transform: scale(0.55); opacity: 0.65; }
  70%  { opacity: 0.12; }
  100% { transform: scale(2.1);  opacity: 0; }
}

/* Collapsed to nothing, then opened to its measured height by
   js/annotations.js, so the lyric above and below slides apart rather
   than jumping. The height is measured rather than guessed: a
   max-height picked by hand either clips a long note or spends most of
   the animation travelling through empty space. */
.annot {
  max-height: 0;
  overflow: hidden;
  margin-block: 0;
  opacity: 0;
  transition:
    max-height   var(--dur-slow) var(--ease),
    margin-block var(--dur-slow) var(--ease),
    opacity      var(--dur-mid)  var(--ease-soft);
}
.annot[data-open="true"] {
  margin-block: 1.5rem;
  opacity: 1;
}

.annot__body {
  max-width: 54ch;
  /* No vertical padding: it would survive the 0fr collapse and
     leave a few pixels of gap wherever a marker exists. The open
     state's margin-block does the spacing instead. */
  padding: 0 0 0 clamp(1.1rem, 2.6vw, 2rem);
  border-left: 1px solid var(--signal);
  font-family: var(--font-display);
  font-weight: 500;
  font-style: italic;
  font-variation-settings: "opsz" 20;
  font-size: clamp(1rem, 1.5vw, 1.1875rem);
  line-height: 1.7;
  color: var(--ink-dim);
  text-wrap: pretty;
  /* Rises very slightly as it opens. */
  transform: translateY(6px);
  transition: transform var(--dur-slow) var(--ease);
}
.annot[data-open="true"] .annot__body { transform: none; }

.annot__who {
  display: block;
  font-family: var(--font-ui);
  font-style: normal;
  font-weight: 400;
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  text-transform: uppercase;
  color: var(--signal);
  margin-bottom: 0.6rem;
}

@media (prefers-reduced-motion: reduce) {
  .annot, .annot__body { transition: none !important; }
  .annot__toggle::after { animation: none !important; }
}

/* ── foot navigation ── */
.song__nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--stack-sm) 2rem;
  padding-top: var(--stack-sm);
  border-top: 1px solid var(--hairline);
}
.song__nav-link { display: flex; flex-direction: column; gap: 0.3rem; }
.song__nav-link--end { text-align: right; }
.song__nav-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 30;
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  line-height: 1.1;
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) var(--ease-soft);
}
.song__nav-link:hover .song__nav-title { border-bottom-color: var(--ink); }


/* ══════════════════════════════════════════════════════════════
   THE UNVEILING
   The cover begins concealed and resolves as release approaches.
   Blur and darkness recede together, so the image surfaces rather
   than slides into view. js/main.js sets the three custom
   properties; everything else is here.
   ══════════════════════════════════════════════════════════════ */
.unveil {
  position: relative;
  display: block;
  overflow: hidden;
}
.unveil .unveil__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  /* Scaled slightly so the blur cannot pull transparent edges in. */
  transform: scale(1.04);
  filter:
    grayscale(1)
    blur(var(--unveil-blur, 0px))
    brightness(var(--unveil-bright, 1));
  transition: filter 1200ms var(--ease), transform 1200ms var(--ease);
}
.unveil__scrim {
  position: absolute;
  inset: 0;
  background: var(--ground);
  opacity: var(--unveil-scrim, 0);
  pointer-events: none;
  transition: opacity 1200ms var(--ease);
}
/* Released: no blur, no scrim, no scale-up needed. */
[data-unveiled="true"] .unveil .unveil__img { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .unveil .unveil__img, .unveil__scrim { transition: none !important; }
}

/* ══════════════════════════════════════════════════════════════
   NEWSLETTER STATUS
   ══════════════════════════════════════════════════════════════ */
.signup__note[data-kind="ok"] { color: var(--signal); }
.signup__note[data-kind="error"] { color: var(--ink); }

/* ══════════════════════════════════════════════════════════════
   EDITION — sold out
   ══════════════════════════════════════════════════════════════ */
.edition[data-sold-out="true"] .btn--solid,
.edition .btn[aria-disabled="true"] {
  pointer-events: none;
  opacity: 0.35;
}
.edition[data-sold-out="true"] .edition__n { color: var(--ink-faint); }

/* ══════════════════════════════════════════════════════════════
   THE CYCLE
   Twenty-nine fragments. Sealed ones use the same veiled bar as the
   unannounced tracks, so the two withholdings read as one idea.
   ══════════════════════════════════════════════════════════════ */
.cycle {
  padding: var(--stack-lg) var(--gutter) var(--section-y);
  max-width: 1300px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--stack-lg);
}

.cycle__head { display: flex; flex-direction: column; gap: var(--stack-sm); }
.cycle__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 88;
  font-size: clamp(2.5rem, 9vw, 7rem);
  line-height: 0.94;
  letter-spacing: 0.004em;
  margin-left: -0.03em;
  text-wrap: balance;
}
.cycle__line {
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-variation-settings: "opsz" 26;
  font-size: clamp(1.0625rem, 2vw, 1.5rem);
  color: var(--ink-dim);
}

.cycle__intro {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--stack-sm) var(--stack-md);
  padding-bottom: var(--stack-sm);
  border-bottom: 1px solid var(--hairline);
}
.cycle__moon { display: inline-flex; align-items: center; gap: 0.85rem; }
.cycle__moon[hidden] { display: none; }

.cycle__list { list-style: none; display: flex; flex-direction: column; }
.cycle__loading { padding-block: var(--stack-md); }

.fragment {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  gap: 0.5rem 1.75rem;
  padding-block: clamp(1.25rem, 3vh, 2.25rem);
  border-bottom: 1px solid var(--hairline);
}
.fragment:first-child { border-top: 1px solid var(--hairline); }

.fragment__n {
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-caption);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  padding-top: 0.4rem;
}
.fragment__body { display: flex; flex-direction: column; gap: 0.6rem; min-width: 0; }

.fragment__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 32;
  font-size: clamp(1.25rem, 2.4vw, 1.875rem);
  line-height: 1.15;
}
.fragment__text {
  max-width: 58ch;
  font-size: var(--fs-small);
  line-height: 1.85;
  color: var(--ink-dim);
}

/* Not yet open — the same veiled bar the sealed tracks use. */
.fragment__veiled {
  display: block;
  width: 58%;
  height: clamp(1rem, 2vw, 1.5rem);
  border-radius: 1px;
  background: linear-gradient(
    100deg,
    rgb(237 234 228 / 0.14) 0%,
    rgb(237 234 228 / 0.06) 44%,
    rgb(237 234 228 / 0.11) 100%);
  filter: blur(3px);
}
.cycle__list .fragment--sealed:nth-child(odd) .fragment__veiled { width: 44%; }
.cycle__list .fragment--sealed:nth-child(3n) .fragment__veiled { width: 66%; }
.cycle__list .fragment--sealed:nth-child(5n) .fragment__veiled { width: 37%; }

.cycle__foot { padding-top: var(--stack-sm); }

@media (max-width: 560px) {
  .fragment { grid-template-columns: 2.5rem minmax(0, 1fr); gap: 0.4rem 1rem; }
}

/* ══════════════════════════════════════════════════════════════
   THE WAY ON
   A line of type and a rule, not a panel. Each section that leads
   somewhere carries one of these at its foot; .wayout on the cycle
   page is the same idea given a whole block to itself.
   ══════════════════════════════════════════════════════════════ */
.gateway__go {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: auto;
  padding-top: var(--stack-sm);
  color: var(--ink-dim);
  transition: color var(--dur-fast) var(--ease-soft);
}
.gateway__go i:not(.mark) {
  display: block;
  width: 34px; height: 1px;
  background: currentColor;
  position: relative;
  transition: width var(--dur-mid) var(--ease);
}
.gateway__go i:not(.mark)::after {
  content: "";
  position: absolute; right: 0; top: 0;
  width: 7px; height: 7px;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
}
/* Hover and focus say the same thing, as they do on every other
   compound control here (.video__trigger, .member__trigger). A
   keyboard user reaching the same panel should not get a lesser
   version of the response — the focus ring tells them where they are,
   these tell them what it is. */
.wayout:hover .gateway__go,
.wayout:focus-visible .gateway__go { color: var(--ink); }

.wayout:hover .gateway__go i:not(.mark),
.wayout:focus-visible .gateway__go i:not(.mark) { width: 58px; }

/* Usually .gateway__go is a marker inside a link that covers a whole
   panel, and the panel's hover drives it. On the thank-you page and
   under the artwork credit it IS the link, so nothing above it is
   listening — it has to answer for its own hover and focus, or the
   arrow sits there dead while everything else on the site moves. */
a.gateway__go:hover,
a.gateway__go:focus-visible { color: var(--ink); }
a.gateway__go:hover i:not(.mark),
a.gateway__go:focus-visible i:not(.mark) { width: 58px; }
a.gateway__go:hover .mark,
a.gateway__go:focus-visible .mark { opacity: 1; }
a.gateway__go:hover .mark::after,
a.gateway__go:focus-visible .mark::after {
  animation: annot-ring 1600ms var(--ease-soft) infinite;
}

/* ── Unveil notice ────────────────────────────────────────────
   Printed over the concealed artwork so it reads as withheld
   rather than broken, and says when it opens. */
.unveil__notice {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  text-align: center;
  padding-inline: 1rem;
  transition: opacity var(--dur-mid) var(--ease);
  pointer-events: none;
}
.unveil__notice .label { color: var(--ink-dim); }
.unveil__date {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 34;
  font-size: clamp(1.25rem, 2.4vw, 1.875rem);
  line-height: 1.1;
  color: var(--ink);
}
/* Once open, the notice has nothing left to say. */
[data-unveiled="true"] .unveil__notice { opacity: 0; }

/* The next fragment says when, beside the bar it explains. */
.fragment--next .fragment__body {
  flex-direction: row;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.fragment--next .fragment__veiled { flex: 0 1 auto; min-width: 34%; }
.fragment__when { white-space: nowrap; }

/* ══════════════════════════════════════════════════════════════
   COPY BUTTON  (press kit)
   ══════════════════════════════════════════════════════════════ */
.bio__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.copy {
  display: none;                       /* shown only if it can work */
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--hairline);
  color: var(--ink-dim);
  transition: color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft);
}
.js-copy .copy { display: inline-flex; }
.copy:hover { color: var(--ink); border-color: var(--ink); }
.copy[data-copied="true"] { color: var(--signal); border-color: var(--signal); }
.copy .label { color: inherit; }

/* ── A song still sealed ──────────────────────────────────────
   The lyrics are not withheld by hiding them; they are not sent.
   What stands in their place should read as deliberate, so it is
   built like the rest of the site rather than like an error. */
.sealed {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--stack-sm);
  padding: var(--stack-md) 0;
  border-block: 1px solid var(--hairline);
}
.sealed__when {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 44;
  font-size: clamp(1.75rem, 4.5vw, 3rem);
  line-height: 1.05;
  letter-spacing: 0.004em;
}
.sealed__note {
  max-width: 42ch;
  font-size: var(--fs-lead);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--ink-dim);
}
.sealed .gateway__go { margin-top: 0.5rem; padding-top: 0; }

.lyrics__loading { padding-block: var(--stack-md); }

/* A proof link says so, on the page, for as long as it is being used
   — so nobody mistakes an early read for a published one. */
.lyrics__preview {
  margin-top: var(--stack-md);
  padding-top: var(--stack-sm);
  border-top: 1px solid var(--hairline);
  color: var(--signal);
}

/* ══════════════════════════════════════════════════════════════
   LUNAR LIGHT
   The site is named after a lunar day, so it carries one. An ambient
   glow scaled by the real illuminated fraction: nothing on a single
   visit, something you cannot name across a month.

   Deliberately a layer of its own, behind nothing that holds text, so
   the palette can move without contrast moving with it.
   ══════════════════════════════════════════════════════════════ */
.lunar {
  position: fixed;
  inset: 0;
  z-index: var(--z-lunar);
  pointer-events: none;
  opacity: calc(0.06 + var(--lunar) * 0.5);
  /* The light sits above the page and slips a little way down it as
     the visitor scrolls — js/main.js sets --lunar-drift from 0 at the
     top to 1 a few screens in — so the page reads as lit from
     somewhere rather than painted. */
  background:
    radial-gradient(120% 70% at 50% calc(-12% + var(--lunar-drift, 0) * 36%),
      rgb(237 234 228 / 0.055) 0%,
      rgb(237 234 228 / 0.018) 38%,
      transparent 70%);
  transition: opacity 2s var(--ease-soft);
}

/* ══════════════════════════════════════════════════════════════
   CURSOR LIGHT
   The cover photograph lit rather than displayed. Pointer only —
   there is nothing to follow on a touchscreen.
   ══════════════════════════════════════════════════════════════ */
@media (hover: hover) and (pointer: fine) {
  /* Any element marked data-light in the markup. It must be positioned
     and clip its overflow, which every photograph frame here already
     is. js/main.js moves the light and sets data-lit while a pointer
     is over the element (or its data-light-scope). */
  [data-light]::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--dur-slow) var(--ease-soft);
    background: radial-gradient(
      clamp(180px, 26vw, 420px) circle at var(--cursor-x, 50%) var(--cursor-y, 50%),
      rgb(237 234 228 / 0.13) 0%,
      rgb(237 234 228 / 0.05) 42%,
      transparent 72%);
  }
  [data-light][data-lit="true"]::before { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  [data-light]::before { display: none; }
  .lunar { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   THE MARK
   One dot, everywhere something is open. The lyric annotations use
   it, the released track carries it, and the two ways further into
   the record are flagged with it — so "there is something here"
   reads the same way wherever it appears. It echoes outward when
   whatever carries it is hovered.

   Sized in em so it scales with its surroundings, and the ring is
   set in per cent of the dot rather than em so the proportion holds
   at any size. Override --mark-size where the type around it is too
   small to give a sensible one.
   ══════════════════════════════════════════════════════════════ */
.mark {
  --mark-size: 0.28em;
  position: relative;
  display: inline-block;
  flex: none;
  width: var(--mark-size);
  height: var(--mark-size);
  margin-left: 0.42em;
  vertical-align: 0.42em;
  border-radius: 50%;
  background: var(--signal);
  opacity: 0.75;
  transition: opacity var(--dur-fast) var(--ease-soft);
}
.mark::after {
  content: "";
  position: absolute;
  inset: -107%;
  border-radius: 50%;
  border: 1px solid var(--signal);
  opacity: 0;
}

.track--open:hover .mark,
.track__link:focus-visible .mark,
.wayout:hover .mark,
.wayout:focus-visible .mark { opacity: 1; }

.track--open:hover .mark::after,
.track__link:focus-visible .mark::after,
.wayout:hover .mark::after,
.wayout:focus-visible .mark::after {
  animation: annot-ring 1600ms var(--ease-soft) infinite;
}

/* In a caption-sized row the em would give a three-pixel dot. */
.gateway__go .mark {
  --mark-size: 5px;
  margin-left: -0.45rem;
  vertical-align: baseline;
}

@media (prefers-reduced-motion: reduce) {
  .mark::after { animation: none !important; }
}

/* ── Day X of the journey ─────────────────────────────────────
   The clock does not stop when the record comes out. */
.journey {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.journey--centred { justify-content: center; }
.journey__n {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 40;
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* ── Shipping in the edition spec ─────────────────────────────
   Stated on the page so nobody meets postage at the last step. */
.ship__note { display: block; margin-top: 0.35rem; }

/* ══════════════════════════════════════════════════════════════
   THANK YOU
   The page somebody lands on straight after paying. It is the one
   moment the buyer has already committed, so it owes them calm and
   specifics rather than celebration.
   ══════════════════════════════════════════════════════════════ */
.thanks {
  padding: var(--stack-lg) var(--gutter) var(--section-y);
  max-width: 1400px;
  margin-inline: auto;
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  align-items: center;
}
/* The artwork sits second in the source, because somebody who has just
   paid should read that it worked before they scroll past a square metre
   of picture. On a wide screen there is room for both at once, so it
   moves back to the left where the eye lands first. */
@media (min-width: 901px) {
  .thanks {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
    gap: clamp(2.5rem, 6vw, 6rem);
  }
  .thanks__art { grid-column: 1; grid-row: 1; }
  .thanks__body { grid-column: 2; grid-row: 1; }
}

.thanks__art { max-width: 34rem; }
.thanks__art img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  filter: grayscale(1);
  border: 1px solid var(--hairline);
}

.thanks__body { display: flex; flex-direction: column; gap: var(--stack-sm); }

.thanks__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 88;
  font-size: clamp(2.5rem, 6.5vw, 5rem);
  line-height: 1;
  letter-spacing: 0.004em;
  text-wrap: balance;
}

.thanks [data-order-eyebrow],
.thanks__number .label { font-size: var(--fs-small); }

.thanks__number {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding-block: var(--stack-sm);
  border-block: 1px solid var(--hairline);
}
.thanks__number[hidden],
.thanks__number [hidden] { display: none; }
.thanks__n {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 48;
  font-size: clamp(2rem, 4.5vw, 3.25rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Everything below the headline runs a step larger than the site's
   defaults. This page is read once, carefully, by somebody who has just
   spent real money and wants to know what happens now — small print is
   exactly the wrong register for it. */
.thanks__lede { font-size: clamp(1.1875rem, 1.8vw, 1.625rem); }

.thanks__next { display: flex; flex-direction: column; }
.thanks__step {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.15rem 1.5rem;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--hairline-soft);
}
@media (min-width: 560px) {
  .thanks__step { grid-template-columns: 6.5rem 1fr; align-items: baseline; }
}
.thanks__step dt { font-size: var(--fs-small); }
.thanks__step dd {
  font-size: clamp(1.0625rem, 1.25vw, 1.1875rem);
  color: var(--ink-dim);
  line-height: 1.65;
  text-wrap: pretty;
}

.thanks__contact {
  margin-top: 0.25rem;
  font-size: var(--fs-body);
  color: var(--ink-faint);
}

.thanks__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2.5rem;
  margin-top: var(--stack-sm);
  padding-top: var(--stack-sm);
  border-top: 1px solid var(--hairline);
}

/* ══════════════════════════════════════════════════════════════
   THE LABEL KIT  (/label/)

   The press kit is written for somebody who has already decided to
   write about the band. This one is written for somebody who has
   not decided anything, is looking at four other bands today, and
   will give the page ninety seconds. So: same world, same type,
   same greys — but the order is ruthless. Music first, facts
   second, prose last, and every claim near the thing that proves
   it.

   It builds almost entirely on the press-kit furniture above
   (.press__block, .factlist, .assetgrid, .datelist, .bio). What is
   new here is only what a label needs and a journalist does not.
   ══════════════════════════════════════════════════════════════ */

/* ── The head ─────────────────────────────────────────────── */
.epk__head { gap: var(--stack-sm); }

.epk__hook {
  max-width: 34ch;
  font-family: var(--font-display);
  font-weight: 500;
  font-variation-settings: "opsz" 32;
  font-size: clamp(1.375rem, 2.9vw, 2.25rem);
  line-height: 1.24;
  text-wrap: balance;
  color: var(--ink);
}
.epk__hook em { font-style: italic; }

/* Four facts, in a row, above the fold. On a phone they stack into
   a list; the point is that they are answered before anybody has to
   ask, not that they are in a row. */
.epk__strip {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border-top: 1px solid var(--hairline);
}
.epk__strip > div {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--hairline-soft);
}
.epk__strip dd {
  font-size: var(--fs-small);
  color: var(--ink);
  line-height: 1.5;
}
.epk__strip dd em { font-family: var(--font-display); font-style: italic; }
@media (min-width: 720px) {
  .epk__strip {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
    border-bottom: 1px solid var(--hairline);
  }
  .epk__strip > div {
    padding: 1rem clamp(1rem, 2vw, 2rem) 1.1rem 0;
    border-bottom: 0;
  }
  .epk__strip > div + div {
    padding-left: clamp(1rem, 2vw, 2rem);
    border-left: 1px solid var(--hairline-soft);
  }
}

.epk__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  margin-top: var(--stack-sm);
}
.epk__actions .btn { align-self: auto; }
.epk__actions .btn[aria-disabled="true"] {
  color: var(--ink-faint);
  border-color: var(--hairline-soft);
  pointer-events: none;
}

.epk__jump {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  padding-block: var(--stack-sm);
  border-block: 1px solid var(--hairline-soft);
}
.epk__jump a {
  font-size: var(--fs-caption);
  letter-spacing: var(--tr-nav);
  text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft);
}
.epk__jump a:hover { color: var(--ink); border-bottom-color: var(--hairline); }

/* Type and photograph side by side, so the band is a face before it is
   a paragraph and the facts still clear the fold. Below 900px the
   picture goes first: on a phone there is no "beside", and a wall of
   type with no idea who wrote it is the worse of the two orders. */
/* Hero, facts and contents are one block with its own tighter rhythm.
   Left to the page's section spacing they read as three unrelated
   things separated by holes. */
.epk__top {
  display: flex;
  flex-direction: column;
  gap: var(--stack-md);
}

.epk__hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--stack-md);
  align-items: center;
}
@media (min-width: 900px) {
  .epk__hero {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.58fr);
    gap: clamp(2rem, 5vw, 4.5rem);
  }
  .epk__hero .epk__head { order: 1; }
  .epk__hero .epk__portrait { order: 2; }
}

/* The page title is set against the whole width elsewhere; here it has
   a column, so it comes down enough to stay on one line rather than
   dropping DAY onto a line of its own. */
@media (min-width: 900px) {
  .epk__hero .page__title { font-size: clamp(2.5rem, 4.4vw, 4rem); }
}

.epk__portrait { display: flex; flex-direction: column; gap: 0.6rem; }
/* The homepage cover's photograph and grade, cropped for a box rather
   than for a whole viewport. The frame carries a lot of empty wall
   above the group and almost none below, so the crop is weighted to
   the bottom: the homepage's 28% is right for a full-height figure and
   here it took the feet off while keeping the ceiling. */
.epk__portrait img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  object-position: 50% 88%;
  filter: grayscale(1) contrast(1.04);
  border: 1px solid var(--hairline-soft);
}
/* On a phone the picture goes first — there is no "beside", and a wall
   of type with no idea who wrote it is the worse of the two orders. It
   squares up rather than staying 4:5 so it does not fill the screen on
   its own, and holds the crop high, where the faces are. */
@media (max-width: 899px) {
  .epk__hero .epk__portrait { order: -1; }
  /* Square rather than landscape: cropping a 2:3 frame to 4:3 throws away
     half its height, and at this crop position what goes is the half with
     the band in it. */
  .epk__portrait img { aspect-ratio: 1; }
}

/* ── Listen ───────────────────────────────────────────────── */
.listen {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  align-items: start;
  margin-top: var(--stack-sm);
}
@media (min-width: 780px) {
  .listen {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(2rem, 5vw, 4rem);
  }
}
.stream__pass { display: block; font-variant-numeric: tabular-nums; }

.riyl {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1.25rem;
  margin-top: var(--stack-sm);
  padding-top: var(--stack-sm);
  border-top: 1px solid var(--hairline-soft);
}
.riyl[hidden] { display: none; }
.riyl__names { font-size: var(--fs-small); color: var(--ink); }

/* ── Audience ─────────────────────────────────────────────── */
.numbers {
  display: flex;
  flex-direction: column;
  gap: var(--stack-sm);
  margin-top: var(--stack-sm);
}
.numbers[hidden] { display: none; }
.numbers__grid {
  list-style: none;
  display: grid;
  gap: var(--stack-sm) clamp(1.5rem, 4vw, 3.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
}
.numbers__item { display: flex; flex-direction: column; gap: 0.15rem; }
.numbers__n {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 46;
  font-size: clamp(1.75rem, 3.6vw, 2.75rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* ── What is already true ─────────────────────────────────── */
.points { list-style: none; display: flex; flex-direction: column; }
.points__item {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: 0.25rem 1.25rem;
  padding-block: clamp(1rem, 2.4vh, 1.6rem);
  border-bottom: 1px solid var(--hairline-soft);
}
.points__item:first-child { border-top: 1px solid var(--hairline); }
.points__n { padding-top: 0.4rem; font-variant-numeric: tabular-nums; }
.points__text {
  max-width: 66ch;
  font-size: var(--fs-body);
  line-height: 1.75;
  color: var(--ink-dim);
  text-wrap: pretty;
}
.points__text strong { font-weight: 400; color: var(--ink); }
.points__text em { font-family: var(--font-display); font-style: italic; color: var(--ink); }

/* ── The record ───────────────────────────────────────────── */
.record__split {
  display: grid;
  gap: var(--stack-md);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .record__split {
    grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4rem);
  }
}
.record__art { display: flex; flex-direction: column; gap: 0.6rem; }
.record__art img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  filter: grayscale(1);
  border: 1px solid var(--hairline-soft);
}
.record__art figcaption em { font-style: italic; }
.record__prose { display: flex; flex-direction: column; gap: var(--stack-sm); }

/* The plan is a separate statement from the description of the record,
   not a continuation of it, and it was reading as one more block in the
   same column. */
.record__plan { margin-top: var(--stack-lg); }
.factlist--tight { margin-top: 0.5rem; }
.factlist--tight .factlist__row { padding-block: 0.6rem; }
.factlist--tight dd { font-size: var(--fs-body); font-family: var(--font-ui); font-weight: 300; }

/* ── The six, as a list rather than six portraits ─────────── */
.roles {
  list-style: none;
  display: grid;
  gap: 0 clamp(1.5rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
  margin-top: var(--stack-sm);
  padding-top: var(--stack-sm);
  border-top: 1px solid var(--hairline-soft);
}
/* Six names divide into two rows of three and nothing else — auto-fit
   leaves a widow on most widths, and a lone drummer under five other
   people reads as an afterthought. */
@media (min-width: 520px) { .roles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 860px) { .roles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.roles__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.55rem;
  border-bottom: 1px solid var(--hairline-soft);
}
.roles__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 18;
  font-size: 1.0625rem;
}

/* The artwork is square and the photographs are not. Rather than crop a
   cover to match a portrait, it keeps its shape inside the same box, so
   the four captions still sit on one line. */
.asset--square img {
  object-fit: contain;
  background: var(--ground-raised);
  padding: 0.75rem;
}
.asset__name em { font-family: var(--font-display); font-style: italic; }

/* ── The ask ──────────────────────────────────────────────── */
.ask {
  display: flex;
  flex-direction: column;
  gap: var(--stack-sm);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  background: var(--ground-raised);
  border: 1px solid var(--hairline);
}
.ask__text {
  max-width: 22ch;
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 48;
  font-size: clamp(1.625rem, 4vw, 3rem);
  line-height: 1.08;
  letter-spacing: 0.004em;
  text-wrap: balance;
}
.ask__text em { font-style: italic; }

/* ── Contact ──────────────────────────────────────────────── */
.contact { display: flex; flex-direction: column; gap: 0.35rem; }
.contact__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 34;
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  line-height: 1.1;
}
.contact__email {
  align-self: flex-start;
  margin-top: 0.6rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 30;
  font-size: clamp(1.125rem, 2.6vw, 1.75rem);
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 3px;
  word-break: break-word;
  transition: border-color var(--dur-fast) var(--ease-soft);
}
.contact__email:hover { border-color: var(--ink); }

/* ── Compose — band only, behind ?compose=1 ───────────────────
   Deliberately looks like a tool rather than like the page it sits
   on: raised ground, monospace, no display face. Nobody should be
   able to mistake it for something a label was meant to read. */
.compose[hidden] { display: none; }
.compose .section-head { border-bottom-color: var(--hairline); }

.rules {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: clamp(1rem, 2.5vw, 1.5rem);
  border: 1px solid var(--hairline-soft);
}
.rules[hidden] { display: none; }
.rules__item {
  position: relative;
  padding-left: 1.5rem;
  font-size: var(--fs-small);
  line-height: 1.65;
  color: var(--ink-dim);
}
.rules__item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 8px;
  height: 8px;
  border: 1px solid var(--ink-faint);
}

.compose__box {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: clamp(1rem, 2.5vw, 1.5rem);
  background: var(--ground-raised);
  border: 1px solid var(--hairline);
}
.compose__body {
  max-height: 60vh;
  overflow: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--ink-dim);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* An empty line in the email must still occupy a line, or the copied
   text and the shown text stop agreeing. */
.compose__line { min-height: 1.7em; }

.epk__sub { max-width: 52ch; }

/* ── The player ───────────────────────────────────────────────
   Built like a piece of equipment rather than a piece of the page:
   a raised panel, one square control, and a waveform that is the
   only wide thing on it. The canvas takes its colours from the
   tokens at draw time, so it is not a second palette. */
.player {
  display: flex;
  flex-direction: column;
  gap: var(--stack-sm);
  padding: clamp(1.1rem, 2.8vw, 1.9rem);
  background: var(--ground-raised);
  border: 1px solid var(--hairline);
}
.player[hidden] { display: none; }

.player__deck {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(0.9rem, 2.4vw, 1.75rem);
}

.player__toggle {
  display: grid;
  place-items: center;
  width: clamp(3rem, 5.5vw, 4rem);
  aspect-ratio: 1;
  border: 1px solid var(--hairline);
  color: var(--ink);
  transition: background-color var(--dur-fast) var(--ease-soft),
              border-color     var(--dur-fast) var(--ease-soft),
              color            var(--dur-fast) var(--ease-soft);
}
.player__toggle:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ground);
}
.player[data-playing] .player__toggle { border-color: var(--ink); }
.player__icon { width: 42%; height: auto; fill: currentColor; }
.player__icon [hidden] { display: none; }

.player__wave {
  position: relative;
  height: clamp(52px, 8vw, 84px);
  cursor: pointer;
  /* Dragging the playhead must scrub, not scroll the page away. */
  touch-action: none;
}
.player__canvas { width: 100%; height: 100%; display: block; }

.player__time {
  display: flex;
  gap: 0.4rem;
  font-size: var(--fs-small);
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}
.player__sep { color: var(--ink-faint); }

/* Under 520px the clock drops beneath the waveform rather than
   squeezing it to a stripe. */
@media (max-width: 520px) {
  .player__deck { grid-template-columns: auto minmax(0, 1fr); }
  .player__time { grid-column: 2; justify-self: end; }
}

.player__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem 1.1rem;
  padding-top: var(--stack-sm);
  border-top: 1px solid var(--hairline-soft);
}
.player__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 30;
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  line-height: 1.1;
}
.player__status:empty { display: none; }

.player__list { list-style: none; display: flex; flex-direction: column; }
.player__list[hidden] { display: none; }
.player__pick {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 1rem;
  width: 100%;
  text-align: left;
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--hairline-soft);
  color: var(--ink-dim);
  transition: color var(--dur-fast) var(--ease-soft);
}
.player__pick:hover { color: var(--ink); }
.player__pick[aria-current="true"] { color: var(--ink); }
.player__pick[aria-current="true"] .player__row-title { text-decoration: underline; text-underline-offset: 4px; }
.player__row-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 18;
  font-size: 1.0625rem;
  color: inherit;
}

/* ── Three ways in ────────────────────────────────────────────
   Numbered rather than bulleted: they are alternatives of equal
   standing, and none of them is a fallback for another. */
.ways { list-style: none; display: flex; flex-direction: column; }
.way {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: 0.15rem 1rem;
  padding-block: clamp(0.9rem, 2.2vh, 1.35rem);
  border-bottom: 1px solid var(--hairline-soft);
}
.way:first-child { border-top: 1px solid var(--hairline); }
.way__n { padding-top: 0.45rem; }
.way__body { display: flex; flex-direction: column; gap: 0.3rem; }
.way__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 22;
  font-size: clamp(1.125rem, 2vw, 1.4375rem);
  line-height: 1.15;
}
.way__link {
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 2px;
  transition: border-color var(--dur-fast) var(--ease-soft);
}
.way__link:hover { border-color: var(--ink); }
.way__note {
  max-width: 48ch;
  font-size: var(--fs-small);
  line-height: 1.7;
  color: var(--ink-dim);
}
.way__note em { font-family: var(--font-display); font-style: italic; color: var(--ink); }
.stream__pass { display: block; font-variant-numeric: tabular-nums; }

/* ── Everywhere else ──────────────────────────────────────────
   These used to be a line of nine-pixel type at the bottom of the
   fact table. They are among the first things an A&R opens, so they
   are boxes you can hit rather than words you have to find — and
   they appear twice, once in the facts and once at the end, because
   the person who decides to go and look is not always the person
   still scrolling. */
.socials-block {
  display: flex;
  flex-direction: column;
  gap: var(--stack-sm);
  margin-top: var(--stack-md);
}
.socials {
  list-style: none;
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11.5rem), 1fr));
}
.socials__item a {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  height: 100%;
  padding: 0.9rem 1.1rem 1rem;
  border: 1px solid var(--hairline-soft);
  transition: border-color var(--dur-fast) var(--ease-soft),
              background-color var(--dur-fast) var(--ease-soft);
}
.socials__item a:hover,
.socials__item a:focus-visible {
  border-color: var(--ink);
  background: var(--ground-raised);
}
.socials__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 20;
  font-size: 1.0625rem;
  line-height: 1.15;
}
.socials__handle { overflow-wrap: anywhere; }
.socials-block--large .socials {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13.5rem), 1fr));
}
.socials-block--large .socials__item a { padding: 1.1rem 1.25rem 1.25rem; }
.socials-block--large .socials__name {
  font-variation-settings: "opsz" 26;
  font-size: clamp(1.125rem, 1.8vw, 1.375rem);
}

/* ── The four asks ────────────────────────────────────────────
   The one part of the page that is about money, so it is set like
   the rest of the document rather than like a pitch deck. */
.asks {
  list-style: none;
  display: flex;
  flex-direction: column;
  margin-top: var(--stack-md);
}
.asks__item {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: 0.25rem 1.25rem;
  padding-block: clamp(1.1rem, 2.6vh, 1.75rem);
  border-bottom: 1px solid var(--hairline-soft);
}
.asks__item:first-child { border-top: 1px solid var(--hairline); }
.asks__n { padding-top: 0.55rem; }
.asks__body { display: flex; flex-direction: column; gap: 0.45rem; }
.asks__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 26;
  font-size: clamp(1.1875rem, 2.3vw, 1.6875rem);
  line-height: 1.14;
  letter-spacing: 0.004em;
}
.asks__note {
  max-width: 62ch;
  font-size: var(--fs-small);
  line-height: 1.75;
  color: var(--ink-dim);
  text-wrap: pretty;
}
.asks__note strong { font-weight: 400; color: var(--ink); }
.asks__note em { font-family: var(--font-display); font-style: italic; color: var(--ink); }
/* Money, set as a ledger rather than as prose. An A&R reads down the
   right-hand column and does the arithmetic, so the figures line up on
   tabular numerals and the labels stay out of their way. */
.figures {
  display: flex;
  flex-direction: column;
  margin-top: 0.75rem;
  max-width: 34rem;
  border-top: 1px solid var(--hairline-soft);
}
.figures__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  padding-block: 0.5rem;
  border-bottom: 1px solid var(--hairline-soft);
}
.figures dt {
  font-size: var(--fs-caption);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.figures dd {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 18;
  font-size: 1.0625rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ask__foot strong { font-weight: 400; color: var(--ink); }
.ask__foot { margin-top: var(--stack-sm); }
.ask__foot em { font-family: var(--font-display); font-style: italic; color: var(--ink); }

/* ── The artwork caption ──────────────────────────────────────
   Two lines under the cover: what it is, and who made it. The
   artwork itself is supplied on request rather than offered here,
   the same way /press/ handles it, so the band can keep track of
   where it ends up. */
.artcap {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--hairline);
}
.artcap__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 20;
  font-size: 1.125rem;
  line-height: 1.15;
}
.artcap__title em { font-style: italic; }
.artcap__by {
  color: var(--ink-dim);
  border-bottom: 1px solid var(--hairline);
  transition: color var(--dur-fast) var(--ease-soft),
              border-color var(--dur-fast) var(--ease-soft);
}
.artcap__by:hover { color: var(--ink); border-color: var(--ink); }

/* ── Watch ────────────────────────────────────────────────────
   Its own section beside the live history, because the question it
   answers is whether they can do it in a room. */
.watchblock {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--stack-md);
  align-items: start;
}
@media (min-width: 900px) {
  .watchblock {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4rem);
  }
}
.watchblock__text { display: flex; flex-direction: column; gap: var(--stack-sm); }
.watchblock__text em { font-family: var(--font-display); font-style: italic; color: var(--ink); }


/* ══════════════════════════════════════════════════════════════
   THE WAY IN  (/label/)

   Black, then a greeting, then a door. It only ever exists because
   js/intro.js reveals it, so none of this can strand a reader.
   ══════════════════════════════════════════════════════════════ */
.intro {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background: var(--ground);
  opacity: 1;
  transition: opacity 1200ms var(--ease-soft);
}
.intro[hidden] { display: none; }
.intro[data-closing] { opacity: 0; pointer-events: none; }

/* The same light the rest of the site carries, arriving slowly from
   nothing. It is the only thing moving during the first beat, and it
   is what stops the black reading as a failed page. */
.intro::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(58% 42% at 50% 46%,
    rgb(237 234 228 / 0.075) 0%,
    rgb(237 234 228 / 0.028) 42%,
    transparent 72%);
  opacity: 0;
  transform: scale(0.82);
  transition: opacity 3200ms var(--ease-soft), transform 5200ms var(--ease);
}
.intro:not([hidden])::before { opacity: 1; transform: none; }

/* Edges pulled down toward black. The glow above lifts the centre; this
   closes the corners, and between them the screen stops being a flat
   rectangle of #050505. */
.intro::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(78% 78% at 50% 50%,
    transparent 32%,
    rgb(0 0 0 / 0.34) 78%,
    rgb(0 0 0 / 0.62) 100%);
}

/* Grain over the type as well as the ground, which is the way round film
   does it. Low z-index, but this is inside the overlay's own stacking
   context, so it reads as "just above the backdrop" rather than 90. */
.intro__grain {
  z-index: 3;
  opacity: 0.07;
}

.intro__inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1rem, 2.8vh, 1.85rem);
  padding: var(--gutter);
  text-align: center;
  transition: opacity 1200ms var(--ease-soft), transform 1600ms var(--ease);
}
/* The card pushes very slightly toward the viewer as it goes, so leaving
   reads as a move rather than a light switch. */
.intro[data-closing] .intro__inner { opacity: 0; transform: scale(1.045); }

/* Each beat is held back until js/intro.js marks it in. One rule for
   the three of them, rather than a step ladder of selectors. */
.intro__word,
.intro__name,
.intro__enter {
  opacity: 0;
  transform: translateY(0.65rem);
  transition: opacity var(--dur-slow) var(--ease),
              transform var(--dur-slow) var(--ease);
}
.intro__word[data-in],
.intro__name[data-in],
.intro__enter[data-in] { opacity: 1; transform: none; }

/* Set as a title card rather than a caption: large, and tracked so far
   apart that it reads as spacing before it reads as a word. It arrives
   wider still and closes to this over two and a half seconds — the one
   piece of motion on the page that is purely for effect.

   letter-spacing pads the right of the last letter, so text-indent
   carries the same value to keep the word optically centred, and has to
   travel with it. */
.intro__word {
  font-size: clamp(1rem, 2.6vw, 1.875rem);
  font-weight: 300;
  letter-spacing: 0.52em;
  text-indent: 0.52em;
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: opacity 1800ms var(--ease),
              transform var(--dur-slow) var(--ease),
              letter-spacing 2600ms var(--ease),
              text-indent 2600ms var(--ease);
}
.intro__word:not([data-in]) {
  letter-spacing: 1.15em;
  text-indent: 1.15em;
}

.intro__name {
  max-width: 18ch;
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 84;
  font-size: clamp(2rem, 7.5vw, 5.5rem);
  line-height: 1.02;
  letter-spacing: 0.004em;
  text-wrap: balance;
  transition: opacity 1600ms var(--ease), transform 2200ms var(--ease);
}
/* Settles down out of a slight enlargement rather than sliding up: the
   name should arrive the way a title does, not the way a list item does. */
.intro__name:not([data-in]) { transform: scale(1.035) translateY(0.35rem); }

/* Drawn, not faded. It follows the name in and is the cue that something
   else is still coming. */
.intro__hair {
  display: block;
  width: clamp(3rem, 9vw, 6rem);
  height: 1px;
  margin-block: 0.35rem 0.15rem;
  background: var(--ink-faint);
  transform: scaleX(0);
  opacity: 0;
  transition: transform 1800ms var(--ease), opacity 900ms var(--ease-soft);
}
.intro__name[data-in] ~ .intro__hair { transform: scaleX(1); opacity: 1; }

.intro__enter {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  padding: 0.5rem 1rem;
  color: var(--ink-dim);
  transition: opacity var(--dur-slow) var(--ease),
              transform var(--dur-slow) var(--ease),
              color var(--dur-fast) var(--ease-soft);
}
.intro__enter:hover,
.intro__enter:focus-visible { color: var(--ink); }
.intro__enter .label { color: inherit; }
.intro__rule {
  display: block;
  width: 30px; height: 1px;
  background: currentColor;
  transition: width var(--dur-mid) var(--ease);
}
.intro__enter:hover .intro__rule,
.intro__enter:focus-visible .intro__rule { width: 66px; }

/* Nothing behind the overlay should scroll while it is up. */
.intro-open, .intro-open body { overflow: hidden; }

/* The greeting is the point; the fading is decoration. With reduced
   motion the card simply is, and leaves the same way. */
.intro[data-reduced],
.intro[data-reduced]::before,
.intro[data-reduced] .intro__inner,
.intro[data-reduced] .intro__word,
.intro[data-reduced] .intro__name,
.intro[data-reduced] .intro__hair,
.intro[data-reduced] .intro__enter,
.intro[data-reduced] .intro__rule { transition: none; }
.intro[data-reduced]::before { opacity: 1; transform: none; }
.intro[data-reduced] .intro__word { letter-spacing: 0.52em; text-indent: 0.52em; }
.intro[data-reduced] .intro__name { transform: none; }
.intro[data-reduced] .intro__hair { transform: scaleX(1); opacity: 1; }

/* ══════════════════════════════════════════════════════════════
   PRINTING THE LABEL KIT
   Somebody will press Cmd-P and attach the PDF to an internal
   email, and that PDF should not be forty pages of black ink.

   Rather than repaint each rule, the whole palette is redeclared on
   the page: every colour downstream reads from these tokens, so
   inverting them here inverts everything at once — including the
   dozen places that set var(--ink) explicitly and would otherwise
   print white on white.
   ══════════════════════════════════════════════════════════════ */
@media print {
  .epk-page {
    --ground:        #ffffff;
    --ground-raised: #ffffff;
    --ink:           #111111;
    --ink-dim:       #333333;
    --ink-faint:     #595959;
    --hairline:      #c9c9c9;
    --hairline-soft: #e4e4e4;
    --scrim:         transparent;
    --signal:        #444444;
    --lunar: 0;

    background: #fff;
    color: #111;
  }

  /* Things that only mean something in a browser. */
  .epk-page .lunar,
  .epk-page .grain,
  .epk-page .skip,
  .epk-page .epk__jump,
  .epk-page .intro,
  .epk-page #watch,
  .epk-page .player,
  .epk-page .compose,
  .epk-page .epk__actions,
  .epk-page .asset__dl,
  .epk-page .copy,
  .epk-page .footer__mark { display: none; }

  /* The wordmark is a white PNG, which is nothing at all on paper. */
  .epk-page .pagenav img { filter: invert(1); }

  .epk-page .page__main { gap: 2rem; padding: 0 0 1rem; max-width: none; }
  .epk-page .press__block,
  .epk-page .points__item,
  .epk-page .factlist__row { break-inside: avoid; }
  .epk-page .section-title { break-after: avoid; }
  .epk-page .section-head { margin-bottom: 1.25rem; }
  .epk-page a { color: inherit; }
}


/* ══════════════════════════════════════════════════════════════
   THE DISPLAY WEIGHTS
   Everything set in the display face takes Widescreen's Thin weight;
   the large titles below take Hair, the lightest of the nine in the
   Adobe Fonts project. Hair at small sizes is too fine to read on the
   dark ground, which is why the two are split. Both rules are last in
   the file, so they win over the weight each rule above declares; the
   first list is every selector in this file that names the face.
   Bodoni has nothing this light, so the fallback renders at its
   lightest.
   ══════════════════════════════════════════════════════════════ */
.offer__title,
.offer__note em,
.js-nav .nav__links a,
.cover__title,
.cover__release-title,
.section-title,
.single__title,
.countdown__n,
.album__title,
.album__body em,
.member__name,
.live__empty,
.datelist__what,
.subscribe__title,
.page__title,
.bio__text em,
.prose h2,
.member__quote,
.edition__n,
.edition__title,
.edition__kind,
.edition__price,
.sl__title,
.sl__out,
.platform__name,
.record__title,
.artwork__name,
.wayout__title,
.track__title,
.song__title,
.song__head em,
.annot__body,
.song__nav-title,
.cycle__title,
.cycle__line,
.fragment__title,
.unveil__date,
.sealed__when,
.journey__n,
.thanks__title,
.thanks__n,
.epk__hook,
.epk__strip dd em,
.numbers__n,
.points__text em,
.roles__name,
.asset__name em,
.ask__text,
.contact__name,
.contact__email,
.player__title,
.player__row-title,
.way__title,
.way__note em,
.socials__name,
.asks__title,
.asks__note em,
.figures dd,
.ask__foot em,
.artcap__title,
.watchblock__text em,
.intro__name {
  font-weight: 200;
}

/* The large titles: Hair. */
.cover__title,
.section-title,
.album__title,
.single__title,
.subscribe__title,
.page__title,
.song__title,
.sl__title,
.record__title,
.cycle__title,
.edition__title,
.offer__title,
.thanks__title,
.wayout__title {
  font-weight: 100;
}

/* The album's name in running text, wherever it is mentioned: the
   display face, standing upright rather than leaning, at Regular so it
   stands out from the Thin around it. The class is repeated to outrank
   rules like ".factlist dd em" above, which would otherwise slant it. */
em.upright.upright.upright {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 400;
}
