/* =====================================================================
   Supersolid Sounds · v2 · After-Midnight
   ===================================================================== */

:root {
  /* palette */
  --bg:        #0A0A0C;
  --bg-soft:   #111114;
  --ink:       #F2F0E8;
  --ink-dim:   #8A8A85;
  --rule:      rgba(242,240,232,0.10);
  --accent:    #32CD32;
  --accent-2:  #E63946;
  --accent-3:  #00CFCF;

  /* type */
  --font-display: "Editorial New", "Times New Roman", Times, serif;
  --font-body:    "Inter", system-ui, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* fluid scale */
  --fs-xs:  12px;
  --fs-sm:  14px;
  --fs-md:  16px;
  --fs-lg:  20px;
  --fs-xl:  28px;
  --fs-h2:  clamp(48px,  8vw, 120px);
  --fs-num: clamp(180px, 32vw, 520px);

  /* layout */
  --pad: clamp(24px, 4vw, 56px);
  --header-h: 76px;
  --np-h: 56px;

  /* motion */
  --e-out: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

html { scroll-behavior: auto; }
html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-md);
  line-height: 1.5;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  cursor: none;
}

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; height: auto; }

::selection { background: var(--accent); color: var(--bg); }

/* helpers ----------------------------------------------------------- */

/* "label" = uppercase Inter at small caps with tracking — replaces the
   old bitmap tags. Modern editorial micro-type. */
.label {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-dim);
}
.idx {
  /* secondary index label like "01 / Latest" */
  font-size: 12px;
  letter-spacing: 0.20em;
}

/* "mono" = JetBrains Mono — for catalog numbers, time codes, system strings */
.mono {
  font-family: var(--font-mono);
  font-feature-settings: "tnum" 1, "ss01" 1;
  font-size: 12px;
  letter-spacing: 0.02em;
}

/* =====================================================================
   Loader (black curtain → split reveal)
   ===================================================================== */
.loader {
  position: fixed; inset: 0;
  z-index: 9999;
  pointer-events: all;
  overflow: hidden;
}
.loader__half {
  position: absolute; left: 0; right: 0;
  background: #000;
  will-change: transform;
}
.loader__half--top { top: 0;     height: 50%; }
.loader__half--bot { top: 50%;   height: 50.5%; }   /* +0.5% to hide sub-pixel seam */

/* CRT-on horizon line — appears at the moment the hero "tubes on" */
.loader__seam {
  position: absolute; left: 0; right: 0; top: 50%;
  height: 2px;
  background: #fff;
  transform: translateY(-50%) scaleY(1) scaleX(0.001);
  transform-origin: center;
  z-index: 3;
  opacity: 0;
  pointer-events: none;
  box-shadow: 0 0 50px rgba(255,255,255,0.8),
              0 0 90px color-mix(in srgb, var(--accent) 40%, transparent);
  mix-blend-mode: screen;
}

