/* ===========================================================================
   ETHEREAL — site styles
   ---------------------------------------------------------------------------
   The brief: it should look like an extravagant 2008 gothic band site that
   somebody built in Photoshop and sliced up. Underneath it is 2026 — semantic
   HTML, CSS grid, container queries, no framework, almost no JavaScript.

   The single most useful technique here: every supplied brand asset is
   light-on-black with the black baked in, no alpha. Compositing them with
   `mix-blend-mode: screen` over the black canvas drops the black to nothing
   and leaves only the ivory and red. That is why nothing needs cutting out,
   and why the artwork can overlap freely without visible rectangles.
   =========================================================================== */

/* ------------------------------------------------------------------ tokens */

:root {
  /* Sampled from the album sleeve and the identity board. */
  --ink:        #080607;
  --ink-2:      #0e0a0b;
  --ash:        #1a1315;
  --bone:       #e8ddc8;
  --bone-2:     #b3a893;
  --bone-3:     #81796c;   /* 4.70:1 on --ink */
  --bone-4:     #383029;   /* 1.56:1 — hairlines and rules ONLY, never text */
  --paper:      #d6c9ad;
  --blood:      #a11217;
  --blood-lit:  #db4348;   /* 4.70:1 on --ink */
  --blood-deep: #5b0808;
  --rust:       #6b3a28;
  --mould:      #3f5450;

  --display: 'Cinzel', 'Trajan Pro', Georgia, serif;
  --serif:   'Cormorant Garamond', Garamond, Georgia, serif;
  --ui:      'Barlow Condensed', 'Trebuchet MS', Arial, sans-serif;
  --hand:    'Parisienne', 'Snell Roundhand', cursive;

  /* A deliberately bounded canvas. Beyond this the page gains more black
     margin rather than stretching the artwork — which is exactly how the
     elaborate sites of the era behaved. */
  --canvas: 1480px;
  --gutter: clamp(16px, 3.4vw, 54px);
  /* Reading measures. Without these the layout stretches to the canvas at
     wide sizes — 100-character lines and tables with 400px of dead air.
     The elaborate sites of this era were densely composed central areas,
     not edge-to-edge fluid grids. */
  --measure: 68ch;        /* prose */
  --measure-wide: 980px;  /* listings, tables */
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone-2);
  font-family: var(--ui);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

/* height:auto is not optional here. Every image carries width/height
   attributes so the browser can reserve space and avoid layout shift — but
   without this, that height attribute wins over the CSS width and the images
   render stretched. */
img { max-width: 100%; height: auto; display: block; }
/* The user-agent stylesheet gives <figure> margin: 1em 40px. Nothing here
   reset it, so every mounted plate silently lost 80px of width — the Music
   sleeve drew a 312px cover in a 392px column — until a song page put one in
   an 88px mobile column and it collapsed to 22px, which is what finally
   showed it. */
figure { margin: 0; }
/* The UA's [hidden] rule is only display:none at user-agent priority, so any
   component that sets its own display — flex, grid — silently un-hides
   itself. Every progressive control on this site starts hidden and is
   revealed by script; this is what makes that true. */
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }

/* Buttons carry a UA background, border and font of their own. Every control
   here is styled from scratch, and anything using <button> for semantics
   rather than appearance — the track rows, the gallery frames — would
   otherwise render as a grey system button. */
button {
  font: inherit; color: inherit; background: none;
  border: 0; padding: 0; text-align: inherit;
}

