/* ============================================================================
   THIRD SHIFT RECORDINGS — Detroit. Built to DESIGN_SYSTEM.md v1.0.

   THE PROBLEM, WHICH IS THE OPPOSITE OF EVERY PREVIOUS BUILD.
   On a record label the artwork IS the design. Six sleeves, six palettes, all
   of them loud, none of them negotiable. Every other build in this series
   supplied its own colour and asked the photography to fit. Here the interface
   has to get out of the way — and "get out of the way" cannot mean "be plain",
   because §12 counts basic as a failure state.

   THE ANSWER: THE INTERFACE TAKES ITS COLOUR FROM WHATEVER IS PLAYING.
   A dominant colour is extracted from the current sleeve at runtime, and the
   paper tints toward it. Not a glow, not an overlay — the room changes colour
   with the record. That is the concept, the colour system and the motion
   signature all at once, and it is a colour SYSTEM none of the previous builds
   used: extracted and reactive rather than chosen and fixed.

   CONTRAST IS NOT NEGOTIABLE THOUGH. The extracted colour is used raw only as
   a FILL. Wherever it carries text it is corrected in JS: the hue survives, the
   lightness is forced to whatever passes AA. Colour follows the art; legibility
   does not.

   ONE LINE   the room changes colour with the record
   REGISTER   a pressing plant and a gallery wall. Detroit techno's own visual
              language is stark, geometric and unsentimental — Metroplex and
              Basic Channel rather than any music-site convention.

   §12.0a — checked before writing, not after:
     · No enumerated section markers. Catalogue numbers appear ON RELEASES,
       because a discography genuinely IS numbered and the order is the content.
       No number is ever used to label a section.
     · No decorative background grid.
     · No monospace face — two builds running now. Figures are tabular in the
       one face, which is what a mono was being used for.

   CONTEXT (§12)  A2 · B1 · C5 · D3 · E3  →  motion ceiling 3
     Nobody is in a hurry on a label site and the session is long. The
     discipline is unchanged: everything interactive answers a real question.
     What does it sound like. What else is on it. What is it. What else is like
     it.

   TYPE (§6) — ratio 1.414 (root two), eight steps. Distinct from 1.333 / 1.5 /
     1.6 / 1.25.
     EXPRESSIVE CHANNEL: CASE. The entire interface is set lower case, without
     exception. The only capitals anywhere on the page belong to the ARTWORK.
     That is the interface receding, made into a rule that can be checked.
     One face, Instrument Sans, in three weights. No second face, no mono.

   TEXTURE — THE WAVEFORM. The signature is the sound itself: a live analyser
     trace behind the player and across the hero. Nothing is printed, stamped,
     grained or gridded; the texture is what is currently audible.

   INTERACTION SIGNATURE — "it cues."
   ========================================================================= */