/* ----- Win98-Setup-style splash content (inside loader) -------- */
@font-face {
  font-family: "Web437_FMTowns_re_8x16-2x";
  src: url("../fonts/Web437_FMTowns_re_8x16-2x.woff") format("woff");
  font-display: block;
}
.loader__crt {
  position: absolute; inset: 0; z-index: 2;
  padding: 53px 46px;
  overflow: hidden auto;
  color: #fff;
  font-family: "Web437_FMTowns_re_8x16-2x", "Courier New", monospace;
  filter: brightness(1.05) contrast(1.08) url("#loaderCRT");
  isolation: isolate;
}
.loader__scanlines {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0.55; mix-blend-mode: screen;
  background:
    repeating-linear-gradient(rgba(255,255,255,0.10) 0 2px, rgba(0,0,0,0) 2px 4px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.04) 0 2px, rgba(0,0,0,0) 2px 4px);
}
.loader__content--splash {
  position: relative;
  display: block;        /* override flex from base */
  inset: auto;
  width: 100%;
  max-width: 1238px;
  text-align: left;
}
.loader__title {
  font-size: 40px;
  margin-bottom: 13px;
  text-shadow: rgba(255,255,255,0.7) 0 0 0.6px,
               rgba(255,255,255,0.18) 0 0 10px;
}
.loader__subtitle {
  font-size: 23px;
  line-height: 1.65;
  margin-bottom: 26px;
  text-shadow: rgba(255,255,255,0.6) 0 0 0.5px,
               rgba(255,255,255,0.16) 0 0 8px;
}
.loader__status {
  font-size: 23px;
  margin-bottom: 13px;
}
.loader__bar {
  width: 100%;
  background-color: #fff;
  border: 1px solid #fff;
  height: 25px;
  display: grid;
  grid-template-columns: repeat(60, 1fr);
  gap: 2px;
  align-items: stretch;
  padding: 1px;
  box-sizing: border-box;
  margin-bottom: 13px;
}
.loader__bar > div {
  position: relative;
  border: 1px solid #fff;
  background: rgba(255,255,255,0.15);
  transition: background 90ms linear;
}
.loader__bar > div.is-filled {
  /* Top a touch lighter, bottom a touch darker — works for any accent. */
  background: linear-gradient(
    color-mix(in srgb, var(--accent) 88%, white 18%),
    color-mix(in srgb, var(--accent) 92%, black 14%)
  );
}
.loader__percent {
  font-size: 23px;
  margin-bottom: 26px;
  font-variant-numeric: tabular-nums;
}
.loader__log {
  color: #eee;
  font-size: 21px;
  max-height: 396px;
  overflow-y: auto;
  border: 1px solid #fff;
  padding: 13px;
  line-height: 1.4;
  background: rgba(255,255,255,0);
  box-shadow: rgba(255,255,255,0.12) 0 0 10px inset;
}
.loader__footer {
  font-size: 23px;
  line-height: 1.5;
  margin-top: 18px;
  color: #eee;
}
.loader__footer a {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

@media (max-width: 720px) {
  .loader__crt { padding: 28px 22px; }
  .loader__title { font-size: 26px; }
  .loader__subtitle, .loader__status, .loader__percent, .loader__footer { font-size: 16px; }
  .loader__log { font-size: 14px; max-height: 240px; padding: 10px; }
  .loader__bar { height: 18px; }
}

body.loader-active { overflow: hidden; cursor: progress; }
body.loader-active .cursor { display: none; }

/* ----- Counter variant — clean italic 00 → 100 + small wordmark ------ */
.loader__counter-view {
  position: absolute; inset: 0; z-index: 2;
  display: none;
  flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  padding-inline: var(--pad);
  color: #fff;
  pointer-events: none;
}
.loader__brand {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.32em;
  font-size: clamp(11px, 1vw, 13px);
  font-weight: 500;
  color: var(--ink-dim);
  margin-bottom: 18px;
}
.loader__count {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(120px, 22vw, 360px);
  line-height: 0.86;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.loader__sub {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: clamp(10px, 0.8vw, 12px);
  color: var(--ink-dim);
  margin-top: 22px;
}

/* Variant switch driven by <html data-splash-type="..."> */
:root[data-splash-type="counter"] .loader__crt          { display: none; }
:root[data-splash-type="counter"] .loader__counter-view { display: flex; }
:root[data-splash-type="none"] #loader                   { display: none; }

@media (prefers-reduced-motion: reduce) {
  .loader__half { transition: none !important; }
}

/* =====================================================================
   Film grain
   ===================================================================== */
.grain {
  position: fixed; inset: 0; pointer-events: none; z-index: 200;
  background-image: url("../assets/noise.png");
  background-size: 128px 128px;
  opacity: 0.06;
  mix-blend-mode: overlay;
  will-change: transform;
}

/* =====================================================================
   Custom cursor
   ===================================================================== */
.cursor {
  position: fixed; left: 0; top: 0; z-index: 300;
  width: 8px; height: 8px;
  background: var(--ink);
  border-radius: 50%;
  pointer-events: none;
  transform: translate(-50%, -50%);
  mix-blend-mode: difference;
  transition: width 200ms var(--e-out), height 200ms var(--e-out);
}
.cursor.is-hover { width: 40px; height: 40px; }
.cursor.is-down  { transform: translate(-50%, -50%) scale(0.7); }
@media (hover: none), (pointer: coarse) {
  body { cursor: auto; }
  .cursor { display: none; }
}

/* =====================================================================
   Masthead
   ===================================================================== */
.masthead {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  height: var(--header-h);
  display: flex; align-items: center; justify-content: space-between;
  padding-inline: var(--pad);
  mix-blend-mode: difference;
  color: #fff;
  transition: height 360ms var(--e-out),
              background 360ms ease,
              backdrop-filter 360ms ease,
              border-color 360ms ease;
}

/* Compact + backdrop-blur after we've scrolled past the hero.
   mix-blend-mode is dropped (incompatible with backdrop-blur) and
   children fall back to their natural ink colour against the blur. */
body.is-scrolled .masthead {
  height: 56px;
  mix-blend-mode: normal;
  background: rgba(10, 10, 12, 0.66);
  backdrop-filter: blur(14px) saturate(1.25);
  -webkit-backdrop-filter: blur(14px) saturate(1.25);
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}
body.is-scrolled .masthead .brand,
body.is-scrolled .masthead nav a,
body.is-scrolled .masthead .cta { color: var(--ink); }
body.is-scrolled .masthead .cta { border-color: var(--rule); }
.brand {
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: -0.005em;
  color: #fff;
}
.brand__mark {
  display: inline-block;
  flex-shrink: 0;
}
/* The hero already shows the logo, so the masthead at the top of the
   page stays empty on the left — keeps the hero composition clean. */
.brand__mark--mini,
.brand__name,
.brand__est,
.brand__mark--full { display: none; }
.brand__mark--mini svg { width: 100%; height: 100%; display: block; }
.brand__mark--mini svg path,
.brand__mark--mini svg g { fill: currentColor; }

/* Full logo mark — appears once the user has scrolled past the hero,
   replacing what was the brand text. Sized so the masthead feels grounded
   without dominating: ~46px tall in the 56px compact header. */
.brand__mark--full {
  height: 46px; width: auto;
}
.brand__mark--full svg { height: 100%; width: auto; display: block; }
.brand__mark--full svg .bf-letters path { fill: var(--ink); }
.brand__mark--full svg .bf-ornaments path { fill: var(--accent); }

body.is-scrolled .brand__mark--full { display: inline-block; }

.brand__name {
  /* hide on small / let mark + EST stand */
}
.brand__est {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-dim);
  letter-spacing: 0.04em;
}

.masthead nav { display: flex; gap: 32px; }
.masthead nav a {
  font-family: var(--font-body);
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.16em;
  font-weight: 500;
  color: #fff;
}

/* Letter-mask hover — replaces scramble in the header.
   Each letter sits in its own overflow-clip; on hover, GSAP slides
   the original letter up and out, while the accent-coloured duplicate
   slides up from below into its place (staggered left→right). */
[data-nav-swap] {
  display: inline-flex;
  vertical-align: bottom;
}
.swap__l {
  display: inline-block;
  position: relative;
  overflow: hidden;
  line-height: 1.05;
  height: 1em;
}
.swap__a,
.swap__b {
  display: block;
  will-change: transform;
}
.swap__b {
  position: absolute;
  inset: 0 auto 0 0;
  color: var(--accent);
}

.cta {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px 9px;
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 999px;
  font-family: var(--font-body);
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.16em;
  font-weight: 500;
  background: transparent;
  color: #fff;
  cursor: none;
  transition: border-color 200ms, color 200ms;
}
.cta i {
  color: var(--accent-2);
  display: inline-block;
  font-style: normal;
  animation: pulse 2.4s infinite ease-in-out;
}
@keyframes pulse {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}
.cta:hover { border-color: var(--accent); color: var(--accent); }

@media (max-width: 720px) {
  .masthead nav { display: none; }
  .brand__name { display: none; }
}

/* =====================================================================
   Hero
   ===================================================================== */
.hero {
  position: relative;
  z-index: 5;                  /* hero sits above following sections so the
                                   ornaments can fly OVER them on scroll */
  min-height: 100vh;
  padding: calc(var(--header-h) + 6vh) var(--pad) 8vh;
  display: grid;
  grid-template-rows: 1fr auto auto;
  gap: 4vh;
  background: var(--bg);
  overflow: visible;           /* let scattered logo paths/ornaments
                                   render outside the hero bounds */
}
.hero__logo  { grid-row: 1 / 2; align-self: end; }
.hero__stamp { grid-row: 2 / 3; }
.hero__logo { overflow: visible; }

/* Bg-clip wrapper: lives behind logo at hero bounds. Owns the clip
   context (overflow: hidden) so GSAP transforms on .hero__video stay
   contained when the video scales/translates beyond its rest box. */
.hero__bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: -1;                      /* behind logo + copy */
  pointer-events: none;
}

/* Hero CRT styling — driven by body[data-hero-crt] which data.js writes
   from settings.hero_crt_filter. Filter on the wrapper (not the video)
   so it composes ON TOP of any GSAP filter the video may carry from the
   filter-sweep mode. Default body[data-hero-crt="none"] applies nothing. */