::selection { background: var(--blood); color: #fff; }

/* Focus is an art-direction opportunity, not something to strip out. */
:focus-visible {
  outline: 2px solid var(--bone);
  outline-offset: 3px;
}

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

.skip {
  position: absolute; top: -60px; left: 12px; z-index: 100;
  background: var(--bone); color: var(--ink); padding: 10px 18px;
  font-size: 13px; letter-spacing: .18em; text-transform: uppercase;
}
.skip:focus { top: 12px; }

/* ------------------------------------------------------------- the canvas */

/* Layer 1: the page ground, which continues past the canvas on wide screens. */
.ground {
  min-height: 100vh;
  background:
    radial-gradient(120% 60% at 50% 0%, #17101200 0%, #000 78%),
    url(art/gen/texture-black-1200.webp) center / 1100px auto repeat;
  background-attachment: scroll, fixed;
}

/* Layer 2: the composed artwork area. Everything else sits inside this. */
.canvas {
  position: relative;
  width: min(100%, var(--canvas));
  margin-inline: auto;
  isolation: isolate;
  /* Tiled for the whole height — however long the page gets, it never runs
     out of grain and drops to flat black. */
  background: url(art/gen/texture-black-1200.webp) center top / 980px auto repeat, var(--ink);
  box-shadow: 0 0 140px -30px #000, 0 0 0 1px #00000080;
  /* Decorative artwork is positioned to bleed past the edges on purpose;
     clip contains it without becoming a scroll container. */
  overflow-x: clip;
}

/* The ornate framed texture sits over the top of the page and dissolves
   into the tiled ground, so the join never reads as a seam. */
.canvas::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: min(1040px, 90%);
  z-index: -1; pointer-events: none;
  background: url(art/gen/texture-framed-1200.webp) center top / 100% auto no-repeat;
  -webkit-mask-image: linear-gradient(#000 0, #000 52%, transparent 100%);
          mask-image: linear-gradient(#000 0, #000 52%, transparent 100%);
}

/* A scrim so the masthead always has something calm to sit on, whatever the
   texture is doing behind it. */
.canvas::after {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 190px;
  z-index: -1; pointer-events: none;
  background: linear-gradient(#000000d9, #00000059 55%, transparent);
}

/* ------------------------------------------------------------------ header */

.masthead {
  position: relative; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  padding: 22px var(--gutter) 18px;
  border-bottom: 1px solid #ffffff14;
}

.brand { display: flex; align-items: center; gap: 14px; }
.brand__sigil {
  width: 46px; height: 46px; object-fit: contain;
  mix-blend-mode: screen;           /* drops the asset's black ground */
  flex-shrink: 0;
}
.brand__name {
  margin: 0;
  font-family: var(--display); font-weight: 500;
  font-size: clamp(1.25rem, 2.6vw, 1.85rem);
  letter-spacing: .34em; text-indent: .34em;
  color: var(--bone);
  text-shadow: 0 1px 0 #000, 0 -1px 0 #ffffff1a;
}
.brand__tag {
  display: block; margin-top: 2px;
  font-size: 9px; letter-spacing: .46em; text-indent: .46em;
  color: var(--bone-3); text-transform: uppercase;
}

/* ---- navigation */

.nav { display: flex; align-items: center; gap: clamp(10px, 1.6vw, 26px); flex-wrap: wrap; }
.nav a {
  position: relative;
  padding: 8px 2px;
  font-size: 12px; font-weight: 500;
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--bone-2);
  transition: color .22s ease;
  /* WCAG 2.2 asks for 24x24 minimum; the padding gets us there without
     visually inflating the link. */
  min-height: 24px; display: inline-flex; align-items: center;
}
/* The underline is a drawn scratch, not a rule. */
.nav a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 2px; height: 2px;
  background: var(--blood-lit);
  clip-path: polygon(0 40%, 14% 0, 28% 70%, 44% 10%, 61% 80%, 76% 20%, 90% 60%, 100% 30%, 100% 100%, 0 100%);
  transform: scaleX(0); transform-origin: left;
  transition: transform .3s cubic-bezier(.2,.8,.25,1);
}
.nav a:hover, .nav a:focus-visible { color: var(--bone); }
.nav a:hover::after, .nav a:focus-visible::after { transform: scaleX(1); }
.nav a[aria-current='page'] { color: var(--bone); }
.nav a[aria-current='page']::after { transform: scaleX(1); }

/* ---- mobile menu toggle: the only JavaScript on the page */

.nav-toggle {
  display: none;
  width: 46px; height: 46px; padding: 0;
  background: none; border: 1px solid #ffffff26; color: var(--bone);
  cursor: pointer;
}
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after {
  display: block; width: 22px; height: 1.5px; background: currentColor;
  margin-inline: auto; transition: transform .28s ease, opacity .2s ease;
}
.nav-toggle span::before, .nav-toggle span::after { content: ''; position: relative; }
.nav-toggle span::before { top: -7px; }
.nav-toggle span::after  { top: 5.5px; }
.nav-toggle[aria-expanded='true'] span { background: transparent; }
.nav-toggle[aria-expanded='true'] span::before { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded='true'] span::after  { transform: translateY(-5.5px) rotate(-45deg); }

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

.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: clamp(20px, 3vw, 56px);
  padding: clamp(30px, 4.4vw, 64px) var(--gutter) 0;
  min-height: min(70vh, 600px);
  max-width: 1180px;          /* keeps the composition together */
  margin-inline: auto;
}

/* The sigil, enormous and ghosted, anchoring the composition behind
   everything. Purely decorative, so it is a background rather than an <img>. */
.hero::before {
  content: '';
  position: absolute; z-index: 0; pointer-events: none;
  right: -6%; top: 50%; translate: 0 -50%;
  width: min(62%, 620px); aspect-ratio: 1;
  background: url(art/gen/sigil-480.webp) center / contain no-repeat;
  mix-blend-mode: screen;
  opacity: .17;
}

.hero__words { position: relative; z-index: 2; }

.hero__scrawl {
  font-family: var(--hand);
  font-size: clamp(2rem, 5.4vw, 3.6rem);
  line-height: 1.06;
  color: var(--bone);
  rotate: -4deg;
  margin: 0 0 clamp(20px, 3vw, 38px);
  text-shadow: 0 2px 14px #000c;
}

.hero__creed {
  display: flex; flex-direction: column; gap: 6px;
  margin: 0 0 26px; padding-left: 4px;
  list-style: none;
}
.hero__creed li {
  font-family: var(--display);
  font-size: clamp(.72rem, 1.35vw, .95rem);
  letter-spacing: .44em; text-indent: .44em; text-transform: uppercase;
  color: var(--bone);
  text-shadow: 0 1px 10px #000, 0 0 3px #000;
}
.hero__creed li + li { border-top: 1px solid #ffffff2e; padding-top: 6px; }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* Buttons look stamped rather than styled. */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  min-height: 46px; padding: 0 24px;
  font-size: 12px; font-weight: 600; letter-spacing: .26em; text-transform: uppercase;
  color: var(--bone);
  background: #0000008c;
  border: 1px solid #ffffff3d;
  backdrop-filter: blur(2px);
  transition: background-color .24s ease, border-color .24s ease, color .24s ease;
}
.btn:hover, .btn:focus-visible {
  background: var(--blood); border-color: var(--blood-lit); color: #fff;
}
.btn--ghost { background: none; }

/* ---- the record, mounted and slightly crooked */

.hero__plate { position: relative; z-index: 2; justify-self: center; width: 100%; max-width: 460px; }
.plate {
  position: relative;
  rotate: -1.6deg;
  border: 1px solid #ffffff2b;
  padding: 10px;
  background: #000;
  box-shadow: 0 40px 90px -30px #000, 0 0 0 1px #0009;
  transition: rotate .5s cubic-bezier(.2,.8,.25,1), box-shadow .5s ease;
}
.plate:hover { rotate: 0deg; box-shadow: 0 46px 110px -28px #000, 0 0 70px -20px #a1121780; }
.plate img { width: 100%; aspect-ratio: 1; object-fit: cover; }
.plate figcaption {
  margin-top: 10px; text-align: center;
  font-size: 10px; letter-spacing: .32em; text-transform: uppercase; color: var(--bone-3);
}

/* ---- the dripping wordmark, deliberately breaking out of the hero */

/* The wrapper carries size and position; the image carries the blend and
   the mask, so it can sit inside a <picture> without losing either. */
.wordmark-h {
  position: relative; z-index: 3;
  display: block;
  width: min(96%, 1180px);
  margin: clamp(-72px, -5vw, -26px) auto clamp(14px, 2.4vw, 32px);
  font-size: inherit; font-weight: inherit;
}
.wordmark-h picture { display: block; }
.wordmark {
  display: block;
  width: 100%;
  mix-blend-mode: screen;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(96% 78% at 50% 50%, #000 34%, rgba(0,0,0,.55) 68%, transparent 90%);
          mask-image: radial-gradient(96% 78% at 50% 50%, #000 34%, rgba(0,0,0,.55) 68%, transparent 90%);
}

/* --------------------------------------------------------------- sections */

.strip { position: relative; z-index: 2; padding: clamp(30px, 4.4vw, 62px) var(--gutter); }

.strip__head {
  display: flex; align-items: baseline; gap: 16px;
  margin: 0 0 clamp(18px, 2.6vw, 30px);
}
.strip__head h2 {
  margin: 0;
  font-family: var(--display); font-weight: 500;
  font-size: clamp(1rem, 2vw, 1.4rem);
  letter-spacing: .34em; text-indent: .34em; text-transform: uppercase;
  color: var(--bone);
  white-space: nowrap;
}
.strip__head .rule { flex: 1; height: 1px; background: linear-gradient(90deg, #ffffff33, transparent); }
.strip__head .more {
  display: inline-flex; align-items: center; min-height: 24px; padding: 3px 0;
  font-size: 11px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--bone-3); white-space: nowrap;
  transition: color .2s ease;
}
.strip__head .more:hover { color: var(--blood-lit); }

/* ---- the two-panel row */

.panels {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  gap: clamp(18px, 2.6vw, 40px);
  align-items: start;
}

/* A pasted panel. The texture already carries burnt edges; feathering the
   mask lets it melt into the canvas instead of showing a hard rectangle. */
.panel {
  position: relative;
  padding: clamp(20px, 2.4vw, 32px);
  background: url(art/gen/texture-parchment-1200.webp) center / cover;
  border: 1px solid #ffffff1f;
  -webkit-mask-image: radial-gradient(150% 150% at 50% 50%, #000 82%, transparent 100%);
          mask-image: radial-gradient(150% 150% at 50% 50%, #000 82%, transparent 100%);
}
.panel--tilt { rotate: .7deg; }

/* ---- news: real markup, not a JPEG */

.news { margin: 0; }
.news__item { padding: 15px 0; border-bottom: 1px solid #ffffff1c; }
.news__item:last-child { border-bottom: 0; padding-bottom: 0; }
.news__item time {
  display: block; margin-bottom: 4px;
  font-size: 11px; letter-spacing: .26em; color: var(--blood-lit); font-variant-numeric: tabular-nums;
}
.news__item h3 { margin: 0 0 4px; font-family: var(--serif); font-size: 1.22rem; font-weight: 500; color: var(--bone); }
.news__item h3 a { transition: color .2s ease; }
.news__item h3 a:hover { color: var(--blood-lit); }
.news__item p { margin: 0; font-size: 13.5px; color: var(--bone-2); }

/* Archive links are compact by design, but still need a comfortable pointer
   target when the sidebar is used on a phone or with a keyboard. */
.newsside__year a, .newsside__months a {
  display: inline-block;
  min-width: 24px;
  min-height: 24px;
  line-height: 24px;
}

/* ---- the player slot */

ethereal-player {
  display: block;
  --ep-height: 560px;
  border: 1px solid #ffffff1f;
  box-shadow: 0 30px 80px -30px #000;
}

/* ---- tour */

.tour {
  width: 100%; max-width: var(--measure-wide);
  border-collapse: collapse; table-layout: fixed;
}
.tour col.c-date   { width: 104px; }
.tour col.c-city   { width: 30%; }
.tour col.c-venue  { width: auto; }
.tour col.c-ticket { width: 132px; }
.tour caption { text-align: left; }
.tour th {
  padding: 0 0 10px; text-align: left;
  font-size: 10px; font-weight: 600; letter-spacing: .3em; text-transform: uppercase;
  color: var(--bone-2); border-bottom: 1px solid #ffffff33;
}
.tour td { padding: 13px 0; border-bottom: 1px solid #ffffff12; vertical-align: baseline; }
.tour tr { transition: background-color .2s ease; }
.tour tbody tr:hover { background: #a1121726; }
.tour .date {
  font-variant-numeric: tabular-nums; letter-spacing: .13em;
  color: var(--blood-lit); font-weight: 500; white-space: nowrap; padding-right: 20px;
}
.tour .city { font-family: var(--serif); font-size: 1.14rem; color: var(--bone); }
.tour .venue { color: var(--bone-2); font-size: 13.5px; }
.tour .status { text-align: right; }
.tour .sold {
  display: inline-block; padding: 3px 10px;
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: #fff; background: var(--blood-deep); border: 1px solid var(--blood);
  rotate: -3deg;
}
.tour .tickets {
  display: inline-flex; align-items: center; min-height: 24px;
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--bone-2); box-shadow: inset 0 -1px 0 #ffffff3d;
  transition: color .2s ease, box-shadow .2s ease;
}
.tour .tickets:hover { box-shadow: inset 0 -1px 0 var(--blood-lit); }
.tour .tickets:hover { color: var(--blood-lit); }

/* --------------------------------------------------------------- footer */

.foot {
  position: relative; z-index: 2;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 20px;
  padding: clamp(28px, 3.4vw, 48px) var(--gutter);
  border-top: 1px solid #ffffff14;
}
.foot__mark { display: flex; align-items: center; gap: 13px; }
.foot__mark img { width: 38px; mix-blend-mode: screen; }
.foot__mark span {
  font-family: var(--display); font-size: 12px;
  letter-spacing: .4em; text-indent: .4em; text-transform: uppercase; color: var(--bone-3);
}
.foot__meta { font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--bone-3); }
.foot__social { display: flex; gap: 8px; }
.foot__social a {
  display: grid; place-items: center; width: 40px; height: 40px;
  border: 1px solid #ffffff1f; color: var(--bone-3);
  transition: color .2s ease, border-color .2s ease, background-color .2s ease;
}
.foot__social a:hover { color: var(--bone); border-color: var(--blood); background: #a1121733; }
.foot__social svg { width: 17px; height: 17px; }

/* ====================================================== responsive layout */
/* Art direction, not shrinking: the pieces are re-composed at each size
   rather than the desktop layout being scaled down. */

@media (max-width: 1000px) {
  .hero { grid-template-columns: minmax(0, 1fr); min-height: 0; text-align: center; }
  .hero::before { right: 50%; translate: 50% -50%; width: min(90%, 520px); opacity: .12; }
  .hero__scrawl { rotate: -2.5deg; }
  .hero__creed { align-items: center; padding-left: 0; }
  .btn-row { justify-content: center; }
  .hero__plate { max-width: 380px; order: -1; }
  .panels { grid-template-columns: minmax(0, 1fr); }
  .panel--tilt { rotate: 0deg; }
}

@media (max-width: 720px) {
  .nav-toggle { display: grid; place-items: center; }
  .nav {
    display: none;
    width: 100%; flex-direction: column; align-items: stretch; gap: 0;
    margin-top: 14px; border-top: 1px solid #ffffff1f;
  }
  .nav[data-open='true'] { display: flex; }
  .nav a {
    padding: 15px 4px; border-bottom: 1px solid #ffffff12;
    font-size: 13px; letter-spacing: .3em;
  }
  .nav a::after { display: none; }

  .canvas { background-size: 160% auto; }
  .wordmark-h { width: 108%; margin-left: -4%; }

  /* Stack the tour rows into flyer fragments rather than squeezing a table. */
  .tour thead { display: none; }
  .tour, .tour tbody, .tour tr, .tour td { display: block; width: 100%; }
  .tour tr {
    position: relative;
    padding: 14px 0 16px; border-bottom: 1px solid #ffffff1f;
  }
  .tour td { border: 0; padding: 1px 0; }
  .tour .status { text-align: left; margin-top: 8px; }
  .tour .date { padding-right: 0; }
}

@media (max-width: 420px) {
  .brand__sigil { width: 38px; height: 38px; }
  .hero__scrawl { font-size: clamp(1.7rem, 10vw, 2.4rem); }
}

/* ------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .plate:hover { rotate: -1.6deg; }
}

/* ------------------------------------------------------------ print */

@media print {
  .ground, .canvas, .canvas::before { background: none; }
  .nav, .foot__social, ethereal-player, .wordmark { display: none; }
  body { color: #000; background: #fff; }
}

/* ===========================================================================
   INTERIOR PAGES — Music · Tour · Gallery · About
   =========================================================================== */

/* Cross-document view transitions, as pure progressive enhancement. Browsers
   without support simply navigate; nothing depends on it working. */
@view-transition { navigation: auto; }
.masthead { view-transition-name: masthead; }
.foot     { view-transition-name: foot; }
::view-transition-old(root) { animation: vt-out .22s ease both; }
::view-transition-new(root) { animation: vt-in  .32s ease both; }
@keyframes vt-out { to   { opacity: 0; filter: brightness(.4); } }
@keyframes vt-in  { from { opacity: 0; filter: brightness(2.2) contrast(.6); } }

/* ------------------------------------------------------------- page head */

.pagehead {
  position: relative; z-index: 2;
  padding: clamp(34px, 5vw, 74px) var(--gutter) clamp(10px, 2vw, 22px);
}
/* The sigil, enormous and nearly invisible, anchoring every interior page. */
.pagehead::after {
  content: ''; position: absolute; pointer-events: none;
  right: 2%; top: 50%; translate: 0 -50%;
  width: min(34%, 340px); aspect-ratio: 1;
  background: url(art/gen/sigil-480.webp) center / contain no-repeat;
  mix-blend-mode: screen; opacity: .13;
}
.pagehead__kicker {
  margin: 0 0 10px;
  font-size: 10px; font-weight: 600; letter-spacing: .46em; text-indent: .46em;
  text-transform: uppercase; color: var(--blood-lit);
}
.pagehead__title {
  margin: 0;
  font-family: var(--display); font-weight: 500;
  font-size: clamp(1.9rem, 5.2vw, 3.4rem);
  letter-spacing: .2em; text-indent: .2em; text-transform: uppercase;
  color: var(--bone);
  text-shadow: 0 2px 0 #000, 0 -1px 0 #ffffff1f, 0 6px 34px #000;
}
.pagehead__standfirst {
  margin: 14px 0 0; max-width: 52ch;
  font-family: var(--serif); font-size: clamp(1rem, 1.7vw, 1.24rem);
  font-style: italic; color: var(--bone-2);
}

/* =================================================================== MUSIC */

.booklet__grid {
  display: grid;
  grid-template-columns: minmax(280px, 392px) minmax(0, 860px);
  gap: clamp(24px, 3.4vw, 60px);
  align-items: start;
  justify-content: start;
}

/* The sleeve stays with you while the listing scrolls — the one thing a
   printed booklet cannot do. */
.booklet__sleeve { position: sticky; top: 22px; }
.plate--still, .plate--still:hover { rotate: 0deg; }

.spec {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 7px 18px;
  margin: 22px 0 0; padding-top: 16px; border-top: 1px solid #ffffff1f;
}
.spec dt { font-size: 10px; letter-spacing: .28em; text-transform: uppercase; color: var(--bone-3); }
.spec dd {
  margin: 0; text-align: right;
  font-family: var(--serif); font-size: 1.02rem; color: var(--bone);
  font-variant-numeric: tabular-nums;
}
.sleeve-note {
  margin: 16px 0 20px;
  font-family: var(--serif); font-size: 1.02rem; font-style: italic; color: var(--bone-2);
}
.btn-row--stack { flex-direction: column; align-items: stretch; }
.btn-row--stack .btn { justify-content: center; }

.listen { margin-bottom: clamp(30px, 4vw, 54px); }
.listen ethereal-player { --ep-height: 620px; }
.listen__note {
  margin: 14px 0 0;
  font-size: 12px; letter-spacing: .1em; color: var(--bone-3); max-width: 60ch;
}

/* ---- the track listing */

.listing__sect + .listing__sect { margin-top: clamp(22px, 3vw, 36px); }
.listing__sect-head { display: flex; align-items: center; gap: 13px; margin-bottom: 8px; }
.listing__sect-head .n {
  font-family: var(--display); font-size: .68rem; letter-spacing: .18em;
  color: var(--verd-lit); min-width: 1.8em;
}
.listing__sect-head .l {
  font-size: 10px; font-weight: 600; letter-spacing: .4em;
  text-transform: uppercase; color: var(--bone-2); white-space: nowrap;
}
.listing__sect-head .r { flex: 1; height: 1px; background: linear-gradient(90deg, #ffffff2e, transparent); }

.listing__tracks { list-style: none; margin: 0; padding: 0; max-width: 760px; }

.trackrow {
  position: relative; isolation: isolate;
  display: flex; align-items: baseline; gap: 14px;
  width: 100%; padding: 11px 12px 11px 14px; text-align: left;
  color: var(--bone-2); cursor: pointer;
  transition: color .26s ease;
}
.trackrow::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, #5b0808b0 0%, #5b080829 42%, transparent 84%);
  transform: scaleX(0); transform-origin: left;
  transition: transform .42s cubic-bezier(.2,.8,.25,1);
}
.trackrow:hover::before, .trackrow:focus-visible::before { transform: scaleX(1); }
.trackrow:hover { color: var(--bone); }
.trackrow:focus-visible { outline: 1px solid var(--bone-2); outline-offset: -1px; }

.trackrow__no {
  font-family: var(--serif); font-size: .92rem; color: var(--bone-3);
  font-variant-numeric: tabular-nums; min-width: 2em; flex-shrink: 0;
  transition: opacity .2s ease;
}
/* The play triangle occupies the number's box and swaps in on hover, so the
   row never changes width as you move down the list. */
.trackrow__play {
  position: absolute; left: 14px; top: 50%; translate: 0 -50%;
  width: 2em; display: grid; place-items: start;
  opacity: 0; transition: opacity .2s ease; color: var(--blood-lit);
}
.trackrow__play svg { width: 13px; height: 13px; }
.trackrow:hover .trackrow__no, .trackrow.is-playing .trackrow__no { opacity: 0; }
.trackrow:hover .trackrow__play, .trackrow.is-playing .trackrow__play { opacity: 1; }

.trackrow__title {
  font-family: var(--serif); font-size: 1.2rem; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: transform .42s cubic-bezier(.2,.8,.25,1);
}
.trackrow:hover .trackrow__title { transform: translateX(4px); }
.trackrow__title i {
  font-style: italic; font-size: .82em; color: var(--bone-3);
  letter-spacing: .05em; margin-left: .5em;
}
.trackrow__lead {
  flex: 1; min-width: 14px; height: 1px; align-self: center; margin-top: 3px;
  background-image: radial-gradient(circle, var(--bone-4) .5px, transparent .5px);
  background-size: 4px 1px; background-repeat: repeat-x;
}
.trackrow__dur {
  font-size: .74rem; letter-spacing: .13em; font-variant-numeric: tabular-nums;
  color: var(--bone-3); flex-shrink: 0; font-weight: 500;
}

.trackrow.is-current { color: var(--bone); }
.trackrow.is-current::before { transform: scaleX(1); }
.trackrow.is-current::after {
  content: ''; position: absolute; left: 0; top: 5px; bottom: 5px; width: 2px;
  background: var(--blood-lit); box-shadow: 0 0 11px #d4202799;
}
.trackrow.is-current .trackrow__title { transform: translateX(4px); }
.trackrow.is-current .trackrow__dur { color: var(--bone-2); }

/* ---- other releases */

.releases {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 268px));
  gap: clamp(16px, 2.4vw, 34px);
}
.release a { display: block; }
.release__art {
  border: 1px solid #ffffff26; padding: 8px; background: #000;
  transition: border-color .3s ease, transform .4s cubic-bezier(.2,.8,.25,1);
}
.release__art img { aspect-ratio: 1; object-fit: cover; }
.release a:hover .release__art { border-color: var(--blood); transform: translateY(-4px); }
.release h3 {
  margin: 14px 0 3px;
  font-family: var(--serif); font-size: 1.26rem; font-weight: 500; color: var(--bone);
}
.release__meta {
  margin: 0 0 8px;
  font-size: 10px; letter-spacing: .28em; text-transform: uppercase; color: var(--blood-lit);
}
.release__note { margin: 0; font-size: 13px; color: var(--bone-3); }

/* ==================================================================== TOUR */

.tourwrap { position: relative; }
.leg + .leg { margin-top: clamp(34px, 4.6vw, 62px); }
.leg__head { display: flex; align-items: baseline; gap: 16px; margin-bottom: 14px; }
.leg__head h2 {
  margin: 0;
  font-family: var(--display); font-weight: 500;
  font-size: clamp(.92rem, 1.9vw, 1.22rem);
  letter-spacing: .3em; text-indent: .3em; text-transform: uppercase;
  color: var(--bone); white-space: nowrap;
}
.leg__head .rule { flex: 1; height: 1px; background: linear-gradient(90deg, #ffffff33, transparent); }
.leg__count {
  font-size: 10px; letter-spacing: .26em; text-transform: uppercase;
  color: var(--bone-3); white-space: nowrap;
}

/* A rubber-stamped date block rather than a line of text. */
.stamp {
  display: inline-grid; place-items: center;
  width: 58px; padding: 5px 0 6px;
  border: 1px solid #ffffff38; rotate: -1.6deg; background: #00000073;
  transition: border-color .26s ease, background-color .26s ease;
}
.stamp__m { font-size: 9px; font-weight: 600; letter-spacing: .22em; color: var(--blood-lit); line-height: 1; }
.stamp__d {
  font-family: var(--serif); font-size: 1.42rem; line-height: 1.05;
  color: var(--bone); font-variant-numeric: tabular-nums;
}
.tour--full tbody tr:hover .stamp { border-color: var(--blood); background: #5b080866; }
.tour--full td { padding: 11px 0; }
.tour--full .date { width: 78px; }
.tour--full .city { font-size: 1.24rem; }
.tour--full tr.is-gone .city,
.tour--full tr.is-gone .venue,
.tour--full tr.is-gone .stamp__d { color: var(--bone-3); }

/* ---- signup */

.signup { margin-top: clamp(34px, 4.6vw, 62px); max-width: 620px; }
.signup__title {
  margin: 0 0 8px;
  font-family: var(--display); font-weight: 500; font-size: 1.05rem;
  letter-spacing: .28em; text-indent: .28em; text-transform: uppercase; color: var(--bone);
}
.signup__note { margin: 0 0 18px; font-size: 13.5px; color: var(--bone-2); max-width: 46ch; }
.signup__form { display: flex; gap: 10px; flex-wrap: wrap; }
.signup__form input {
  flex: 1 1 220px; min-height: 46px; padding: 0 14px;
  background: #00000099; color: var(--bone); border: 1px solid #ffffff2e;
  font-family: var(--ui); font-size: 14px; letter-spacing: .1em;
}
.signup__form input::placeholder { color: var(--bone-3); }
.signup__form input:focus-visible { outline: 2px solid var(--bone); outline-offset: 1px; }

.scrawl-aside {
  position: absolute; right: 0; bottom: -10px; margin: 0; rotate: -6deg;
  font-family: var(--hand); font-size: clamp(1.5rem, 3.4vw, 2.6rem);
  line-height: 1.05; color: var(--bone-2); text-align: right;
  text-shadow: 0 2px 16px #000; pointer-events: none;
}

/* ================================================================= GALLERY */

.filters {
  display: flex; flex-wrap: wrap; gap: 8px;
  max-width: 1200px; margin: 0 auto clamp(20px, 2.6vw, 32px);
}
.filter {
  min-height: 36px; padding: 0 18px;
  font-size: 10px; font-weight: 600; letter-spacing: .28em; text-transform: uppercase;
  color: var(--bone-3); background: none; border: 1px solid #ffffff1f; cursor: pointer;
  transition: color .22s ease, border-color .22s ease, background-color .22s ease;
}
.filter:hover { color: var(--bone); border-color: #ffffff4d; }
.filter[aria-pressed=true] { color: var(--bone); border-color: var(--blood); background: #5b08084d; }

.sheet {
  list-style: none; margin: 0 auto; padding: 0; max-width: 1200px;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: clamp(18px, 2.6vw, 40px) clamp(14px, 2vw, 30px);
}
.sheet__cell { min-width: 0; }   /* same reason, for the grid items */
.sheet__empty {
  text-align: center; padding: 40px 0; color: var(--bone-3);
  letter-spacing: .2em; text-transform: uppercase; font-size: 11px;
}

.frame {
  position: relative; display: block; width: 100%; padding: 9px 9px 0; cursor: pointer;
  background: #0d0a0b; border: 1px solid #ffffff1f;
  rotate: var(--rot, 0deg);
  box-shadow: 0 18px 40px -18px #000;
  transition: rotate .45s cubic-bezier(.2,.8,.25,1), transform .45s cubic-bezier(.2,.8,.25,1),
              box-shadow .45s ease, border-color .3s ease;
}
.frame:hover, .frame:focus-visible {
  rotate: 0deg; transform: translateY(-6px) scale(1.02);
  border-color: var(--blood); box-shadow: 0 28px 60px -20px #000, 0 0 50px -18px #a1121780;
}
/* A strip of tape holding it to the board. */
.frame__tape {
  position: absolute; left: 50%; top: -9px; translate: -50% 0;
  width: 62px; height: 18px; rotate: -2.4deg;
  background: linear-gradient(#e8ddc81f, #e8ddc814);
  border-left: 1px solid #ffffff1a; border-right: 1px solid #ffffff1a;
}
.frame__img { display: block; overflow: hidden; background: #000; }
.frame__img img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.frame__cap { display: block; padding: 9px 2px 10px; text-align: left; }
.frame__caption {
  display: block; font-family: var(--serif); font-size: 1rem; color: var(--bone);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.frame__credit {
  display: block; margin-top: 2px;
  font-size: 9px; letter-spacing: .26em; text-transform: uppercase; color: var(--bone-3);
}

/* ---- lightbox */

.lightbox {
  width: min(94vw, 1200px); max-width: none; max-height: 92vh;
  padding: 0; border: 1px solid #ffffff26;
  background: #0a0708; color: var(--bone); overflow: visible;
}
.lightbox::backdrop { background: #030203f2; backdrop-filter: blur(6px); }
.lightbox__fig { margin: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.lightbox__fig img {
  width: 100%; max-height: calc(92vh - 78px); object-fit: contain; background: #000;
}
.lightbox__fig figcaption {
  display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
  padding: 14px 18px; border-top: 1px solid #ffffff1a;
}
#lightbox-cap { font-family: var(--serif); font-size: 1.12rem; color: var(--bone); }
#lightbox-credit { font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--bone-3); }
#lightbox-count {
  margin-left: auto; font-size: 11px; letter-spacing: .2em;
  font-variant-numeric: tabular-nums; color: var(--bone-3);
}

.lightbox__close {
  position: absolute; top: -14px; right: -14px; z-index: 3;
  width: 40px; height: 40px; display: grid; place-items: center;
  background: #0a0708; border: 1px solid #ffffff38; color: var(--bone); cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease;
}
.lightbox__close:hover { background: var(--blood); border-color: var(--blood-lit); }
.lightbox__close svg { width: 17px; height: 17px; }

.lightbox__nav {
  position: absolute; top: 50%; translate: 0 -50%; z-index: 3;
  width: 46px; height: 66px; display: grid; place-items: center;
  background: #0a0708cc; border: 1px solid #ffffff26; color: var(--bone); cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease;
}
.lightbox__nav:hover { background: var(--blood); border-color: var(--blood-lit); }
.lightbox__nav svg { width: 20px; height: 20px; }
.lightbox__nav--prev { left: -23px; }
.lightbox__nav--next { right: -23px; }

/* =================================================================== ABOUT */

.about {
  display: grid;
  grid-template-columns: minmax(150px, 190px) minmax(0, 820px);
  gap: clamp(22px, 3.2vw, 52px); align-items: start;
}

/* Tabs pasted down the edge of a scrapbook. */
.about__index { position: sticky; top: 22px; }
.about__index ul { list-style: none; margin: 0; padding: 0; }
.about__index a {
  display: block; padding: 12px 14px;
  font-size: 10px; font-weight: 600; letter-spacing: .28em; text-transform: uppercase;
  color: var(--bone-3); background: #ffffff05;
  border: 1px solid #ffffff14; border-bottom: 0;
  transition: color .22s ease, background-color .22s ease, transform .3s ease;
}
.about__index li:last-child a { border-bottom: 1px solid #ffffff14; }
.about__index a:hover, .about__index a:focus-visible {
  color: var(--bone); background: #5b080859; transform: translateX(4px);
}
.about__index a.is-first { color: var(--bone); background: #5b080873; }

.about__body { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(22px, 3vw, 42px); }

.paper {
  position: relative; padding: clamp(22px, 2.8vw, 40px); max-width: 760px;
  background: url(art/gen/texture-parchment-1200.webp) center / cover;
  border: 1px solid #ffffff1f;
  -webkit-mask-image: radial-gradient(150% 150% at 50% 50%, #000 84%, transparent 100%);
          mask-image: radial-gradient(150% 150% at 50% 50%, #000 84%, transparent 100%);
}
.paper--tilt { rotate: -.5deg; }
.paper h2 {
  margin: 0 0 16px;
  font-family: var(--display); font-weight: 500; font-size: clamp(1rem, 2vw, 1.3rem);
  letter-spacing: .28em; text-indent: .28em; text-transform: uppercase; color: var(--bone);
}
.paper p {
  font-family: var(--serif); font-size: 1.1rem; line-height: 1.72;
  color: var(--bone-2); margin: 0 0 14px; max-width: var(--measure);
}
.paper p:last-child { margin-bottom: 0; }
.paper .lede { font-size: 1.28rem; color: var(--bone); font-style: italic; }
.paper .muted { font-size: 1rem; color: var(--bone-3); }
.paper .sign { margin-top: 20px; font-family: var(--hand); font-size: 1.7rem; color: var(--bone); }

.about__portrait { margin: 0; max-width: 560px; }
.about__portrait figcaption {
  margin-top: 10px; text-align: center;
  font-size: 10px; letter-spacing: .3em; text-transform: uppercase; color: var(--bone-3);
}

.timeline { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; max-width: var(--measure); }
.timeline li { display: grid; grid-template-columns: 4.5em minmax(0, 1fr); gap: 16px; align-items: baseline; }
.timeline__y {
  font-family: var(--serif); font-size: 1.1rem; color: var(--blood-lit);
  font-variant-numeric: tabular-nums;
}
.timeline__t { font-family: var(--serif); font-size: 1.06rem; color: var(--bone-2); }
.timeline em { font-style: italic; color: var(--bone); }

.pullquote { margin: 0; padding: clamp(14px, 2.4vw, 30px) 0; text-align: center; max-width: 760px; }
.pullquote p {
  margin: 0; font-family: var(--hand);
  font-size: clamp(1.7rem, 4.6vw, 3rem); line-height: 1.15;
  color: var(--bone); rotate: -1.6deg; text-shadow: 0 2px 20px #000;
}

.lyric-index {
  list-style: none; margin: 0; padding: 0; max-width: 760px;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 4px 20px;
}
.lyric-index a {
  display: block; padding: 6px 0;
  font-family: var(--serif); font-size: 1.06rem; color: var(--bone-2);
  border-bottom: 1px solid #ffffff0f;
  transition: color .2s ease, border-color .2s ease;
}
.lyric-index a:hover { color: var(--blood-lit); border-color: var(--blood); }

.disco { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; max-width: 520px; }
.disco li { display: grid; grid-template-columns: 4.5em minmax(0, 1fr) auto; gap: 16px; align-items: baseline; }
.disco__y { font-variant-numeric: tabular-nums; color: var(--blood-lit); font-size: .95rem; }
.disco__t { font-family: var(--serif); font-size: 1.14rem; color: var(--bone); }
.disco__f { font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--bone-3); }

/* ============================================ interior responsive layout */

@media (max-width: 900px) {
  .booklet__grid { grid-template-columns: minmax(0, 1fr); }
  .booklet__sleeve {
    position: static;
    display: grid; grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
    gap: 22px; align-items: start;
  }
  .booklet__sleeve .spec { margin-top: 0; padding-top: 0; border-top: 0; }
  .booklet__sleeve .plate { grid-row: span 3; }
  .listen ethereal-player { --ep-height: 560px; }

  .about { grid-template-columns: minmax(0, 1fr); }
  .about__index { position: static; }
  .about__index ul { display: flex; flex-wrap: wrap; gap: 6px; }
  .about__index a { border: 1px solid #ffffff14; }
  .about__index a:hover { transform: none; }

  .scrawl-aside { position: static; text-align: center; rotate: -3deg; margin-top: 30px; }
}

@media (max-width: 700px) {
  .booklet__sleeve { grid-template-columns: minmax(0, 1fr); }
  .booklet__sleeve .plate { grid-row: auto; max-width: 260px; }
  .sheet { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 12px; }
  .frame { padding: 6px 6px 0; }
  .frame__tape { width: 44px; height: 14px; top: -7px; }
  .lightbox { width: 96vw; }
  .lightbox__nav--prev { left: 4px; }
  .lightbox__nav--next { right: 4px; }
  .lightbox__close { top: 4px; right: 4px; }
  /* Each show becomes a ticket stub: the stamp on the left, the details
     stacked beside it. The generic stacking rule above is not enough on its
     own because .tour--full td is more specific than .tour td. */
  .tour--full tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0 15px;
    align-items: start;
    padding: 13px 0 14px;
  }
  .tour--full td { padding: 0; }
  .tour--full .date { width: auto; grid-row: span 3; align-self: center; }
  .tour--full .city { font-size: 1.16rem; line-height: 1.25; }
  .tour--full .venue { font-size: 13px; }
  .tour--full .status { text-align: left; margin-top: 6px; }
  .stamp { rotate: -1deg; }
}

@media (max-width: 420px) {
  .lyric-index { grid-template-columns: minmax(0, 1fr); }
  .timeline li, .disco li { grid-template-columns: 3.6em minmax(0, 1fr); }
  .disco__f { grid-column: 2; }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  .frame:hover, .frame:focus-visible { transform: none; rotate: var(--rot, 0deg); }
}

/* Shown only if <ethereal-player> never upgraded — see playerEmbed(). */
.player-fallback {
  margin: 0; padding: clamp(22px, 3vw, 40px); text-align: center;
  border: 1px solid var(--bone-4); background: var(--ink-2);
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  line-height: 2.2; color: var(--bone-3);
}
.player-fallback code {
  text-transform: none; letter-spacing: 0; color: var(--bone);
  background: #000; border: 1px solid var(--bone-4); padding: 2px 7px;
  font-family: ui-monospace, Consolas, monospace;
}

/* ---------------------------------------------------- footer, composed */

.foot__mark { display: flex; align-items: center; gap: 13px; }
.foot__name {
  font-family: var(--display); font-size: 12px;
  letter-spacing: .4em; text-indent: .4em; text-transform: uppercase; color: var(--bone-2);
}
.foot__creed {
  padding-left: 13px; border-left: 1px solid var(--bone-4);
  font-size: 9px; letter-spacing: .32em; text-transform: uppercase; color: var(--bone-3);
}
.foot__nav { display: flex; flex-wrap: wrap; gap: 4px 22px; }
.foot__nav a {
  display: inline-flex; align-items: center; min-height: 24px;
  font-size: 10px; letter-spacing: .28em; text-transform: uppercase;
  color: var(--bone-3); transition: color .2s ease;
}
.foot__nav a:hover, .foot__nav a:focus-visible { color: var(--bone); }
.foot__nav a[aria-current='page'] { color: var(--bone-2); }
.foot__end { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; justify-content: flex-end; }

@media (max-width: 820px) {
  .foot { flex-direction: column; align-items: center; text-align: center; gap: 18px; }
  .foot__end { flex-direction: column; gap: 14px; }
  .foot__creed { display: none; }
}

/* --------------------------------------- tour: a right rail at wide sizes */
/* Constraining the table to a reading measure leaves usable space beside it.
   Rather than let that sit empty, the signup and the scrawl move into a rail
   — placed purely with grid line numbers, so the markup stays a plain
   sequence of legs. */

@media (min-width: 1180px) {
  .tourwrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 330px;
    column-gap: clamp(40px, 4vw, 72px);
    align-items: start;
  }
  .leg { grid-column: 1; }
  .signup {
    grid-column: 2; grid-row: 1;
    margin-top: 0; max-width: none;
    position: sticky; top: 22px;
  }
  .scrawl-aside {
    grid-column: 2; grid-row: 2;
    position: static; align-self: start;
    margin-top: 34px; text-align: center;
  }
}

/* ===========================================================================
   TORN EDGES
   ---------------------------------------------------------------------------
   Everything above is built from 1px rectangles, and that is the single
   clearest giveaway that this is a modern site wearing a grunge texture
   rather than something cut out and pasted down in 2008. Paper does not have
   hairline borders and rubber stamps do not print perfect rectangles.

   The edges below are generated, not drawn: an feTurbulence noise field
   displaces the edge of a white rectangle, and the result is used as a mask.
   No extra image assets, resolution independent, and a different `seed`
   gives every panel its own tear so repeated elements never look cloned.

   The mask goes on a ::before layer carrying the background rather than on
   the element itself — masking the element would chew the text sitting near
   its edges.
   =========================================================================== */

:root {
  /* Big, soft tears — for sheets of paper. */
  --torn-a: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300' preserveAspectRatio='none'%3E%3Cfilter id='t' x='-15%25' y='-15%25' width='130%25' height='130%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.013 0.021' numOctaves='5' seed='11'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='13' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3Crect x='5' y='4' width='390' height='292' fill='%23fff' filter='url(%23t)'/%3E%3C/svg%3E");
  --torn-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300' preserveAspectRatio='none'%3E%3Cfilter id='t' x='-15%25' y='-15%25' width='130%25' height='130%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.017 0.026' numOctaves='5' seed='29'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='11' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3Crect x='4' y='5' width='392' height='290' fill='%23fff' filter='url(%23t)'/%3E%3C/svg%3E");
  --torn-c: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300' preserveAspectRatio='none'%3E%3Cfilter id='t' x='-15%25' y='-15%25' width='130%25' height='130%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.021 0.018' numOctaves='5' seed='47'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='12' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3Crect x='5' y='5' width='390' height='290' fill='%23fff' filter='url(%23t)'/%3E%3C/svg%3E");

  /* Tight, high-frequency erosion — for small controls and stamps, where a
     big tear would eat the label. */
  --eroded: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cfilter id='t' x='-20%25' y='-40%25' width='140%25' height='180%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.09 0.14' numOctaves='4' seed='5'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='3' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3Crect x='3' y='3' width='194' height='54' fill='%23fff' filter='url(%23t)'/%3E%3C/svg%3E");
  --eroded-hard: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cfilter id='t' x='-20%25' y='-40%25' width='140%25' height='180%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.14 0.2' numOctaves='3' seed='23'/%3E%3CfeDisplacementMap in='SourceGraphic' scale='4' xChannelSelector='R' yChannelSelector='G'/%3E%3C/filter%3E%3Crect x='4' y='4' width='192' height='52' fill='%23fff' filter='url(%23t)'/%3E%3C/svg%3E");
}

.torn-mask {
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

/* ---------------------------------------------------------- paper sheets */
/* The background and its border move to a ::before so the mask never
   touches the text. */

.panel, .paper {
  background: none;
  border: 0;
  -webkit-mask-image: none; mask-image: none;   /* was a soft radial vignette */
  isolation: isolate;
}
.panel::before, .paper::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, #d6c9ad1c, #d6c9ad0a 38%, #00000040),
    url(art/gen/texture-parchment-1200.webp) center / cover;
  box-shadow: inset 0 0 0 1px #ede4d41a, inset 0 0 60px -20px #000;
  -webkit-mask-image: var(--torn-a); mask-image: var(--torn-a);
  -webkit-mask-size: 100% 100%;    mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;  mask-repeat: no-repeat;
}
/* A second, slightly smaller tear in near-black sits just inside the first,
   so the edge reads as a dark burn rather than a clean cut. */
.paper--tilt::before, .panel--tilt::before { -webkit-mask-image: var(--torn-c); mask-image: var(--torn-c); }

/* The signup panel sits on the tour page and should look like a different
   sheet again. */
.signup::before { -webkit-mask-image: var(--torn-b); mask-image: var(--torn-b); }

/* ------------------------------------------------------------- controls */
/* Buttons were the most obviously "2026 UI" thing on the page: a 1px border
   and a perfect rectangle. Now they are printed labels with a bitten edge. */

.btn, .filter, .signup__form input {
  border: 0;
  background: none;
  backdrop-filter: none;      /* blurs a rectangle, defeating the torn edge */
  position: relative;
  isolation: isolate;
}
.btn::before, .filter::before, .signup__form input::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  /* Lighter than the ground, not darker — a printed label has to lift off
     the page, and a 1px hairline cannot survive a torn edge. */
  background: linear-gradient(180deg, #ede4d414, #00000073);
  box-shadow: inset 0 0 0 2px #ffffff2b;
  -webkit-mask-image: var(--eroded); mask-image: var(--eroded);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transition: background-color .24s ease, box-shadow .24s ease;
}
.btn:hover::before, .btn:focus-visible::before {
  background: var(--blood);
  box-shadow: inset 0 0 0 1px var(--blood-lit);
}
.btn--ghost::before { background: #00000059; }

.filter::before { background: #ede4d40a; box-shadow: inset 0 0 0 2px #ffffff1f; }
.filter:hover::before { box-shadow: inset 0 0 0 2px #ffffff4d; }
.filter[aria-pressed=true]::before { background: #5b080859; box-shadow: inset 0 0 0 2px var(--blood); }

/* <input> cannot carry a ::before, so it takes the mask directly — the text
   sits well inside the 5px erosion. */
.signup__form input {
  -webkit-mask-image: var(--eroded); mask-image: var(--eroded);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px #ffffff2e;
}
.signup__form input::before { display: none; }

/* ---------------------------------------------------------------- stamps */
/* Rubber stamps print unevenly — the ink starves at the edges. */

.sold {
  border: 0;
  -webkit-mask-image: var(--eroded-hard); mask-image: var(--eroded-hard);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  background: var(--blood-deep);
  box-shadow: inset 0 0 0 1px var(--blood);
}
.stamp {
  border: 0;
  background: none;
  position: relative;
  isolation: isolate;
}
.stamp::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, #ede4d40f, #00000080);
  box-shadow: inset 0 0 0 2px #ffffff33;
  -webkit-mask-image: var(--eroded-hard); mask-image: var(--eroded-hard);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transition: background-color .26s ease, box-shadow .26s ease;
}
.tour--full tbody tr:hover .stamp::before {
  background: #5b080866; box-shadow: inset 0 0 0 1px var(--blood);
}

/* ------------------------------------------------------------- the frame */
/* A photographic print IS a clean rectangle, so the gallery frames keep their
   straight edge — but the mount they are pasted onto should not be. */

.frame { border: 0; background: none; }
.frame::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: #14100f;
  box-shadow: inset 0 0 0 2px #ffffff1f;
  -webkit-mask-image: var(--torn-c); mask-image: var(--torn-c);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transition: box-shadow .3s ease;
}
.frame:hover::after, .frame:focus-visible::after { box-shadow: inset 0 0 0 2px var(--blood); }

/* Safari before 16 and any engine without mask-image gets clean rectangles
   back rather than invisible panels. */
@supports not ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .panel, .paper { border: 1px solid #ffffff1f; background: url(art/gen/texture-parchment-1200.webp) center / cover; }
  .panel::before, .panel::after, .paper::before, .paper::after { display: none; }
  .btn, .filter { border: 1px solid #ffffff2e; }
  .btn::before, .filter::before { display: none; }
  .sold { border: 1px solid var(--blood); }
  .stamp { border: 1px solid #ffffff38; }
  .stamp::before { display: none; }
  .frame { border: 1px solid #ffffff1f; }
  .frame::after { display: none; }
}

/* --------------------------------------------- lighter grounds on phones */
/* Background images cannot use srcset, so a phone was downloading the same
   1200px textures as a desktop — roughly 300 KB it has no use for. The 768px
   variants are more than enough at these tile sizes. */

@media (max-width: 820px) {
  .ground {
    background:
      radial-gradient(120% 60% at 50% 0%, #17101200 0%, #000 78%),
      url(art/gen/texture-black-768.webp) center / 700px auto repeat;
  }
  .canvas {
    background: url(art/gen/texture-black-768.webp) center top / 640px auto repeat, var(--ink);
  }
  .canvas::before {
    background: url(art/gen/texture-framed-768.webp) center top / 100% auto no-repeat;
  }
  .panel::before, .paper::before {
    background:
      linear-gradient(180deg, #d6c9ad1c, #d6c9ad0a 38%, #00000040),
      url(art/gen/texture-parchment-768.webp) center / cover;
  }
  .pagehead::after, .hero::before {
    background-image: url(art/gen/sigil-480.webp);
  }
}

/* ===========================================================================
   EXTRAS — the fan kit
   ---------------------------------------------------------------------------
   The most period-specific page here. Before platforms owned distribution, a
   band's reach was a mesh of fan sites linking to each other and the 88x31
   button was the unit of exchange. Reproducing the era means reproducing the
   ritual: a preview, and a box of HTML to copy.
   =========================================================================== */

.kit__note {
  margin: 0 0 20px; max-width: 62ch;
  font-family: var(--serif); font-size: 1.04rem; color: var(--bone-2);
}

.kit { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(18px, 2.4vw, 30px); }
.kit--buttons { grid-template-columns: repeat(auto-fill, minmax(260px, 320px)); }
.kit--banners { grid-template-columns: repeat(auto-fill, minmax(300px, 520px)); }

.kit__item {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; align-content: start;
  position: relative; isolation: isolate;
  padding: clamp(14px, 1.8vw, 20px);
}
/* The same torn plate the rest of the site uses, so the kit reads as pinned
   to the page rather than as a component tray. */
.kit__item::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, #d6c9ad14, #d6c9ad06 40%, #0000004d),
    url(art/gen/texture-parchment-1200.webp) center / cover;
  box-shadow: inset 0 0 0 1px #ede4d414, inset 0 0 50px -18px #000;
  -webkit-mask-image: var(--torn-b); mask-image: var(--torn-b);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.kit__item:nth-child(even)::before { -webkit-mask-image: var(--torn-c); mask-image: var(--torn-c); }

/* A button is 88x31 and must be shown at exactly that — scaling it up would
   misrepresent what you are taking, and these were designed pixel by pixel. */
.kit__art {
  display: grid; place-items: center;
  padding: 14px 10px; background: #00000073;
  box-shadow: inset 0 0 0 1px #ffffff14;
}
.kit__art img { image-rendering: pixelated; max-width: 100%; height: auto; }
.kit--banners .kit__art img { image-rendering: auto; }

.kit__meta { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.kit__label {
  font-size: 10px; letter-spacing: .28em; text-transform: uppercase; color: var(--bone-2);
}
.kit__dim {
  font-size: 10px; letter-spacing: .18em; color: var(--bone-3);
  font-variant-numeric: tabular-nums;
}

/* ---- the copy box */

.codebox { display: flex; align-items: stretch; gap: 0; }
.codebox code {
  flex: 1; min-width: 0; overflow-x: auto; white-space: nowrap;
  padding: 8px 10px; background: #000000a6;
  box-shadow: inset 0 0 0 1px #ffffff1a;
  font-family: ui-monospace, Consolas, monospace; font-size: 10.5px;
  color: var(--bone-2); letter-spacing: 0;
  scrollbar-width: thin; scrollbar-color: var(--bone-4) transparent;
}
.copy {
  flex-shrink: 0; min-height: 24px; padding: 0 14px; cursor: pointer;
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--bone-2); background: #ffffff0d;
  box-shadow: inset 0 0 0 1px #ffffff26;
  transition: color .2s ease, background-color .2s ease;
}
.copy:hover { color: var(--bone); background: #a1121759; }
.copy[data-done] { color: var(--verd-lit); }

.kit__dl {
  justify-self: start; display: inline-flex; align-items: center; min-height: 24px;
  font-size: 10px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--bone-3); box-shadow: inset 0 -1px 0 #ffffff33;
  transition: color .2s ease, box-shadow .2s ease;
}
.kit__dl:hover { color: var(--blood-lit); box-shadow: inset 0 -1px 0 var(--blood-lit); }

/* ---- wallpapers */

.walls {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: clamp(16px, 2.2vw, 28px); max-width: 1100px;
}
.wall a { display: grid; grid-template-columns: minmax(0, 1fr); gap: 9px; }
.wall__art {
  display: block; overflow: hidden; background: #000;
  box-shadow: inset 0 0 0 1px #ffffff1f;
  transition: box-shadow .3s ease, transform .4s cubic-bezier(.2,.8,.25,1);
}
.wall__art img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.wall a:hover .wall__art { box-shadow: inset 0 0 0 1px var(--blood); transform: translateY(-4px); }
.wall__meta { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.wall__res {
  font-family: var(--serif); font-size: 1.02rem; color: var(--bone);
  font-variant-numeric: tabular-nums;
}
.wall__label {
  font-size: 9px; letter-spacing: .26em; text-transform: uppercase; color: var(--bone-3);
}

/* ---- affiliates */

.affil { max-width: 760px; }
.affil__list {
  list-style: none; margin: 0 0 14px; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 96px)); gap: 10px;
}
.affil__slot {
  display: grid; place-items: center;
  width: 88px; height: 31px;
  background: #00000059;
  box-shadow: inset 0 0 0 1px #ffffff14;
}
.affil__slot span {
  font-size: 9px; letter-spacing: .18em; color: var(--bone-3);
  font-variant-numeric: tabular-nums;
}
.affil__foot {
  margin: 0; font-size: 11px; letter-spacing: .12em; color: var(--bone-3); max-width: 56ch;
}

@media (max-width: 560px) {
  .kit--buttons, .kit--banners { grid-template-columns: minmax(0, 1fr); }
  .walls { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}

/* ===========================================================================
   SONGS — one page per song, and the lyric book
   ---------------------------------------------------------------------------
   The lyric archives this genre's fans actually read (DarkLyrics above all)
   were organised as the record is: a numbered list, the words under each
   number. The band's own lyric page mirrored that. What 2009 could not add
   is below: the real shape of the recording, and words set like a
   manuscript — divisions rubricated in red in the margin, the first verse
   opening on an illuminated initial.
   =========================================================================== */

/* ------------------------------------------------------------- engraving */

.engraving { margin: 0 0 clamp(26px, 3.6vw, 46px); }

.engraving__plate {
  position: relative; isolation: isolate;
  height: clamp(92px, 12.5vw, 172px);
  cursor: pointer; touch-action: none;
  outline: none;
}
/* An iron plate with a torn edge, like everything else pinned to the page. */
.engraving__plate::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, #0000004d, #00000026 50%, #00000066),
    url(art/gen/texture-black-1200.webp) center / cover;
  box-shadow: inset 0 0 0 1px #ede4d412, inset 0 0 60px -10px #000;
  -webkit-mask-image: var(--torn-b); mask-image: var(--torn-b);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.engraving__plate:focus-visible::after {
  content: ''; position: absolute; inset: -4px; pointer-events: none;
  box-shadow: 0 0 0 1px var(--bone-2);
}

.engraving__svg {
  position: absolute; left: 1.5%; right: 1.5%; top: 10%; height: calc(80% - 18px);
  width: 97%; overflow: visible;
}
.engraving__staff { stroke: #e8ddc81f; stroke-width: 1; }
.engraving__ghost { fill: #e8ddc812; stroke: #e8ddc840; stroke-width: 1; }
.engraving__ink   { fill: url(#inkfade); stroke: #e8ddc866; stroke-width: 1; }
.engraving__plate:hover .engraving__ghost { fill: #e8ddc81c; stroke: #e8ddc85c; }

/* The pen: a hairline at the playhead, shown only while this song plays. */
.engraving__head {
  position: absolute; top: 8%; bottom: 20px; width: 1px;
  left: calc(1.5% + var(--p, 0) * 97%);
  background: var(--bone); box-shadow: 0 0 10px #db434899;
  opacity: 0; transition: opacity .3s ease;
  pointer-events: none;
}
.engraving.is-live .engraving__head { opacity: 1; }
.engraving__head::after {
  content: ''; position: absolute; left: -3px; top: 50%; width: 7px; height: 11px;
  translate: 0 -50%; background: var(--blood-lit);
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
}

.engraving__ticks {
  list-style: none; margin: 0; padding: 0;
  position: absolute; left: 1.5%; right: 1.5%; bottom: 3px; height: 16px;
  pointer-events: none;
}
.engraving__ticks li {
  position: absolute; bottom: 0; translate: -50% 0;
  font-size: 10px; letter-spacing: .08em; color: var(--bone-3);
  font-variant-numeric: tabular-nums;
}
.engraving__ticks li::before {
  content: ''; position: absolute; left: 50%; bottom: 15px;
  width: 1px; height: 5px; background: #e8ddc84d;
}

.engraving__cap {
  display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  margin-top: 10px;
  font-size: 10px; letter-spacing: .28em; text-transform: uppercase; color: var(--bone-3);
}
.engraving__time { letter-spacing: .14em; font-variant-numeric: tabular-nums; color: var(--bone-2); }

/* ------------------------------------------------------------ song page */

.songpage__grid {
  display: grid;
  grid-template-columns: minmax(210px, 250px) minmax(0, 780px);
  gap: clamp(24px, 3.6vw, 64px);
  align-items: start;
}
.songpage__side { position: sticky; top: 22px; }
.songpage__plate { max-width: 250px; }
.songpage__play { width: 100%; justify-content: center; margin-top: 18px; }
.songpage__play.is-on::before { background: var(--blood); box-shadow: inset 0 0 0 1px var(--blood-lit); }

.spec__versions { display: grid; justify-items: end; gap: 2px; }
.spec__versions a {
  color: var(--bone); font-style: italic;
  box-shadow: inset 0 -1px 0 #e8ddc84d; transition: color .2s ease, box-shadow .2s ease;
}
.spec__versions a:hover { color: var(--blood-lit); box-shadow: inset 0 -1px 0 var(--blood-lit); }

.songnav {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px;
  margin-top: 22px; padding-top: 14px; border-top: 1px solid #ffffff1f;
}
.songnav__link { display: grid; gap: 3px; min-width: 0; padding: 4px 0; min-height: 24px; }
.songnav__link--next { text-align: right; }
.songnav__dir {
  font-size: 10px; letter-spacing: .24em; text-transform: uppercase; color: var(--blood-lit);
  font-variant-numeric: tabular-nums;
}
.songnav__t {
  font-family: var(--serif); font-size: 1rem; color: var(--bone-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color .2s ease;
}
a.songnav__link:hover .songnav__t, a.songnav__link:focus-visible .songnav__t { color: var(--bone); }

/* Extra room at the foot: the torn mask bites ~15px into the bottom edge,
   which left the last line of words sitting right on the tear. */
.songpage__words { max-width: 780px; padding-bottom: calc(clamp(22px, 2.8vw, 40px) + 18px); }

/* ----------------------------------------------------------- lyric sheet */

.sheet-lyric { position: relative; }
.sheet-lyric__borrowed {
  font-family: var(--serif); font-style: italic; color: var(--bone-3);
  margin: -6px 0 22px !important;
}
.sheet-lyric__borrowed a { color: var(--bone-2); box-shadow: inset 0 -1px 0 #e8ddc84d; }

/* Rubric in the margin, words beside it. */
.lyric {
  display: grid; grid-template-columns: 7.2em minmax(0, 1fr);
  column-gap: clamp(14px, 2vw, 26px);
  margin: 0 0 clamp(16px, 2vw, 24px);
}
.lyric:last-child { margin-bottom: 0; }
.lyric__rubric {
  grid-column: 1; margin: .42em 0 0 !important;
  font-family: var(--display) !important; font-size: 11px !important; line-height: 1.4 !important;
  letter-spacing: .24em; text-transform: uppercase; text-align: right;
  color: var(--blood-lit) !important;
  /* Small red caps on a parchment scan: measured identical in colour, the
     rubrics that landed on the sheet's lighter ornament and burnt edge still
     read dimmer. A tight dark halo keeps them legible wherever they fall. */
  text-shadow: 0 0 7px #000, 0 0 2px #000;
}
.sheet-lyric .lyric__stanza {
  grid-column: 2; max-width: 46ch;
  margin: 0 0 12px; font-family: var(--serif);
  font-size: clamp(1.08rem, 1.5vw, 1.2rem); line-height: 1.62; color: var(--bone);
}
.sheet-lyric .lyric__stanza:last-child { margin-bottom: 0; }

/* Refrains indented on a thin red rule, as a hymnal sets them. */
.lyric--chorus .lyric__stanza {
  padding-left: 18px; box-shadow: inset 1px 0 0 #db434880; font-style: italic;
}
.lyric--bridge .lyric__stanza { padding-left: 34px; }
.lyric--pre .lyric__stanza { color: var(--bone-2); }
.lyric--direction .lyric__stanza { font-style: italic; color: var(--bone-3); }
/* Backing vocals: one step down from the sung line, not three. At --bone-3
   the "(That one prayer)" asides in The Last Prayer all but vanished into
   the parchment scan. */
.lyric__aside { font-style: italic; color: var(--bone-2); }

/* A tag with no words — [Guitar Solo] — sits as a marker across the sheet. */
.lyric--marker { grid-template-columns: minmax(0, 1fr); }
.lyric--marker .lyric__rubric {
  grid-column: 1; text-align: center; margin: 0 !important;
  display: flex; align-items: center; gap: 14px;
}
.lyric--marker .lyric__rubric::before, .lyric--marker .lyric__rubric::after {
  content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, transparent, #db43484d, transparent);
}

/* The illuminated initial. */
.lyric__stanza--first::first-letter {
  float: left;
  font-family: var(--display); font-weight: 600;
  font-size: 3.5em; line-height: .82;
  margin: .06em .1em 0 0;
  color: var(--blood-lit);
  text-shadow: 0 0 18px #a1121780;
}
.lyric--chorus .lyric__stanza--first::first-letter { font-style: normal; }

/* ---- nothing written up yet: a ruled, empty sheet that says so plainly. */
.sheet-lyric--empty { min-height: 280px; display: grid; grid-template-rows: auto 1fr; }
.sheet-lyric__ruled {
  grid-row: 2; grid-column: 1;
  margin-top: 6px;
  background:
    linear-gradient(90deg, transparent calc(7.2em + 12px), #db434838 calc(7.2em + 12px), #db434838 calc(7.2em + 13px), transparent calc(7.2em + 13px)),
    repeating-linear-gradient(180deg, transparent 0 calc(1.62em - 1px), #e8ddc814 calc(1.62em - 1px) 1.62em);
  font-size: 1.14rem;
  -webkit-mask-image: linear-gradient(180deg, #000 30%, transparent);
          mask-image: linear-gradient(180deg, #000 30%, transparent);
}
.sheet-lyric__empty {
  grid-row: 2; grid-column: 1; align-self: center;
  margin: 0 !important; padding-left: calc(7.2em + 26px);
  font-family: var(--serif); font-style: italic;
  font-size: 1.14rem !important; color: var(--bone-2) !important;
}
.sheet-lyric__empty em { color: var(--bone); }

/* ------------------------------------------------------------ recordlist */
/* The back of the sleeve: two columns of numbers, titles and times. */

.recordlist {
  list-style: none; margin: 0; padding: 0;
  columns: 2 300px; column-gap: clamp(26px, 4vw, 64px);
  max-width: var(--measure-wide);
}
.recordlist li { break-inside: avoid; }
.recordlist a {
  display: grid; grid-template-columns: 2.1em minmax(0, 1fr) auto; gap: 10px; align-items: baseline;
  padding: 8px 4px; border-bottom: 1px solid #ffffff12;
  color: var(--bone-2); transition: color .2s ease, background-color .2s ease;
}
.recordlist a:hover, .recordlist a:focus-visible { color: var(--bone); background: #5b080833; }
.recordlist__no { font-family: var(--serif); color: var(--bone-3); font-variant-numeric: tabular-nums; }
.recordlist__t {
  font-family: var(--serif); font-size: 1.06rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.recordlist__t i { font-size: .84em; color: var(--bone-3); margin-left: .45em; }
.recordlist__d { font-size: .72rem; letter-spacing: .12em; color: var(--bone-3); font-variant-numeric: tabular-nums; }
.recordlist a[aria-current='page'] { color: var(--bone); box-shadow: inset 2px 0 0 var(--blood-lit); }
.recordlist a[aria-current='page'] .recordlist__no { color: var(--blood-lit); }

/* ------------------------------------------------------------ lyric book */

.book {
  display: grid;
  grid-template-columns: minmax(190px, 240px) minmax(0, 780px);
  gap: clamp(24px, 3.6vw, 64px);
  align-items: start;
}
.book__index {
  position: sticky; top: 22px;
  max-height: calc(100vh - 44px); overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--bone-4) transparent;
  padding-right: 6px;
}
.book__index ol { list-style: none; margin: 0; padding: 0; }
.book__index a {
  display: grid; grid-template-columns: 2em minmax(0, 1fr); gap: 6px; align-items: baseline;
  min-height: 24px; padding: 5px 0; border-bottom: 1px solid #ffffff0f;
  font-family: var(--serif); font-size: 1rem; color: var(--bone-2);
  transition: color .2s ease, transform .3s ease;
}
.book__index a:hover, .book__index a:focus-visible { color: var(--bone); transform: translateX(3px); }
.book__index-no { color: var(--blood-lit); font-variant-numeric: tabular-nums; }
.book__index-t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.book__index-t i { color: var(--bone-3); font-size: .86em; }

.book__body { display: grid; grid-template-columns: minmax(0, 1fr); }
.book__song {
  scroll-margin-top: 20px;
  padding: clamp(22px, 3vw, 38px) 0;
  border-top: 1px solid #ffffff17;
}
.book__song:first-child { border-top: 0; padding-top: 0; }
.book__head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 14px; align-items: baseline;
  margin-bottom: clamp(14px, 2vw, 22px);
}
/* Cormorant, not Cinzel: Cinzel is a Trajan-style capitals face whose "1"
   is indistinguishable from a Roman "I", so track 1 read as "I." while
   track 2 read as "2." — a numbering scheme that changed mid-page. */
.book__no {
  font-family: var(--serif); font-size: clamp(1.4rem, 2.6vw, 1.85rem); color: var(--blood-lit);
  font-variant-numeric: tabular-nums; min-width: 1.6em;
}
.book__title {
  margin: 0; font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.45rem, 2.8vw, 2rem); line-height: 1.15; color: var(--bone);
}
.book__title a { transition: color .2s ease; }
.book__title a:hover { color: var(--blood-lit); }
.book__title i { font-size: .6em; color: var(--bone-3); }
.book__dur { font-size: .74rem; letter-spacing: .14em; color: var(--bone-3); font-variant-numeric: tabular-nums; }
.book__borrowed { margin: 0; font-family: var(--serif); font-style: italic; font-size: 1.08rem; color: var(--bone-3); }
.book__borrowed a { color: var(--bone-2); box-shadow: inset 0 -1px 0 #e8ddc84d; }
.book__top {
  display: inline-flex; align-items: center; min-height: 24px; margin-top: 16px;
  font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--bone-3);
}
.book__top:hover { color: var(--bone); }
/* In the book an empty song is one quiet line, not a ruled page. */
.book .sheet-lyric--empty { min-height: 0; display: block; }
.book .sheet-lyric__ruled { display: none; }
.book .sheet-lyric__empty { padding-left: 0; color: var(--bone-3) !important; font-size: 1.04rem !important; }
.book .lyric { grid-template-columns: 6.4em minmax(0, 1fr); }

/* --------------------------------------------- music page: row → song */

.listing__row { display: flex; align-items: stretch; }
.listing__row > .trackrow { flex: 1 1 auto; min-width: 0; width: auto; }
.trackrow__page {
  flex: 0 0 34px; display: grid; place-items: center;
  color: var(--bone-3); transition: color .2s ease, background-color .2s ease;
}
.trackrow__page svg { width: 15px; height: 15px; }
.trackrow__page:hover, .trackrow__page:focus-visible { color: var(--blood-lit); background: #5b080833; }

.lyric-index li.has-words a::after {
  content: ''; display: inline-block; width: 5px; height: 5px; margin-left: 8px;
  vertical-align: middle; border-radius: 50%; background: var(--blood-lit);
}

/* ------------------------------------------------------------ responsive */

@media (max-width: 900px) {
  .songpage__grid, .book { grid-template-columns: minmax(0, 1fr); }
  .songpage__side {
    position: static;
    display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 0 18px; align-items: start;
  }
  .songpage__plate { grid-row: span 3; max-width: 120px; }
  .songpage__side .spec { margin-top: 12px; padding-top: 0; border-top: 0; }
  .songpage__play { margin-top: 12px; }
  .songnav { grid-column: 1 / -1; }
  .book__index { position: static; max-height: none; }
  .book__index ol { columns: 2 180px; column-gap: 24px; }
  .book__index li { break-inside: avoid; }
}

@media (max-width: 560px) {
  .lyric, .book .lyric { grid-template-columns: minmax(0, 1fr); }
  .lyric__rubric { grid-column: 1; text-align: left; margin: 0 0 4px !important; }
  .sheet-lyric .lyric__stanza { grid-column: 1; }
  .sheet-lyric__ruled {
    background: repeating-linear-gradient(180deg, transparent 0 calc(1.62em - 1px), #e8ddc814 calc(1.62em - 1px) 1.62em);
  }
  .sheet-lyric__empty { padding-left: 0; }
  .songpage__side { grid-template-columns: 88px minmax(0, 1fr); }
  .songpage__plate { max-width: 88px; }
  /* Child combinator matters: a descendant `span:first-child` also caught the
     live time readout — itself a first child — and left "/ 4:37" on its own. */
  .engraving__cap > span:first-child { display: none; }
  .engraving__ticks li:nth-child(even) { visibility: hidden; }
}

/* ===========================================================================
   THE GATE — the intro
   ---------------------------------------------------------------------------
   The most period-specific thing a 2008 band site did, and the most resented.
   Built against what the resentment was about: skip is on screen from the
   first frame, sound is a choice between two doors, and it appears once.
   The click on Enter is also the user gesture browsers demand before audio.

   Sequence (from .is-running, after the artwork has decoded):
     0.35s  sigil inks in from darkness
     1.45s  wordmark burns in left to right (its tagline is part of the art)
     2.95s  a couplet from the real lyrics
     3.60s  the release
     3.90s  .is-ready — the doors open
   =========================================================================== */

html.is-gated, html.is-gated body { overflow: hidden; }

.gate {
  position: fixed; inset: 0; z-index: 1000;
  /* Auto margins on the stage rather than place-items: center — centred
     content taller than a scroll container overflows upward, out of reach.
     Auto margins collapse to zero instead, so the top stays reachable. */
  display: grid; justify-items: center;
  overflow-y: auto; overscroll-behavior: contain;
  padding: clamp(40px, 6vh, 84px) 20px clamp(22px, 4.4vh, 52px);
  color: var(--bone);
  background: #030203;
  isolation: isolate;
}

.gate__ground {
  position: fixed; inset: 0; z-index: -2;
  background:
    radial-gradient(58% 46% at 50% 40%, #2a0f13d9 0%, transparent 72%),
    url(art/gen/texture-framed-1200.webp) center / cover;
  animation: gate-fade 1.6s ease both;
}
.gate__ground::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(120% 92% at 50% 44%, transparent 34%, #000000f2 100%);
}
.gate__ash {
  position: fixed; inset: 0; z-index: -1;
  width: 100%; height: 100%; pointer-events: none;
}

/* ---- the Flash-era control, on screen from the first frame */
.gate__skip {
  position: fixed; top: clamp(12px, 2.4vh, 24px); right: clamp(12px, 2.4vw, 28px);
  min-height: 34px; padding: 0 14px;
  font-family: var(--ui); font-size: 11px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--bone-2); background: none; border: 0; cursor: pointer;
  transition: color .2s ease, opacity .4s ease, visibility 0s linear 0s;
}
.gate__skip:hover, .gate__skip:focus-visible { color: var(--bone); }
.gate__skip:focus-visible { outline: 1px solid var(--bone-2); outline-offset: 2px; }
.gate.is-ready .gate__skip {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .4s ease, visibility 0s linear .4s;
}

.gate__stage {
  margin-block: auto;
  width: min(680px, 100%);
  display: grid; justify-items: center; text-align: center;
  gap: clamp(6px, 1.4vh, 14px);
}

/* ---- the sigil, inked in from darkness.
   Blend modes go on the MASKED element, not the <img> inside it: a mask makes
   an isolated group, so an image blending inside it only blends with
   transparency — and its black ground would come back as a black box. */
@property --gate-r { syntax: '<percentage>'; inherits: false; initial-value: 0%; }
@property --gate-w { syntax: '<percentage>'; inherits: false; initial-value: -16%; }

.gate__sigil {
  width: min(27vh, 52vw, 340px); aspect-ratio: 1266 / 1242;
  mix-blend-mode: screen;
  -webkit-mask-image: radial-gradient(circle at 50% 46%, #000 0%, #000 var(--gate-r), transparent calc(var(--gate-r) + 22%));
          mask-image: radial-gradient(circle at 50% 46%, #000 0%, #000 var(--gate-r), transparent calc(var(--gate-r) + 22%));
  animation: gate-ink 2.3s cubic-bezier(.3,.55,.2,1) .35s both;
}
.gate__sigil picture, .gate__sigil-img { display: block; width: 100%; height: 100%; }
.gate__sigil-img { object-fit: contain; }
@keyframes gate-ink {
  from { --gate-r: 0%;  filter: blur(16px) brightness(1.9); transform: scale(1.07); }
  to   { --gate-r: 95%; filter: blur(0) brightness(1);     transform: scale(1); }
}

/* ---- the wordmark, burned in left to right.
   Two masks, intersected: the moving burn edge, and an ellipse fitted to the
   lettering, which spans roughly 21–81% of the image. The asset carries its
   own smoky ground and bright scratches in the corners; screened over the
   gate those read as a lit rectangle. (The homepage's mask is a far larger
   ellipse — its radii are 96% and 78% of the box — which suits a band across
   the page and leaves a box here.) The contrast lift pushes the remaining
   grey ground toward black, which screen then drops. */
.gate__title {
  margin: clamp(-26px, -2.6vh, -10px) 0 0;
  width: min(560px, 88vw, 66vh);
  mix-blend-mode: screen;
  -webkit-mask-image:
    linear-gradient(90deg, #000 0%, #000 var(--gate-w), transparent calc(var(--gate-w) + 16%)),
    radial-gradient(44% 62% at 50% 52%, #000 70%, transparent 100%);
          mask-image:
    linear-gradient(90deg, #000 0%, #000 var(--gate-w), transparent calc(var(--gate-w) + 16%)),
    radial-gradient(44% 62% at 50% 52%, #000 70%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
  animation: gate-burn 1.7s cubic-bezier(.45,.1,.2,1) 1.45s both;
}
.gate__title picture, .gate__wordmark { display: block; width: 100%; height: auto; }
@keyframes gate-burn {
  from { --gate-w: -16%; filter: blur(7px) brightness(1.5) contrast(1); }
  to   { --gate-w: 100%; filter: blur(0) brightness(.9) contrast(1.35); }
}

.gate__quote { margin: clamp(10px, 2vh, 20px) 0 0; max-width: 34em; animation: gate-rise 1.2s ease 2.95s both; }
.gate__quote blockquote { margin: 0; }
.gate__quote p {
  margin: 0; font-family: var(--serif); font-style: italic;
  font-size: clamp(1.1rem, 2.3vw, 1.48rem); line-height: 1.45; color: var(--bone);
  text-wrap: balance; text-shadow: 0 2px 18px #000;
}
.gate__quote figcaption {
  margin-top: 9px; font-family: var(--ui); font-size: 11px;
  letter-spacing: .3em; text-transform: uppercase;
  /* --blood-lit is 4.84:1 on black but only 4.17:1 at the centre of the
     gate's red glow, and WCAG's ratio gives no credit for a text-shadow. This
     red is lifted just far enough: 4.71:1 on the glow, 5.46:1 on black. */
  color: #de5459;
  text-shadow: 0 0 8px #000, 0 0 2px #000;
}
.gate__quote cite { font-style: normal; }

.gate__release {
  margin: clamp(6px, 1.6vh, 16px) 0 0;
  font-family: var(--ui); font-size: 10px; letter-spacing: .34em; text-transform: uppercase;
  color: var(--bone-2);
  animation: gate-rise 1s ease 3.6s both;
}

/* ---- the doors: not focusable until the sequence has reached them */
.gate__doors {
  display: grid; justify-items: center; gap: 12px;
  margin-top: clamp(12px, 2.4vh, 24px);
  visibility: hidden;
}
.gate.is-ready .gate__doors { visibility: visible; animation: gate-rise .9s ease both; }

.gate__enter {
  position: relative; isolation: isolate;
  display: grid; justify-items: center; gap: 3px;
  min-width: 230px; padding: 15px 42px 13px;
  background: none; border: 0; cursor: pointer; color: var(--bone);
}
.gate__enter::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: #000000a6;
  box-shadow: inset 0 0 0 1px #e8ddc866;
  -webkit-mask-image: var(--eroded); mask-image: var(--eroded);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transition: background-color .3s ease, box-shadow .3s ease;
}
.gate__enter:hover::before, .gate__enter:focus-visible::before {
  background: var(--blood); box-shadow: inset 0 0 0 1px var(--blood-lit);
}
.gate__enter:focus-visible { outline: 1px solid var(--bone); outline-offset: 7px; }
/* A slow glow, so the eye finds the door once the sequence ends. */
.gate__enter::after {
  content: ''; position: absolute; inset: -10px; z-index: -2; pointer-events: none;
  box-shadow: 0 0 46px -4px #a11217; opacity: 0;
}
.gate.is-ready .gate__enter::after { animation: gate-pulse 3s ease-in-out 1.2s infinite; }
.gate__enter-word {
  font-family: var(--display); font-weight: 600; line-height: 1.1;
  font-size: clamp(1.5rem, 3.4vw, 2rem); letter-spacing: .42em; text-indent: .42em;
}
.gate__enter-sub {
  font-family: var(--ui); font-size: 10px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--bone-2); transition: color .3s ease;
}
.gate__enter:hover .gate__enter-sub, .gate__enter:focus-visible .gate__enter-sub { color: var(--bone); }

.gate__silent {
  min-height: 34px; padding: 0 10px; cursor: pointer;
  background: none; border: 0;
  font-family: var(--serif); font-style: italic; font-size: 1.04rem; color: var(--bone-2);
  box-shadow: inset 0 -1px 0 #e8ddc833;
  transition: color .2s ease, box-shadow .2s ease;
}
.gate__silent:hover, .gate__silent:focus-visible { color: var(--bone); box-shadow: inset 0 -1px 0 var(--bone-2); }
.gate__silent:focus-visible { outline: 1px solid var(--bone-2); outline-offset: 3px; }

.gate__note {
  margin: clamp(8px, 1.8vh, 18px) 0 0;
  font-family: var(--ui); font-size: 9px; letter-spacing: .34em; text-transform: uppercase;
  color: var(--bone-3); visibility: hidden;
}
.gate.is-ready .gate__note { visibility: visible; animation: gate-rise .9s ease .4s both; }

/* ---- sequencing controls */

/* Everything waits for .is-running (set once the artwork has decoded). A
   paused animation holds its delay too, so the timeline starts intact. */
.gate:not(.is-running):not(.is-skipped) :is(.gate__sigil, .gate__title, .gate__quote, .gate__release) {
  animation-play-state: paused;
}
/* Skip jumps the entrance to its end state — but only the entrance; the
   door's infinite glow must not be sped up into a flicker. */
.gate.is-skipped :is(.gate__ground, .gate__sigil, .gate__title, .gate__quote, .gate__release) {
  animation-delay: 0s !important; animation-duration: .01ms !important;
}

/* Exit, where view transitions are unavailable. */
.gate.is-leaving { animation: gate-leave .9s cubic-bezier(.4,0,.2,1) both; pointer-events: none; }

@keyframes gate-fade  { from { opacity: 0; } }
@keyframes gate-rise  { from { opacity: 0; transform: translateY(10px); filter: blur(3px); } }
@keyframes gate-pulse { 0%, 100% { opacity: .15; } 50% { opacity: .9; } }
@keyframes gate-leave { to { opacity: 0; filter: brightness(1.7) blur(3px); } }

/* ---- exit by view transition: the gate's sigil becomes the masthead's */

:root.gate-vt::view-transition-old(root) { animation: gate-vt-out 1s cubic-bezier(.4,0,.2,1) both; }
:root.gate-vt::view-transition-new(root) { animation: gate-vt-in 1.2s cubic-bezier(.2,.7,.2,1) both; }
/* Snapshots are captured without their backdrop, so the sigil's black
   ground would fly to the corner as a black square. Screen the group. */
:root.gate-vt::view-transition-group(gate-sigil) {
  mix-blend-mode: screen;
  animation-duration: 1.1s;
  animation-timing-function: cubic-bezier(.55,0,.15,1);
}
@keyframes gate-vt-out { to { opacity: 0; filter: brightness(1.6) blur(4px); } }
@keyframes gate-vt-in  { from { opacity: 0; } }

@media (max-height: 900px) {
  .gate__note { display: none; }
}
/* 1280×720 is what a 1080p laptop reports at 150% scaling — common, and the
   size where the doors first fell below the fold. */
@media (max-height: 820px) {
  .gate { padding-top: clamp(28px, 5vh, 60px); }
  .gate__sigil { width: min(24vh, 50vw, 300px); }
  .gate__title { width: min(520px, 88vw, 60vh); }
}
@media (max-height: 640px) {
  .gate__sigil { width: min(22vh, 42vw, 260px); }
  .gate__title { width: min(460px, 84vw, 60vh); }
  .gate__quote { margin-top: 4px; }
  .gate__quote p { font-size: 1.02rem; }
}

@media (prefers-reduced-motion: reduce) {
  .gate *, .gate::before, .gate::after, .gate .gate__ground { animation: none !important; }
  /* No animation means the custom properties sit at their initial values
     (hidden), so pin the masks at their fully revealed state instead. */
  .gate__sigil { -webkit-mask-image: none; mask-image: none; }
  .gate__title {
    -webkit-mask-image: radial-gradient(96% 78% at 50% 50%, #000 34%, rgba(0,0,0,.55) 68%, transparent 90%);
            mask-image: radial-gradient(96% 78% at 50% 50%, #000 34%, rgba(0,0,0,.55) 68%, transparent 90%);
  }
}

/* ===========================================================================
   THE POP-OUT PLAYER, AND NOW PLAYING
   ---------------------------------------------------------------------------
   On a 2008 band site every click was a fresh page load, so the music
   stopped whenever you went anywhere. The period's answer was a small
   separate player window. listen.html is that window; the strip below is
   how every other page shows it and drives it.
   =========================================================================== */

/* ---- the strip, in the masthead: its own row, only while a pop-out lives */

.nowplaying {
  flex-basis: 100%;
  position: relative; isolation: isolate;
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px;
  margin-top: 2px; padding: 6px 12px 6px 14px;
  font-size: 11px; letter-spacing: .12em;
  animation: np-arrive .5s cubic-bezier(.2,.8,.25,1) both;
}
.nowplaying::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, #5b08086b, #0000009e 26%, #0000009e 74%, #5b080838);
  box-shadow: inset 0 0 0 1px #e8ddc81f;
  -webkit-mask-image: var(--eroded); mask-image: var(--eroded);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
@keyframes np-arrive { from { opacity: 0; transform: translateY(-6px); } }

/* The period's "now playing" equaliser, as four drawn bars. */
.nowplaying__eq { display: inline-flex; align-items: flex-end; gap: 2px; width: 17px; height: 13px; flex-shrink: 0; }
.nowplaying__eq i {
  flex: 1; height: 100%; background: var(--blood-lit);
  transform-origin: bottom; transform: scaleY(.25);
}
.nowplaying.is-playing .nowplaying__eq i { animation: np-eq .82s ease-in-out infinite alternate; }
.nowplaying__eq i:nth-child(2) { animation-delay: -.42s !important; }
.nowplaying__eq i:nth-child(3) { animation-delay: -.2s !important; animation-duration: .66s !important; }
.nowplaying__eq i:nth-child(4) { animation-delay: -.61s !important; animation-duration: .95s !important; }
@keyframes np-eq { from { transform: scaleY(.18); } to { transform: scaleY(1); } }

.nowplaying__label {
  font-size: 10px; letter-spacing: .3em; text-transform: uppercase; color: var(--bone-3);
  white-space: nowrap;
}
.nowplaying__title {
  flex: 1 1 12em; min-width: 0; min-height: 24px;
  display: inline-flex; align-items: center;
  font-family: var(--serif); font-size: 1.04rem; letter-spacing: .01em; color: var(--bone);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color .2s ease;
}
.nowplaying__title:hover, .nowplaying__title:focus-visible { color: var(--blood-lit); }
.nowplaying__time {
  font-variant-numeric: tabular-nums; letter-spacing: .1em; color: var(--bone-2); white-space: nowrap;
}
.nowplaying__controls { display: inline-flex; align-items: center; gap: 2px; }
.nowplaying__controls button {
  display: grid; place-items: center; width: 32px; height: 32px;
  background: none; border: 0; cursor: pointer; color: var(--bone-2);
  transition: color .2s ease, background-color .2s ease;
}
.nowplaying__controls button svg { width: 14px; height: 14px; }
.nowplaying__controls button:hover { color: var(--bone); background: #ffffff0f; }
.nowplaying__controls button:focus-visible { outline: 1px solid var(--bone-2); outline-offset: -2px; }
.nowplaying__controls [data-np='toggle'] { color: var(--bone); }

/* ---- under each embedded player: the hand-off */

.listen-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; margin-top: 12px; }
.listen-bar__pop {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; gap: 9px;
  min-height: 36px; padding: 0 16px;
  background: none; border: 0; cursor: pointer;
  font-family: var(--ui); font-size: 11px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase; color: var(--bone-2);
  transition: color .25s ease;
}
.listen-bar__pop::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: #0000008c; box-shadow: inset 0 0 0 1px #e8ddc842;
  -webkit-mask-image: var(--eroded); mask-image: var(--eroded);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transition: background-color .25s ease, box-shadow .25s ease;
}
.listen-bar__pop:hover, .listen-bar__pop:focus-visible { color: var(--bone); }
.listen-bar__pop:hover::before, .listen-bar__pop:focus-visible::before {
  background: var(--blood); box-shadow: inset 0 0 0 1px var(--blood-lit);
}
.listen-bar__pop:focus-visible { outline: 1px solid var(--bone-2); outline-offset: 3px; }
.listen-bar__pop svg { width: 15px; height: 15px; flex-shrink: 0; }
.listen-bar__note { font-size: 12px; letter-spacing: .05em; color: var(--bone-3); }
.listen-bar.is-away .listen-bar__note {
  font-family: var(--serif); font-style: italic; font-size: 1rem; letter-spacing: 0; color: var(--bone-2);
}

/* While a pop-out is playing, the embedded players step back — they are not
   the one making the sound. Still fully usable: pressing play here takes
   the music back, and the pop-out stands down. */
html.popout-playing ethereal-player {
  filter: saturate(.35) brightness(.72);
  transition: filter .5s ease;
}
html.popout-playing ethereal-player:hover,
html.popout-playing ethereal-player:focus-within { filter: none; }

/* ---- listen.html: the window itself */

body.popout {
  background: #050405 url(art/gen/texture-black-768.webp) center / cover fixed;
  overflow: hidden;
}
.popout-shell {
  height: 100vh; height: 100dvh;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
}
.popout-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 14px;
  background: linear-gradient(#000000e6, #0000008c);
  border-bottom: 1px solid #ffffff14;
}
.popout-bar__brand { display: inline-flex; align-items: center; gap: 10px; min-height: 30px; }
.popout-bar__sigil { width: 30px; height: 30px; object-fit: contain; mix-blend-mode: screen; }
.popout-bar__name {
  font-family: var(--display); font-weight: 500; font-size: 14px;
  letter-spacing: .34em; text-indent: .34em; color: var(--bone);
}
.popout-bar__song {
  display: inline-flex; align-items: center; min-height: 28px; padding: 0 2px;
  font-size: 10px; letter-spacing: .22em; text-transform: uppercase; color: var(--bone-2);
  box-shadow: inset 0 -1px 0 #e8ddc833; white-space: nowrap;
  transition: color .2s ease, box-shadow .2s ease;
}
.popout-bar__song:hover, .popout-bar__song:focus-visible { color: var(--bone); box-shadow: inset 0 -1px 0 var(--blood-lit); }

.popout-player { min-height: 0; padding: 10px 10px 0; }
.popout-player ethereal-player { height: 100%; min-height: 420px; --ep-height: 100%; }
.popout-player .listen-bar { display: none; }

.popout-foot {
  margin: 0; padding: 8px 14px 10px; text-align: center;
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--bone-3);
}

.popout-resume {
  position: fixed; inset: 0; z-index: 50;
  display: grid; place-content: center; justify-items: center; gap: 16px;
  padding: 24px; text-align: center;
  background: #000000d1;
}
.popout-resume__btn {
  position: relative; isolation: isolate;
  display: grid; justify-items: center; gap: 5px;
  min-width: 220px; padding: 16px 34px 14px;
  background: none; border: 0; cursor: pointer; color: var(--bone);
}
.popout-resume__btn::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--blood-deep); box-shadow: inset 0 0 0 1px var(--blood-lit);
  -webkit-mask-image: var(--eroded); mask-image: var(--eroded);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  transition: background-color .25s ease;
}
.popout-resume__btn:hover::before, .popout-resume__btn:focus-visible::before { background: var(--blood); }
.popout-resume__btn:focus-visible { outline: 1px solid var(--bone); outline-offset: 6px; }
.popout-resume__word {
  font-family: var(--display); font-weight: 600; font-size: 1.45rem;
  letter-spacing: .36em; text-indent: .36em;
}
.popout-resume__what { font-family: var(--serif); font-style: italic; font-size: 1.02rem; color: var(--bone-2); }
.popout-resume__why { margin: 0; max-width: 30ch; font-size: 11px; letter-spacing: .06em; line-height: 1.6; color: var(--bone-2); }

@media (max-width: 560px) {
  .nowplaying__label, .nowplaying__time { display: none; }
  .nowplaying { gap: 6px 10px; padding: 5px 8px 5px 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .nowplaying, .nowplaying.is-playing .nowplaying__eq i { animation: none !important; }
  .nowplaying.is-playing .nowplaying__eq i { transform: scaleY(.7); }
}

/* ---------------------------------------------------------------- members */

.members {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px;
  max-width: var(--measure);
}
.member {
  display: grid; grid-template-columns: minmax(10em, auto) minmax(0, 1fr);
  gap: 2px 18px; align-items: baseline;
  padding-bottom: 14px; border-bottom: 1px solid #ffffff14;
}
.member:last-child { padding-bottom: 0; border-bottom: 0; }
.paper .member__name { grid-column: 1; margin: 0; font-family: var(--serif); font-size: 1.18rem; color: var(--bone); }
.paper .member__role {
  grid-column: 2; margin: 0;
  font-family: var(--ui); font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--blood-lit);
}
.paper .member__note { grid-column: 1 / -1; margin: 3px 0 0; font-size: 1.02rem; color: var(--bone-2); }
@media (max-width: 560px) {
  .member { grid-template-columns: minmax(0, 1fr); }
  .paper .member__role { grid-column: 1; }
}

/* ===========================================================================
   THE LOADING SCREEN
   ---------------------------------------------------------------------------
   A cold first load used to show the page assembling itself: fallback fonts
   swapping to the real ones, textures popping in behind the text, bare boxes
   where the art would be, and the player's plain-text fallback before its
   script arrived. The first page of a visit now waits behind this until the
   typefaces, the artwork in view, the page textures and the player are in.
   Flash-era sites always had one; this one reports real progress.
   =========================================================================== */

.loader { display: none; }

html.is-loading .loader {
  position: fixed; inset: 0; z-index: 3000;
  display: grid; place-content: center; justify-items: center; gap: 20px;
  background:
    radial-gradient(46% 38% at 50% 44%, #1d0c0f 0%, transparent 70%),
    #050405;
  color: #e8ddc8;
  /* Fades in only after a beat, so a load that is already cached never
     flashes the screen at all. The second animation is the failsafe. */
  animation: loader-in .45s ease .18s both, loader-failsafe-out .5s ease 8s forwards;
  transition: opacity .6s ease;
}
html.is-loading body > :not(.loader) {
  visibility: hidden;
  animation: loader-failsafe-in 0s linear 8s forwards;
}
html.is-loading.is-ready .loader { opacity: 0; pointer-events: none; }
html.is-loading.is-ready body > :not(.loader) {
  visibility: visible;
  animation: page-reveal .8s cubic-bezier(.2,.7,.2,1) both;
}

.loader__emblem { width: 84px; height: auto; overflow: visible; }
.loader__track { stroke: #e8ddc81f; stroke-width: 1.2; }
.loader__ring {
  stroke: #db4348; stroke-width: 1.6; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: calc(100 - var(--p, 0) * 100);
  transform: rotate(-90deg); transform-origin: 50px 64px;
  transition: stroke-dashoffset .35s ease;
  filter: drop-shadow(0 0 4px #a1121799);
}
.loader__blade { fill: #e8ddc8; opacity: .9; }
.loader__guard { stroke: #e8ddc8; stroke-width: 1.4; opacity: .75; }
.loader__jewel { fill: #db4348; }
.loader__emblem { animation: loader-breathe 2.6s ease-in-out infinite; }

.loader__rule { width: 132px; height: 1px; background: #e8ddc81f; overflow: hidden; }
.loader__rule span {
  display: block; height: 100%; background: #db4348;
  transform-origin: left; transform: scaleX(var(--p, 0));
  transition: transform .35s ease;
}
.loader__label {
  margin: 0;
  font: 500 10px/1 ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  letter-spacing: .42em; text-indent: .42em; text-transform: uppercase;
  color: #b3a893; font-variant-numeric: tabular-nums;
}

@keyframes loader-in           { from { opacity: 0; } }
@keyframes loader-breathe      { 50% { opacity: .72; } }
@keyframes loader-failsafe-out { to { opacity: 0; visibility: hidden; } }
@keyframes loader-failsafe-in  { to { visibility: visible; } }
@keyframes page-reveal         { from { opacity: 0; } }

/* ---- the player, before its script has run
   Its height is set from inside its own shadow root, so until the element
   upgrades it collapses to the height of its fallback text and then jumps.
   Reserve the space, and keep the "serve over http" message out of sight
   unless the player genuinely failed to start. */
ethereal-player:not(:defined) {
  height: var(--ep-height);
  min-height: 420px;
  background: #050405;
}
ethereal-player:not(:defined) .player-fallback {
  opacity: 0;
  animation: fallback-reveal .4s ease 5s forwards;
}
@keyframes fallback-reveal { to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  html.is-loading .loader, .loader__emblem { animation: loader-failsafe-out .01s linear 8s forwards; }
  html.is-loading.is-ready body > :not(.loader) { animation: none; }
  .loader__ring, .loader__rule span { transition: none; }
}