:root {
  --paper:   #F1F2F4;
  /* the literal, which never changes. --ink is re-pointed inside the inverted
     band, so anything that must stay dark in there reads --ink-0 instead. */
  --ink-0:   #0E0F11;
  --ink:     var(--ink-0);   /* 17.12:1 on paper */
  --ink-2:   #54585E;   /* 6.39 */
  /* solved against EVERY ground the reactive tint can produce, not just
     plain paper: #74797F measured 4.55 on paper but only 3.92 once the
     page had tinted toward a blue sleeve. #606469 holds >=4.60 across
     all six catalogue accents at the 7% tint. */
  --ink-3:   #606469;
  --line:    #D8DAE0;
  --line-2:  #BFC3CB;
  --panel:   #E7E9ED;

  /* set at runtime from the playing sleeve. --accent is contrast-corrected in
     JS and safe for text; --accent-raw is the untouched extraction and is only
     ever used as a fill. */
  --accent:     #54585E;
  --accent-raw: #54585E;
  --tint: 7%;

  /* THE INVERTED GROUND. The page was divided by whitespace and 1px rules and
     nothing else, which is why it read plain (§4: a page needs three or four
     KINDS of edge, and division you can predict stops registering). This is
     the second channel, and it tints with the record like everything else.
     Solved across all six catalogue accents, not against plain ink:
       paper on the band   15.29:1 worst
       --on-ink-2          6.37:1 worst  */
  --ink-band: color-mix(in srgb, var(--ink-0) 94%, var(--accent-raw));
  --on-ink-2: #9A9EA6;
  --line-ink: color-mix(in srgb, var(--paper) 20%, transparent);

  --f: 'Instrument Sans', system-ui, -apple-system, sans-serif;

  /* ratio 1.414 */
  --t-3xs: .6875rem; --t-2xs: .78125rem; --t-xs: .875rem;
  --t-sm: .9375rem;  --t-base: 1.0625rem; --t-md: 1.5rem;
  --t-lg: clamp(1.9rem, 1.3rem + 2.2vw, 2.6rem);
  --t-xl: clamp(3.2rem, 1.1rem + 4.6vw, 4.6rem);

  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:20px; --s-6:24px;
  --s-8:32px; --s-10:40px; --s-12:48px; --s-16:64px; --s-20:80px; --s-24:96px; --s-32:128px;
  --measure: 62ch;

  --ease: cubic-bezier(.2,.8,.25,1);
  --cue: 200ms;
  --slow: 700ms;
  --bar: 84px;          /* the player never covers content */
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--paper); scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0; color: var(--ink);
  font-family: var(--f); font-size: var(--t-base); line-height: 1.6;
  overflow-x: hidden;
  padding-bottom: var(--bar);
  /* THE REACTIVE GROUND. Verified: at a 10% tint with the most extreme accent
     in the catalogue, ink still measures 13.97:1 and ink-2 5.21:1. */
  background: color-mix(in srgb, var(--paper) calc(100% - var(--tint)), var(--accent-raw) var(--tint));
  transition: background var(--slow) var(--ease);
}
img { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--ink); color: var(--paper); }

/* THE CHANNEL: lower case, everywhere, without exception. The only capitals on
   this site are inside the artwork. */
body, button, input, select, h1, h2, h3, h4 { text-transform: lowercase; }
/* proper nouns that would read as errors keep their capitals */
.keepcase { text-transform: none; }

.shell { width: min(1320px, 100%); margin-inline: auto; padding-inline: clamp(var(--s-5), 4vw, var(--s-16)); }
.band { padding-block: clamp(var(--s-16), 6vw, var(--s-32)); }
.band--tight { padding-block: clamp(var(--s-10), 4vw, var(--s-16)); }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ---------------------------------------------------------- the ink band
   A ground change, and the one bleed moment on the page — full width, no
   shell. Everything inside it re-points at the on-ink tokens rather than
   overriding colours one selector at a time. */
.band--ink {
  background: var(--ink-band);
  color: var(--paper);
  transition: background var(--slow) var(--ease);
  --ink: var(--paper);
  --ink-2: var(--on-ink-2);
  --ink-3: var(--on-ink-2);
  --line: var(--line-ink);
  --line-2: color-mix(in srgb, var(--paper) 34%, transparent);
  --panel: color-mix(in srgb, var(--paper) 10%, transparent);
}
.band--ink .btn { background: var(--paper); color: var(--ink-0); }
.band--ink .btn:hover, .band--ink .btn:focus-visible { background: #FFFFFE; }
.band--ink .btn--ghost { background: transparent; color: var(--paper); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--paper) 38%, transparent); }
.band--ink .btn--ghost:hover, .band--ink .btn--ghost:focus-visible { background: color-mix(in srgb, var(--paper) 12%, transparent); box-shadow: inset 0 0 0 1px var(--paper); }
.band--ink :where(a,button,input,select,summary):focus-visible { outline-color: var(--paper); }
.band--ink ::selection { background: var(--paper); color: var(--ink-0); }