body[data-hero-crt="subtle"] .hero__bg {
  filter: url(#heroCRTSubtle);
}
body[data-hero-crt="full"] .hero__bg {
  filter: url(#heroCRTFull);
}

/* Scanlines overlay via pseudo-element. Only visible when CRT is on.
   Two repeating gradients give horizontal + vertical CRT-grid look. */
body[data-hero-crt="subtle"] .hero__bg::after,
body[data-hero-crt="full"] .hero__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
}
body[data-hero-crt="subtle"] .hero__bg::after {
  opacity: 0.18;
  background:
    repeating-linear-gradient(rgba(255,255,255,0.05) 0 1px, rgba(0,0,0,0) 1px 3px);
}
body[data-hero-crt="full"] .hero__bg::after {
  opacity: 0.32;
  background:
    repeating-linear-gradient(rgba(255,255,255,0.10) 0 2px, rgba(0,0,0,0) 2px 4px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.04) 0 2px, rgba(0,0,0,0) 2px 4px);
}

/* Atmospheric background video — fills the wrapper, subtle so it
   doesn't fight for attention. Hidden by default until data.js
   confirms hero_video is set in CMS. */
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;                       /* fade-in via JS once loaded */
  transition: opacity 1.2s ease;
  filter: brightness(0.55) saturate(0.6) blur(2px);
  pointer-events: none;
  /* mix-blend hint: when paired with the dark bg, video adds ambient
     motion without dominating. */
  mix-blend-mode: screen;
}
.hero__video.is-loaded { opacity: 0.45; }

.hero__cat {
  align-self: start;
}
.hero__cat .label {
  background: var(--accent);
  color: var(--bg);
  padding: 5px 10px 5px;
  letter-spacing: 0.16em;
  font-weight: 600;
}

/* HERO LOGO ----------------------------------------------------------- */
.hero__logo {
  width: 100%;
  align-self: center;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-block: 2vh;
}
.hero__logo svg {
  width: min(86vw, 1100px);
  height: auto;
  display: block;
  fill: var(--ink);
  overflow: visible;
}
/* Letters use ink colour, ornaments in accent yellow. */
.hero__logo svg #sounds path,
.hero__logo svg #supersolid path { fill: var(--ink); }
.hero__logo svg #ornaments path { fill: var(--accent); }

/* Ornament groups need transform-box for proper rotate/scale pivot.
   Letter paths are NOT included — GSAP transforms them via matrix and
   adding transform-box on individual paths breaks SVG composition in
   Safari (paths render at their getBBox origin instead of consolidated
   in the viewBox). */
.hero__logo svg #ornaments > g {
  transform-box: fill-box;
  transform-origin: center;
}

/* gsap.from() handles the start state; no CSS pre-state needed. */

.hero__bottom {
  display: grid;
  grid-template-columns: 2fr 3fr;
  gap: var(--pad);
  align-items: end;
}
.hero__lede {
  margin: 0;
  font-size: clamp(16px, 1.2vw, 19px);
  max-width: 56ch;
  color: var(--ink);
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: -0.005em;
}
.hero__lede .arrow { color: var(--accent); display: inline-block; transform: translateY(-1px); }

.hero__stats {
  margin: 0; padding: 0;
  list-style: none;
  display: grid; grid-template-columns: repeat(3, auto);
  gap: 28px; justify-content: end;
}
.hero__stats li {
  display: grid; gap: 4px;
  text-align: right;
}
.hero__stats .num {
  font-family: var(--font-display);
  font-weight: 500;
  font-style: italic;
  font-size: clamp(36px, 4.8vw, 72px);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-feature-settings: "tnum" 0, "lnum" 1;
}
.hero__stats em {
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--ink-dim);
  font-style: normal;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.hero__scroll {
  position: absolute;
  left: var(--pad); bottom: 24px;
  display: flex; align-items: center; gap: 12px;
  color: var(--ink-dim);
}
.hero__scroll svg { animation: bounce 2.4s infinite var(--e-out); }
@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}

@media (max-width: 720px) {
  .hero__bottom { grid-template-columns: 1fr; gap: 32px; }
  .hero__stats { justify-content: start; gap: 18px; }
  .hero__logo svg { width: 92vw; }
}

/* =====================================================================
   Horizontal pinned releases
   ===================================================================== */
.horiz {
  position: relative;
  height: 100vh;
}
.horiz__pin {
  height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr;
  gap: 32px;
  padding: 6vh var(--pad) 6vh;
  overflow: hidden;
}
.horiz__head {
  display: grid; grid-template-columns: auto 1fr auto;
  gap: 32px; align-items: end;
}
.horiz__head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 500;
  font-style: italic;
  letter-spacing: -0.015em;
  line-height: 0.96;
}
.horiz__head .link {
  align-self: end;
  font-family: var(--font-body);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-weight: 500;
  color: var(--ink-dim);
}
.horiz__head .link:hover { color: var(--accent); }

.horiz__track {
  display: flex;
  gap: 32px;
  align-items: stretch;
  will-change: transform;
  perspective: 1400px;          /* 3D scene for cover tilts */
  perspective-origin: center;
}

.rel {
  flex: 0 0 clamp(280px, 26vw, 460px);
  display: grid; gap: 16px;
  align-content: start;
  text-decoration: none; color: inherit;
}
.rel__cover {
  position: relative;
  aspect-ratio: 1;
  background: var(--c2, var(--bg-soft));
  overflow: hidden;
  border-radius: 2px;
  transform-style: preserve-3d;
  will-change: transform;
}
.rel__art {
  position: absolute; inset: 0;
  background:
    radial-gradient(60% 50% at 70% 25%, var(--c1) 0%, transparent 60%),
    radial-gradient(40% 40% at 25% 75%, var(--c3) 0%, transparent 55%),
    linear-gradient(135deg, var(--c2) 0%, color-mix(in srgb, var(--c2) 70%, var(--c1) 30%) 100%);
  filter: contrast(1.1) saturate(1.1);
  will-change: transform;
}
/* The global .grain overlay already covers covers; no per-cover noise. */
.rel__cat {
  position: absolute; left: 12px; top: 12px;
  background: rgba(0,0,0,0.55);
  color: var(--ink);
  padding: 4px 8px;
  letter-spacing: 0.12em;
  font-size: 10px;
  font-weight: 500;
}
.rel__meta h3 {
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-weight: 500;
  font-style: italic;
  font-size: clamp(20px, 1.6vw, 30px);
  letter-spacing: -0.005em;
  line-height: 1.1;
}
.rel__meta p {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--ink-dim);
  letter-spacing: 0.01em;
}

