/* Vendored from Google Fonts (OFL). No CDN: the container serves its own type. */
@font-face {
  font-family: 'Big Shoulders Display';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/big-shoulders-display-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Big Shoulders Display';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/big-shoulders-display-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Big Shoulders Display';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(/assets/fonts/big-shoulders-display-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Big Shoulders Display';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(/assets/fonts/big-shoulders-display-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(/assets/fonts/spectral-300-italic-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(/assets/fonts/spectral-300-italic-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(/assets/fonts/spectral-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(/assets/fonts/spectral-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/spectral-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/spectral-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/ibm-plex-mono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================== tokens ===
   The only colour on this site comes from the artists' cover art. Everything
   the site itself draws is ground, paper, or rule — with one exception: oxide
   marks the places where money reaches a band, and nothing else. */

:root {
  --ground:    #080f0e;
  --ground-up: #0d1615;
  --paper:     #e8e4da;
  --paper-dim: #8d938f;
  --rule:      #1b2523;
  --track:     rgba(232, 228, 218, 0.24);
  --oxide:     #c1613f;

  --display: 'Big Shoulders Display', 'Oswald', 'Arial Narrow', sans-serif;
  --text: 'Spectral', Georgia, 'Times New Roman', serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --measure: 46ch;
}

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

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

body {
  margin: 0;
  padding: 0 var(--gutter) 8rem;
  background: var(--ground);
  color: var(--paper);
  font: 300 0.95rem/1.65 var(--text);
  font-feature-settings: "kern", "liga";
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--gutter);
  top: 0.75rem;
  z-index: 20;
  padding: 0.5rem 0.75rem;
  background: var(--paper);
  color: var(--ground);
}

/* ============================================================ masthead === */

.masthead {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  max-width: 1500px;
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 3.75rem) 0 clamp(2rem, 4vw, 3rem);
  border-bottom: 1px solid var(--rule);
}

/* The mark is a path, so it is set like one: monospace, with a block caret
   sitting where the next character would be typed. */
.wordmark {
  justify-self: start;
  display: inline-flex;
  align-items: baseline;
  gap: 0.3ch;
  font: 500 clamp(1.1rem, 2vw, 1.5rem)/1 var(--mono);
  letter-spacing: -0.02em;
  text-decoration: none;
}

.wordmark__caret {
  width: 0.55ch;
  height: 0.95em;
  background: var(--paper);
  transform: translateY(0.1em);
}

.statement {
  max-width: var(--measure);
  margin: 0;
  color: var(--paper-dim);
  font-size: 0.95rem;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.35rem;
}

.chip {
  padding: 0.15rem 0;
  color: var(--paper-dim);
  font: 700 1rem/1.4 var(--display);
  letter-spacing: 0.02em;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.chip:hover { color: var(--paper); }
.chip--on {
  color: var(--paper);
  border-bottom-color: var(--paper);
}

/* ============================================================= leaving ===
   The interstitial for a link we did not collect ourselves. "Go anyway" is an
   outlined button, not a filled one: the way out is obvious without the page
   encouraging you through it. */

.masthead--bare {
  border-bottom: 0;
  padding-bottom: 0;
}

.leaving {
  max-width: 44rem;
  /* Left-aligned like everything else — centring it detaches it from the mark. */
  margin: 0;
  padding: clamp(2.5rem, 9vw, 6rem) 0;
}

.leaving__head {
  margin: 0;
  font: 800 clamp(2rem, 5vw, 3.5rem)/0.95 var(--display);
  letter-spacing: -0.01em;
}

.leaving__body {
  max-width: var(--measure);
  margin: 1rem 0 0;
  color: var(--paper-dim);
}

.leaving__target {
  margin: 1.75rem 0 0;
  padding: 0.9rem 1rem;
  background: var(--ground-up);
  border-left: 2px solid var(--track);
  font: 500 0.85rem/1.55 var(--mono);
  overflow-wrap: anywhere;
}

.leaving__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
  margin-top: 1.75rem;
}

.leaving__go {
  padding: 0.55rem 1.6rem;
  border: 1px solid var(--track);
  color: var(--paper);
  font: 700 1.05rem/1 var(--display);
  letter-spacing: 0.04em;
  text-decoration: none;
}
.leaving__go:hover { border-color: var(--paper); }

.leaving__back {
  color: var(--paper-dim);
  font-size: 0.9rem;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.leaving__back:hover { color: var(--paper); border-bottom-color: currentColor; }

/* ============================================================== plinth ===
   One record, given the room a record deserves. */

.plinth {
  display: grid;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  align-items: end;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  max-width: 1500px;
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 5rem) 0 clamp(3rem, 7vw, 6rem);
}

.plinth__art {
  position: relative;
  aspect-ratio: 1;
  background: var(--ground-up);
}
.plinth__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.plinth__blank {
  display: grid;
  place-items: center;
  height: 100%;
  padding: 1.5rem;
  font: 800 clamp(1.5rem, 4vw, 2.5rem)/0.95 var(--display);
  text-align: center;
  color: var(--paper-dim);
}

