.lyrics-index__back {
  margin: var(--space-4) 0 0;
}

.lyrics-index__back a {
  color: var(--color-text-muted);
}

.lyrics-index__heading {
  /* Was var(--space-5) 0 (40px both sides, 80px total) — more breathing room above the title than
     this page actually needed, and (with the 7-album + EPs/All-Songs grid right below it being a
     fixed, deliberately-sized 280px-tile 2-row block, not compressible padding) that excess above
     the title was the main reducible source of this page running past one screen's height on
     shorter viewports (13" MacBook-class laptops). */
  margin: var(--space-3) 0 var(--space-4);
}

.lyrics-index__heading--eps {
  text-transform: none;
}

.lyrics-index__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0;
  max-width: 1120px;
  margin: 0 auto;
}

.lyrics-index__grid--3col {
  /* same responsive auto-fill as the base grid, just capped narrower so it settles at 3
     columns (280px x 3) on desktop instead of 4, while still reflowing on resize */
  max-width: 840px;
}

/* Short-viewport override (13" MacBook-class laptops, not narrow-width mobile — deliberately a
   height query, not a width one): the 7-album + EPs/All-Songs grid is 2 full rows of fixed-size
   tiles, real content rather than trimmable padding, and was the dominant reason this page ran
   past one screen's height there even after tightening the title's spacing above it. Smaller tiles
   here specifically trades a bit of visual size for fitting in one screen on short laptop displays
   — every taller viewport (including this same 1280px width on an external monitor) keeps the
   original 280px tiles unchanged. */
@media (max-height: 820px) {
  .lyrics-index__grid {
    grid-template-columns: repeat(auto-fill, minmax(185px, 1fr));
  }
}

/* Narrow-width override, per request — a genuinely separate axis from the max-height one above:
   a narrow-but-*tall* phone (the common case; most modern phones are well over 820px logical
   height in portrait) never triggers that query at all, so it was falling through to the base
   280px floor, which auto-fill can only ever resolve to a single column once available width
   (main's own padding eats var(--space-4) off each side) drops under ~560px. Forced to exactly
   2 columns rather than another auto-fill/minmax floor, since the goal here is "always at least
   2," not "as many as comfortably fit" — placed after the max-height block so it wins if a
   viewport is ever narrow *and* short at once.
   minmax(0, 1fr), not bare 1fr — confirmed directly this actually mattered here, not just
   theoretical caution: a bare 1fr track's minimum width defaults to auto (its content's own
   min-content size), not 0, so the "EPs"/"All Songs" links tile's own text (2.25rem, no
   white-space:nowrap, but still with its own per-word min-content floor as a flex child) was
   pushing its whole column wider than its fair half-share, overflowing the grid past the
   viewport on real phones — every image tile was already immune since object-fit:cover images
   have a genuine 0 min-content width, unlike text. */
@media (max-width: 600px) {
  .lyrics-index__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* overflow isn't set here (stays visible) deliberately — each tile now holds a Tilted Card
   (css/tilted-card-spring.css, js/tilted-card-spring.js) whose hover scale/tilt needs room to
   bulge slightly past its own resting footprint; clipping it here would cut that off right at
   the tile's edge. In this gap:0 grid that bulge visually overlaps whichever neighbour is
   closest, same as every other Tilted Card use on this site — the hover z-index lift (in
   js/tilted-card-spring.js) is what makes that read as "this one popped forward" rather than a
   glitch. */
.lyrics-index__tile {
  position: relative;
  aspect-ratio: 1;
  display: block;
}

/* Reused fade+rise keyframe from css/base.css (same shape as the sitewide page-load reveal) —
   only applied to tiles built by js/lyrics-grid.js, not the static `--links` corner tile already
   in the HTML, so the two don't compound. --tile-i is set inline on each tile's <a> (inherits
   down to this class fine, custom properties cascade through inheritance regardless of which
   element the animation itself lives on) and staggers the reveal into a cascade instead of every
   cover popping in at once. No plain opacity fallback needed here the way the sitewide gate needs
   one: these tiles don't exist in the DOM until JS creates them, so disabling the animation under
   prefers-reduced-motion just leaves them at the default opacity (1) instead of stuck invisible.
   Deliberately applied to the tile's inner .tilted-card-figure, NOT its <a> wrapper — see the
   comment in js/lyrics-grid.js's buildTile() for why putting it on the anchor breaks the hover
   z-index lift that's supposed to pop a tile above its neighbours. */
.lyrics-index__tile--reveal {
  animation: page-fade-in 0.5s ease both;
  animation-delay: calc(var(--tile-i, 0) * 0.05s);
}

.lyrics-index__tile--links {
  background: var(--color-bg);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-end;
  gap: var(--space-1);
  padding: var(--space-4);
}

.lyrics-index__tile--links a {
  color: var(--color-text-muted);
  font-size: 2.25rem;
  letter-spacing: 0.02em;
  text-align: right;
  transition: color 0.4s ease 0.1s;
}

/* "All Songs" is the one link here that can actually wrap onto two lines — "EPs" is a single
   short word, never affected by line-height at all — and inherits the sitewide 1.5 body
   line-height by default, which reads as too loose once it's wrapped ("All" / "Songs") in the
   narrow 2-column layout (css/lyrics.css's own max-width:600px rule). Tightened here specifically
   rather than on the shared .lyrics-index__tile--links a rule, so "EPs" is untouched. */
.lyrics-index__all-songs-link {
  line-height: 1.1;
}

.lyrics-index__back-bottom {
  text-align: center;
  margin: var(--space-6) 0 var(--space-4);
}

.lyrics-index__back-bottom a {
  color: var(--color-text-muted);
}

.lyrics-index__tile--links a.lyrics-index__all-songs-link,
.lyrics-index__tile--links a.lyrics-index__albums-link {
  text-transform: uppercase;
}

.lyrics-index__tile--links a:hover,
.lyrics-index__tile--links a:focus-visible {
  color: var(--color-accent);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

/* The nav bar has no background of its own (see .site-nav in base.css) — it's always just shown
   through whatever colour <body> happens to be. Every other page type on the site never notices
   this because body stays the sitewide white default there and only a child element (e.g.
   .tracklist-hero) gets its own colour; the lyrics-detail template sets background/color directly
   on body per page (black, cream, navy, etc.), which bled that colour straight into the nav strip
   above the content too. Pinned back to the sitewide white-bar/dark-text look specifically within
   lyrics pages — .site-nav__brand has no colour of its own either and would otherwise inherit
   white text from a dark page's own body colour, becoming invisible against a white bar. */
.lyrics-page .site-nav {
  background: var(--color-bg);
  color: var(--color-text);
}

.lyrics-page__header {
  position: relative;
  padding: var(--space-6) var(--space-4);
  isolation: isolate;
  overflow: hidden;
}

.lyrics-page__header::before,
.lyrics-page__header::after {
  content: '';
  position: absolute;
  inset: -20px;
}

.lyrics-page__header::before {
  background-size: cover;
  background-position: center;
  z-index: -2;
}

.lyrics-page__header::after {
  z-index: -1;
}

/* Generic templates (lyrics/release.html, lyrics/release-lyrics.html): both start with
   placeholder/empty content while their fetch(es) resolve, then swap it in via textContent/
   innerHTML — without this, that swap is a hard blip even though everything around it already
   fades in smoothly via the sitewide gate (css/base.css). Needs the same dual opacity:1-plus-
   animation shape as that sitewide gate (not just relying on the animation's own `to` state) for
   the same reason: prefers-reduced-motion disables the animation but not the plain property
   below it. */
#tracklist-title,
#tracklist-list,
#lyrics-title,
#lyrics-tracklists {
  opacity: 0;
}

#tracklist-title.is-populated,
#tracklist-list.is-populated,
#lyrics-title.is-populated,
#lyrics-tracklists.is-populated {
  opacity: 1;
  animation: page-fade-in 0.5s ease;
}

.lyrics-page__header h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  letter-spacing: -0.02em;
}

.lyrics-page__back {
  color: var(--color-text-muted);
  font-family: var(--font-body-light);
}

.spotify-embed iframe {
  width: 100%;
  border: none;
  border-radius: 8px;
}

.lyrics-page__note {
  color: var(--color-text-muted);
  font-family: var(--font-body-light);
  font-size: 0.85rem;
  margin: var(--space-3) 0 0;
}

.spotify-embed--pending {
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--color-border);
  border-radius: 8px;
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

.tracklist {
  border-top: 1px solid var(--color-border);
}

/* scroll-margin-top (not padding/margin — this only affects scroll-snapping, not layout) is what
   js/drawer.js's and js/lyrics-data.js's track.scrollIntoView({block:'start'}) calls actually
   land against. Without it, opening a track (or landing on one via #hash) scrolled its title
   right behind the nav bar once .site-nav actually became sticky and started permanently
   occupying that space (css/base.css) — previously nav quietly failed to stick at all, so
   scrolling to the very top of the viewport never had anything sitting there to hide behind.
   --nav-height (js/nav.js) is measured live off the real element since it differs by breakpoint/
   device, rather than a hardcoded px value kept in sync with nav's own CSS by hand. */
.track {
  border-bottom: 1px solid var(--color-border);
  scroll-margin-top: var(--nav-height, 0px);
}

.track__toggle {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3) 0;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--color-text);
  transition: color 0.4s ease 0.1s;
}

.track__toggle:hover,
.track__toggle[aria-expanded="true"] {
  color: var(--color-accent);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.track__number {
  color: var(--color-text-muted);
  font-family: var(--font-body-light);
  width: 1.5rem;
}

/* Was duplicated as font-size:1.1rem in every per-album block (Silent Alarm, AWITC, Intimacy,
   Four, Hymns) — promoted here since no album has ever actually wanted a different size, only
   different colour/font/transform, matching how font-size was never one of the axes those blocks
   customise. */
.track__title {
  font-size: 1.2rem;
}

/* Same Lucide chevron-down mask technique as .tracklist-hero__bsides-toggle::after — reused as-is
   rather than the rotated-border-corner trick abandoned there, for the same reason: rotating a
   plain square around its own center doesn't line up with a chevron's actual visual weight. */
.track__toggle::after {
  content: '';
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-left: auto;
  flex-shrink: 0;
  background-color: var(--color-text-muted);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  transition: transform 0.25s ease;
}

.track__toggle[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

.track__body {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: 0 0 var(--space-4) 2.5rem;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 0.35s ease, opacity 0.3s ease;
}

.track__body[hidden] {
  display: none;
}

/* max-height is driven from JS (js/drawer.js), not a fixed value here — it measures the real
   content height (scrollHeight) so the slide matches however long a given track's lyrics
   actually are, then relaxes the cap to `none` once the open transition finishes so later
   content growth (e.g. js/lyrics-data.js filling in real lyrics after this has already opened)
   isn't clipped at the original, shorter measurement. */
.track__body--open {
  opacity: 1;
}

/* Base/legacy shape: .track__art and .track__meta as plain direct children of .track__body
   (every page still on the old per-album flat-HTML-lyrics design uses exactly this — Four,
   Hymns, Alpha Games, Anatomy, every EP, AWITC, Intimacy). Kept as the default so those pages
   are untouched; the new "floating details card" look (.track__details below) only applies on
   pages that actually opt into the new markup, via more specific selectors. */
.track__art {
  width: 100px;
  flex-shrink: 0;
  border-radius: 2px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
}

.track__meta {
  font-family: var(--font-body-light);
  font-size: 0.85rem;
  color: var(--color-text-muted);
  min-width: 180px;
}

.track__meta p {
  margin: 0 0 var(--space-1);
}

/* The "floating" box (new design) — artwork (only for tracks that were released as their own
   single) plus the metadata block, set apart from the lyrics as its own elevated card rather
   than plain inline content. Lyrics come first in the DOM (the main content, and what a
   no-CSS/reader-mode view should lead with); this sits second, which in a plain flex row already
   reads as "lyrics left, details right" with no `order` needed. Fixed width, not shrink-to-fit,
   so a track with only metadata (no artwork) doesn't render a noticeably narrower card than one
   with both — every track's card lines up at the same width. */
.track__details {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex-shrink: 0;
  width: 220px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
  padding: var(--space-3);
}

/* "Play from [YouTube logo]" — sits where the credits used to (now on the album-level box
   instead), either alone for a track with a video but no single of its own, or stacked under
   that single's artwork. flex+gap above is what lets both cases share one rule with no per-case
   margin. Text-forward by design (not just an icon) so it's unmistakable this streams from
   YouTube rather than being hosted on this site — that's the whole point of the label, not
   decoration. Logo image is the "almostblack" variant (dark on light) since this card is always
   on the light --color-bg; a white variant exists in Resources for the day a dark-background
   album needs it, not wired up until that's a real case. */
.track__yt-play {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--color-text);
}

.track__yt-play:hover {
  border-color: var(--color-text-muted);
}

/* Touch-only, per request. Some tracks pair this with single artwork inside the same
   .track__details card (that stays, just without the button below it); others have nothing but
   this button in there — :has() drops the now-empty card entirely for those, rather than leaving
   a blank bordered box with nothing inside it. */
@media (hover: none) {
  .track__yt-play {
    display: none;
  }

  .track__details:has(> .track__yt-play:only-child) {
    display: none;
  }
}

.track__yt-play.is-playing {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.track__yt-play-icon {
  font-size: 0.75rem;
  flex-shrink: 0;
}

.track__yt-play-logo {
  height: 0.85rem;
  width: auto;
  display: block;
  flex-shrink: 0;
}

/* Overrides the base .track__art shape above — inside the card, the image should fill the
   card's own width (minus its padding) instead of the old fixed 100px, and doesn't need its own
   shadow since the card itself already has one. No bottom margin: on Silent Alarm the artwork is
   always the only thing in the card now (credits moved to the album-level box), so a bottom
   margin with no top counterpart just padded the square image into a taller-than-wide frame. */
.track__details .track__art {
  width: 100%;
  flex-shrink: initial;
  display: block;
  border-radius: 4px;
  box-shadow: none;
  margin: 0;
}

.track__details .track__meta {
  min-width: 0;
}

.track__lyrics {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-serif);
  font-size: 1.1rem;
  white-space: pre-line;
  line-height: 1.3;
}

.track__lyrics p {
  margin: 0 0 var(--space-3);
}

.track__lyrics-placeholder {
  font-family: var(--font-body);
  font-style: italic;
  color: var(--color-text-muted);
  border: 1px dashed var(--color-border);
  border-radius: 4px;
  padding: var(--space-2) var(--space-3);
  display: inline-block;
}

/* Below this width the fixed-width details card plus lyrics text no longer sit comfortably
   side by side — stacks them instead, details card first (above the lyrics) since that's the
   more useful reading order once there's no room to keep them side-by-side: know what single/
   art you're looking at before the wall of text starts. */
@media (max-width: 700px) {
  .track__body {
    flex-direction: column;
  }

  .track__details {
    order: -1;
    width: 100%;
    max-width: 220px;
  }
}

.tracklist--bonus {
  margin-top: var(--space-4);
}

.tracklist__label {
  color: var(--color-text-muted);
  font-family: var(--font-body-light);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: var(--space-4) 0 0;
}

/* Slightly heavier than the Bonus Tracks label — swaps the light font face for the regular one
   (Gill Sans Light is a genuinely separate registered typeface here, not just a font-weight
   value, so this is a real visible change, not the no-op a numeric font-weight bump would be on
   Gill Sans MT, which only has one weight file registered). */
.tracklist__label--bsides {
  font-family: var(--font-body);
}

/* Silent Alarm: no header background photo — plain title only. Vertical padding is cut way down
   from the shared rule's var(--space-6) (4rem, sized for a full-bleed photo header with real
   visual weight to breathe against), since a plain text-only title doesn't need nearly that much
   air above/below it. Every future no-photo album needs this same padding cut — it's just not
   promoted to the shared rule since photo headers elsewhere still want the full var(--space-6). */
.lyrics-page--silent-alarm .lyrics-page__header {
  /* Horizontal padding deliberately isn't here — see .lyrics-page__header-row below for why it
     has to live there instead of here. */
  padding: var(--space-4) 0;
}

.lyrics-page--silent-alarm .lyrics-page__header h1 {
  color: #333;
}

/* The title aligns with the tracklist column, not the album artwork beside it — a plain padding
   offset on the header would need to be kept in sync by hand with .lyrics-page__album-box's own
   width + .lyrics-page__layout's own gap below; mirroring that same width/gap here as an invisible
   spacer keeps the two in sync automatically off one real value instead of two matching numbers
   living in different rules.
   width/max-width/margin here (not on the outer .lyrics-page__header) is what actually centres
   this row to match <main>'s own capped+centred content — body is a column flex container (see
   base.css), and a flex item with auto cross-axis margins skips the default stretch-to-container
   behaviour entirely, shrink-wrapping to content instead (main avoids the same trap the same way).
   Belongs on this shared rule, not per-album, precisely because every album using this row/spacer
   header needs it identically — AWITC shipped without it at first (only Silent Alarm had a
   duplicate of this same fix, scoped to itself), so the row rendered at body's own left edge
   instead of matching main's actual capped-and-centred inset, landing the title 40px left of the
   tracklist.
   Horizontal padding lives here, not on the outer .lyrics-page__header, for the same reason
   width/max-width/margin do — the header's own padding would be subtracted from the width this
   row's max-width is computed against, before this row's own auto-margin runs, undercounting the
   centering margin by exactly that padding amount (measured: 16px auto-margin instead of the 40px
   main itself gets, landing the title a further 24px left of the tracklist even after fixing the
   centering above). Keeping both the cap AND the padding on this one element means both are
   computed against the same reference width (the header's, unpadded), matching main exactly. */
.lyrics-page__header-row {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--space-4);
}