@media (max-width: 720px) {
  .horiz, .horiz__pin { height: auto; }
  .horiz__pin { padding: 6vh var(--pad); }
  .horiz__track { flex-direction: column; gap: 24px; }
  .rel { flex: 0 0 auto; }
  .horiz__head { grid-template-columns: 1fr; }
}

/* =====================================================================
   Artists
   ===================================================================== */
.artists {
  padding: 12vh var(--pad);
  border-top: 1px solid var(--rule);
}
.section-head {
  display: grid; grid-template-columns: auto 1fr; gap: 40px; align-items: end;
  margin-bottom: 6vh;
}
.section-head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  letter-spacing: -0.015em;
  line-height: 0.96;
  font-weight: 500;
  font-style: italic;
}

.artists__list {
  list-style: none;
  margin: 0; padding: 0;
}
.artists__list li {
  border-top: 1px solid var(--rule);
}
.artists__list li:last-child { border-bottom: 1px solid var(--rule); }
.artists__list a {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 24px;
  padding: 24px 8px;
  position: relative;
  overflow: hidden;
  transition: padding 620ms var(--e-out);
}
.artists__list a::before {
  content: ""; position: absolute; inset: 0;
  background: var(--accent);
  transform: translateX(-101%);
  transition: transform 820ms var(--e-out);
  z-index: -1;
}
.artists__list a:hover { padding-inline-start: 32px; color: var(--bg); }
.artists__list a:hover::before { transform: translateX(0); }
.artists__list a:hover i { color: var(--bg); }
.artists__list .n {
  align-self: center;
  font-size: 11px;
}
.artists__list .t {
  font-family: var(--font-display);
  font-size: clamp(28px, 4vw, 64px);
  font-weight: 500;
  font-style: italic;
  letter-spacing: -0.01em;
  line-height: 1;
}
.artists__list i {
  font-style: normal;
  font-size: 12px;
  color: var(--ink-dim);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
  transition: color 520ms;
}
.artists__list a::after {
  content: "→";
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  color: var(--ink-dim);
  transform: translateX(-12px);
  opacity: 0;
  transition: transform 580ms var(--e-out), opacity 380ms;
}
.artists__list a:hover::after { transform: translateX(0); opacity: 1; color: var(--bg); }

@media (max-width: 720px) {
  .artists__list a { grid-template-columns: 1fr auto; }
  .artists__list a::after { display: none; }
}

/* =====================================================================
   Imagery (lag-parallax tiles)
   ===================================================================== */
.imagery {
  position: relative;
  padding: 18vh var(--pad) 22vh;
  border-top: 1px solid var(--rule);
  overflow: visible;
}
.imagery__head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 24px;
  align-items: end;
  max-width: 1100px;
  margin: 0 auto 12vh;
}
.imagery__head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: var(--fs-h2);
  letter-spacing: -0.015em;
  line-height: 0.96;
}
.imagery__head h2 em {
  font-style: italic;
  color: var(--accent);
}
.imagery__sub {
  font-family: var(--font-body);
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-align: right;
  max-width: 28ch;
  align-self: end;
}

.imagery__stack {
  position: relative;
  display: block;
  max-width: 1200px;
  margin: 0 auto;
}

.imagery__tile {
  position: relative;
  display: block;
  margin: 0 0 14vh;
  overflow: hidden;
  background: var(--c2, #111);
  box-shadow: 0 32px 80px rgba(0,0,0,0.4);
  will-change: transform;
  cursor: none;
}
.imagery__tile:last-child { margin-bottom: 0; }
.imagery__tile--w {
  width: clamp(280px, 64%, 760px);
  height: clamp(360px, 70vh, 720px);
  margin-left: 0;
  margin-right: auto;
}
.imagery__tile--n {
  width: clamp(240px, 50%, 580px);
  height: clamp(320px, 60vh, 640px);
  margin-left: auto;
  margin-right: 0;
}

.imagery__art {
  position: absolute; inset: 0;
  background:
    radial-gradient(60% 50% at 65% 22%, var(--c1) 0%, transparent 62%),
    radial-gradient(45% 45% at 22% 78%, var(--c3) 0%, transparent 58%),
    linear-gradient(135deg, var(--c2) 0%, color-mix(in srgb, var(--c2) 60%, var(--c1) 40%) 100%);
  filter: contrast(1.1) saturate(1.15);
}

.imagery__tile figcaption {
  position: absolute;
  left: 24px; bottom: 24px;
  display: grid; gap: 4px;
  z-index: 2;
  color: var(--ink);
  text-shadow: 0 1px 8px rgba(0,0,0,0.35);
}
.imagery__cap--dark { color: var(--bg); text-shadow: none; }
.imagery__tile figcaption .cat {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
  background: rgba(0,0,0,0.55);
  color: var(--ink);
  padding: 4px 8px;
  align-self: start;
  margin-bottom: 6px;
}
.imagery__cap--dark .cat { background: rgba(255,255,255,0.65); color: var(--bg); }
.imagery__tile figcaption .title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(28px, 3.5vw, 56px);
  line-height: 1;
  letter-spacing: -0.015em;
}
.imagery__tile figcaption .meta {
  font-family: var(--font-body);
  font-size: 13px;
  letter-spacing: 0.06em;
  opacity: 0.85;
}

@media (max-width: 720px) {
  .imagery__head { grid-template-columns: 1fr; }
  .imagery__sub { text-align: left; }
  .imagery__tile--w, .imagery__tile--n {
    width: 100%;
    aspect-ratio: 4 / 5;
  }
}

/* =====================================================================
   Tour
   ===================================================================== */
.tour {
  padding: 14vh var(--pad);
  border-top: 1px solid var(--rule);
}
.tour .section-head { margin-bottom: 4vh; }
.tour__list {
  display: grid;
  border-top: 1px solid var(--rule);
}
.tour__row {
  display: grid;
  grid-template-columns: 160px 1fr 1fr 1.4fr auto;
  align-items: center;
  gap: 24px;
  padding: 18px 8px;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-md);
  position: relative;
  transition: padding 280ms var(--e-out);
}
.tour__row:hover { padding-inline-start: 24px; }
.tour__date {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}
.tour__artist {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(20px, 1.6vw, 30px);
  letter-spacing: -0.005em;
}
.tour__city {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
}
.tour__venue {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink-dim);
}
.tour__status {
  justify-self: end;
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 11px;
  color: var(--ink-dim);
}
.tour__status a { color: var(--ink); border-bottom: 1px solid var(--rule); padding-bottom: 2px; }
.tour__status a:hover { color: var(--accent); border-color: var(--accent); }