.plinth__text { min-width: 0; }

.plinth__artist {
  margin: 0;
  font: 800 clamp(2.6rem, 8.5vw, 8rem)/0.82 var(--display);
  letter-spacing: -0.015em;
  overflow-wrap: anywhere;
}

.plinth__release {
  margin: 0.75rem 0 0;
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  font-style: italic;
}

.plinth__place,
.plinth__credit {
  margin: 0.15rem 0 0;
  color: var(--paper-dim);
  font-size: 0.9rem;
}
.plinth__place { margin-top: 0.6rem; }

.plinth__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
  margin-top: 1.75rem;
}

.play {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 1.4rem 0.5rem 1.1rem;
  background: var(--paper);
  color: var(--ground);
  border: 0;
  font: 700 1.05rem/1 var(--display);
  letter-spacing: 0.04em;
  cursor: pointer;
}
.play:hover { background: #fff; }
.play__glyph {
  width: 0;
  height: 0;
  border-left: 0.7em solid currentColor;
  border-top: 0.42em solid transparent;
  border-bottom: 0.42em solid transparent;
}
.play[data-state="playing"] .play__glyph {
  width: 0.62em;
  height: 0.8em;
  border: 0;
  border-left: 0.2em solid currentColor;
  border-right: 0.2em solid currentColor;
}

.buy {
  color: var(--oxide);
  font-size: 0.9rem;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}
.buy:hover { color: var(--paper); }

/* ================================================================ wall === */

.wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(8.5rem, 15vw, 12rem), 1fr));
  align-items: start;
  gap: clamp(2rem, 3.5vw, 3.25rem) clamp(1rem, 2vw, 1.75rem);
  max-width: 1500px;
  margin: 0 auto;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--rule);
}

.tile { min-width: 0; }

.tile__face--inert { cursor: default; }

.tile__face {
  position: relative;
  display: block;
  overflow: hidden;
  text-decoration: none;
  width: 100%;
  aspect-ratio: 1;
  padding: 0;
  background: var(--ground-up);
  border: 0;
  color: inherit;
  cursor: pointer;
}

/* Pinned rather than sized at 100%: a percentage height does not resolve
   against a <button>, and the playable tiles are buttons. */
.tile__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Keep a cover that has not arrived yet from spilling its alt text. */
  font-size: 0.7rem;
  color: var(--paper-dim);
}

/* Archive entries have no cover — nobody has photographed these bands. Rather
   than invent an image, the name itself becomes the face. */
.tile__name {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 0.9rem;
  font: 800 clamp(1rem, 1.9vw, 1.6rem)/0.95 var(--display);
  text-align: center;
  color: var(--paper);
  overflow-wrap: anywhere;
}
.tile--plain .tile__face {
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(232, 228, 218, 0.035) 0 1px,
      transparent 1px 7px
    ),
    var(--ground-up);
  outline: 1px solid var(--rule);
  outline-offset: -1px;
}

.tile__cue {
  position: absolute;
  left: 0.6rem;
  bottom: 0.6rem;
  width: 0;
  height: 0;
  border-left: 0.85rem solid var(--paper);
  border-top: 0.5rem solid transparent;
  border-bottom: 0.5rem solid transparent;
  opacity: 0;
  filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.7));
}
.tile__face:hover .tile__cue,
.tile__face:focus-visible .tile__cue { opacity: 1; }
.tile__face:hover .tile__art { opacity: 0.72; }

.tile.is-playing .tile__cue {
  opacity: 1;
  border-left-color: var(--paper);
}
.tile.is-playing .tile__face { outline: 2px solid var(--paper); outline-offset: 0; }

.tile__caption { padding-top: 0.7rem; }

.tile__artist {
  margin: 0;
  font: 700 1.05rem/1.15 var(--display);
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
}

.tile__release {
  margin: 0.1rem 0 0;
  font-size: 0.82rem;
  font-style: italic;
  color: var(--paper);
}

.tile__place,
.tile__credit {
  margin: 0.1rem 0 0;
  color: var(--paper-dim);
  font-size: 0.78rem;
  line-height: 1.45;
}

/* The band's own name is the way to their page. No second link, no second
   colour — the wall stays quiet enough for the covers to do the talking. */