/* ---------------------------------------------------------------- type */
h1,h2,h3,h4 { margin: 0; font-weight: 600; line-height: 1.05; letter-spacing: -0.025em; }
.h1 { font-size: var(--t-xl); }
.h2 { font-size: var(--t-lg); margin-bottom: var(--s-5); }
.h3 { font-size: var(--t-md); letter-spacing: -0.015em; }
.lede { font-size: var(--t-md); line-height: 1.4; max-width: 38ch; margin: 0; color: var(--ink-2); }
.prose { max-width: var(--measure); color: var(--ink-2); }
.prose p { margin: 0 0 var(--s-5); }
.prose p:last-child { margin-bottom: 0; }
.prose strong { color: var(--ink); font-weight: 600; }
.prose a { color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.fig { font-variant-numeric: tabular-nums lining-nums; }
.dim { color: var(--ink-3); }

/* the catalogue number — the one place figures lead. A discography IS numbered
   and the order IS the content (§12.0a), so this is a legitimate number and
   never a section label. */
.cat { font-variant-numeric: tabular-nums; font-weight: 600; letter-spacing: .02em; }

/* ---------------------------------------------------------------- actions
   INTERACTION SIGNATURE — "it cues."
   A 2px marker drops in at the leading edge, the way a cue point lands, and
   the surface lifts a shade. 200ms, no travel, no scale, no glow. Everything
   reverses on leave. Distinct from thickens / seats / advances / rises. */
.btn {
  position: relative; display: inline-flex; align-items: center; gap: var(--s-3);
  font-family: var(--f); font-weight: 600; font-size: var(--t-sm);
  text-decoration: none; cursor: pointer;
  padding: var(--s-4) var(--s-6); border: 0;
  background: var(--ink); color: var(--paper);
  transition: background var(--cue) var(--ease);
}
.btn::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--accent-raw); transform: scaleY(0); transform-origin: top;
  transition: transform var(--cue) var(--ease);
}
.btn:hover, .btn:focus-visible { background: #1B1D21; }
.btn:hover::before, .btn:focus-visible::before { transform: scaleY(1); }
.btn:active { background: #000; }
.btn--lg { font-size: var(--t-md); padding: var(--s-5) var(--s-8); }
.btn--ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-2); }
.btn--ghost:hover, .btn--ghost:focus-visible { background: var(--panel); box-shadow: inset 0 0 0 1px var(--ink); }

.tlink { color: var(--ink); text-decoration: none; box-shadow: inset 0 -1px 0 var(--line-2); transition: box-shadow var(--cue) var(--ease); }
.tlink:hover, .tlink:focus-visible { box-shadow: inset 0 -2px 0 var(--ink); }

:where(a,button,input,select,summary):focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.skip { position: absolute; left: -9999px; background: var(--ink); color: var(--paper); padding: var(--s-3) var(--s-5); z-index: 90; }
.skip:focus { left: var(--s-4); top: var(--s-4); }
.vh { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); clip-path: inset(50%); white-space:nowrap; }

/* ---------------------------------------------------------------- masthead */
.masthead { position: sticky; top: 0; z-index: 50; background: color-mix(in srgb, var(--paper) 88%, transparent); backdrop-filter: blur(12px); border-bottom: 1px solid var(--line); }
.masthead__in { display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-8); align-items: center; justify-content: space-between; padding-block: var(--s-4); }
.wordmark { font-weight: 600; font-size: var(--t-md); letter-spacing: -0.03em; text-decoration: none; line-height: 1; display: flex; align-items: baseline; gap: var(--s-3); }
.wordmark span { font-size: var(--t-3xs); font-weight: 400; letter-spacing: .04em; color: var(--ink-3); }
.nav { display: flex; flex-wrap: wrap; gap: var(--s-6); font-size: var(--t-sm); }
.nav a { position: relative; text-decoration: none; color: var(--ink-2); padding-bottom: 3px; transition: color var(--cue) var(--ease); }
.nav a::after { content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background: var(--ink); transform: scaleX(0); transform-origin: left; transition: transform var(--cue) var(--ease); }
.nav a:hover, .nav a:focus-visible, .nav a[aria-current="page"] { color: var(--ink); }
.nav a:hover::after, .nav a:focus-visible::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }

/* ---------------------------------------------------------------- sleeves */
.sleeve { display: block; position: relative; overflow: hidden; background: var(--panel); aspect-ratio: 1/1; }
.sleeve img { width: 100%; height: 100%; object-fit: cover; }
.sleeve--play::after {
  content: ""; position: absolute; inset: 0;
  background: color-mix(in srgb, var(--ink) 0%, transparent);
  transition: background var(--cue) var(--ease);
}
a:hover .sleeve--play::after, a:focus-visible .sleeve--play::after { background: color-mix(in srgb, var(--ink) 14%, transparent); }

/* ================================================================== HERO
   DEPTH (§8) runs on three channels here, not one: the sleeve OVERLAPS the
   trace register below it, it is the largest thing on the page by a wide
   margin (scale), and it casts a two-layer tinted shadow — a tight contact
   shadow and a wide ambient one, both mixed from the record's own colour
   rather than from black. The planes are the site's own subject: the
   waveform behind, the sleeve in front. Nothing is borrowed scenery. */
.hero { display: grid; gap: var(--s-10); align-items: center; padding-block: clamp(var(--s-16), 6vw, var(--s-24)) 0; }
@media (min-width: 900px) { .hero { grid-template-columns: 1fr .8fr; gap: var(--s-20); } }
.hero__art { position: relative; z-index: 2; }
.hero__art .sleeve {
  box-shadow:
    0 2px 5px -2px color-mix(in srgb, var(--accent-raw) 38%, transparent),
    0 34px 64px -30px color-mix(in srgb, var(--accent-raw) 60%, transparent);
}

/* the register the sleeve sits into: full bleed, no shell. A third division
   channel (texture change + bleed) between the hero and the catalogue. */