@media (max-width: 720px) {
  .tour__row { grid-template-columns: 1fr; gap: 6px; padding: 16px 0; }
  .tour__status { justify-self: start; }
}

/* =====================================================================
   Demo Drop
   ===================================================================== */
.demos {
  padding: 14vh var(--pad);
  border-top: 1px solid var(--rule);
}
.demos .section-head {
  grid-template-columns: 1fr;
  gap: 16px;
}
.demos__lede {
  max-width: 52ch;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--ink-dim);
  line-height: 1.5;
  margin: 0;
}
.demos__lede a {
  color: var(--ink);
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  transition: color 200ms, border-color 200ms;
}
.demos__lede a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.demos__form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px 24px;
  max-width: 720px;
  margin-top: 4vh;
}
.demos__field {
  display: flex; flex-direction: column;
  gap: 6px;
}
.demos__field--wide { grid-column: 1 / -1; }
.demos__field span {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.demos__field input,
.demos__field textarea {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  padding: 8px 0;
  outline: none;
  resize: none;
  transition: border-color 200ms;
}
.demos__field input::placeholder,
.demos__field textarea::placeholder {
  color: color-mix(in srgb, var(--ink-dim) 60%, transparent);
}
.demos__field input:focus,
.demos__field textarea:focus {
  border-bottom-color: var(--accent);
}
.demos__send {
  grid-column: 1 / -1;
  justify-self: start;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 18px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 500;
  cursor: none;
  transition: border-color 200ms, color 200ms, background 200ms;
}
.demos__send:hover { border-color: var(--accent); color: var(--accent); }
.demos__send i { color: var(--accent); font-style: normal; }
.demos__fine {
  grid-column: 1 / -1;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-dim);
  margin: 0;
  min-height: 1.4em;
}
.demos__fine[data-state="ok"]   { color: var(--accent); }
.demos__fine[data-state="err"]  { color: var(--accent-2); }
@media (max-width: 720px) {
  .demos__form { grid-template-columns: 1fr; }
}

/* =====================================================================
   About
   ===================================================================== */
.about {
  position: relative;
  padding: 14vh var(--pad);
  border-top: 1px solid var(--rule);
  overflow: hidden;
}
.big-num {
  position: absolute;
  right: -2vw; top: -2vh;
  font-family: var(--font-display);
  font-size: var(--fs-num);
  font-weight: 500;
  font-style: italic;
  line-height: 0.8;
  letter-spacing: -0.04em;
  color: var(--accent);
  opacity: 0.92;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.about__copy {
  position: relative; z-index: 1;
  max-width: 60ch;
  display: grid; gap: 24px;
}
.about__copy h2 {
  margin: 8px 0 0;
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 500;
  font-style: italic;
  letter-spacing: -0.01em;
  line-height: 0.98;
}
.about__copy p {
  margin: 0;
  font-size: clamp(17px, 1.3vw, 21px);
  color: var(--ink);
  line-height: 1.55;
}
.about__copy .link {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 500;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 2px;
  align-self: start;
}
.about__copy .link:hover { color: var(--accent); border-color: var(--accent); }

/* =====================================================================
   Footer
   ===================================================================== */
.site-footer {
  border-top: 1px solid var(--rule);
  padding-bottom: calc(var(--np-h) + 24px);
}
.footer-marquee {
  overflow: hidden;
  border-bottom: 1px solid var(--rule);
}
.footer-marquee__track {
  display: flex; align-items: center; gap: 56px;
  white-space: nowrap;
  padding: 4vh 0;
  /* base size for all variants — individual fm-item classes can adjust */
  font-size: clamp(80px, 14vw, 220px);
  line-height: 0.9;
  will-change: transform;
}
.fm-item { display: inline-flex; align-items: center; }

/* Separator dots — ink-dim, not accent. Accent loses meaning when sprayed
   on every separator; saving lime for things that actually matter. */
.fm-sep {
  color: var(--rule);
  font-size: 0.4em;
  font-style: normal;
  line-height: 1;
}

/* Variant 1 — italic display serif (the editorial wordmark register) */
.fm-display {
  font-family: var(--font-display);
  font-weight: 500;
  font-style: italic;
  letter-spacing: -0.02em;
  color: var(--ink);
}

/* Variant 2 — uppercase mono geo stamp (label-tradition: Detroit, Berlin…) */
.fm-mono {
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-weight: 500;
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-dim);
  font-size: 0.32em;       /* mono reads bigger per glyph; scale down */
}

/* Variant 3 — horizontal brand mark.  Single SVG produced by
   horizontalLogoSvg() in app.js, which translates the #sounds layer to the
   right of #supersolid, drops ornaments, and snaps the viewBox to fit. */
.fm-logo-h {
  display: inline-flex; align-items: center;
  /* 1.4em + 0.30 viewBox top-pad: caps slightly larger than the italic and
     vertically aligned (cap-line lands on the marquee axis instead of
     floating above it). */
  height: 1.4em;
}
.fm-logo-glyph {
  height: 100%;
  width: auto;
  display: block;
  fill: var(--ink);
}
.fm-logo-glyph path { fill: var(--ink); }

/* =====================================================================
   Footer-marquee FX (opt-in via ?fx=name or live with `F` keypress).
   ===================================================================== */