.tile__link {
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.tile__link:hover { border-bottom-color: currentColor; }

/* How many people followed this band's link today. Deliberately not oxide —
   this is not a place money changes hands, it is a sign of life. */
.checked {
  margin: 0.45rem 0 0;
  color: var(--paper-dim);
  font-size: 0.78rem;
  font-style: italic;
}
.plinth .checked {
  margin-top: 0.9rem;
  font-size: 0.88rem;
}

.empty {
  grid-column: 1 / -1;
  max-width: var(--measure);
  color: var(--paper-dim);
}

/* ================================================================ more === */

.more {
  max-width: 1500px;
  margin: clamp(3rem, 6vw, 5rem) auto 0;
}

.more__btn {
  padding: 0.55rem 1.6rem;
  background: transparent;
  color: var(--paper);
  border: 1px solid var(--rule);
  font: 700 1.05rem/1 var(--display);
  letter-spacing: 0.04em;
  cursor: pointer;
}
.more__btn:hover { border-color: var(--paper); }
.more__btn[disabled] { color: var(--paper-dim); cursor: default; }

/* =========================================================== colophon === */

.colophon {
  max-width: var(--measure);
  margin: clamp(4rem, 8vw, 7rem) auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  color: var(--paper-dim);
  font-size: 0.8rem;
}
.colophon p { margin: 0; }

/* =============================================================== deck === */

.deck {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 10;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 1rem;
  /* Top padding clears the seek strip so it cannot swallow clicks. */
  padding: 1rem var(--gutter) 0.65rem;
  background: var(--ground-up);
  border-top: 1px solid var(--rule);
}
.deck[hidden] { display: none; }

.deck__art {
  width: 2.75rem;
  height: 2.75rem;
  object-fit: cover;
  background: var(--ground);
}
.deck__art:not([src]) { visibility: hidden; }

.deck__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.6rem;
  min-width: 0;
}
.deck__artist {
  font: 700 1.05rem/1.2 var(--display);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.deck__release {
  color: var(--paper-dim);
  font-size: 0.82rem;
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The progress line is the seek control: a 3px rule with a 14px hit area, so
   it can be clicked, dragged, and arrowed along from the keyboard. */
.deck__seek {
  --played: 0%;
  position: absolute;
  inset: 0 0 auto 0;
  width: 100%;
  height: 14px;
  margin: 0;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}
/* Not seekable until the duration is known, but it is still the progress
   readout — it must not be dimmed by the browser's disabled styling. */
.deck__seek:disabled { cursor: default; opacity: 1; }

/* The unplayed remainder has to be visible on its own: at 0% played it is the
   only thing on screen, and --rule is a divider tone, near-invisible here. */
.deck__seek::-webkit-slider-runnable-track {
  height: 4px;
  background: linear-gradient(to right, var(--paper) var(--played), var(--track) var(--played));
}
.deck__seek::-moz-range-track {
  height: 4px;
  background: linear-gradient(to right, var(--paper) var(--played), var(--track) var(--played));
}

/* A hairline marker rather than a knob — it belongs to this typeface, not to
   the operating system. Shown only when the control is in use. */
.deck__seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 2px;
  height: 11px;
  margin-top: -3px;
  border: 0;
  border-radius: 0;
  background: var(--paper);
  opacity: 0;
}
.deck__seek::-moz-range-thumb {
  width: 2px;
  height: 11px;
  border: 0;
  border-radius: 0;
  background: var(--paper);
  opacity: 0;
}
.deck__seek:hover:not(:disabled)::-webkit-slider-thumb,
.deck__seek:focus-visible::-webkit-slider-thumb { opacity: 1; }
.deck__seek:hover:not(:disabled)::-moz-range-thumb,
.deck__seek:focus-visible::-moz-range-thumb { opacity: 1; }

.deck__time {
  color: var(--paper-dim);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.deck__stop {
  padding: 0.3rem 0.9rem;
  background: transparent;
  color: var(--paper-dim);
  border: 1px solid var(--rule);
  font: 700 0.9rem/1 var(--display);
  letter-spacing: 0.04em;
  cursor: pointer;
}
.deck__stop:hover { color: var(--paper); border-color: var(--paper); }

.deck__buy {
  color: var(--oxide);
  font-size: 0.85rem;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  white-space: nowrap;
}

/* ============================================================ motion ===
   One orchestrated moment: the featured name arrives. Nothing else animates
   unless a person asked it to. */

@keyframes plinth-in {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

.plinth__artist { animation: plinth-in 900ms cubic-bezier(0.16, 0.84, 0.32, 1) both; }

.deck { transform: translateY(0); transition: transform 220ms ease-out; }
.deck.is-entering { transform: translateY(100%); }

.tile__art, .tile__cue, .chip, .buy, .tile__buy, .more__btn, .deck__stop {
  transition: opacity 160ms ease, color 160ms ease, border-color 160ms ease, background-color 160ms ease;
}

/* ======================================================== small screens === */

@media (max-width: 44rem) {
  .plinth {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
  }
  .plinth__art { max-width: 20rem; }
  .deck {
    grid-template-columns: auto minmax(0, 1fr) auto;
    row-gap: 0.45rem;
  }
  .deck__time { display: none; }
  .deck__stop { grid-column: 3; grid-row: 1; }
  .deck__buy { grid-column: 2 / -1; grid-row: 2; justify-self: start; }
}

@media (hover: none) {
  .tile__cue { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