.register {
  position: relative;
  /* net -56px, so the sleeve genuinely descends into the register rather
     than stopping on top of it — overlap is the depth channel, not the gap */
  margin-top: calc(var(--s-16) * -1);
  padding-top: var(--s-2);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
@media (max-width: 899px) { .register { margin-top: var(--s-8); padding-top: 0; } }

/* ============================================================== CATALOGUE
   An index, because a discography is one. Rows, not cards: a catalogue is
   scanned down a column, and every row is playable in place. */
.cat-list { border-top: 1px solid var(--line); }
.rel {
  display: grid; gap: var(--s-2) var(--s-5);
  align-items: center; padding-block: var(--s-4);
  border-bottom: 1px solid var(--line); position: relative;
  transition: background var(--cue) var(--ease);
  /* NARROW FIRST. The old narrow track was `56px 1fr auto` with three of the
     six children pushed to `grid-column: 2 / -1`, which left the title to
     auto-place into the 56px art column and collapsed the play column to
     0px: measured at 390px, every row was 317px tall with the title broken
     one word per line. Explicit areas, so nothing auto-places. */
  grid-template-columns: 64px auto minmax(0, 1fr) 44px;
  grid-template-areas:
    "art cat cat play"
    "art t   t   play"
    "art ma  mb  play";
}
.rel__art  { grid-area: art; align-self: start; }
.rel__cat  { grid-area: cat; }
.rel__t    { grid-area: t; }
.rel__meta--a { grid-area: ma; }
.rel__meta--b { grid-area: mb; }
.rel > .play { grid-area: play; }
/* tightened: at 1440 the old track was 56px 9ch 1fr 14ch 12ch auto, which
   parked the meta columns against the right edge and left a ~500px void in
   the middle of every row. An index earns its authority from density (§5). */
@media (min-width: 860px) {
  .rel {
    grid-template-columns: 64px 8ch minmax(0, 1fr) 15ch 15ch auto;
    grid-template-areas: "art cat t ma mb play";
    gap: var(--s-4) var(--s-5);
  }
  /* the slack goes to the title; the two meta columns are fixed and right
     aligned so they line up down the page instead of ragging */
  .rel__meta { text-align: right; }
}
.rel[hidden] { display: none; }
.rel::before {
  content: ""; position: absolute; left: calc(var(--s-4) * -1); top: 0; bottom: 0; width: 3px;
  background: var(--accent-raw); transform: scaleY(0); transform-origin: center;
  transition: transform var(--cue) var(--ease);
}
.rel:hover, .rel:focus-within { background: color-mix(in srgb, var(--panel) 60%, transparent); }
.rel:hover::before, .rel:focus-within::before { transform: scaleY(1); }
.rel.is-playing::before { transform: scaleY(1); }
.rel.is-playing { background: color-mix(in srgb, var(--accent-raw) 8%, transparent); }
.rel.is-loaded::before { transform: scaleY(1); opacity: .4; }
/* where the record has got to, on the row itself — so the catalogue shows the
   position without the player bar having to be looked at */
.rel.is-playing::after, .track.is-playing::after {
  content: ""; position: absolute; left: 0; bottom: -1px; height: 2px;
  width: var(--prog, 0%); background: var(--accent-raw);
}
.rel__art { width: 64px; }
.rel__cat { font-size: var(--t-2xs); color: var(--ink-3); }
.rel__t { font-weight: 600; line-height: 1.25; }
.rel__t a { text-decoration: none; }
.rel__t a:hover { text-decoration: underline; text-underline-offset: 3px; }
.rel__a { font-size: var(--t-sm); color: var(--ink-2); }
.rel__sep { margin-inline: .35em; }
.rel__meta { font-size: var(--t-2xs); color: var(--ink-3); }
@media (max-width: 859px) {
  .rel { column-gap: var(--s-3); }
  .rel__t { font-size: var(--t-sm); }
  /* the artist goes to its own line, so the separator would be an orphan
     bullet at the start of it */
  .rel__a { display: block; }
  .rel__sep { display: none; }
}

/* play button — the one control that appears everywhere */
.play {
  width: 44px; height: 44px; flex: none; display: grid; place-items: center;
  background: transparent; border: 1px solid var(--line-2); cursor: pointer;
  color: var(--ink); border-radius: 50%;
  transition: background var(--cue) var(--ease), border-color var(--cue) var(--ease);
}
.play:hover, .play:focus-visible { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.play[aria-pressed="true"] { background: var(--accent-raw); border-color: transparent; color: var(--ink); }
.play svg { width: 15px; height: 15px; display: block; }

/* ================================================================ FILTERS */
/* three filter groups rendered as one undifferentiated run of pills: 2019
   looked exactly like Kessler and there was nothing to say which axis you
   were on. Each group is now named. */
.filters { display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-8); align-items: flex-start; padding-block: var(--s-6); }
.fgroup { display: grid; gap: var(--s-2); }
.fgroup__l { font-size: var(--t-3xs); color: var(--ink-3); letter-spacing: .04em; }
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.filters__end { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; margin-left: auto; }
.chip {
  font-family: var(--f); font-size: var(--t-2xs); font-weight: 500;
  padding: var(--s-2) var(--s-4); cursor: pointer;
  background: transparent; color: var(--ink-2); border: 1px solid var(--line-2);
  border-radius: 999px; transition: all var(--cue) var(--ease);
}
.chip:hover { color: var(--ink); border-color: var(--ink); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.fcount { font-size: var(--t-2xs); color: var(--ink-3); margin: 0; }

/* ================================================================= RELEASE */
/* the sleeve column ran out ~480px before the text column did, leaving the
   left half of the page empty from the credits down. The credits now sit
   under the sleeve, where the two columns end together. */
.rel-head { display: grid; gap: var(--s-10); align-items: start; }
@media (min-width: 900px) { .rel-head { grid-template-columns: .85fr 1fr; gap: var(--s-16); } }
.rel-head__art .sleeve {
  box-shadow:
    0 2px 5px -2px color-mix(in srgb, var(--accent-raw) 32%, transparent),
    0 28px 56px -28px color-mix(in srgb, var(--accent-raw) 52%, transparent);
}
.tracks { border-top: 1px solid var(--line); margin-top: var(--s-8); }
.track { position: relative; display: grid; grid-template-columns: 44px 3ch 1fr auto; gap: var(--s-4); align-items: center; padding-block: var(--s-3); border-bottom: 1px solid var(--line); transition: background var(--cue) var(--ease); }
.track:hover, .track:focus-within { background: color-mix(in srgb, var(--panel) 60%, transparent); }
.track.is-playing { background: color-mix(in srgb, var(--accent-raw) 10%, transparent); }
.track.is-loaded { background: color-mix(in srgb, var(--accent-raw) 4%, transparent); }
.track__n { font-size: var(--t-2xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.track__t { font-weight: 500; }
.track__d { font-size: var(--t-2xs); color: var(--ink-3); font-variant-numeric: tabular-nums; }
.credits { display: grid; gap: var(--s-3); margin-top: var(--s-8); }
.credits div { display: grid; grid-template-columns: 14ch 1fr; gap: var(--s-4); font-size: var(--t-sm); }
.credits dt { color: var(--ink-3); }
.credits dd { margin: 0; }

/* ============================================================== THE PLAYER
   Persistent, and the one thing on the site that never scrolls away. It is a
   bar rather than a floating widget because a bar can be reserved for in the
   body padding and therefore never covers anything.

   THE WAVE SURVIVES ON TOUCH. It used to be display:none under 720px, which
   took the seek control, the progress and the entire textural signature off
   every phone at once — on a site whose texture IS the waveform. The bar
   goes to two rows there instead and reserves the extra height. */
.player {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  height: var(--bar);
  background: var(--ink-band);
  color: var(--paper);
  display: grid;
  grid-template-columns: auto auto auto minmax(0, 22ch) 1fr auto auto;
  grid-template-areas: "prev play next meta wave time x";
  align-items: center;
  gap: var(--s-2) var(--s-4);
  padding-inline: clamp(var(--s-4), 3vw, var(--s-10));
  transform: translateY(100%);
  transition: transform 420ms var(--ease), background var(--slow) var(--ease);
}
.player.is-up { transform: translateY(0); }
#p-prev { grid-area: prev; } #p-play { grid-area: play; } #p-next { grid-area: next; }
/* grid, not inline: the title and the artist are two lines, and until they
   were block-level the ellipsis on each of them could never apply */
.player__meta { grid-area: meta; min-width: 0; padding-left: var(--s-2); display: grid; align-content: center; }
.player__wave { grid-area: wave; }
.player__time { grid-area: time; }
.player__x    { grid-area: x; }

.player .play { border-color: color-mix(in srgb, var(--paper) 40%, transparent); color: var(--paper); }
.player .play:hover, .player .play:focus-visible { background: var(--paper); color: var(--ink-0); border-color: var(--paper); }
.player .play:focus-visible { outline-color: var(--paper); }
.player .play[disabled] { opacity: .3; cursor: default; }
.player .play[disabled]:hover { background: transparent; color: var(--paper); border-color: color-mix(in srgb, var(--paper) 40%, transparent); }
/* the transport sits a step below the play button — same family, less weight */
.play--nav { border-color: transparent; }
.play--nav svg { width: 13px; height: 13px; }
.player__t { font-weight: 600; font-size: var(--t-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.player__a { font-size: var(--t-2xs); color: var(--on-ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.player__wave { position: relative; height: 44px; cursor: pointer; }
.player__wave canvas { display: block; width: 100%; height: 100%; }
.player__time { font-size: var(--t-2xs); font-variant-numeric: tabular-nums; color: var(--on-ink-2); white-space: nowrap; }
.player__x { background: none; border: 0; color: var(--on-ink-2); cursor: pointer; font-size: var(--t-md); line-height: 1; min-width: 44px; min-height: 44px; }
.player__x:hover { color: var(--paper); }
.player__x:focus-visible { outline-color: var(--paper); }
@media (max-width: 760px) {
  :root { --bar: 132px; }
  .player {
    height: var(--bar);
    grid-template-columns: auto 1fr auto auto;
    grid-template-areas:
      "play meta meta x"
      "prev wave next time";
    align-content: center;
  }
  .player__meta { padding-left: 0; }
}

/* THE TEXTURAL SIGNATURE (§11), present in the first viewport whether or not
   anything is playing. At rest it draws the envelope of the bar this record
   WOULD play, off the same catalogue seed; on play the live analyser takes
   the same line over. A flat line was not a texture. */
.trace { display: block; width: 100%; height: clamp(72px, 11vw, 132px); opacity: .78; }

/* ================================================================ ARTISTS */
.roster { display: grid; gap: var(--s-8) var(--s-6); }
@media (min-width: 700px) { .roster { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .roster { grid-template-columns: repeat(3, 1fr); } }
.artist { border-top: 1px solid var(--ink); padding-top: var(--s-4); }
.artist h3 { margin-bottom: var(--s-2); }
.artist p { margin: 0; color: var(--ink-2); font-size: var(--t-sm); }
.artist__n { font-size: var(--t-2xs); color: var(--ink-3); }

/* ============================================================== EDITORIAL */
.rail { display: grid; gap: var(--s-10); }
@media (min-width: 940px) { .rail { grid-template-columns: 4fr 8fr; gap: var(--s-16); } }
.blk { padding-bottom: var(--s-8); }
.blk + .blk { border-top: 1px solid var(--line); padding-top: var(--s-8); }
.blk h3 { margin-bottom: var(--s-3); max-width: 34ch; }
.blk p { margin: 0; color: var(--ink-2); max-width: 60ch; }
.split { display: grid; gap: var(--s-10); align-items: center; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; gap: var(--s-16); } }

/* ================================================================= FOOTER */
.foot { border-top: 1px solid var(--line); padding-block: var(--s-16) var(--s-10); }
.foot__grid { display: grid; gap: var(--s-10); }
@media (min-width: 900px) { .foot__grid { grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--s-10); } }
.foot h2 { font-size: var(--t-sm); font-weight: 600; margin-bottom: var(--s-4); }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); font-size: var(--t-sm); }
.foot a { color: var(--ink-2); text-decoration: none; }
.foot a:hover, .foot a:focus-visible { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.legal { margin-top: var(--s-12); padding-top: var(--s-5); border-top: 1px solid var(--line); font-size: var(--t-3xs); color: var(--ink-3); max-width: 92ch; line-height: 1.8; }
.legal p { margin: 0 0 var(--s-3); }
.legal strong { color: var(--ink-2); }

/* ---------------------------------------------------------------- touch */
@media (pointer: coarse), (max-width: 760px) {
  .nav a, .foot ul a, .wordmark { min-height: 44px; display: inline-flex; align-items: center; }
  .wordmark { flex-wrap: wrap; }
  /* a release title in a row is a list link, not a link inside a sentence,
     so the WCAG 2.5.8 inline exception does not cover it */
  .rel__t a, .rel__art { min-height: 44px; display: inline-flex; align-items: center; }
  .btn, .chip { min-height: 44px; }
  /* a text link that is a paragraph on its own ("back to the catalogue") is a
     standalone control, so WCAG 2.5.8's exception for links inside a sentence
     does not cover it. One inside running prose still does. */
  p > .tlink:only-child { min-height: 44px; display: inline-flex; align-items: center; }
  .chip { display: inline-flex; align-items: center; }
  .masthead { position: static; }
}

/* ---------------------------------------------------------------- reduced */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; }
  /* the analyser keeps drawing — it is information, not decoration, and it is
     the only way to see that sound is actually playing. It is not motion for
     its own sake. */
}

/* September UI refinement */
.play[data-visible-label]{display:inline-flex;align-items:center;justify-content:center}.play-label{font-size:15px;white-space:nowrap}
.play[data-visible-label]{border-radius:0}