.footer-marquee { position: relative; }   /* anchor scan-line + ghosts */
.footer-marquee__ghost {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.footer-marquee__ghost.ghost-slow { filter: blur(0.5px); }

/* FX: BPM-pulse — 118bpm = 508ms/beat default, configureerbaar via
   --bpm-period CSS-variabele (zie marquee-fx.html control bar). */
@keyframes fm-bpm {
  0%, 100% { transform: scale(1); }
  18%      { transform: scale(1.045); }
  36%      { transform: scale(1); }
}
.footer-marquee.fx-bpm .fm-logo-h {
  animation: fm-bpm var(--bpm-period, 0.508s) cubic-bezier(.4,0,.2,1) infinite;
  transform-origin: center;
  will-change: transform;
}

/* FX: drip — wet-paint sag, very slow + slight skew. Stagger between
   neighbouring instances so the row breathes instead of throbbing. */
@keyframes fm-drip {
  0%, 100% { transform: skewY(0deg)   translateY(0); }
  50%      { transform: skewY(0.6deg) translateY(2px); }
}
.footer-marquee.fx-drip .fm-logo-h {
  animation: fm-drip 5.5s ease-in-out infinite;
  transform-origin: center top;
}
.footer-marquee.fx-drip .fm-logo-h:nth-child(odd)  { animation-delay: -2.7s; }
.footer-marquee.fx-drip .fm-logo-h:nth-child(4n)   { animation-delay: -1.3s; }

/* FX: glitch — slow horizontal scan-line, occasional RGB-split jitter on
   the wordmark itself. Uses steps(1) so transitions feel discrete. */
.fm-scanline {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 4px;
  background: linear-gradient(180deg, transparent, rgba(255,255,255,0.28) 50%, transparent);
  pointer-events: none;
  z-index: 5;
  animation: fm-scanline 4.8s linear infinite;
  mix-blend-mode: screen;
}
@keyframes fm-scanline {
  0%   { top: -4px; opacity: 0; }
  6%   { opacity: 1; }
  94%  { opacity: 1; }
  100% { top: 100%; opacity: 0; }
}
@keyframes fm-glitch-jitter {
  0%, 95%, 100% { transform: translateX(0);  filter: none; }
  96%           { transform: translateX(-2px); filter: drop-shadow(2px 0 0 #f0f) drop-shadow(-2px 0 0 #0ff); }
  97%           { transform: translateX(3px);  filter: drop-shadow(-2px 0 0 #f0f) drop-shadow(2px 0 0 #0ff); }
  98%           { transform: translateX(-1px); filter: drop-shadow(1px 0 0 #f0f) drop-shadow(-1px 0 0 #0ff); }
  99%           { transform: translateX(0);    filter: none; }
}
.footer-marquee.fx-glitch .fm-logo-h {
  animation: fm-glitch-jitter 7s steps(1) infinite;
}

/* FX: magnet — JS-driven scale, just need the smoothing transition. */
.footer-marquee.fx-magnet .fm-item {
  transition: transform 140ms cubic-bezier(.2,.7,.2,1);
}

/* FX: breathe — brightness pulse op het dubbele van --bpm-period (één
   ademhaling per twee beats). Zelfde keyframe als bpm maar via filter. */
@keyframes fm-breathe {
  0%, 100% { filter: brightness(0.82); }
  50%      { filter: brightness(1.18); }
}
.footer-marquee.fx-breathe .fm-logo-h {
  animation: fm-breathe calc(var(--bpm-period, 0.508s) * 2) ease-in-out infinite;
  will-change: filter;
}

/* FX: liquid — SVG feTurbulence + feDisplacementMap (gedefinieerd in
   ensureLiquidFilter() in app.js). Vloeiend wobbly oppervlak. */
.footer-marquee.fx-liquid .fm-logo-glyph {
  filter: url(#fx-liquid);
}

/* FX: 3dtilt — perspective wordt inline gezet door JS, hier alleen
   transform-style en transitie-vriendelijke wills. */
.footer-marquee.fx-3dtilt .footer-marquee__track {
  transform-style: preserve-3d;
  will-change: transform;
}

/* ----------------------------------------------------------------------
   Block 4 — micro-interacties

   1. Click ripple
      - JS wireClickRipple() prikt een .ripple span op clickpositie
      - currentColor laat hem auto-tinten met de host (white-on-dark / dark-on-light)
      - Lage opacity zodat het voelt als "tap-feedback" en niet als shockwave
   ---------------------------------------------------------------------- */
.ripple {
  position: absolute;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.22;
  pointer-events: none;
  transform: scale(0);
  animation: ripple-anim 0.65s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  z-index: 1;
}
@keyframes ripple-anim {
  0%   { transform: scale(0);   opacity: 0.30; }
  60%  {                         opacity: 0.20; }
  100% { transform: scale(1.2); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .ripple { display: none; } }

/* 2. Release cover hover-glow — accent-tinted shadow + scale, GPU-friendly. */
.rel:hover .rel__cover,
.rel:focus-visible .rel__cover {
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.04),
    0 18px 42px -12px rgba(50, 205, 50, 0.28),
    0 6px 18px -6px rgba(0, 207, 207, 0.15);
  transform: translateY(-3px) scale(1.02);
}
.rel__cover { transition: transform 280ms cubic-bezier(.2,.7,.2,1), box-shadow 280ms cubic-bezier(.2,.7,.2,1); }

/* 3. Animated underline (opt-in via data-underline). Sweeps from left,
      shrinks back to right on leave — feels typographically intentional. */
[data-underline] {
  position: relative;
  display: inline-block;
}
[data-underline]::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 380ms cubic-bezier(.2,.7,.2,1);
}
[data-underline]:hover::after,
[data-underline]:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}


/* FX toast — bottom-right pill, fades in/out on F-keypress. */
.fm-fx-toast {
  position: fixed;
  bottom: 80px;
  right: 24px;
  padding: 8px 14px;
  background: rgba(0,0,0,0.85);
  color: #fff;
  font-family: var(--font-mono, "JetBrains Mono", monospace);
  font-size: 11px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 2px;
  z-index: 9999;
  opacity: 0;
  transition: opacity 220ms ease;
  pointer-events: none;
}

.footer-cols {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 48px;
  padding: 8vh var(--pad);
}
.footer-h {
  margin: 0 0 16px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(28px, 3vw, 44px);
  letter-spacing: -0.01em;
  line-height: 1;
}
.footer-cols p {
  margin: 8px 0 16px;
  max-width: 36ch; color: var(--ink-dim);
}

.sub-form {
  display: grid; grid-template-columns: 1fr auto;
  border-bottom: 1px solid var(--ink);
  max-width: 420px;
}
.sub-form input {
  background: transparent; border: 0; outline: none;
  color: var(--ink); padding: 12px 0;
  font: inherit; font-size: var(--fs-md);
}
.sub-form input::placeholder { color: var(--ink-dim); }
.sub-form button {
  background: transparent; border: 0; color: var(--ink);
  padding: 12px 0;
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 500;
  cursor: none;
}
.sub-form button:hover { color: var(--accent); }

.footer-links {
  display: grid; grid-template-columns: 1fr 1fr; gap: 48px;
  justify-self: end;
}
.footer-links ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.footer-links a {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--ink-dim);
}
.footer-links a:hover { color: var(--ink); }

.footer-fine {
  display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap;
  padding: 24px var(--pad);
  border-top: 1px solid var(--rule);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.footer-fine .mono {
  text-transform: none;
  letter-spacing: 0.02em;
}

@media (max-width: 720px) {
  .footer-cols { grid-template-columns: 1fr; gap: 48px; }
  .footer-links { justify-self: start; }
}

/* =====================================================================
   Now-Playing
   ===================================================================== */
.np {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  height: var(--np-h);
  background: var(--bg);
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: auto 1fr 1fr auto auto;
  align-items: center;
  gap: 16px;
  padding-inline: var(--pad);
  transform: translateY(0);
  opacity: 1;
  transition: transform 320ms var(--e-out), opacity 240ms var(--e-out);
}
.np[data-np-state="hidden"] {
  transform: translateY(110%);
  opacity: 0;
  pointer-events: none;
}
.np__close {
  width: 24px; height: 24px;
  display: grid; place-items: center;
  background: transparent;
  color: var(--ink-dim);
  border: 0;
  cursor: none;
  transition: color 160ms;
}
.np__close:hover { color: var(--ink); }
.np__play {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: var(--accent);
  color: var(--bg);
  border: 0;
  border-radius: 50%;
  cursor: none;
  transition: transform 200ms var(--e-out), background 200ms;
}
.np__play:hover { transform: scale(1.06); background: var(--ink); }

.np__info { display: flex; align-items: center; gap: 12px; min-width: 0; }
.np__cat {
  font-size: 10px;
  color: var(--ink-dim);
}
.np__title {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.np__title b { font-weight: 600; color: var(--ink); }

.np__wave { width: 100%; height: 24px; color: var(--ink-dim); }

.np__time {
  color: var(--ink-dim);
}
.np__time i {
  font-style: normal;
  margin: 0 6px;
  color: var(--rule);
}

@media (max-width: 720px) {
  .np { grid-template-columns: auto 1fr auto auto; }
  .np__wave { display: none; }
}

/* =====================================================================
   Release detail overlay
   ===================================================================== */
.detail-overlay {
  position: fixed; inset: 0; z-index: 70;
  background: var(--bg);
  overflow-y: auto;
  display: none;
  padding: var(--header-h) var(--pad) calc(var(--np-h) + 24px);
}
.detail-overlay.is-active { display: block; }

.detail__back {
  position: sticky; top: 0;
  display: inline-flex; align-items: center; gap: 8px;
  background: transparent; border: 0;
  color: var(--ink-dim);
  font-family: var(--font-body);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  padding: 16px 0;
  cursor: none;
  z-index: 5;
}
.detail__back:hover { color: var(--accent); }
.detail__back span { font-size: 18px; }

.detail__inner {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(320px, 1.1fr);
  gap: clamp(32px, 6vw, 96px);
  align-items: start;
  max-width: 1400px;
  margin: 24px auto 0;
}

.detail__cover {
  position: relative;
  aspect-ratio: 1;
  background: var(--c2, #111);
  overflow: hidden;
  border-radius: 2px;
  box-shadow: 0 32px 80px rgba(0,0,0,0.5);
}
.detail__cover .rel__art {
  position: absolute; inset: 0;
  background:
    radial-gradient(60% 50% at 70% 25%, var(--c1) 0%, transparent 60%),
    radial-gradient(40% 40% at 25% 75%, var(--c3) 0%, transparent 55%),
    linear-gradient(135deg, var(--c2) 0%, color-mix(in srgb, var(--c2) 70%, var(--c1) 30%) 100%);
  filter: contrast(1.1) saturate(1.1);
}
/* No per-cover noise on detail either — global grain handles it. */
.detail__cover .rel__cat {
  position: absolute; left: 12px; top: 12px;
  background: rgba(0,0,0,0.55);
  color: var(--ink);
  padding: 5px 9px;
  letter-spacing: 0.12em;
  font-size: 11px;
  font-weight: 500;
}

.detail__content { display: grid; gap: 28px; align-content: start; }

.detail__artist {
  margin: 0;
  font-family: var(--font-body);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--ink-dim);
}
.detail__title {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(48px, 6vw, 96px);
  line-height: 0.96;
  letter-spacing: -0.015em;
}

/* Meta — list of dt/dd pairs each wrapped in .detail__row so individual
   rows can be hidden via the `hidden` attribute when their PB field is
   empty. See docs/release-detail-spec.md (meta-row visibility rules). */
.detail__meta {
  display: grid;
  gap: 6px;
  margin: 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 16px 0;
  font-size: 14px;
}
.detail__row {
  display: grid;
  grid-template-columns: 130px 1fr;
  column-gap: 24px;
  align-items: center;
}
.detail__row[hidden] { display: none; }
.detail__row dt {
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-dim);
  font-size: 12px;
}
.detail__row dd { margin: 0; color: var(--ink); }

.detail__tracks {
  margin: 0; padding: 0;
  list-style: none;
  counter-reset: track;
  display: grid;
  border-top: 1px solid var(--rule);
}
.detail__tracks li {
  counter-increment: track;
  display: grid;
  grid-template-columns: 32px 1fr auto;
  align-items: center;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  font-size: 15px;
}
.detail__tracks li::before {
  content: counter(track, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-dim);
  letter-spacing: 0.05em;
}
.detail__tracks .track-title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(18px, 1.4vw, 22px);
}
.detail__tracks .track-time {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-dim);
  letter-spacing: 0.05em;
}
.detail__tracks li:hover .track-title { color: var(--accent); }

.detail__credits {
  margin: 0;
  max-width: 56ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-dim);
  white-space: pre-line;     /* honour newlines from PB free-text */
}
.detail__credits[hidden] { display: none; }

/* Description blurb — sits between title and tracklist. Larger, more
   editorial type than the credits paragraph. Hidden when PB.description
   is empty (no decorative empty space). */
.detail__description {
  margin: 0;
  max-width: 60ch;
  font-family: var(--font-body);
  font-size: clamp(15px, 1.1vw, 17px);
  line-height: 1.5;
  color: var(--ink);
}
.detail__description[hidden] { display: none; }

/* Status badge — sits in the cover, top-right opposite the cat#. Hidden
   for `out_now` (default), shown otherwise. Colour-coded by data-status. */
.detail__cover .rel__status {
  position: absolute; right: 12px; top: 12px;
  background: rgba(0,0,0,0.55);
  color: var(--ink);
  padding: 5px 9px;
  letter-spacing: 0.12em;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
}
.detail__cover .rel__status[data-status="forthcoming"] { background: rgba(0,0,0,0.55); color: var(--accent); }
.detail__cover .rel__status[data-status="sold_out"]    { background: var(--accent-2); color: var(--ink); }
.detail__cover .rel__status[data-status="repressed"]   { background: var(--accent); color: var(--bg); }

.detail__buy { display: flex; gap: 12px; flex-wrap: wrap; }
.detail__cta {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 14px 22px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-weight: 500;
  color: var(--ink);
  cursor: none;
  transition: border-color 200ms, background 200ms, color 200ms;
}
.detail__cta:hover { border-color: var(--ink); }
.detail__cta--primary {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
.detail__cta--primary:hover { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.detail__cta[hidden] { display: none; }

/* Other-channels strip — small text-links under the primary CTAs.
   Surfaces every populated streaming/sales URL that isn't already used
   as a primary button (see populateDetail in app.js). */
.detail__channels {
  list-style: none;
  margin: 0; padding: 0;
  display: flex; flex-wrap: wrap;
  gap: 8px 14px;
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.detail__channels[hidden] { display: none; }
.detail__channels li {
  display: inline-flex; align-items: center;
}
.detail__channels li + li::before {
  content: "·";
  margin-right: 14px;
  color: var(--rule);
}
.detail__channels a {
  color: var(--ink-dim);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
  transition: color 160ms, border-color 160ms;
}
.detail__channels a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* Body lock during detail */
body.detail-open { overflow: hidden; }
body.detail-open .grain { opacity: 0.04; }

/* =====================================================================
   Artist detail overlay
   ===================================================================== */
.artist-overlay {
  position: fixed; inset: 0; z-index: 70;
  background: var(--bg);
  overflow-y: auto;
  display: none;
  padding: var(--header-h) var(--pad) calc(var(--np-h) + 24px);
}
.artist-overlay.is-active { display: block; }

.artist__inner {
  max-width: 1400px;
  margin: 24px auto 0;
  display: grid; gap: 6vh;
}

.artist__head {
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2vh;
}
.artist__city {
  font-family: var(--font-body);
  font-size: 13px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
  display: block;
  margin-bottom: 8px;
}
.artist__name {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(64px, 11vw, 200px);
  letter-spacing: -0.02em;
  line-height: 0.92;
}

.artist__body {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: clamp(32px, 6vw, 96px);
  align-items: start;
}
.artist__bio p {
  margin: 0 0 1em;
  font-size: clamp(17px, 1.4vw, 22px);
  line-height: 1.55;
  max-width: 60ch;
  color: var(--ink);
}

.artist__side h3 {
  margin: 0 0 16px;
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.artist__side ul {
  list-style: none; margin: 0; padding: 0;
  border-top: 1px solid var(--rule);
}
.artist__side ul li {
  display: grid; grid-template-columns: 80px 1fr;
  gap: 16px; align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--rule);
}
.artist__side ul li .cat {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-dim);
  letter-spacing: 0.04em;
}
.artist__side ul li .title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: 18px;
  color: var(--ink);
  cursor: none;
  transition: color 200ms;
}
.artist__side ul li .title:hover { color: var(--accent); }

.artist__links { margin-top: 24px; display: grid; gap: 8px; align-content: start; }
.artist__links .detail__cta { justify-self: start; padding: 10px 18px; font-size: 12px; }

@media (max-width: 720px) {
  .artist__body { grid-template-columns: 1fr; }
  .artist__side ul li { grid-template-columns: 60px 1fr; }
}

body.artist-open { overflow: hidden; }
body.artist-open .grain { opacity: 0.04; }

@media (max-width: 720px) {
  .detail__inner { grid-template-columns: 1fr; }
  .detail__meta  { grid-template-columns: 100px 1fr; }
}

/* =====================================================================
   Hero stamp — mono "INDEPENDENT RECORD LABEL · ROTTERDAM" line under logo.
   Replaces the old hero__bottom (lede + stats) — committed-design language.
   ===================================================================== */
.hero__stamp {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 14px;
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--ink-dim);
  text-transform: uppercase;
  padding-block: 2vh;
}
.hero__stamp i {
  font-style: normal;
  color: var(--rule);
}
@media (max-width: 720px) {
  .hero__stamp { font-size: 10px; gap: 10px; letter-spacing: 0.18em; }
}

/* =====================================================================
   ID Files — file-explorer UI for unreleased / works-in-progress.
   Visual: 1998 file-listing inside the CRT chrome. Monospace, dense.
   ===================================================================== */
.idfiles {
  padding: 10vh var(--pad);
  background: var(--bg);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.idfiles__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 32px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--rule);
}
.idfiles__head h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(36px, 5vw, 72px);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.idfiles__sub {
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 11px;
  color: var(--ink-dim);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.idfiles__list {
  list-style: none;
  margin: 0; padding: 0;
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 13px;
  color: var(--ink);
}
.idfile {
  display: grid;
  grid-template-columns: 28px 1.4fr 1.2fr 2fr auto auto;
  align-items: center;
  gap: 16px;
  padding: 14px 8px;
  border-bottom: 1px dashed var(--rule);
  transition: background 160ms;
}
.idfile:hover { background: rgba(255,255,255,0.02); }
.idfile:last-child { border-bottom: 1px solid var(--rule); }
.idfile__play {
  width: 24px; height: 24px;
  display: grid; place-items: center;
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--ink-dim);
  cursor: none;
  transition: background 160ms, color 160ms, border-color 160ms;
  padding: 0;
}
.idfile__play:hover {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
.idfile.is-playing .idfile__play {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
.idfile__name {
  color: var(--ink-dim);
  letter-spacing: 0.04em;
}
.idfile__artist {
  color: var(--ink);
  font-weight: 500;
}
.idfile__title {
  color: var(--ink);
  font-style: italic;
}
.idfile__size,
.idfile__time {
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
}
.idfiles__foot {
  margin: 28px 0 0;
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 11px;
  color: var(--ink-dim);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.idfiles__foot a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1px;
}
.idfiles__foot a:hover {
  border-bottom-color: var(--accent);
  color: var(--accent);
}

@media (max-width: 720px) {
  .idfile {
    grid-template-columns: 24px 1fr auto;
    grid-template-rows: auto auto;
    column-gap: 12px;
    row-gap: 4px;
    padding: 12px 4px;
  }
  .idfile__play { grid-row: 1 / span 2; }
  .idfile__name { grid-column: 2; grid-row: 1; font-size: 11px; }
  .idfile__artist { grid-column: 2; grid-row: 2; font-size: 13px; }
  .idfile__title { grid-column: 2; grid-row: 2; font-size: 13px;
    /* artist · title on one line; emulate by placing title after artist via space */
    margin-left: auto; padding-left: 8px;
  }
  .idfile__size { display: none; }
  .idfile__time { grid-column: 3; grid-row: 1 / span 2; }
}

/* =====================================================================
   Reduced motion
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  .footer-marquee__track,
  .grain { animation: none !important; }
  body { cursor: auto; }
  .cursor { display: none; }
  .np { transition: none; }
}