.lyrics-page__header-spacer {
  flex-shrink: 0;
  width: 300px;
}

@media (max-width: 900px) {
  /* Below this width .lyrics-page__layout stacks (album box above tracklist, not beside it) — the
     title should span the same full-width column the stacked content now uses too. */
  .lyrics-page__header-spacer {
    display: none;
  }
}

/* Track titles read as uppercase dark grey (not the site's near-black --color-text, which is
   reserved for body copy elsewhere); the red accent lives on the track number instead of the
   whole toggle. Setting color directly on these two child spans wins over the parent
   .track__toggle's own hover/aria-expanded color rule (an inherited value never beats an
   element's own explicit color), so no override of that rule is needed here. */
.lyrics-page--silent-alarm .track__title {
  text-transform: uppercase;
  color: #333;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--silent-alarm .track__number {
  color: var(--color-accent);
}

/* Hovering the title itself turns it red — the number's own always-red colour doesn't communicate
   "clickable" the way a hover state change does, and the title's explicit resting colour above
   otherwise blocks the parent .track__toggle:hover rule from ever reaching it (see that rule's own
   comment). Deliberately :hover only, not also [aria-expanded="true"] — this is about signalling
   the row is clickable before interaction, not marking which one is currently open. */
.lyrics-page--silent-alarm .track__toggle:hover .track__title {
  color: var(--color-accent);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--silent-alarm .track__lyrics {
  font-family: var(--font-body);
}

/* Album info box: sits to the left of the tracklist column, once per page (not per track) —
   Recorded/Label/Producer are album-level facts, identical across every Silent Alarm track, so
   this replaces what used to be repeated in each track's own .track__meta. Not scoped to
   .lyrics-page--silent-alarm since the markup is brand new and only this page uses it so far;
   becomes the shared template once every album adopts this layout. */
.lyrics-page__layout {
  display: flex;
  /* align-items left at the default (stretch), not flex-start — .lyrics-page__album-box needs to
     be stretched as tall as its much-taller sibling .lyrics-page__tracklists, so the sticky inner
     wrapper below has room to travel/stick within as the page scrolls through the full tracklist
     instead of running out of container after its own ~400px of real content. */
  gap: var(--space-5);
}

.lyrics-page__album-box {
  flex-shrink: 0;
  width: 300px;
}

/* The actual sticky element — kept separate from .lyrics-page__album-box itself (which is now
   stretched tall to match the tracklist column) since an element can't both span that full height
   and stick within it; this inner wrapper is only as tall as its real content (art + facts) and
   sticks near the top of the viewport until its tall parent's bottom edge scrolls past.
   top: var(--space-4) alone stuck this partway *behind* the nav bar once .site-nav itself became
   genuinely sticky (css/base.css) and started permanently occupying that space — previously nav
   quietly failed to stick at all, so a flat var(--space-4) from the true viewport top happened to
   be correct by accident. --nav-height (js/nav.js) added on top of that same gap now accounts
   for nav's real height. */
.lyrics-page__album-sticky {
  position: sticky;
  top: calc(var(--nav-height, 0px) + var(--space-4));
}

.lyrics-page__album-art {
  width: 300px;
  height: 300px;
  object-fit: cover;
  display: block;
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}

.lyrics-page__album-facts {
  margin-top: var(--space-3);
  font-family: var(--font-body-light);
  font-size: 0.9rem;
  color: var(--color-text-muted);
}

.lyrics-page__album-facts p {
  margin: 0 0 var(--space-1);
}

.lyrics-page__tracklists {
  flex: 1 1 auto;
  min-width: 0;
}

@media (max-width: 900px) {
  .lyrics-page__layout {
    flex-direction: column;
  }

  .lyrics-page__album-box {
    width: 100%;
  }

  /* Stacked layout: the album box sits above the tracklist as a normal block, not beside a much
     taller sibling — nothing for the sticky wrapper to travel within, and pinning it here would
     just trap the artwork on screen while the header/rest of the page scrolls past underneath. */
  .lyrics-page__album-sticky {
    position: static;
  }

  .lyrics-page__album-art {
    width: 100%;
    max-width: 300px;
    height: auto;
    aspect-ratio: 1;
  }
}

/* Persistent "back to album" pill, fixed to the viewport corner regardless of scroll position —
   the sole way back to the tracklist page now that the header's own back link is gone. Brand new,
   not yet scoped to any one page, so every future album's lyrics page picks it up automatically. */
.lyrics-page__back-fixed {
  position: fixed;
  bottom: var(--space-4);
  right: var(--space-4);
  padding: 0.6rem 1.5rem;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  border-radius: 8px;
  font-family: var(--font-body-light);
  z-index: 10;
  transition: background 0.2s ease;
}

.lyrics-page__back-fixed:hover {
  background: rgba(0, 0, 0, 0.9);
}

/* A Weekend In The City: dark identity carried through the whole page, not just the header —
   its own cover is a night-time photo and its tracklist page already established cream text on
   dark, unlike Silent Alarm's plain white treatment that the shared rules above default to.
   Track number stays the sitewide red accent (unchanged from Silent Alarm) since red-on-black
   reads fine and keeps that one constant across albums; #6e4e00 is reserved for hover/active
   states specifically (title hover, playing button) per this album's own chosen palette. Card
   backgrounds (#141414) are a slight lift off pure black so .track__details reads as a distinct
   surface rather than blending flat into the page, mirroring how the white cards on Silent Alarm
   read as "elevated" via shadow — a shadow would be invisible here, so a lightness difference
   does that job instead. */
.lyrics-page--awitc {
  background: #000;
  color: #fffcdf;
}

.lyrics-page--awitc .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--awitc .lyrics-page__header h1 {
  color: #fffcdf;
}

.lyrics-page--awitc .track__title {
  text-transform: uppercase;
  color: #fffcdf;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--awitc .track__toggle:hover .track__title {
  color: #6e4e00;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--awitc .track__number {
  color: #6e4e00;
}

.lyrics-page--awitc .track__toggle::after {
  background-color: rgba(255, 252, 223, 0.5);
}

.lyrics-page--awitc .track,
.lyrics-page--awitc .tracklist {
  border-color: rgba(255, 252, 223, 0.15);
}

.lyrics-page--awitc .track__lyrics {
  font-family: var(--font-body);
}

.lyrics-page--awitc .track__details {
  background: #141414;
  border-color: rgba(255, 252, 223, 0.15);
  /* The shared rule's shadow is cast in black — genuinely invisible against this page's own
     black background (and the #141414 card itself), unlike on Silent Alarm's white page where it
     does real work. Dead code here, so it's turned off rather than left computing for nothing. */
  box-shadow: none;
}

.lyrics-page--awitc .lyrics-page__album-art {
  /* Same reasoning as .track__details above — a black shadow against a black page paints nothing. */
  box-shadow: none;
}

.lyrics-page--awitc .track__yt-play {
  border-color: rgba(255, 252, 223, 0.25);
  color: #fffcdf;
}

.lyrics-page--awitc .track__yt-play:hover {
  border-color: rgba(255, 252, 223, 0.5);
}

.lyrics-page--awitc .track__yt-play.is-playing {
  border-color: #6e4e00;
  color: #6e4e00;
}

.lyrics-page--awitc .lyrics-page__album-facts {
  color: rgba(255, 252, 223, 0.65);
}

.lyrics-page--awitc .tracklist__label {
  color: rgba(255, 252, 223, 0.5);
}

.lyrics-page--awitc .track__lyrics-placeholder {
  color: rgba(255, 252, 223, 0.5);
  border-color: rgba(255, 252, 223, 0.25);
}

/* Same fix as the tracklist-hero page's own back button: the shared dark pill is invisible
   against a page that's already solid black. */
.lyrics-page--awitc .lyrics-page__back-fixed {
  background: rgba(255, 252, 223, 0.15);
  color: #fffcdf;
}

.lyrics-page--awitc .lyrics-page__back-fixed:hover {
  background: rgba(255, 252, 223, 0.3);
}

/* Intimacy: white page like Silent Alarm — no photo header, plain title, Gill Sans MT
   throughout. Track number and title-hover get their own distinct tones (unlike Silent Alarm,
   where both used the single sitewide red accent) — the number stays that colour constantly, at
   rest, same as Silent Alarm's own number treatment; only the title actually transitions on
   hover. No border/shadow overrides needed anywhere here, unlike AWITC — this page shares Silent
   Alarm's white background, so the shared rules' default light-grey borders and dark shadows
   already read correctly without any per-album adjustment. */
.lyrics-page--intimacy .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--intimacy .lyrics-page__header h1 {
  color: #000;
}

.lyrics-page--intimacy .track__title {
  text-transform: uppercase;
  color: #000;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--intimacy .track__toggle:hover .track__title {
  color: #dca2ab;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--intimacy .track__number {
  color: #a3767a;
}

.lyrics-page--intimacy .track__lyrics {
  font-family: var(--font-body);
}

.lyrics-page--intimacy .track__yt-play {
  color: #000;
}

.lyrics-page--intimacy .track__yt-play.is-playing {
  border-color: #a3767a;
  color: #a3767a;
}

/* Four: the odd one out. Georgia italic for song titles and lyrics, matching this album's own
   tracklist page (which already sets every track/bonus title in italic serif, no uppercase) —
   the album title itself stays the sitewide default Gill Sans MT, same as how that tracklist
   page's own "Bonus Tracks" label deliberately stays Gill Sans MT too (UI chrome, not a song
   name). No text-transform:uppercase override here either, for the same "match the tracklist
   page's own established treatment" reason every other album's uppercase titles don't apply.
   Hover cycles through this album's own 4 identity colours (red/blue/yellow/green, from its own
   four-rings cover) instead of one flat tone — --track-hover is set inline per <section
   class="track"> in the HTML, one constant per track in the exact repeating order the tracklist
   page already uses, so this single rule covers all 14 tracks without hardcoding any of the 4
   colours here. */
.lyrics-page--four {
  background: #000;
  color: #fff;
}

.lyrics-page--four .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--four .lyrics-page__header h1 {
  color: #fff;
}

.lyrics-page--four .track__title {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: bold;
  font-size: 1.4rem;
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--four .track__toggle:hover .track__title {
  color: var(--track-hover);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--four .track__number {
  color: var(--color-text-muted);
}

.lyrics-page--four .track__toggle::after {
  background-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--four .track,
.lyrics-page--four .tracklist {
  border-color: rgba(255, 255, 255, 0.15);
}

.lyrics-page--four .track__lyrics {
  font-family: var(--font-serif);
  font-style: italic;
}

.lyrics-page--four .track__details {
  background: #141414;
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow: none;
}

.lyrics-page--four .lyrics-page__album-art {
  box-shadow: none;
  /* Four's own cover is mostly black (four rings on black), so with no shadow it has no edge at
     all against this page's own black background — a border does the job the shadow used to,
     matching the same light rgba(255,255,255,0.15) already used for every other border on this
     page. */
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.lyrics-page--four .track__yt-play {
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.lyrics-page--four .track__yt-play:hover {
  border-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--four .track__yt-play.is-playing {
  border-color: var(--track-hover);
  color: var(--track-hover);
}

.lyrics-page--four .lyrics-page__album-facts {
  color: rgba(255, 255, 255, 0.65);
}

.lyrics-page--four .tracklist__label {
  color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--four .lyrics-page__back-fixed {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.lyrics-page--four .lyrics-page__back-fixed:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* Hymns: Gill Sans Light for everything, including the "Bonus Tracks" chrome label and the
   YT-play button text — unlike Four, this album's own tracklist page never carves out a
   Gill-Sans-MT exception for UI chrome (its own "Bonus Tracks" label is Light too), so this page
   doesn't invent one either. Hover and the track number share the single grey (#7a7a7a) that
   tracklist page already established for hover — there's no separate, distinct "accent" tone
   here the way other albums have one; both roles were given the same value.
   The shared body rule's -webkit-font-smoothing:antialiased (kept sitewide to match the original
   Wix site's Gill Sans MT rendering) makes Gill Sans Light specifically render blurry/pixelated on
   non-Retina displays — confirmed on a 27" 1440p screen, fine on Retina. Scoped back to normal
   ("auto") here rather than removed sitewide, since every other page still uses the default
   Gill Sans MT this was tuned for. Alpha Games gets the identical override below for the same
   reason — those are the only two pages that commit to Light this heavily (titles + lyrics + UI
   chrome, not just a label or two). */
.lyrics-page--hymns,
.lyrics-page--alpha-games {
  -webkit-font-smoothing: auto;
  -moz-osx-font-smoothing: auto;
}

.lyrics-page--hymns {
  background: #000;
  color: #fff;
}

.lyrics-page--hymns .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--hymns .lyrics-page__header h1 {
  font-family: var(--font-body-light);
  color: #fff;
}

.lyrics-page--hymns .track__title {
  font-family: var(--font-body-light);
  color: #fff;
  text-transform: uppercase;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--hymns .track__toggle:hover .track__title {
  color: #7a7a7a;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--hymns .track__number {
  color: #7a7a7a;
}

.lyrics-page--hymns .track__toggle::after {
  background-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--hymns .track,
.lyrics-page--hymns .tracklist {
  border-color: rgba(255, 255, 255, 0.15);
}

.lyrics-page--hymns .track__lyrics {
  font-family: var(--font-body-light);
}

.lyrics-page--hymns .track__details {
  background: #141414;
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow: none;
}

.lyrics-page--hymns .lyrics-page__album-art {
  box-shadow: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.lyrics-page--hymns .track__yt-play {
  font-family: var(--font-body-light);
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.lyrics-page--hymns .track__yt-play:hover {
  border-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--hymns .track__yt-play.is-playing {
  border-color: #7a7a7a;
  color: #7a7a7a;
}

.lyrics-page--hymns .tracklist__label {
  font-family: var(--font-body-light);
  color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--hymns .lyrics-page__note {
  color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--hymns .lyrics-page__back-fixed {
  font-family: var(--font-body-light);
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.lyrics-page--hymns .lyrics-page__back-fixed:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* Alpha Games: based on Hymns — same black background, white text, Gill Sans Light everywhere,
   same font-smoothing fix (see the shared rule above), same border/shadow treatment. The one
   deliberate difference is hover/accent colour: #ea636a, this album's own established hover
   colour from its tracklist page, replacing Hymns' #7a7a7a grey in both roles (constant track
   number, title-on-hover) the same way Hymns used its one colour for both.
   Note: this album's own tracklist page uses normal capitalisation, not all-caps, unlike Hymns —
   left as uppercase here anyway since the brief named colour as the only difference; flag if that
   should change too. */
.lyrics-page--alpha-games {
  background: #000;
  color: #fff;
}

.lyrics-page--alpha-games .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--alpha-games .lyrics-page__header h1 {
  font-family: var(--font-body-light);
  color: #fff;
}

.lyrics-page--alpha-games .track__title {
  font-family: var(--font-body-light);
  color: #fff;
  text-transform: uppercase;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--alpha-games .track__toggle:hover .track__title {
  color: #ea636a;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--alpha-games .track__number {
  color: #ea636a;
}

.lyrics-page--alpha-games .track__toggle::after {
  background-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--alpha-games .track,
.lyrics-page--alpha-games .tracklist {
  border-color: rgba(255, 255, 255, 0.15);
}

.lyrics-page--alpha-games .track__lyrics {
  font-family: var(--font-body-light);
}

.lyrics-page--alpha-games .track__details {
  background: #141414;
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow: none;
}

.lyrics-page--alpha-games .lyrics-page__album-art {
  box-shadow: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.lyrics-page--alpha-games .track__yt-play {
  font-family: var(--font-body-light);
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.lyrics-page--alpha-games .track__yt-play:hover {
  border-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--alpha-games .track__yt-play.is-playing {
  border-color: #ea636a;
  color: #ea636a;
}

.lyrics-page--alpha-games .tracklist__label {
  font-family: var(--font-body-light);
  color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--alpha-games .lyrics-page__back-fixed {
  font-family: var(--font-body-light);
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.lyrics-page--alpha-games .lyrics-page__back-fixed:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* Anatomy Of A Brief Romance: based on Silent Alarm's light template, not a dark reskin like
   Four/Hymns/AWITC/Alpha Games — page background is a specific light sage (#dfe0da), not the
   sitewide pure white --color-bg, with black text and a single red (#bf2f3c) for both hover and
   the constant track-number accent, same "one colour, two roles" pattern as Hymns/Alpha Games.
   Lyrics (not titles) render in EB Garamond, a Google Font loaded via <link> in this page's own
   <head> — no other page on the site pulls a font from Google Fonts, they're all self-hosted
   .ttf files, but this one was named explicitly as a Google Font rather than something to
   source and self-host to match that convention.
   Card backgrounds (.track__details, .lyrics-page__album-box) are left at the shared default
   (pure white --color-bg), not switched to match #dfe0da — only page background/text/accent were
   specified, so the cards read as a deliberately distinct white surface floating on the sage
   page, same relationship Silent Alarm's own white cards have to its white page (there, invisible
   since both are white; here, a visible but unrequested difference — flag if it should match). */
.lyrics-page--anatomy {
  background: #f1f0ed;
  color: #000;
}

.lyrics-page--anatomy .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--anatomy .lyrics-page__header h1 {
  color: #000;
}

.lyrics-page--anatomy .track__title {
  text-transform: uppercase;
  color: #000;
  font-size: 1.3rem;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--anatomy .track__toggle:hover .track__title {
  color: #bf2f3c;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--anatomy .track__number {
  color: #bf2f3c;
}

.lyrics-page--anatomy .track__lyrics {
  font-family: 'EB Garamond', serif;
  font-size: 1.2rem;
}

.lyrics-page--anatomy .track__yt-play.is-playing {
  border-color: #bf2f3c;
  color: #bf2f3c;
}

/* Bloc Party EP: AWITC-based dark theme — black background, white text, single accent for both
   hover and the constant track-number colour. This EP's own tracklist page never established a
   colour of its own for this, just using the sitewide var(--color-accent) red, so this page
   reuses that directly rather than hardcoding its current hex. Same card/border/shadow treatment
   as every other dark-background page (see AWITC/Four/Hymns above). */
.lyrics-page--bloc-party-ep {
  background: #000;
  color: #fff;
}

.lyrics-page--bloc-party-ep .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--bloc-party-ep .lyrics-page__header h1 {
  color: #fff;
}

.lyrics-page--bloc-party-ep .track__title {
  text-transform: uppercase;
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--bloc-party-ep .track__toggle:hover .track__title {
  color: var(--color-accent);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--bloc-party-ep .track__number {
  color: var(--color-accent);
}

.lyrics-page--bloc-party-ep .track__toggle::after {
  background-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--bloc-party-ep .track,
.lyrics-page--bloc-party-ep .tracklist {
  border-color: rgba(255, 255, 255, 0.15);
}

/* Every text element on this page in Gill Sans MT, per explicit request — overrides the shared
   defaults that would otherwise land on Gill Sans Light (.track__number, .lyrics-page__back-fixed,
   .lyrics-page__album-facts) or the serif lyrics font (.track__lyrics). */
.lyrics-page--bloc-party-ep .track__number {
  font-family: var(--font-body);
}

.lyrics-page--bloc-party-ep .track__lyrics {
  font-family: var(--font-body);
}

.lyrics-page--bloc-party-ep .lyrics-page__album-facts {
  font-family: var(--font-body);
}

.lyrics-page--bloc-party-ep .lyrics-page__back-fixed {
  font-family: var(--font-body);
}

.lyrics-page--bloc-party-ep .track__details {
  background: #141414;
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow: none;
}

.lyrics-page--bloc-party-ep .lyrics-page__album-art {
  box-shadow: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.lyrics-page--bloc-party-ep .track__yt-play {
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.lyrics-page--bloc-party-ep .track__yt-play:hover {
  border-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--bloc-party-ep .track__yt-play.is-playing {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.lyrics-page--bloc-party-ep .lyrics-page__album-facts {
  color: rgba(255, 255, 255, 0.65);
}

.lyrics-page--bloc-party-ep .lyrics-page__back-fixed {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.lyrics-page--bloc-party-ep .lyrics-page__back-fixed:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* Little Thoughts EP: Silent-Alarm-based light theme — this page's own cream (#f9f4e8), not the
   sitewide white --color-bg, matching its own tracklist page's background exactly; single olive
   accent (#8fac31, that page's own hover colour) for both hover and the constant track-number
   colour. No border/shadow overrides needed, same reasoning as Anatomy's own light page — a light
   background never had the black-shadow-on-black-page problem the dark pages needed fixing. */
.lyrics-page--little-thoughts-ep {
  background: #f9f4e8;
  color: #000;
}

.lyrics-page--little-thoughts-ep .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--little-thoughts-ep .lyrics-page__header h1 {
  color: #000;
}

.lyrics-page--little-thoughts-ep .track__title {
  text-transform: uppercase;
  color: #000;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--little-thoughts-ep .track__toggle:hover .track__title {
  color: #8fac31;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--little-thoughts-ep .track__number {
  color: #8fac31;
  font-family: var(--font-body);
}

/* Every text element on this page in Gill Sans MT, per explicit request — see Bloc Party EP's
   identical override above for why this is needed (the shared defaults land on Gill Sans Light
   or the serif lyrics font otherwise). */
.lyrics-page--little-thoughts-ep .track__lyrics {
  font-family: var(--font-body);
}

.lyrics-page--little-thoughts-ep .lyrics-page__album-facts {
  font-family: var(--font-body);
}

.lyrics-page--little-thoughts-ep .track__yt-play {
  color: #000;
}

.lyrics-page--little-thoughts-ep .track__yt-play.is-playing {
  border-color: #8fac31;
  color: #8fac31;
}

.lyrics-page--little-thoughts-ep .lyrics-page__back-fixed {
  font-family: var(--font-body);
}

/* Four More EP: reuses Four's own design wholesale, per explicit instruction — Georgia italic
   titles/lyrics, Gill Sans MT album title, black background, white text, light-grey track
   numbers, and the exact same 4-colour --track-hover cycle (same hex values, same order,
   restarting at track 1) as the parent album. */
.lyrics-page--four-more-ep {
  background: #000;
  color: #fff;
}

.lyrics-page--four-more-ep .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--four-more-ep .lyrics-page__header h1 {
  color: #fff;
}

.lyrics-page--four-more-ep .track__title {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: bold;
  font-size: 1.4rem;
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--four-more-ep .track__toggle:hover .track__title {
  color: var(--track-hover);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--four-more-ep .track__number {
  color: var(--color-text-muted);
}

.lyrics-page--four-more-ep .track__toggle::after {
  background-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--four-more-ep .track,
.lyrics-page--four-more-ep .tracklist {
  border-color: rgba(255, 255, 255, 0.15);
}

.lyrics-page--four-more-ep .track__lyrics {
  font-family: var(--font-serif);
  font-style: italic;
}

.lyrics-page--four-more-ep .track__details {
  background: #141414;
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow: none;
}

.lyrics-page--four-more-ep .lyrics-page__album-art {
  box-shadow: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.lyrics-page--four-more-ep .track__yt-play {
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.lyrics-page--four-more-ep .track__yt-play:hover {
  border-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--four-more-ep .track__yt-play.is-playing {
  border-color: var(--track-hover);
  color: var(--track-hover);
}

.lyrics-page--four-more-ep .lyrics-page__album-facts {
  color: rgba(255, 255, 255, 0.65);
}

.lyrics-page--four-more-ep .lyrics-page__back-fixed {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.lyrics-page--four-more-ep .lyrics-page__back-fixed:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* The Nextwave Sessions: same Four-style skeleton as Four More EP (black background, Georgia
   italic, Gill Sans MT title, light-grey track numbers) but a single blue accent (#2a7b90, this
   EP's own established colour from its tracklist page) for hover/is-playing instead of Four's
   4-colour cycle — no per-track --track-hover custom property needed since there's only ever one
   colour here, unlike the parent album. */
.lyrics-page--nextwave-sessions {
  background: #000;
  color: #fff;
}

.lyrics-page--nextwave-sessions .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--nextwave-sessions .lyrics-page__header h1 {
  color: #fff;
}

.lyrics-page--nextwave-sessions .track__title {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: bold;
  font-size: 1.4rem;
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--nextwave-sessions .track__toggle:hover .track__title {
  color: #2a7b90;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--nextwave-sessions .track__number {
  color: var(--color-text-muted);
}

.lyrics-page--nextwave-sessions .track__toggle::after {
  background-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--nextwave-sessions .track,
.lyrics-page--nextwave-sessions .tracklist {
  border-color: rgba(255, 255, 255, 0.15);
}

.lyrics-page--nextwave-sessions .track__lyrics {
  font-family: var(--font-serif);
  font-style: italic;
}

.lyrics-page--nextwave-sessions .track__details {
  background: #141414;
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow: none;
}

.lyrics-page--nextwave-sessions .lyrics-page__album-art {
  box-shadow: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.lyrics-page--nextwave-sessions .track__yt-play {
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.lyrics-page--nextwave-sessions .track__yt-play:hover {
  border-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--nextwave-sessions .track__yt-play.is-playing {
  border-color: #2a7b90;
  color: #2a7b90;
}

.lyrics-page--nextwave-sessions .lyrics-page__album-facts {
  color: rgba(255, 255, 255, 0.65);
}

.lyrics-page--nextwave-sessions .lyrics-page__back-fixed {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.lyrics-page--nextwave-sessions .lyrics-page__back-fixed:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* The High Life EP: AWITC-based dark theme — background changed from plain black to this EP's
   own navy blue (#1e3886) per a follow-up request, white text, single dusty-pink accent
   (#c88278, this EP's own hover colour from its tracklist page) for both hover and the constant
   track-number colour. Every text element explicitly set to Gill Sans MT (see the override block
   below) — the shared defaults would otherwise land on Gill Sans Light or the serif lyrics font,
   same fix as Bloc Party EP/Little Thoughts EP above. */
.lyrics-page--high-life-ep {
  background: #1e3886;
  color: #fff;
}

.lyrics-page--high-life-ep .lyrics-page__header {
  padding: var(--space-4) 0;
}

.lyrics-page--high-life-ep .lyrics-page__header h1 {
  color: #fff;
}

.lyrics-page--high-life-ep .track__title {
  text-transform: uppercase;
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--high-life-ep .track__toggle:hover .track__title {
  color: #c88278;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--high-life-ep .track__number {
  color: #c88278;
  font-family: var(--font-body);
}

.lyrics-page--high-life-ep .track__toggle::after {
  background-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--high-life-ep .track,
.lyrics-page--high-life-ep .tracklist {
  border-color: rgba(255, 255, 255, 0.15);
}

.lyrics-page--high-life-ep .track__lyrics {
  font-family: var(--font-body);
}

.lyrics-page--high-life-ep .lyrics-page__album-facts {
  font-family: var(--font-body);
}

.lyrics-page--high-life-ep .lyrics-page__back-fixed {
  font-family: var(--font-body);
}

.lyrics-page--high-life-ep .track__details {
  background: #141414;
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow: none;
}

.lyrics-page--high-life-ep .lyrics-page__album-art {
  box-shadow: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.lyrics-page--high-life-ep .track__yt-play {
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.lyrics-page--high-life-ep .track__yt-play:hover {
  border-color: rgba(255, 255, 255, 0.5);
}

.lyrics-page--high-life-ep .track__yt-play.is-playing {
  border-color: #c88278;
  color: #c88278;
}

.lyrics-page--high-life-ep .lyrics-page__album-facts {
  color: rgba(255, 255, 255, 0.65);
}

.lyrics-page--high-life-ep .lyrics-page__back-fixed {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.lyrics-page--high-life-ep .lyrics-page__back-fixed:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* All Songs: no tracklist-hero page behind it (there's no single album/EP this list belongs to),
   so it skips .lyrics-page__layout/.lyrics-page__album-box entirely — just the header row (for
   the shared title-alignment fix, even with no spacer since there's no sidebar to align against)
   followed by a flat, JS-generated A–Z list. White background/black text/Gill Sans MT are all
   already the sitewide defaults, so only the things that genuinely need overriding are here:
   uppercase titles (matching every other album), and the elements that default to Gill Sans
   Light (.lyrics-page__back-fixed) or the serif lyrics font (.track__lyrics) elsewhere on this
   template — same fix as Bloc Party EP/Little Thoughts EP/The High Life EP above. Content itself
   (letter headers, tracks, lyrics) is rendered entirely by js/all-songs.js straight from
   data/lyrics-database.json — with 150 songs, hand-authoring this page's HTML the way every
   single-album page does wasn't practical, and "based on the JSON" was the explicit brief anyway. */
.lyrics-page--all-songs .lyrics-page__header {
  padding: var(--space-4) 0;
}

/* Keeps the title aligned with the tracklist column below it now that main's own left padding is
   widened (see the jump-nav comment further down) — the header title's horizontal position comes
   from .lyrics-page__header-row's own independent padding, not main's, so that padding needs the
   same adjustment or the title would drift 24px left of the now-wider content column beneath it. */
.lyrics-page--all-songs .lyrics-page__header-row {
  padding-left: 5rem;
}

.lyrics-page--all-songs .track__title {
  text-transform: uppercase;
  color: #000;
  transition: color 0.4s ease 0.1s;
}

.lyrics-page--all-songs .track__toggle:hover .track__title {
  color: var(--color-accent);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.lyrics-page--all-songs .track__lyrics {
  font-family: var(--font-body);
}

.lyrics-page--all-songs .lyrics-page__back-fixed {
  font-family: var(--font-body);
}

/* No .track__number on this page (an alphabetical list has no meaningful "number"), so the
   expanded body no longer needs the flex-row-plus-left-indent layout built for lyrics-beside-a-
   details-card — stacked instead, flush with the title above it. */
.lyrics-page--all-songs .track__body {
  display: block;
  max-width: 600px;
  padding: 0 0 var(--space-4) 0;
}

/* Real bug: the rule above and the shared .track__body[hidden] { display:none; } (base rule,
   near the top of this file) both have equal specificity (two class/attribute selectors each),
   so source order alone decided the winner — this rule, being later in the file, was beating
   [hidden] and forcing every collapsed drawer to render as display:block regardless of the
   hidden attribute or aria-expanded state. Every song looked permanently expanded and clicking
   never visibly closed anything, even though the underlying hidden/aria-expanded toggle in
   drawer.js was working correctly the whole time. Needs its own higher-specificity override
   (three selectors) so [hidden] reliably wins again. */
.lyrics-page--all-songs .track__body[hidden] {
  display: none;
}

.all-songs__letter {
  text-transform: uppercase;
  color: var(--color-text-muted);
  font-size: 1.4rem;
  margin: var(--space-5) 0 var(--space-2);
  /* Same fix, same reason as .track above — js/all-songs.js's jump-nav
     scrollIntoView({block:'start'}) would otherwise land a letter heading right behind the now
     genuinely-sticky nav bar. Not separately reported, but the same latent bug from the same
     cause, caught while fixing the other two. */
  scroll-margin-top: var(--nav-height, 0px);
}

.all-songs__letter:first-of-type {
  margin-top: 0;
}

/* The whole A-Z accordion (js/all-songs.js) lands via a single innerHTML assignment, so without
   this it just blipped into existence as one block. Staggering by letter group (not by
   individual song, which could mean hundreds of tiny staggered elements) keeps the cascade
   readable; --group-i is set inline on both a letter heading and its tracklist together so they
   animate in as one unit per letter. Scoped to direct children of the list container specifically
   so this never reaches into `.tracklist--flat`'s own descendants. */
#all-songs-list > .all-songs__letter,
#all-songs-list > .tracklist--flat {
  animation: page-fade-in 0.5s ease both;
  animation-delay: calc(var(--group-i, 0) * 0.05s);
}

.all-songs__meta {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--color-text-muted);
  margin: 0 0 var(--space-2);
}

/* The leading article a title's own .track__title colour (#000, set above) would otherwise cover
   — greyed out instead of the italics tried first, per direct feedback that italics "didn't look
   as nice." Same var(--color-text-muted) already used for every other de-emphasised bit of text
   on this page (album-facts equivalent, track numbers elsewhere on the site). */
.all-songs__ignored-article {
  color: var(--color-text-muted);
}

/* main's own left padding is widened on this page specifically (48px instead of the sitewide 24px
   var(--space-4)) to give the jump nav genuine dedicated space of its own, rather than cramming
   it into the same gutter real content already uses right up to its own edge — that was the
   original approach and it left only ~3.6px between the nav and the text, reading as "touching"
   at any viewport width, narrow ones especially. Only padding-left is touched (not the shorthand
   padding on main, which would also disturb right/top/bottom). */
.lyrics-page--all-songs main {
  padding-left: 5rem;
}

/* Fixed A-Z jump nav, always visible regardless of scroll position ("from anywhere on the page")
   — position:fixed rather than position:sticky, since sticky needs a bounded parent to detach
   from and this page has no existing sidebar container to attach one to (unlike every other
   lyrics page's .lyrics-page__layout, which All Songs deliberately skips — see its own comment
   above). Vertically centered on the left edge, sitting inside main's own widened left padding
   above with real breathing room on both sides — a few px clear of the viewport edge, and a
   further gap before the content that padding now reserves — rather than pinned flush to either.
   Clears the .lyrics-page__back-fixed pill pinned to the bottom-*right* corner regardless.
   Letters with no songs (e.g. currently J, Q) render as plain, muted, non-interactive <span>s
   rather than being omitted outright — same "show the whole alphabet, dim what's unavailable"
   convention as a typical iOS/Finder-style A-Z index, so the nav's own shape doesn't shift as
   data changes. Font-size is a vh-based clamp, not a fixed rem value, specifically so the
   *entire* 27-entry alphabet (A-Z plus "#") always stays visible even on a very short window
   rather than overflowing past the top/bottom edges or needing to hide itself below some
   breakpoint (which is exactly what a previous width-based @media rule used to do, since removed)
   — 27 rows at this line-height total out to a constant ~88% of viewport height at any size, by
   construction (27 × 1.25 line-height × 2.6vh ≈ 0.88 × viewport height), so it always fits with
   headroom to spare, right up until the 0.55rem floor (only reached on an unrealistically short
   window, well under any real browser chrome + usable content height). */
/* top is set by js/all-songs.js (positionJumpNav()), not here — it needs the real, currently-
   rendered height of both the site nav (which wraps to two lines on narrow viewports) and this
   panel itself (whose own font-size/height depends on the vh clamp below) to centre correctly in
   the space actually left between them, which no static CSS value can express. */
.all-songs__jumpnav {
  position: fixed;
  top: 80px;
  left: 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 10;
  font-family: var(--font-body);
  font-size: clamp(0.55rem, 2.6vh, 1.15rem);
  line-height: 1.25;
  max-height: 95vh;
}

.all-songs__jumpnav a,
.all-songs__jumpnav span {
  display: block;
  width: 1em;
  text-align: center;
  /* Same dock-style rubber-band magnify as the Gigs year tabs (css/gigs.css) — transform doesn't
     affect layout, so growing a letter never pushes its neighbours up/down the column, and the
     overshoot in the easing is what gives the "expands, then settles back with a little bounce"
     feel rather than a flat symmetric shrink. */
  transform: scale(1);
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.4s ease 0.1s;
}

.all-songs__jumpnav a {
  color: var(--color-text-muted);
}

.all-songs__jumpnav a:hover {
  color: var(--color-accent);
  transform: scale(1.6);
  position: relative;
  z-index: 1;
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.2s ease;
}

/* Falloff to the letter immediately above/below the hovered one — only <a> triggers the grow
   (spans have nothing to jump to, so hovering one shouldn't invite a click that does nothing),
   but a dimmed span neighbour still grows a little when an adjacent link is hovered, same as any
   other neighbour would. :is() covers both possible neighbour tags in one selector each
   direction; :has() covers "previous sibling" since no native selector for that exists otherwise. */
.all-songs__jumpnav a:hover + :is(a, span),
.all-songs__jumpnav :is(a, span):has(+ a:hover) {
  transform: scale(1.25);
}

.all-songs__jumpnav span {
  color: var(--color-border);
}

/* Tracklist pages (lyrics/<slug>/index.html) — a bespoke full-bleed hero per album, background
   image + layout supplied per page. Structure is shared; exact colours/image are page-specific. */
.tracklist-hero {
  /* deliberately no isolation:isolate here — confirmed by direct testing that on this element
     (no overflow:hidden, ::before uses inset:0 not inset:-20px) it hides the ::before background
     entirely (same root cause as the z-index note below: isolation:isolate itself creates a
     stacking context, and apparently does so in a way that still buries a negative-z-index child
     — removing it was the verified fix at the time).
     z-index:0 (added later, for Four): position:relative alone does NOT establish a new stacking
     context — only position + an explicit (non-auto) z-index does. Without one, a background-color
     set directly on this element (first added for Four's solid-black page) doesn't paint as "this
     element's own background, safely below all its children" — it instead participates in
     whatever ANCESTOR stacking context actually exists, in the same phase as this element's other
     "z-index:0-ish" content, which is a LATER paint phase than its own ::before's z-index:-1. Net
     effect: the element's own background-color can paint on top of its own negative-z-index
     ::before, hiding it completely. Confirmed via isolated test (a plain background on a bare div
     showed the image fine) and via a live z-index override (z-index:0 on the ::before revealed
     it instantly). z-index:0 here gives every .tracklist-hero its own real stacking context, so
     this can't happen on any current or future page that sets its own background-color. */
  position: relative;
  z-index: 0;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  /* Vertical padding is a "CSS lock" (linear interpolation via calc(), clamped at both ends) —
     not a flat cut — between 24px (var(--space-4)) at an actual 1470x832 MacBook Air viewport
     and 64px (var(--space-6), the original value) at ~1350px, a maximised window on a 1440p
     monitor (2560x1440 minus macOS's menu bar + Safari's own chrome). A flat 24px alone fixed
     the original complaint (a long tracklist running past the bottom of a short laptop viewport)
     but overcorrected on a genuinely tall window: hero still stretches to fill it (flex:1 0 auto),
     and with the content now shorter, that leftover space had nowhere sensible to go, confirmed
     directly by reproducing a real 1470x1300 viewport. Scaling padding (and the title/list sizes
     below, same technique) back up toward the original values as height grows fills that space
     properly instead of leaving it dead — same vh-based-clamp technique already used for the All
     Songs jump nav, just solved as a two-point line instead of a single multiplier, since here
     both ends of the range needed to hit a specific target rather than just capping one side.
     Stored as a custom property, not just inlined here, because Four's own carousel (see
     .tracklist-hero__carousel) cancels this exact padding with an equal negative margin-top to
     sit flush against the nav bar — it was hardcoded to the old flat var(--space-6) and only
     found out this value could now be *smaller*, over-cancelling and pulling the carousel up
     into the nav bar on a real MacBook Air, when the user reported it looking broken there. One
     shared variable is what keeps a future change to this lock from silently breaking that
     again. */
  --tracklist-hero-vpad: clamp(var(--space-4), calc(7.72vh - 40.3px), var(--space-6));
  padding: var(--tracklist-hero-vpad) var(--space-5) var(--tracklist-hero-vpad);
  /* flex:1 0 auto, not min-height:100vh — body is now the flex column that spans 100vh (see
     base.css), with the nav bar and footer include as its other two children. This item fills
     whatever's actually left after them (typically ~100vh minus the nav's own height), rather
     than assuming the full 100vh for itself on top of theirs. flex-basis:auto (not 0%) means it
     still sizes to its own content first and foremost — flex-grow:1 only stretches it to use any
     leftover space beyond that, and flex-shrink:0 stops it from ever being compressed smaller
     than its content needs, so tall tracklists still grow the page exactly as before. */
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

.tracklist-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  z-index: -1;
}

.tracklist-hero__title {
  color: var(--color-text-muted);
  /* No per-album override touches font-size or margin here (checked: every
     .tracklist-hero--X .tracklist-hero__title rule only sets colour/text-align/font-family/
     line-height), so this one change reaches every album/EP page.
     font-size keeps its original 4.5vw term (still the thing keeping the title from getting huge
     on a narrow mobile screen, regardless of height) but picks whichever of that OR a new
     vh-based lock is smaller, so a short-but-wide viewport can't grow it past what the vh lock
     allows either — min() of two independently-capped values, rather than one flat number, is
     what makes both the original narrow-screen safety and the new short-screen safety hold at
     once. The vh lock itself is the same two-point technique as the hero's own padding above,
     tuned to land on the same 3.25rem this shrunk to at a real 1470x832 MacBook Air viewport,
     growing back toward the original 4.5rem ceiling by ~1350px (a maximised 1440p window). */
  font-size: clamp(2rem, min(4.5vw, calc(3.86vh + 19.9px)), 4.5rem);
  text-align: left;
  max-width: 1100px;
  /* As a flex child of .tracklist-hero (flex-direction:column), this h1 turned out not to
     actually stretch to fill the cross axis by default — it shrinks to fit its own text and
     centres within the leftover space instead (an h1-in-flex quirk, not the max-width-capped-
     stretch behaviour that was assumed). First found and fixed only for Four
     (.tracklist-hero--four, back when it was the one page needing a non-default text-align where
     the bug is actually visible — a *centred* title looks identical whether its own box is
     content-width or full-width, so every text-align:center page never revealed this). Recurred
     on Bloc Party EP, the first later page to also need left/right alignment instead of centre —
     promoted here to the shared rule instead of patching a third page-specific copy. */
  width: 100%;
  /* Reuses the hero's own --tracklist-hero-vpad — same lock, same reason it's a shared variable
     rather than its own separate clamp() (see that property's own comment). */
  margin: 0 auto var(--tracklist-hero-vpad);
}

.tracklist-hero__body {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  column-gap: var(--space-5);
  row-gap: 0.075rem;
  max-width: 1100px;
  margin: 0 auto;
  width: 100%;
}

/* Touch-only, EPs specifically, per request — none of the 5 EP pages' own .tracklist-hero__body
   overrides set margin-top/bottom:auto the way some albums' do (Anatomy, for one), so with far
   fewer tracks than a full album, the hero (flex:1 0 auto, always at least viewport-tall) still
   stretches to fill the screen but has nothing similar to spend that leftover space on — it all
   collapses into one large gap between the tracklist and the "Back to EPs" link, which
   .tracklist-hero__back's own margin-top:auto pushes to the very bottom regardless. Centring the
   body vertically instead distributes that same leftover space evenly above and below the actual
   content, which reads as intentional rather than like spacing was simply forgotten. Listed by
   each EP's own class rather than matched generically, since a couple of albums already set
   their own margin-top/bottom here for reasons specific to their own layout and don't need (or
   might conflict with) this. */
@media (hover: none) {
  .tracklist-hero--little-thoughts-ep .tracklist-hero__body,
  .tracklist-hero--bloc-party-ep .tracklist-hero__body,
  .tracklist-hero--four-more-ep .tracklist-hero__body,
  .tracklist-hero--nextwave-sessions .tracklist-hero__body,
  .tracklist-hero--high-life-ep .tracklist-hero__body {
    margin-top: auto;
    margin-bottom: auto;
  }
}

.tracklist-hero__list {
  display: contents;
}

.tracklist-hero__list a {
  grid-column: 1;
  /* Same vh lock as the hero's own padding/title above (1.5rem at a real 1470x832 viewport,
     growing back to the original 2.1rem by ~1350px) — a few albums (Alpha Games, Anatomy)
     already override this to a flat 1.8rem for their own reasons and are untouched by this;
     the rest (Silent Alarm, AWITC, Intimacy, Four, Hymns, Bloc Party EP, Little Thoughts EP,
     Four More EP) all inherit this directly. line-height stays a flat unitless ratio rather than
     also being vh-locked — as a plain number it already scales proportionally with font-size on
     its own, so it doesn't need (and can't cleanly take, being unitless rather than a length) a
     separate lock. */
  font-size: clamp(1.5rem, calc(1.85vh + 8.6px), 2.1rem);
  font-weight: 300;
  line-height: 1.15;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  /* Grid items default to justify-self:stretch, so without this, every link stretches to fill
     column 1's full width — which is auto-sized to the *longest* title — making the hoverable/
     clickable box for every shorter line extend well past its own visible text. This is the
     recurring "whole line is a hyperlink" bug (first fixed as a one-off on Four, which happens to
     use flex instead of grid for its own layout — align-self is the flex equivalent, included
     here too so this same rule covers every current and future layout mode instead of needing a
     fresh page-specific patch each time). */
  justify-self: start;
  align-self: start;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero__list a:hover {
  color: #000 !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

/* Bonus Tracks: songs added to the album on some regional/special edition — distinct from
   B-Sides (below), which come from promo singles and were never part of any album release.
   Always visible, always below the main list (never beside it) — spans the full grid width
   (1/-1) rather than staying in column 1 so it can hug either edge independently of however wide
   the main list's own column happens to be. grid-row is left on "auto" rather than a hardcoded
   row number so it auto-places into the first row where every spanned column is free — since the
   main list occupies column 1 for every one of its own rows, that's always the row right after
   the last track, regardless of how many tracks the album has. width:fit-content stops the item
   from stretching to fill the full spanned width (grid's default), so text-align/margin can
   actually hug an edge instead of just centering text inside an already-full-width box. Default
   is left-aligned; add .tracklist-hero__bonus--right (or a page-scoped override) for albums where
   the right edge reads better instead — a per-album call, same as everything else about this
   block's home page. */
.tracklist-hero__bonus {
  grid-column: 1 / -1;
  grid-row: auto;
  /* Same vh-lock technique as the rest of this shared rule set — var(--space-3) at a real
     1470x832 viewport, growing back to the original var(--space-4) by ~1350px. */
  margin-top: clamp(var(--space-3), calc(1.55vh + 3.1px), var(--space-4));
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  width: fit-content;
  text-align: left;
}

.tracklist-hero__bonus--right {
  margin-left: auto;
  text-align: right;
}

.tracklist-hero__bonus-label {
  color: #000;
  font-family: var(--font-body-light);
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0;
}

.tracklist-hero__bonus a {
  color: #7a7a7a;
  /* Matches .tracklist-hero__list a's own vh lock above — same reasoning, same exceptions
     (Four and Nextwave Sessions override this too, for font-family/style, not size). */
  font-size: clamp(1.5rem, calc(1.85vh + 8.6px), 2.1rem);
  font-weight: 300;
  line-height: 1.15;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  /* Same "whole line clickable" issue as .tracklist-hero__list a, different flavour: .tracklist-hero__bonus
     is always display:flex;flex-direction:column, and flex's default align-items:stretch makes
     every link stretch to match the *container's* fit-content width — which is itself sized to
     the single widest bonus track — so any shorter one gets the same oversized click target. */
  align-self: flex-start;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero__bonus a:hover {
  color: #000;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero__back {
  text-align: right;
  margin-top: auto;
  padding-top: var(--space-3);
}

.tracklist-hero__back a {
  display: inline-block;
  padding: 0.6rem 1.5rem;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  border-radius: 8px;
  transition: background 0.2s ease;
}

.tracklist-hero__back a:hover {
  background: rgba(0, 0, 0, 0.55);
}

/* AWITC-only: light button, since this page's photo is dark throughout (unlike Silent Alarm's
   pale treeline background, where the dark pill was the better fit). */
.tracklist-hero--awitc .tracklist-hero__back a {
  background: rgba(255, 255, 255, 0.45);
  color: #000;
}

.tracklist-hero--awitc .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.7);
}

.tracklist-hero--silent-alarm::before {
  background-image: url('/Assets/Artwork/Textless Artwork/SA_background.jpeg');
  /* cover, not a forced 100%-width — on wide/landscape viewports this is width-driven and gives
     the identical result "100% auto" did, but on narrow/portrait ones (mobile) it switches to
     height-driven scaling instead, so the image always fully covers the box with no white gap
     showing above it. */
  background-size: cover;
  background-position: center bottom;
}

/* Silent Alarm-only: the shared drawer-inner colour (#7a7a7a) reads as grey-on-grey against the
   frosted panel's dark translucent background here — AWITC gets away with its cream because that
   panel sits over a genuinely dark photo, but Silent Alarm's is mostly light, so its own version
   of that same panel needs real white for contrast instead. */
.tracklist-hero--silent-alarm .tracklist-hero__bsides-drawer-inner a {
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — no font-size override of its own, so it was inheriting
   the shared height-based clamp() regardless of width; this album's own longest B-side title,
   "Every Time Is The Last Time," was wide enough at the clamp's ceiling to overflow the drawer
   box (and the page itself) rather than just wrap. */
@media (max-width: 600px) {
  .tracklist-hero--silent-alarm .tracklist-hero__bsides-drawer-inner a {
    font-size: 0.95rem;
  }
}

.tracklist-hero--silent-alarm .tracklist-hero__bsides-drawer-inner a:hover {
  color: #000;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

/* B-Sides-as-a-drawer: promo-single b-sides, never part of any album release — a distinct
   category from Bonus Tracks (above), which are always visible since they're genuinely part of
   the album on some edition. A drawer suits B-Sides specifically because there can be a lot of
   them (AWITC alone has 12) — too many to list permanently. Absolutely positioned, deliberately
   NOT a grid item — a grid item placed at grid-row:1 forces that row to grow to fit its expanded
   height, pushing every row below it down (the main list visibly "splits"). A fixed width
   (rather than shrink-to-fit) is equally deliberate: shrink-to-fit made the whole panel narrower
   while collapsed than while expanded, and since it's anchored at right:0, growing/shrinking
   width shifted where its *left* edge — and therefore the toggle's own left-aligned text —
   landed. Fixed width means the panel never moves, collapsed or expanded. This default position
   (top-right) is itself just AWITC's own choice, same as everything else about this block —
   override position/top/right/width per page via a `.tracklist-hero--<slug>` selector when a
   future album wants the drawer somewhere else. The translucent+blur "frosted glass" treatment
   lives on .tracklist-hero__bsides-drawer-body, not this wrapper — that way it's only visible
   once expanded (max-height:0 + box-sizing:border-box collapses the whole box, background
   included, to nothing while closed); the toggle label floats directly over the photo with no
   box around it at all, matching that it's a plain label, not a button-shaped chip. */
.tracklist-hero__bsides-drawer {
  position: absolute;
  top: 0;
  right: 0;
  width: 440px;
}

/* Below ~1080px (measured directly, same method as before: the point where the longest main-list
   line, "Song For Clay (Disappear Here)", runs into the drawer's fixed-position left edge — moved
   further out than the original ~950px once the drawer widened from 320px to fit larger text)
   there isn't room for the list and the drawer side by side, so an absolutely-positioned top-right
   box has nowhere to go but directly over the track text. 1200px keeps a safe margin above that —
   confirmed a 110px+ gap at 1250px — re-check this number if a future album's tracklist has a
   longer line than AWITC's, or if the drawer's width changes again. Below the breakpoint the
   drawer drops out of absolute positioning and flows as a normal grid item, full-width, right
   after the last track. */
@media (max-width: 1200px) {
  .tracklist-hero__bsides-drawer {
    position: static;
    grid-column: 1;
    width: 100%;
    margin-top: var(--space-4);
  }
}

.tracklist-hero__bsides-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  color: #000;
  font-family: var(--font-body-light);
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: color 0.4s ease 0.1s;
}

/* Grey, since this toggle's resting colour (base/Silent Alarm) is already black — hovering to
   another dark tone would give no feedback, so this goes lighter instead. AWITC overrides to
   black below, the opposite direction, since IT rests at a pale cream. */
.tracklist-hero__bsides-toggle:hover {
  color: #7a7a7a;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

/* A proper chevron glyph (Lucide's chevron-down path) via CSS mask, rather than the earlier
   rotated-border-corner trick — that approach rotated a square around its own center, which
   isn't where a chevron's visual weight sits, so it never quite lined up with the text no matter
   how much margin was added to compensate. A mask keeps the icon a plain, correctly-centered box
   at any rotation, and mask-based icons pick up colour from `background-color` (here
   `currentColor`), so hover/page colour overrides need no separate rule for the icon itself. */
.tracklist-hero__bsides-toggle::after {
  content: '';
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  background-color: currentColor;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  transition: transform 0.25s ease, background-color 0.2s ease;
}

.tracklist-hero__bsides-toggle[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

/* max-height:0 alone can't shrink an element below its own padding — even at border-box, the
   padding still has to be painted around a (clamped-to-zero) content box, so a padded element
   never visually reaches true zero height. That's why the frosted-glass styling (background,
   blur, padding) lives on a separate .tracklist-hero__bsides-drawer-inner instead of directly on
   the max-height-animated .tracklist-hero__bsides-drawer-body: the *body* has zero padding of its
   own, so it genuinely collapses to nothing, and overflow:hidden fully hides the inner (padding
   and all) along with it. */
.tracklist-hero__bsides-drawer-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.35s ease;
}

.tracklist-hero__bsides-drawer-body.is-open {
  margin-top: var(--space-3);
}

.tracklist-hero__bsides-drawer-inner {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  box-sizing: border-box;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 8px;
  padding: var(--space-3) var(--space-4);
}

.tracklist-hero__bsides-drawer-inner a {
  color: #7a7a7a;
  font-size: 1.6rem;
  font-weight: 300;
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  white-space: nowrap;
  /* Same stretch issue as .tracklist-hero__list a / .tracklist-hero__bonus a — this is also
     display:flex;flex-direction:column (see .tracklist-hero__bsides-drawer-inner), so without
     this every b-side's clickable box stretches to the drawer's full width instead of its own
     text. Third instance of the same bug in three different components; worth grepping for
     "display: flex" + "flex-direction: column" in this file before adding any new one. */
  align-self: flex-start;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero__bsides-drawer-inner a:hover {
  color: #000;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--awitc .tracklist-hero__title {
  color: #fffcde;
}

.tracklist-hero--awitc .tracklist-hero__list a {
  color: #fffcde;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — same underlying cause as Hymns above (no font-size
   override of its own, so it inherits the shared height-based clamp() regardless of how narrow
   the viewport actually is), but the opposite visible symptom: this album's own longest title,
   "Song For Clay (Disappear Here)", was wide enough at the clamp's ceiling to overflow the page
   and force horizontal scroll, rather than just wrapping onto an ugly second line. */
@media (max-width: 600px) {
  .tracklist-hero--awitc .tracklist-hero__list a {
    font-size: 0.95rem;
  }
}

.tracklist-hero--awitc .tracklist-hero__bonus-label {
  color: #fffcde;
}

.tracklist-hero--awitc .tracklist-hero__bonus a {
  color: #fffcde;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — same reasoning as the main tracklist list above. */
@media (max-width: 600px) {
  .tracklist-hero--awitc .tracklist-hero__bonus a {
    font-size: 1rem;
  }
}

.tracklist-hero--awitc .tracklist-hero__bonus a:hover {
  color: #000;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--awitc .tracklist-hero__bsides-toggle {
  color: #fffcde;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero--awitc .tracklist-hero__bsides-toggle:hover {
  color: #000;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--awitc .tracklist-hero__bsides-drawer-inner a {
  color: #fffcde;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — same reasoning as the main tracklist list above. */
@media (max-width: 600px) {
  .tracklist-hero--awitc .tracklist-hero__bsides-drawer-inner a {
    font-size: 1rem;
  }
}

.tracklist-hero--awitc .tracklist-hero__bsides-drawer-inner a:hover {
  color: #000;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--awitc::before {
  background-image: url('/Assets/Artwork/Textless Artwork/AWITC_Bsides_artwork.jpeg');
  /* cover, not a forced 100%-width — on wide/landscape viewports this is width-driven and gives
     the identical result "100% auto" did, but on narrow/portrait ones (mobile) it switches to
     height-driven scaling instead, so the image always fully covers the box with no white gap
     showing above it. */
  background-size: cover;
  background-position: center bottom;
}

/* Intimacy: solid black, no background image at all — a genuinely different treatment from every
   other album so far, all of which use a photo. Centred throughout (title, both track lists),
   unlike the left-aligned default everywhere else. */
.tracklist-hero--intimacy {
  background-color: #000;
  /* This page's own content (11 tracks + Bonus Tracks stacked in one column, plus the marquee)
     is the tallest of any tracklist page — its natural height sits close enough to a real 1440p
     browser's *usable* viewport height (screen height minus the browser's own tabs/toolbar chrome,
     which the exact-pixel-height check below can't account for) that a few pixels of genuine
     scroll can appear depending on that chrome's size. The shared rule's padding-bottom is dead
     black space below the marquee that flex-grow already fills in on the far more common case
     where content fits — trimming it here buys back margin for the tight case without touching
     anything visible above the marquee. */
  padding-bottom: var(--space-3);
}

.tracklist-hero--intimacy::before {
  display: none;
}

.tracklist-hero--intimacy .tracklist-hero__title {
  color: #fff;
  text-align: center;
}

/* The shared .tracklist-hero__body is a 3-column grid (main list / spacer / side drawer) because
   most albums put something — a static bonus block or a drawer — beside the list. Intimacy has
   neither (no B-Sides, and Bonus Tracks always sit below regardless), so a plain centred flex
   column is simpler and correctly centres both the list and the bonus block as a unit, rather
   than fighting the grid's own column-based alignment. */
.tracklist-hero--intimacy .tracklist-hero__body {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.tracklist-hero--intimacy .tracklist-hero__list a {
  color: #fff;
  /* The base rule's align-self:start (added to stop links stretching to fill their column/
     container — see .tracklist-hero__list a) overrides this page's own centring, since align-self
     on the item always wins over the parent's align-items. Intimacy never had the stretch
     problem in the first place — align-items:center on .tracklist-hero__body already implies
     each item sizes to its own content, it just centres that content instead of left-aligning
     it — so this only needs to put align-self back to match. */
  align-self: center;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero--intimacy .tracklist-hero__list a:hover {
  color: #7a7a7a !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--intimacy .tracklist-hero__bonus {
  text-align: center;
}

.tracklist-hero--intimacy .tracklist-hero__bonus-label {
  color: #fff;
}

.tracklist-hero--intimacy .tracklist-hero__bonus a {
  color: #fff;
  /* Same reasoning as .tracklist-hero__list a above — the base .tracklist-hero__bonus a rule's
     align-self:flex-start needs putting back to center for this page specifically. */
  align-self: center;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero--intimacy .tracklist-hero__bonus a:hover {
  color: #7a7a7a;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--intimacy .tracklist-hero__back {
  /* margin-top really is auto here, same as the shared base rule — reverted back to that after
     briefly trying a small fixed margin instead (padding-top:0 is left over from that attempt,
     harmless either way since auto swallows it). The fixed version seemed right on paper ("the
     marquee already handles being pinned to the bottom, so back doesn't need to") but broke on
     a genuinely tall viewport (confirmed directly: a real 1470x1300 window, well within a
     maximised 1440p monitor's range): with NEITHER back nor marquee claiming the hero's own
     leftover flex-grow space, that space just sat as dead black area *after* the marquee, at the
     very bottom of the page, instead of being distributed anywhere sensible. Restoring back's own
     auto margin makes the browser push the whole {back, marquee} group down as one unit to
     absorb that space *before* itself, so marquee stays flush against the hero's actual bottom
     edge at any viewport height — matching how every other album's own back button already
     behaves, just with the marquee riding along right after it instead of being the very last
     unclaimed child. margin-bottom:0 still overrides the browser's default <p> margin, which
     would otherwise add its own gap before the marquee on top of the marquee's own margin-top
     (flex siblings don't collapse adjoining margins the way normal block-flow ones do). */
  padding-top: 0;
  margin-top: auto;
  margin-bottom: 0;
  text-align: right;
}

/* The shared frosted-pill treatment (rgba(0,0,0,0.35) over a photo) is invisible on Intimacy's
   solid black — black-on-black has no contrast at all — so it needs its own light-on-dark tint
   to read as a button here. */
.tracklist-hero--intimacy .tracklist-hero__back a {
  /* color was missing here originally — the shared rule's own color:#fff (meant for the dark
     pill everywhere else) was never overridden, so this was genuinely white text on a near-white
     pill (rgba(255,255,255,0.12)) at first. #000 was tried next, but the pill itself blends white
     at only 12% opacity into the page's own black, so it renders as a dark grey, not a light one
     — black text on dark grey is just as illegible the other way. Light grey splits the
     difference and reads clearly against this specific pill on both this page and Four's. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--intimacy .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* Four: static row of 4 photos up top (not a moving marquee — deliberately a different, simpler
   component from Intimacy's), a bottom-anchored background photo blending into black behind the
   tracklist (Silent Alarm's own technique, reused as-is), and a 2-column tracklist (main list
   left, Bonus Tracks right) instead of the "always below" layout every other album uses — a
   deliberate one-off for this page specifically, not a change to the shared component. */
/* Full-bleed, touching both the nav bar above and the viewport's left/right edges at any width —
   cancels the hero's own padding on all three sides (top/left/right) rather than just left/right
   like the marquee does, since this sits flush against the top of the hero, not somewhere in the
   middle of it. */
/* Width behaviour has three stages: capped at the site's usual 1100px content width and centred
   on wide viewports (fixed-height, natural-aspect-ratio photos with real empty space on both
   sides) — then, exactly where that 1100px cap would otherwise start touching the hero's own side
   padding (1100px + 2×the hero's padding = 1180px), it drops the cap AND cancels that padding in
   the same breath, jumping straight to flush-with-the-viewport-edges with no padded-but-uncapped
   step in between — then, once the fixed-height photos would no longer fit without overflowing
   (same 700px breakpoint the 2-column tracklist already collapses at), it drops the fixed height
   entirely and reverts to the original behaviour: an equal 4-column grid that always fills the
   available width, each photo square-cropped via aspect-ratio+object-fit so nothing overflows
   regardless of how narrow the viewport gets. margin-top stays negative at every stage — that's
   just closing the gap with the nav bar above, unrelated to any of this — and now reuses the
   hero's own --tracklist-hero-vpad instead of a hardcoded -var(--space-6): that custom property
   is itself a vh-based lock (see .tracklist-hero's own comment), so it's genuinely smaller than
   var(--space-6) on a short viewport — hardcoding this to the old flat value meant it kept
   cancelling a *bigger* padding than the hero actually had once that lock shipped, over-cancelling
   and pulling the carousel up into the nav bar. Confirmed directly on a real MacBook Air. */
.tracklist-hero__carousel {
  display: flex;
  gap: 0;
  max-width: 1100px;
  margin: calc(-1 * var(--tracklist-hero-vpad)) auto var(--space-3);
  overflow: hidden;
}

.tracklist-hero__carousel img {
  display: block;
  height: 280px;
  width: auto;
  flex-shrink: 0;
}

@media (max-width: 1180px) {
  .tracklist-hero__carousel {
    max-width: none;
    width: calc(100% + 2 * var(--space-5));
    margin-left: calc(-1 * var(--space-5));
    margin-right: calc(-1 * var(--space-5));
  }
}

@media (max-width: 700px) {
  .tracklist-hero__carousel {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
  }

  .tracklist-hero__carousel img {
    aspect-ratio: 1;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

.tracklist-hero--four {
  background-color: #000;
}

.tracklist-hero--four::before {
  background-image: url('/Assets/Artwork/Four Artwork/Four background.JPG');
  /* NOT cover: the image's only real content (thin red/blue/yellow/green corner brackets, a nod
     to the album's 4-rings art) sits right at its far left and right edges, with a huge plain
     black field in between. "cover" on any viewport taller/narrower than the image's own very
     wide 1391:751 ratio crops symmetrically from the sides inward — cutting off both bracket
     pairs entirely and leaving nothing but that plain black middle, which is exactly the "I don't
     see the image at all" bug. 100% width, height auto keeps the *entire* width always in frame
     (never crops left/right), so the brackets stay visible regardless of viewport shape — still
     "stuck to the bottom" and always exactly as wide as the browser window, matching the original
     ask, just without cropping away the only part of the image with anything visible in it. This
     also can't reintroduce Silent Alarm's old white-gap-on-narrow-screens bug (the reason it
     switched to cover in the first place): any gap here is Four's own black page background
     showing through, which is indistinguishable from the image's own near-black field. */
  background-size: 100% auto;
  background-position: center bottom;
}

.tracklist-hero--four .tracklist-hero__title {
  color: #fff;
  /* Mirrors the carousel's own two width stages exactly (capped+centred on wide, edge-to-edge
     below 1180px) so "FOUR" always lines up with the carousel's actual right edge, at any
     viewport width — not just whichever stage the carousel happens to be in. (width:100% is now
     on the shared base rule — see .tracklist-hero__title — no longer needs repeating here.) */
  text-align: right;
}

@media (max-width: 1180px) {
  .tracklist-hero--four .tracklist-hero__title {
    max-width: none;
    width: calc(100% + 2 * var(--space-5));
    margin-left: calc(-1 * var(--space-5));
    margin-right: calc(-1 * var(--space-5));
  }
}

.tracklist-hero--four .tracklist-hero__body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  column-gap: var(--space-5);
}

.tracklist-hero--four .tracklist-hero__list {
  /* Not display:contents here (unlike the shared default) — that trick exists specifically to
     let individual tracks auto-place across the old 3-column grid; a clean 2-column layout wants
     the whole list to be one grid item (column 1) with its own tracks stacked inside it. */
  display: flex;
  flex-direction: column;
  grid-column: 1;
}

.tracklist-hero--four .tracklist-hero__list a,
.tracklist-hero--four .tracklist-hero__bonus a {
  font-family: var(--font-serif);
  font-style: italic;
  color: #fff;
  text-transform: none;
  /* align-self:flex-start (fixing the clickable-area-too-wide issue this page hit first) now
     lives on the shared base rules instead, since the same bug recurred on Hymns' grid-based
     layout — see .tracklist-hero__list a / .tracklist-hero__bonus a. */
  transition: color 0.4s ease 0.1s;
}

/* Per-track hover colour, set inline as a custom property per <a> (--track-hover) rather than
   one shared rule, since each track needs its own colour — cycling red/blue/yellow/green in a
   fixed repeating order across the 12 main tracks guarantees no two adjacent tracks ever match
   (a straight period-4 cycle never repeats immediately, whatever the list length). Needs
   !important to beat the shared .tracklist-hero__list a:hover rule, which is itself !important. */
.tracklist-hero--four .tracklist-hero__list a:hover {
  color: var(--track-hover) !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--four .tracklist-hero__bonus {
  grid-column: 2;
  grid-row: 1;
  margin-top: 0;
  width: auto;
  text-align: left;
}

/* Below this, the two Georgia-italic columns get cramped — Bonus Tracks drops under the main
   list instead, matching the "always below" convention every other album already uses. */
@media (max-width: 700px) {
  .tracklist-hero--four .tracklist-hero__body {
    grid-template-columns: 1fr;
  }

  .tracklist-hero--four .tracklist-hero__bonus {
    grid-column: 1;
    grid-row: auto;
    margin-top: var(--space-4);
    width: fit-content;
  }
}

.tracklist-hero--four .tracklist-hero__bonus-label {
  /* Explicitly Gill Sans MT, not the Georgia italic used for every actual track title (main or
     bonus) on this page — the label is UI chrome, not a song name. Keeps its uppercase too,
     unlike the actual track titles, for the same reason. */
  font-family: var(--font-heading);
  font-style: normal;
  color: #fff;
}

/* Same --track-hover custom-property technique as the main list, just with only 2 tracks and no
   adjacency concern to cycle around. */
.tracklist-hero--four .tracklist-hero__bonus a:hover {
  color: var(--track-hover);
  transition-duration: 0.2s;
  transition-delay: 0s;
}

/* The shared frosted-pill treatment (rgba(0,0,0,0.35)) is invisible against Four's own
   near-entirely-black page for the same reason Intimacy's was — swap to a light tint instead. */
.tracklist-hero--four .tracklist-hero__back a {
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--four .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* Hymns: Gill Sans Light for every piece of text on the page (one of the three lyrics pages this
   typeface is reserved for, per the site-wide typography rule) — centred title over a left-aligned
   tracklist (the base layout's own default already does this: max-width:1100px;margin:0 auto
   centres the .tracklist-hero__body box as a unit, while column 1 inside it is left-aligned, so no
   layout override is needed for the list itself, only the title). All-caps on the tracklist is
   already the shared default too. No B-Sides for this album — just the standard "always below"
   Bonus Tracks block, unmodified. */
.tracklist-hero--hymns {
  background-color: #000;
}

.tracklist-hero--hymns::before {
  background-image: url('/Assets/Artwork/hymns_bg.jpg');
  /* cover + centre bottom — same "always fills the window width, anchored to the bottom" logic
     as Silent Alarm/Four, matching "sticky to the bottom and centred... when the window resizes". */
  background-size: cover;
  background-position: center bottom;
}

.tracklist-hero--hymns .tracklist-hero__title {
  font-family: var(--font-body-light);
  color: #fff;
  text-align: center;
}

.tracklist-hero--hymns .tracklist-hero__list a {
  font-family: var(--font-body-light);
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — this album never had its own font-size override, so it
   was inheriting the shared .tracklist-hero__list a rule's own clamp(), which is a *height*-based
   lock (tuned for short laptop screens), not a width one — a narrow-but-tall phone still got the
   clamp's full ~2.1rem ceiling regardless of how little horizontal room it actually had. */
@media (max-width: 600px) {
  .tracklist-hero--hymns .tracklist-hero__list a {
    font-size: 1.15rem;
  }
}

.tracklist-hero--hymns .tracklist-hero__list a:hover {
  color: #7a7a7a !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--hymns .tracklist-hero__bonus-label {
  font-family: var(--font-body-light);
  color: #fff;
}

.tracklist-hero--hymns .tracklist-hero__bonus a {
  font-family: var(--font-body-light);
  color: #fff;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — same reasoning as the main tracklist list above (no
   font-size override of its own, so it inherits the shared height-based clamp() regardless of
   width). Sized a touch smaller than that one since bonus tracks have no leading track number to
   disambiguate a wrapped second line from a new entry. */
@media (max-width: 600px) {
  .tracklist-hero--hymns .tracklist-hero__bonus a {
    font-size: 1rem;
  }
}

.tracklist-hero--hymns .tracklist-hero__bonus a:hover {
  color: #7a7a7a;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--hymns .tracklist-hero__back a {
  font-family: var(--font-body-light);
  /* Same contrast fix as Intimacy/Four — the shared dark pill is invisible against this page's
     own predominantly black photo. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--hymns .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* Alpha Games: almost identical to Hymns (Gill Sans Light throughout, centred title over a
   left-aligned tracklist, white text, standard "always below" Bonus Tracks, no B-Sides) — the
   three differences are the background's anchor/sizing, normal capitalisation instead of
   all-caps, and a flat hover colour instead of grey. */
.tracklist-hero--alpha-games {
  background-color: #000;
}

.tracklist-hero--alpha-games::before {
  background-image: url('/Assets/Artwork/Alpha Games/AG_bg.jpeg');
  /* auto 100% — height is always forced to exactly the box's own height (so it can never leave a
     gap at the top or bottom, growing/shrinking as the window resizes vertically), width follows
     the image's own aspect ratio and is anchored to the right, cropping from the left if the
     image ends up wider than the box at that height. This is a genuinely different technique
     from every other album's background so far (all height-driven-when-needed via `cover`) —
     here it's *always* height-driven, by design, regardless of the viewport's own aspect ratio. */
  background-size: auto 100%;
  background-position: right top;
}

.tracklist-hero--alpha-games .tracklist-hero__title {
  font-family: var(--font-body-light);
  color: #fff;
  text-align: center;
}

.tracklist-hero--alpha-games .tracklist-hero__list a {
  font-family: var(--font-body-light);
  color: #fff;
  text-transform: none;
  font-size: 1.8rem;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — this album's own titles include their track number
   directly in the link text ("03. You Should Know The Truth"), longer than any other album's
   plain title, so the flat 1.8rem above was wrapping well before the tracklist column's own
   right edge on a real phone. Width-based, not touch-gated, same reasoning as the Lyrics/Bios
   grid column fixes — this is about whether the text actually fits, not input capability. */
@media (max-width: 600px) {
  .tracklist-hero--alpha-games .tracklist-hero__list a {
    font-size: 1.1rem;
  }
}

.tracklist-hero--alpha-games .tracklist-hero__list a:hover {
  color: #ea636a !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--alpha-games .tracklist-hero__bonus-label {
  font-family: var(--font-body-light);
  color: #fff;
}

.tracklist-hero--alpha-games .tracklist-hero__bonus a {
  font-family: var(--font-body-light);
  color: #fff;
  text-transform: none;
  font-size: 1.8rem;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — same reasoning as the main tracklist list above. Sized a
   touch smaller than that one (1.0 vs 1.1rem) since bonus tracks have no leading track number to
   disambiguate a wrapped second line from a new entry, unlike the main list. */
@media (max-width: 600px) {
  .tracklist-hero--alpha-games .tracklist-hero__bonus a {
    font-size: 1rem;
  }
}

.tracklist-hero--alpha-games .tracklist-hero__bonus a:hover {
  color: #ea636a;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--alpha-games .tracklist-hero__back {
  text-align: center;
}

.tracklist-hero--alpha-games .tracklist-hero__back a {
  font-family: var(--font-body-light);
  /* Same contrast fix as Intimacy/Four/Hymns — the shared dark pill is invisible against a
     predominantly dark page background. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--alpha-games .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* Anatomy Of A Brief Romance: almost identical to Alpha Games (centred title, left-aligned
   tracklist, white text, flat hover colour, no Bonus Tracks/B-Sides) — differences are the
   background's anchor/sizing, no track numbers, and Gill Sans MT instead of Light (so no
   font-family override anywhere here — the site's own default already is Gill Sans MT). */
.tracklist-hero--anatomy {
  background-color: #000;
}

.tracklist-hero--anatomy::before {
  /* Two stacked background layers on the same ::before — a translucent gradient "banner" behind
     the title (dark near the top, fading smoothly to fully transparent by its own bottom edge
     rather than a hard cutoff line, so the busy tunnel photo underneath doesn't fight with the
     title text) painted on top of the actual photo. Comma order matters: the first layer listed
     paints on top, so the gradient goes first, the real photo second — both still sit behind
     every real child of the hero (title, tracklist, back button) via this element's own
     z-index:-1 from the shared base rule. Holds a near-solid tone for its first third before
     fading — a straight 2-stop fade starting at full opacity from the very first pixel (the
     original attempt) blended into the photo's own dark upper vignette closely enough that it
     read as barely-there rather than an actual banner; confirmed via a direct A/B screenshot
     (gradient vs. no gradient) that the plain 2-stop version was technically rendering but too
     subtle to register. */
  background-image:
    linear-gradient(to bottom, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.8) 35%, rgba(0, 0, 0, 0) 100%),
    url('/Assets/Artwork/Textless Artwork/anatomy_artwork.jpeg');
  /* cover + center center for the photo — anchored to the middle on both axes, scaled so whichever
     dimension (width or height) needs to grow more to fully cover the box is the one driving the
     size, cropping the other axis's overflow. Unlike Alpha Games' always-height-driven auto 100%,
     this one genuinely swaps which axis drives sizing depending on the viewport's own aspect
     ratio. The gradient's own size (400px tall, full width, not tiled) is independent of this. */
  background-size: 100% 400px, cover;
  background-position: top center, center center;
  background-repeat: no-repeat, no-repeat;
}

.tracklist-hero--anatomy .tracklist-hero__title {
  color: #e3e5db;
  text-align: center;
}

.tracklist-hero--anatomy .tracklist-hero__body {
  /* Centres the tracklist vertically in whatever space is left between the title and the back
     button, rather than sitting flush under the title — margin-top/bottom:auto on a flex column
     item claims 100% of the hero's free space split evenly above and below it, provided nothing
     else in the column also has an auto margin competing for that space (see the back button's
     own margin-top override below). */
  margin-top: auto;
  margin-bottom: auto;
}

.tracklist-hero--anatomy .tracklist-hero__list a {
  color: #e3e5db;
  text-transform: uppercase;
  font-size: 1.8rem;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — same reasoning as Alpha Games above: the flat 1.8rem was
   wrapping before the tracklist column's own right edge on a real phone. */
@media (max-width: 600px) {
  .tracklist-hero--anatomy .tracklist-hero__list a {
    font-size: 1.05rem;
  }
}

.tracklist-hero--anatomy .tracklist-hero__list a:hover {
  color: #c6000c !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--anatomy .tracklist-hero__back {
  text-align: right;
  /* The shared base rule's margin-top:auto would otherwise compete with the tracklist body's own
     auto margins above for the hero's free space, pulling the tracklist off-centre toward the top
     (flexbox splits free space evenly across *every* auto margin in the column, not per-element) —
     zeroed out so the body's auto margins get all of it. The base rule's own padding-top is enough
     spacing above this button on its own. */
  margin-top: 0;
}

.tracklist-hero--anatomy .tracklist-hero__back a {
  /* Same contrast fix as Intimacy/Four/Hymns/Alpha Games — the shared dark pill is invisible
     against a predominantly dark page background. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--anatomy .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* Bloc Party EP: first EP, and the first page to put a second visual element (the vectorized
   star pattern) beside the tracklist. Body is overridden from the shared 3-column grid to a
   flex row — the grid's col1/col2(1fr)/col3 approach (as used by AWITC's B-Sides drawer and
   Four's Bonus Tracks column) stretches its two occupants to opposite edges of the full 1100px
   width, which read as too far apart here; a flex row with a fixed gap keeps the list and image
   close together as one visual unit instead of spread across the hero. Left-aligned as a whole
   (title + body share the same left edge, matching the real Wix site's own layout), not centred.
   Also: sharing an explicit grid row with the list's first item (the original attempt) forced
   that row to the image's full 230px height, visually splitting "Banquet" away from the rest of
   the list with a dead gap — confirmed via getBoundingClientRect (a ~144px gap between the first
   and second track that no other page has) before switching to this flex approach, where the
   image and the list are independent siblings with no shared row-sizing to distort. */
.tracklist-hero--bloc-party-ep {
  background-color: #000;
}

.tracklist-hero--bloc-party-ep::before {
  background-image: url('/Assets/Artwork/EPs/ep_bg.jpeg');
  /* auto 100% / left bottom — back to the user's original spec (centring the anchor was tried as
     a fix for the figure/tracklist collision, but that fought the "title and tracklist share the
     real Wix site's left edge" alignment instead — reverted). The actual fix for the collision
     is the scrim on .tracklist-hero__title/__list below, not the background's own position:
     tying the image's rendered width to *viewport width* instead of height can't work here
     regardless — under auto-100%-height sizing the figure's reach is driven by hero *height*
     (rendered width = heroHeight × the image's own fixed aspect ratio), not width, so a
     width-based shrink wouldn't track the actual variable causing the reach to grow. And even a
     width-tied size can't create real separation at any realistic viewport: the tracklist starts
     only ~40px from the hero's own left padding, so the image would have to shrink to a sliver
     for the figure to never reach that far, defeating "always full height" outright. */
  background-size: auto 100%;
  background-position: left bottom;
}

.tracklist-hero--bloc-party-ep .tracklist-hero__title {
  color: #fff;
  /* Left-aligned, per the real Wix site's own layout (screenshot reference) — matches the
     shared base default already, so no text-align override needed at all; the title and the
     tracklist below both just use the shared .tracklist-hero__title / __body boxes as-is, which
     already share the same left edge (both max-width:1100px;margin:0 auto within the hero). */
  /* Translucent scrim, not a repositioning fix — the figure sits at the same left edge as the
     title/tracklist at every realistic hero height (see the background-position note above), so
     nothing short of moving the text away from the real Wix site's own left-aligned position (a
     non-starter — that's the alignment being matched here) can create actual separation.
     rgba(0,0,0,0.55) over the page's own solid-black background composites to the *same* black —
     the scrim is only visible where it's dimming something that isn't already black, i.e.
     exactly the figure's white linework, with no rectangle/box edge visible anywhere else.
     inline-block + padding so the box hugs the actual text rather than stretching full width. */
  display: inline-block;
  background: rgba(0, 0, 0, 0.8);
  padding: var(--space-2) var(--space-3);
}

.tracklist-hero--bloc-party-ep .tracklist-hero__body {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
}

/* .tracklist-hero__list is display:contents in the base rule (so a column-direction *parent*
   flex/grid can flatten it away and lay its <a> children out directly) — wrong here, since this
   page's body is a *row*, and contents would scatter the five links as separate row items
   instead of a single stacked column. Given its own real box so it becomes one flex item
   alongside the image. */
.tracklist-hero--bloc-party-ep .tracklist-hero__list {
  display: flex;
  flex-direction: column;
  order: 1;
  /* Same translucent-scrim reasoning as the title above — invisible over the page's own solid
     black, dims the figure's white linework just enough to keep the text readable wherever the
     two do overlap. One box behind the whole list (sized to the longest line), not per-line —
     the base .tracklist-hero__list a rule's own align-self:start keeps each link's *hoverable
     area* hugging its own text width regardless, so this doesn't reopen the old "whole line is a
     hyperlink" bug even though the visible scrim box itself spans the full list width. */
  background: rgba(0, 0, 0, 0.8);
  padding: var(--space-2) var(--space-3);
}

.tracklist-hero--bloc-party-ep .tracklist-hero__list a {
  color: #fff;
  text-transform: uppercase;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero--bloc-party-ep .tracklist-hero__list a:hover {
  color: var(--color-accent) !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--bloc-party-ep .tracklist-hero__side-image {
  width: 250px;
  height: auto;
  flex-shrink: 0;
  order: 2;
}

/* Below this width the list's own longest line + the 250px image + the flex gap no longer sit
   comfortably side by side — stacks them instead, image on top (order swapped so it's first
   regardless of a:hover DOM order) rather than squeezing the list narrower. */
@media (max-width: 860px) {
  .tracklist-hero--bloc-party-ep .tracklist-hero__body {
    flex-direction: column;
    align-items: center;
  }

  .tracklist-hero--bloc-party-ep .tracklist-hero__list {
    order: 2;
  }

  .tracklist-hero--bloc-party-ep .tracklist-hero__side-image {
    order: 1;
  }
}

.tracklist-hero--bloc-party-ep .tracklist-hero__back a {
  /* Same contrast fix as every other predominantly-black page — the shared dark pill is
     invisible against a predominantly dark page background. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--bloc-party-ep .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* Little Thoughts EP: almost identical to Bloc Party EP (same left-aligned title+list, side
   image at the level of the first track, flex-row layout with the same 860px stacking
   breakpoint) — differences are no background photo (a flat pale colour instead, so none of
   Bloc Party EP's figure-collision scrim is needed here at all), a different side image, and a
   light-page colour scheme (black text, olive hover) instead of white-on-black. */
.tracklist-hero--little-thoughts-ep {
  background-color: #f9f4e8;
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__title {
  color: #000;
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__body {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__list {
  display: flex;
  flex-direction: column;
  order: 1;
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__list a {
  color: #000;
  text-transform: uppercase;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__list a:hover {
  color: #8fac31 !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__side-image {
  width: 250px;
  height: auto;
  flex-shrink: 0;
  order: 2;
}

@media (max-width: 860px) {
  .tracklist-hero--little-thoughts-ep .tracklist-hero__body {
    flex-direction: column;
    align-items: center;
  }

  .tracklist-hero--little-thoughts-ep .tracklist-hero__list {
    order: 2;
  }

  .tracklist-hero--little-thoughts-ep .tracklist-hero__side-image {
    order: 1;
  }
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__back a {
  /* The shared base pill (rgba(0,0,0,0.35), meant for white text) composites to a mid-grey that
     has almost no luminance difference from #8fac31 itself — confirmed via computed style, the
     button was nearly illegible. A light pill instead gives the olive text something to actually
     contrast against. */
  background: rgba(255, 255, 255, 0.6);
  color: #8fac31;
}

.tracklist-hero--little-thoughts-ep .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.85);
}

/* Four More EP: reuses Four's own 4-colour hover cycle (same --track-hover custom-property
   technique, same hex values) and its rings background, but everything else is simpler —
   centred title/list instead of Four's 2-column layout, no track numbers, no Bonus Tracks. */
.tracklist-hero--four-more-ep {
  background-color: #000;
}

.tracklist-hero--four-more-ep::before {
  background-image: url('/Assets/Artwork/Four Artwork/Four 2K.jpeg');
  /* auto 100% — height always matches the browser window's own height, anchored to horizontal
     centre; the rings themselves already sit centred in the source photo, so this needs no
     vertical-anchor decision beyond the default centre. */
  background-size: auto 100%;
  background-position: center center;
}

/* "FOUR MORE EP" as three explicit lines (FOUR / MORE / EP, via literal <br> in the HTML — not
   just wrapping) — FOUR and MORE share one larger size, EP is exactly half of it (both the
   min/preferred/max clamp values halved, so the ratio holds at every viewport width, not just
   the one it was eyeballed at). text-transform:uppercase is already the shared h1 default, so
   the HTML can stay mixed-case. */
.tracklist-hero--four-more-ep .tracklist-hero__title {
  color: #fff;
  text-align: center;
  line-height: 0.85;
  /* Vertically centres the title+tracklist as one group in the space between the hero's own top
     and the back button — margin-top:auto here paired with margin-bottom:auto on
     .tracklist-hero__body (and the back button's own margin-top zeroed out below, so it isn't a
     third auto margin competing for the same free space) is the same technique used to centre
     Anatomy's tracklist alone, just spanning both the title and the list as a single pair this
     time since nothing sits between them needing its own centring. */
  margin-top: auto;
}

.tracklist-hero--four-more-ep .tracklist-hero__title-word--big {
  font-size: clamp(3.5rem, 8vw, 6.5rem);
}

.tracklist-hero--four-more-ep .tracklist-hero__title-word--small {
  font-size: clamp(1.75rem, 4vw, 3.25rem);
}

/* No side image and no Bonus Tracks on this page, so the shared 3-column grid
   (list/spacer/side-content) has nothing to put in columns 2/3 — swapped for a plain centred
   flex column instead, same technique as Intimacy. */
.tracklist-hero--four-more-ep .tracklist-hero__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: auto;
}

.tracklist-hero--four-more-ep .tracklist-hero__list a {
  color: #fff;
  text-transform: uppercase;
  /* The base rule's align-self:start (fixing "whole line is a hyperlink" elsewhere) overrides
     this page's own centred body — put back to match, same reasoning as Intimacy. */
  align-self: center;
  /* On narrow viewports "Straight Thru Cru" wraps to two lines — without this, the wrapped
     second line defaults to the page's own left text-align instead of following the link's own
     centred position. */
  text-align: center;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero--four-more-ep .tracklist-hero__list a:hover {
  color: var(--track-hover) !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--four-more-ep .tracklist-hero__back {
  /* The shared base rule's margin-top:auto would otherwise be a third auto margin competing
     with the title/body pair above for the hero's free space, pulling the group off-centre
     toward the top — zeroed out so all of it goes to the title+body pair instead. */
  margin-top: 0;
}

.tracklist-hero--four-more-ep .tracklist-hero__back a {
  /* Same contrast fix as every other predominantly-black page. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--four-more-ep .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* The Nextwave Sessions: no side image, no Bonus Tracks. Originally left the shared 3-column
   grid as-is (list left-aligned, block centred) since that matched the first-round instructions
   — the user's own follow-up asked for the list aligned *with the title* instead, i.e. sharing
   the title's own centred axis, so this now matches Intimacy/Four More EP's technique instead:
   .tracklist-hero__body swapped to a centred flex column, each link's align-self put back to
   center (the base rule's align-self:start, fixing "whole line is a hyperlink" elsewhere,
   otherwise overrides a centred parent's own align-items). */
.tracklist-hero--nextwave-sessions {
  background-color: #040001;
}

.tracklist-hero--nextwave-sessions::before {
  background-image: url('/Assets/Artwork/EPs/tns_bg_big.jpg');
  /* cover, not 100% auto — width-driven sizing left height uncovered whenever the hero's own
     aspect ratio (content/flex-driven, can exceed the image's own ~2.7:1) was narrower than the
     image, revealing a plain #040001 band above the texture instead of it. Confirmed directly:
     at 2560x1440 and worse at 3840x2160, the rendered image fell hundreds of px short of the
     hero's actual height. cover guarantees full coverage on both axes regardless of the box's
     aspect ratio, cropping whichever axis has slack — center bottom still anchors which part of
     the (now taller-than-native) image survives the horizontal crop. */
  background-size: cover;
  background-position: center bottom;
}

.tracklist-hero--nextwave-sessions .tracklist-hero__title {
  color: #2a7b90;
  text-align: center;
}

.tracklist-hero--nextwave-sessions .tracklist-hero__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Legibility fix found during verification, not requested: on shorter browser windows (roughly
   under ~950px tall at 1280px wide) the last track ("Children Of The Future") lands on the
   image's own busiest region (dense orange/teal texture) — confirmed via screenshot at
   1280×900 vs 1280×1200, fully legible at the taller height and not at the shorter one. Same fix
   as Bloc Party EP's figure collision: a translucent scrim behind the whole list, composited
   over this page's own solid-black background it stays black (invisible), and only actually
   dims the texture where the two genuinely overlap. Needs display:flex here too — the base
   rule's display:contents makes this element generate no box of its own at all (by design, so a
   column-direction parent can flatten it away and lay its <a> children out directly), so a
   background/padding on it is otherwise a complete no-op; confirmed via
   getBoundingClientRect reporting 0×0 before this was added.
   margin-left: aligns the list's own left edge (plus its own padding-left below) with where
   "The" — the title's first word — actually starts. Measured directly via a Range over the
   title's text node at the standard 1280px test width used throughout this project (title text
   left edge 214.5px) and tuned by direct measurement of the rendered result, not just formula —
   an initial 100px estimate (214.5 − body's own 90px left edge − the list's own 24px
   padding-left) landed 8.5px short, so nudged to 109px, confirmed sub-pixel (0.5px) accurate
   afterward. Since the title is centred text in a variable-width box whose own font-size is
   itself a vw-based clamp(), no fixed formula holds at every viewport width — this is a best-fit
   tuned at the one reference width every other measurement in this project has used, not a
   dynamic alignment that tracks the title at arbitrary widths. */
.tracklist-hero--nextwave-sessions .tracklist-hero__list {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: rgba(0, 0, 0, 0.7);
  padding: var(--space-2) var(--space-3);
  margin-left: 109px;
}

/* The 109px offset was tuned for the title's own single-line rendered width at the desktop
   reference — below the width where the title wraps to two lines (confirmed via rendered height:
   88px/2 lines at 500px wide vs 46px/1 line at 700px), "aligned with The" no longer means
   anything coherent, and the fixed offset just eats into an already-narrow column, forcing every
   longer track title into an awkward multi-line wrap ("French Exit" → "French"/"Exit"). Dropped
   back to flush-left at the hero's own padding instead. */
@media (max-width: 700px) {
  .tracklist-hero--nextwave-sessions .tracklist-hero__list {
    margin-left: 0;
  }
}

.tracklist-hero--nextwave-sessions .tracklist-hero__list a {
  color: #2a7b90;
  font-family: var(--font-serif);
  font-style: italic;
  text-transform: none;
  font-size: 2.6rem;
  transition: color 0.4s ease 0.1s;
}

.tracklist-hero--nextwave-sessions .tracklist-hero__list a:hover {
  color: #fff !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--nextwave-sessions .tracklist-hero__back a {
  /* Same contrast fix as every other predominantly-dark page. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--nextwave-sessions .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* The High Life EP — final EP. List pinned left, side image pinned right, vertically centred
   relative to each other: a flex row with justify-content:space-between (not the shared grid's
   1fr spacer column, and not Bloc Party EP's tight centred gap — this page wants the pair pushed
   to opposite edges, not held close together) and align-items:center. List first in the DOM,
   image second — happens to already read as "list left, image right" in the row layout with no
   order override needed, and stacks as "image below list" once the row collapses to a column,
   matching what was asked without needing Bloc Party EP's DOM-order-plus-flex-order trick. */
.tracklist-hero--high-life-ep {
  background-color: #000;
}

.tracklist-hero--high-life-ep::before {
  background-image: url('/Assets/Artwork/EPs/high-life-ep-bg-scaled.jpeg');
  /* cover — scales so whichever dimension (width or height) needs to grow more to fully cover
     the box drives the size, cropping the other axis's overflow; the source photo's own content
     (an abstract blue skyline/cityscape pattern) is fairly uniform throughout with nothing
     off-centre to bias toward, so a plain centre anchor needed no further decision. */
  background-size: cover;
  background-position: center center;
}

.tracklist-hero--high-life-ep .tracklist-hero__title {
  color: #fff;
}

.tracklist-hero--high-life-ep .tracklist-hero__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}

.tracklist-hero--high-life-ep .tracklist-hero__list {
  display: flex;
  flex-direction: column;
}

.tracklist-hero--high-life-ep .tracklist-hero__list a {
  color: #fff;
  font-size: 2.6rem;
  transition: color 0.4s ease 0.1s;
}

/* Narrow-width override, per request — the flat 2.6rem here is larger than any other album's own
   override, so despite this EP's titles being short, it was still wrapping before the tracklist
   column's own right edge on a real phone. */
@media (max-width: 600px) {
  .tracklist-hero--high-life-ep .tracklist-hero__list a {
    font-size: 1.6rem;
  }
}

.tracklist-hero--high-life-ep .tracklist-hero__list a:hover {
  color: #c88278 !important;
  transition-duration: 0.2s;
  transition-delay: 0s;
}

.tracklist-hero--high-life-ep .tracklist-hero__side-image {
  width: 400px;
  flex-shrink: 0;
}

/* Below this width the list's own longest line ("Keep It Rolling (feat. KennyHoopla)") + the
   400px image + the flex gap no longer sit comfortably side by side — collapses to a column,
   image second in the DOM so it lands below the list with no order override needed. */
@media (max-width: 1000px) {
  .tracklist-hero--high-life-ep .tracklist-hero__body {
    flex-direction: column;
    align-items: flex-start;
  }
}

.tracklist-hero--high-life-ep .tracklist-hero__back a {
  /* Same contrast fix as every other predominantly-dark page. */
  background: rgba(255, 255, 255, 0.12);
  color: #ccc;
}

.tracklist-hero--high-life-ep .tracklist-hero__back a:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* A full-bleed, slowly-scrolling strip of artwork — reusable for any future album that wants one,
   not Intimacy-specific by name. Follows immediately after whatever comes before it (originally
   pinned to the very bottom of a min-height:100vh hero via margin-top:auto, but on a tall/short-
   content viewport that left a large dead gap between the tracklist and the marquee, and could
   push the marquee itself below the fold — sits right after in normal flow instead, with just a
   small fixed gap). Cancels the hero's own left/right padding so the images touch the actual
   viewport edges rather than stopping at the hero's normal content padding. */
.tracklist-hero__marquee {
  width: calc(100% + 2 * var(--space-5));
  margin-left: calc(-1 * var(--space-5));
  margin-right: calc(-1 * var(--space-5));
  margin-top: var(--space-2);
  overflow: hidden;
}

.tracklist-hero__marquee-track {
  display: flex;
  align-items: center;
  gap: 0;
  width: max-content;
  animation: tracklist-hero-marquee 40s linear infinite;
}

.tracklist-hero__marquee-track img {
  display: block;
  height: 200px;
  width: auto;
  flex-shrink: 0;
}

/* The track's own content is duplicated once in the HTML (two full, identical copies back to
   back), so translating by exactly -50% of the doubled track's total width always lands on a
   frame pixel-identical to the start — a seamless loop regardless of how many images there are
   or how wide any individual one is, with no per-image width math needed. */
@keyframes tracklist-hero-marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tracklist-hero__marquee-track {
    animation: none;
  }
}

/* CMS-built releases (lyrics/release.html + js/lyrics-release.js): unlike every other album/EP's
   own hand-written modifier block above, every visual choice here comes from a CSS custom
   property set by JS per release (from the Tracklist Page fields in the CMS), falling back to
   sane shared-token defaults when a release leaves a field blank. */
.tracklist-hero--generic {
  background-color: var(--tt-bg-color, #000);
}

.tracklist-hero--generic::before {
  background-image: var(--tt-bg-image, none);
  background-size: cover;
  background-position: center center;
}

.tracklist-hero--generic .tracklist-hero__title {
  font-family: var(--tt-title-font, var(--font-body));
  color: var(--tt-title-color, var(--color-text-muted));
  text-align: var(--tt-title-align, left);
}

.tracklist-hero--generic .tracklist-hero__list a,
.tracklist-hero--generic .tracklist-hero__bonus a,
.tracklist-hero--generic .tracklist-hero__bsides-drawer-inner a {
  font-family: var(--tt-song-font, var(--font-body));
  color: var(--tt-song-color, var(--color-text-muted));
  text-align: var(--tt-song-align, left);
  justify-self: var(--tt-song-justify, start);
  align-self: var(--tt-song-justify, start);
}

.tracklist-hero--generic .tracklist-hero__list a:hover,
.tracklist-hero--generic .tracklist-hero__bonus a:hover,
.tracklist-hero--generic .tracklist-hero__bsides-drawer-inner a:hover {
  color: var(--tt-song-hover-color, #000) !important;
}

/* CMS-built releases' Lyrics Page (lyrics/release-lyrics.html + js/lyrics-release-lyrics.js) —
   same custom-property-driven approach as .tracklist-hero--generic above. .track__title and
   .track__number get their own explicit colour (rather than just inheriting .track__toggle's
   shared hover colour, the way most hand-built pages do it) because a release's song-titles
   colour is independently choosable here — that breaks the simple inheritance path, so hover/
   open state needs its own explicit rule too, same fix Anatomy's own block already needed for
   the same reason. */
.lyrics-page--generic {
  background: var(--lp-bg-color, var(--color-bg));
}

.lyrics-page--generic .lyrics-page__header h1 {
  font-family: var(--lp-title-font, var(--font-body));
  color: var(--lp-title-color, var(--color-text));
}

.lyrics-page--generic .track__title {
  font-family: var(--lp-song-font, var(--font-body));
  color: var(--lp-song-color, var(--color-text));
}

.lyrics-page--generic .track__toggle:hover .track__title,
.lyrics-page--generic .track__toggle[aria-expanded="true"] .track__title {
  color: var(--lp-song-hover-color, var(--color-accent));
}

.lyrics-page--generic .track__number {
  color: var(--lp-song-hover-color, var(--color-text-muted));
}

.lyrics-page--generic .track__lyrics {
  font-family: var(--lp-lyrics-font, var(--font-serif));
  color: var(--lp-lyrics-color, var(--color-text));
}
