/* Compact Disc Club — the archive
   Styled like the web the club itself lived on: a 2010-era portal. Boxed
   light page on a striped backdrop, glossy navy header, Georgia headings over
   Verdana body text, blue underlined links, zebra tracklists, beveled buttons.
   No blur, no glass, no floating cards. */

:root {
  --page: #dfe3e8;
  --paper: #ffffff;
  --paper-2: #f4f6f8;        /* module headers, hover rows */
  --stripe: #f7f8fa;         /* zebra rows */
  --line: #b9c0c9;           /* outer box borders */
  --line-soft: #dce0e5;      /* inner rules */
  --text: #222222;
  --muted: #555e68;
  --dim: #7d858e;
  --navy: #1d3c6b;
  --navy-2: #33619e;
  --link: #1550a8;
  --link-hover: #0b3c86;
  --gold: #b8860b;           /* the club's gold, toned for paper */
  --danger: #a33c2a;
  --teal: #2c7a72;

  --radius: 3px;
  --shadow: 0 1px 4px rgba(30, 40, 55, .25);
  --player-h: 92px;

  /* Kept for app.js, which reads these for the toast. */
  --surface: #ffffff;
  --surface-2: #f4f6f8;

  --sans: Verdana, Geneva, Tahoma, "DejaVu Sans", sans-serif;
  --serif: Georgia, "Times New Roman", Times, serif;
}

* { box-sizing: border-box; }

/* The player and queue both set display:grid/flex, which would otherwise beat
   the UA rule for [hidden] and leave them laid out — invisible but still
   swallowing clicks across the page. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  color: var(--text);
  font-family: var(--sans);
  font-size: 12px;
  line-height: 1.6;
}

/* The classic tiled backdrop behind a boxed site. */
body {
  background: var(--page) repeating-linear-gradient(
    45deg, rgba(255, 255, 255, .35) 0 2px, transparent 2px 6px);
  padding-bottom: calc(var(--player-h) + 24px);
}

/* One centered column with a hard edge, like every site had. */
main, .topbar, .site-footer {
  max-width: 1100px;
  margin-left: auto;
  margin-right: auto;
}
main {
  display: block;
  min-height: 60vh;
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 0;
  box-shadow: var(--shadow);
  padding-bottom: 24px;
}

a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }
button { font: inherit; color: inherit; cursor: pointer; }
img { max-width: 100%; display: block; }

/* ------------------------------------------------------------------ topbar */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 10px 20px;
  background: linear-gradient(180deg, var(--navy-2), var(--navy));
  border: 1px solid #142a4c;
  border-top: 3px solid var(--gold);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), var(--shadow);
}

.brand { display: flex; align-items: center; gap: 10px; }
.brand:hover { text-decoration: none; }

.brand-disc {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background:
    radial-gradient(circle at 50% 50%, var(--navy) 0 18%, transparent 19%),
    conic-gradient(from 210deg, #e8c489, #8d6a2c, #f3ddb0, #7d5f2a, #e8c489);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .5);
}

.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-text strong {
  font-family: var(--serif); font-size: 17px; font-weight: 700;
  color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, .4);
}
.brand-text small {
  color: #c9d6ea; font-size: 9px; letter-spacing: .28em; text-transform: uppercase;
}

/* Tab-style navigation, sat on the header's bottom edge. */
.nav { display: flex; gap: 4px; align-self: flex-end; }
.nav a {
  color: #dbe4f2; font-size: 12px; font-weight: 700;
  padding: 6px 16px 8px;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  margin-bottom: -11px;
}
.nav a:hover { color: #fff; text-decoration: none; background: rgba(255, 255, 255, .12); }
.nav a.active {
  color: var(--navy); background: var(--paper);
  border-color: #142a4c;
  text-decoration: none;
}

.search { margin-left: auto; }
.search input {
  width: 260px; max-width: 40vw;
  padding: 5px 8px;
  background: #fff;
  border: 1px solid #7f9db9;   /* the old form-field blue-gray */
  border-radius: 2px;
  color: var(--text);
  font-family: var(--sans);
  font-size: 12px;
  outline: none;
}
.search input:focus { border-color: var(--navy-2); box-shadow: 0 0 3px rgba(51, 97, 158, .5); }
.search input::placeholder { color: #98a2ad; }

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

.wrap { padding: 0 20px; }
.section-head {
  display: flex; align-items: baseline; gap: 12px;
  margin: 26px 20px 10px;
  padding: 0 0 5px;
  border-bottom: 2px solid var(--navy-2);
}
.section-head h2 {
  font-family: var(--serif); font-size: 19px; font-weight: 700;
  color: var(--navy); margin: 0;
}
.section-head .sub { color: var(--dim); font-size: 11px; }
.section-head .count { margin-left: auto; color: var(--dim); font-size: 11px; }

.loading, .empty { padding: 70px 20px; text-align: center; color: var(--dim); }
.spinner {
  width: 24px; height: 24px; margin: 0 auto 12px;
  border: 3px solid var(--line-soft); border-top-color: var(--navy-2);
  border-radius: 50%; animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* The first paint. Every route is also rendered to plain HTML on the server so
   that crawlers running no JavaScript have something to read (cdc/seo.py), but
   that copy is a list of bare links: shown to a person it does not read as a
   page still loading, it reads as a different and worse site — for as long as
   the app takes to boot. So where there is JavaScript, hide it and show the
   same spinner every later navigation shows. The app drops the attribute the
   moment it takes over, which hands these children back to the rules above.
   With JavaScript off, .js is never set, nothing here matches, and the list
   stays exactly as the crawler sees it. */
.boot { display: none; }
.js #view[data-prerendered="1"] > .boot { display: block; }
.js #view[data-prerendered="1"] > :not(.boot) { display: none; }

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

.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 28px;
  align-items: center;
  margin: 16px 20px 6px;
  padding: 22px 24px;
  background: linear-gradient(180deg, #fdfdfe, #eef1f5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 #fff;
}
/* The blurred-cover backdrop belongs to the old skin; the featured panel is
   a plain box now, so the element is simply not shown. */
.hero-bg { display: none; }
.hero::after { content: none; }

.hero-kicker {
  color: var(--gold); font-size: 10px; font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase; margin-bottom: 8px;
}
.hero h1 {
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(22px, 3.4vw, 34px);
  line-height: 1.12; margin: 0 0 8px; color: var(--navy);
}
.hero .blurb { color: var(--muted); font-size: 12px; font-weight: 700; margin-bottom: 6px; }
.hero .notes {
  color: var(--dim); font-size: 11px; line-height: 1.7;
  max-width: 62ch; margin-bottom: 16px;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.hero-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* A photo in a frame, not a floating card. */
.hero-cover {
  aspect-ratio: 1;
  background: #fff;
  padding: 6px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}
.hero-cover img { width: 100%; height: 100%; object-fit: cover; }

.hero-dots { display: flex; gap: 5px; margin-top: 16px; }
.hero-dots button {
  width: 12px; height: 12px; border: 1px solid var(--line); padding: 0;
  border-radius: 2px;
  background: linear-gradient(180deg, #fff, #dfe3e8);
}
.hero-dots button.on { background: var(--navy-2); border-color: var(--navy); }

/* The library totals, demoted to a footnote now that the kicker above names
   the day's style instead. They also arrive after the shelf is already drawn,
   so the line has to be standing there empty first — otherwise the hero grows
   when they land and everything below it jumps. */
.hero-stats {
  margin-top: 14px; padding-top: 10px;
  border-top: 1px dotted var(--line);
  color: var(--dim); font-size: 11px; min-height: 1.2em;
}

/* ------------------------------------------------------------------ buttons */

/* The glossy bevel every 2010 site shipped. */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 14px;
  border-radius: var(--radius);
  border: 1px solid #9aa2ac;
  background: linear-gradient(180deg, #fdfdfd, #d9dde2);
  color: #333;
  font-size: 12px; font-weight: 700;
  box-shadow: inset 0 1px 0 #fff;
  text-decoration: none;
}
.btn:hover {
  background: linear-gradient(180deg, #f2f4f6, #c9cfd6);
  color: #111; text-decoration: none;
}
.btn:active { box-shadow: inset 0 2px 3px rgba(0, 0, 0, .18); }
.btn.primary {
  background: linear-gradient(180deg, #6ca1e8, #2f66c0);
  border-color: #1f4d99;
  color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45);
}
.btn.primary:hover { background: linear-gradient(180deg, #7cadee, #3a74d0); color: #fff; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* -------------------------------------------------------------------- rows */

.row { margin-bottom: 4px; }
.row-scroll {
  display: flex; gap: 12px;
  padding: 10px 20px 18px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Snap points align to the scrollport edge, which ignores padding and would
     scroll the first card flush against the window. This keeps it inset. */
  scroll-padding-left: 20px;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.row-scroll::-webkit-scrollbar { height: 10px; }
.row-scroll::-webkit-scrollbar-thumb { background: var(--line); border: 2px solid var(--paper); border-radius: 5px; }
.row-scroll > * { scroll-snap-align: start; }

/* ------------------------------------------------------------------- cards */

.card {
  width: 168px; flex: none;
  display: flex; flex-direction: column; gap: 6px;
  padding: 7px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.card:hover {
  border-color: var(--navy-2);
  box-shadow: var(--shadow);
  text-decoration: none;
}

.card-art {
  position: relative; aspect-ratio: 1;
  overflow: hidden;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
}
.card-art img { width: 100%; height: 100%; object-fit: cover; }

/* Books whose Discogs page has no artwork at all get the same silhouette
   everywhere a cover would go — card, hero and book header. */
.placeholder {
  display: grid; place-items: center;
  width: 100%; height: 100%;
  background: var(--paper-2);
  color: #c2cad3;
}
.placeholder svg { width: 58%; height: auto; }
.card-art .placeholder { position: absolute; inset: 0; }

.card-play {
  position: absolute; right: 6px; bottom: 6px;
  width: 34px; height: 34px; border-radius: var(--radius);
  border: 1px solid #1f4d99;
  background: linear-gradient(180deg, #6ca1e8, #2f66c0);
  color: #fff; font-size: 12px;
  display: none; place-items: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}
.card:hover .card-play { display: grid; }
.card-play:hover { background: linear-gradient(180deg, #7cadee, #3a74d0); }

.card-discs {
  position: absolute; top: 0; left: 0;
  background: var(--navy);
  padding: 2px 8px;
  font-size: 9px; letter-spacing: .08em; font-weight: 700; color: #fff;
}

/* Card titles read as links, the way catalogue listings did. */
.card-title {
  font-size: 12px; font-weight: 700; line-height: 1.35; color: var(--link);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card:hover .card-title { text-decoration: underline; }
.card-sub { color: var(--dim); font-size: 10px; }

/* -------------------------------------------------------------------- grid */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 14px;
  padding: 10px 20px 30px;
}
.grid .card { width: auto; }

/* ----------------------------------------------------------------- filters */

.filters {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin: 8px 20px 14px;
  padding: 8px 10px;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.filters select, .filters input {
  padding: 4px 6px; background: #fff; color: var(--text);
  border: 1px solid #7f9db9; border-radius: 2px;
  font-family: var(--sans); font-size: 12px; outline: none;
}
.filters select:focus { border-color: var(--navy-2); }
.filters .clear { color: var(--link); font-size: 11px; background: none; border: 0; text-decoration: underline; }
.filters .clear:hover { color: var(--link-hover); }

.pager { display: flex; gap: 10px; justify-content: center; align-items: center; padding: 10px 0 40px; }
.pager span { color: var(--dim); font-size: 11px; }

/* --------------------------------------------------------------- book page */

.book-head {
  position: relative;
  display: grid; grid-template-columns: 250px minmax(0, 1fr);
  gap: 24px;
  margin: 16px 20px 20px;
  padding: 20px;
  background: linear-gradient(180deg, #fdfdfe, #eef1f5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.book-head .hero-bg { display: none; }
.book-head::after { content: none; }

.book-cover {
  aspect-ratio: 1; overflow: hidden;
  background: #fff; padding: 6px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  align-self: start;
}
.book-cover img { width: 100%; height: 100%; object-fit: cover; }

.book-info h1 {
  font-family: var(--serif); font-size: clamp(20px, 3vw, 30px);
  margin: 0 0 6px; line-height: 1.15; font-weight: 700; color: var(--navy);
}
.book-meta {
  color: var(--muted); font-size: 11px; font-weight: 700; margin-bottom: 10px;
  padding-bottom: 8px; border-bottom: 1px dotted var(--line);
}
.book-notes {
  color: var(--muted); font-size: 11px; line-height: 1.7;
  max-width: 70ch; white-space: pre-wrap; margin-bottom: 14px;
}
.book-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }

/* The caveat box every reference site of the era had: a hard border and a pale
   fill, not a floating alert. Same gold as the per-track "unsure" flag it
   points at. */
.notice {
  border: 1px solid #d9c08a;
  border-left: 4px solid var(--gold);
  background: #faf5e8;
  color: #6b5a33;
  font-size: 11px; line-height: 1.7;
  padding: 8px 11px;
  margin-bottom: 14px;
  max-width: 70ch;
}
.notice strong { color: #5a4a26; }
.notice .flag { vertical-align: baseline; }

.tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 12px; }
.tag {
  font-size: 10px; padding: 2px 8px; border-radius: 2px;
  border: 1px solid var(--line-soft); color: var(--link); background: var(--paper-2);
}
.tag:hover { border-color: var(--navy-2); background: #e7edf6; text-decoration: none; }

.gallery { display: flex; gap: 8px; overflow-x: auto; padding: 4px 0 6px; }
.gallery img {
  height: 96px; width: auto; flex: none; object-fit: cover;
  background: #fff; padding: 3px; border: 1px solid var(--line);
  cursor: zoom-in;
}
.gallery img:hover { border-color: var(--navy-2); }

/* --------------------------------------------------------------- tracklist */

.disc {
  margin: 0 20px 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper);
}
/* The classic module header: gradient strip with a bold small title. */
.disc-head {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px;
  background: linear-gradient(180deg, #f5f7fa, #e2e7ee);
  border-bottom: 1px solid var(--line);
}
.disc-head h3 {
  margin: 0; font-size: 12px; font-weight: 700;
  color: var(--navy); text-transform: uppercase; letter-spacing: .05em;
}
.disc-head .n { color: var(--dim); font-size: 11px; }
.disc-head .play-disc { margin-left: auto; font-size: 11px; padding: 3px 10px; }

.track {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto auto;
  gap: 12px; align-items: center;
  padding: 5px 12px;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
}
.track:last-child { border-bottom: 0; }
.track:nth-child(even) { background: var(--stripe); }  /* zebra */
.track:hover { background: #e9f0fa; }
.track.playing { background: #dcebff; }
.track.playing .track-title { color: var(--navy); }
.track.playing .track-title::before { content: "▶ "; color: var(--gold); }
.track.unplayable { opacity: .5; cursor: default; }

.track-no { color: var(--dim); font-size: 11px; text-align: right; font-variant-numeric: tabular-nums; }
.track:hover .track-no .num { display: none; }
.track-no .go { display: none; color: var(--navy-2); }
.track:hover .track-no .go { display: inline; }
.track.unplayable:hover .track-no .num { display: inline; }
.track.unplayable:hover .track-no .go { display: none; }

.track-main { min-width: 0; }
.track-title { font-size: 12px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.track-artist { color: var(--muted); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.track-artist a { color: var(--link); }
.track-dur { color: var(--dim); font-size: 11px; font-variant-numeric: tabular-nums; }

.track-flags { display: flex; gap: 5px; align-items: center; }
.flag {
  font-size: 9px; letter-spacing: .05em; text-transform: uppercase; font-weight: 700;
  padding: 1px 6px; border-radius: 2px; border: 1px solid var(--line); color: var(--dim);
  background: var(--paper-2);
}
.flag.warn { color: var(--gold); border-color: #d9c08a; background: #faf5e8; }
.flag.off { color: var(--danger); border-color: #d3a89e; background: #f9eeec; }
.flag.pending { color: var(--dim); }
.flag.link { color: var(--teal); border-color: #9cc5c0; background: #ecf5f4; }
.flag.link:hover { text-decoration: underline; }
/* Keep the flag readable even though the row itself is dimmed. */
.track.unplayable .flag { opacity: 1; }

/* ------------------------------------------------------------------ player */

/* The one dark strip on the page, like the desktop media players of the day. */
.player {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  height: var(--player-h);
  display: grid;
  grid-template-columns: 156px minmax(140px, 1fr) auto minmax(200px, 1.4fr) auto;
  gap: 18px; align-items: center;
  padding: 0 18px;
  background: linear-gradient(180deg, #4a4f57, #23262b 60%, #191b1f);
  border-top: 1px solid #000;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14);
  color: #e8eaed;
}

/* The iframe stays on-screen: a real visible player, never a hidden one. */
.player-stage {
  position: relative; width: 156px; height: 70px;
  overflow: hidden; background: #000;
  border: 1px solid #000;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .12);
}
.player-stage iframe { width: 100%; height: 100%; border: 0; display: block; }
#sp-frame, #yt-frame { width: 100%; height: 100%; }

/* Mark the source so the difference is never a mystery. */
.player.via-spotify { border-top-color: #1db954; }
/* Spotify's compact player needs ~80px of height to render its own controls. */
.player.via-spotify { grid-template-columns: 300px minmax(140px, 1fr) auto minmax(200px, 1.4fr) auto; }
.player.via-spotify .player-stage { width: 300px; height: 80px; }
.player.via-spotify .stage-toggle { display: none; }
.player.via-spotify .player-stage { box-shadow: 0 0 0 1px rgba(29, 185, 84, .6); }
.player.via-spotify.preview-only .player-title::after {
  content: "Spotify · 30s preview";
  color: #e8c489;
  border-color: rgba(232, 196, 137, .6);
}
.player.via-spotify .player-title::after {
  content: "Spotify";
  margin-left: 8px; padding: 1px 6px; border-radius: 2px;
  font-size: 9px; letter-spacing: .07em; text-transform: uppercase;
  color: #1db954; border: 1px solid rgba(29, 185, 84, .5);
}
.stage-toggle {
  position: absolute; top: 3px; right: 3px;
  width: 20px; height: 20px; border: 1px solid rgba(255, 255, 255, .25); border-radius: 2px;
  background: rgba(0, 0, 0, .65); color: #fff;
  font-size: 10px; line-height: 1; display: grid; place-items: center;
  opacity: 0;
}
.player-stage:hover .stage-toggle { opacity: 1; }

.player.expanded { height: auto; padding-bottom: 12px; }
.player.expanded .player-stage {
  position: fixed; right: 18px; bottom: calc(var(--player-h) + 12px);
  width: min(520px, 46vw); height: min(292px, 26vw);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .6); z-index: 70;
}

.player-meta { min-width: 0; }
.player-title { font-size: 12px; font-weight: 700; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player-sub { color: #9aa1ab; font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player-sub a { color: #b9c6d8; }
.player-sub a:hover { color: #fff; }

.player-controls { display: flex; align-items: center; gap: 6px; }
.ctl {
  width: 32px; height: 32px; border-radius: var(--radius);
  border: 1px solid #14161a;
  background: linear-gradient(180deg, #5a6069, #33373d);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2);
  color: #e8eaed;
  display: grid; place-items: center; font-size: 11px;
}
.ctl:hover { background: linear-gradient(180deg, #6a707a, #3d424a); }
.ctl:active { box-shadow: inset 0 2px 3px rgba(0, 0, 0, .5); }
.ctl.play {
  width: 40px; height: 40px; font-size: 13px;
  background: linear-gradient(180deg, #6ca1e8, #2f66c0);
  border-color: #1f4d99; color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4);
}
.ctl.play:hover { background: linear-gradient(180deg, #7cadee, #3a74d0); }
.ctl.ghost { border-color: transparent; background: none; box-shadow: none; color: #8b929c; }
.ctl.ghost:hover { color: #fff; }
.ctl.ghost.on { color: #7cadee; }

.player-progress { display: flex; align-items: center; gap: 10px; }
.player-progress .t { color: #9aa1ab; font-size: 10px; font-variant-numeric: tabular-nums; min-width: 34px; }
.player-progress .t:last-child { text-align: right; }

#seek, #vol {
  -webkit-appearance: none; appearance: none;
  flex: 1; height: 6px; border-radius: 3px;
  background: linear-gradient(180deg, #14161a, #2b2f35);
  border: 1px solid #000;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .6);
  outline: none;
}
#seek::-webkit-slider-thumb, #vol::-webkit-slider-thumb {
  -webkit-appearance: none; width: 13px; height: 13px; border-radius: 2px;
  background: linear-gradient(180deg, #fdfdfd, #c9cfd6);
  border: 1px solid #666; cursor: pointer;
}
#seek::-moz-range-thumb, #vol::-moz-range-thumb {
  width: 12px; height: 12px; border: 1px solid #666; border-radius: 2px;
  background: linear-gradient(180deg, #fdfdfd, #c9cfd6); cursor: pointer;
}

/* Volume: a short slider next to the transport, like every player of the era. */
.volume { display: flex; align-items: center; gap: 5px; }
#vol { flex: none; width: 74px; }
#btn-mute { width: 24px; height: 24px; font-size: 12px; }
#btn-mute.muted { color: #e8c489; }
/* Spotify's embed exposes no volume command; dim rather than pretend. */
.volume.na { opacity: .35; }
.volume.na #vol, .volume.na #btn-mute { pointer-events: none; }

.player-side { display: flex; align-items: center; gap: 6px; }
.chip {
  font-size: 10px; font-weight: 700; padding: 3px 9px; border-radius: 2px;
  border: 1px solid #4a505a; color: #b9c0c9; white-space: nowrap;
  background: rgba(255, 255, 255, .05);
}
.chip:hover { border-color: #8b929c; color: #fff; text-decoration: none; }
.chip.hidden { display: none; }

/* ------------------------------------------------------------------- queue */

.queue-panel {
  position: fixed; right: 0; bottom: var(--player-h); top: 0; z-index: 55;
  width: 320px; max-width: 92vw;
  background: var(--paper); border-left: 1px solid var(--line);
  display: flex; flex-direction: column;
  box-shadow: -3px 0 12px rgba(30, 40, 55, .3);
}
.queue-panel header {
  display: flex; align-items: center; padding: 9px 14px;
  background: linear-gradient(180deg, var(--navy-2), var(--navy));
  border-bottom: 1px solid #142a4c;
}
.queue-panel h3 {
  margin: 0; font-size: 12px; font-weight: 700; color: #fff;
  text-transform: uppercase; letter-spacing: .06em;
}
.queue-panel header button { margin-left: auto; background: none; border: 0; color: #c9d6ea; }
.queue-panel header button:hover { color: #fff; }
.queue-panel ol { list-style: none; margin: 0; padding: 4px 0; overflow-y: auto; flex: 1; }
.queue-panel li {
  display: flex; gap: 10px; align-items: center;
  padding: 6px 14px; cursor: pointer; font-size: 11px;
  border-bottom: 1px solid var(--line-soft);
}
.queue-panel li:nth-child(even) { background: var(--stripe); }
.queue-panel li:hover { background: #e9f0fa; }
.queue-panel li.on { background: #dcebff; }
.queue-panel li.on .q-title { color: var(--navy); font-weight: 700; }
.queue-panel li.off { opacity: .5; }
.q-num { color: var(--dim); font-size: 10px; min-width: 20px; font-variant-numeric: tabular-nums; }
.q-body { min-width: 0; }
.q-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.q-artist { color: var(--dim); font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------------------------------------------------------- lightbox */

.lightbox {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(20, 24, 30, .85);
  display: grid; place-items: center; padding: 40px;
}
.lightbox img {
  max-width: 92vw; max-height: 88vh;
  background: #fff; padding: 8px; border: 1px solid #000;
  box-shadow: 0 4px 24px rgba(0, 0, 0, .7);
}

/* ---------------------------------------------------------------- results */

.result-list { padding: 0 20px 24px; }
.result-row {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: 12px; align-items: center; padding: 6px 10px;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
}
.result-row:nth-child(even) { background: var(--stripe); }
.result-row:hover { background: #e9f0fa; }
.result-row img { width: 44px; height: 44px; object-fit: cover; border: 1px solid var(--line-soft); }
.result-row .ph { width: 44px; height: 44px; background: var(--paper-2); border: 1px solid var(--line-soft); }
.result-row.unplayable { opacity: .5; cursor: default; }

.artist-chips { display: flex; flex-wrap: wrap; gap: 7px; padding: 4px 20px 20px; }

.site-footer {
  padding: 16px 20px 26px;
  color: var(--dim); font-size: 10px; line-height: 1.8;
  text-align: center;
}
.site-footer p { margin: 0 auto; max-width: 82ch; }
/* The build stamp, in the small print where a 2010 site would have put it. */
.site-footer .version {
  margin-top: 8px; letter-spacing: .06em; text-transform: uppercase;
  font-size: 9px; color: var(--dim); opacity: .8;
}

/* ------------------------------------------------------- source preference */

.source-pref {
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: center; justify-content: center;
  margin: 0 auto 14px;
  padding: 8px 12px;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  width: fit-content; max-width: 100%;
}
.source-pref-label { font-size: 11px; font-weight: 700; color: var(--muted); }
.source-pref-note { font-size: 10px; color: var(--dim); }
/* Spotify chosen, but this browser only gets clips out of it. */
.source-pref:has(.segmented.warn) { border-color: #d9c08a; background: #faf5e8; }
.segmented.warn ~ .source-pref-note { color: var(--danger); font-weight: 700; }

/* Joined beveled buttons; the chosen one reads as pressed in. */
.segmented { display: inline-flex; }
.segmented button {
  padding: 4px 14px;
  font-size: 11px; font-weight: 700;
  color: #333;
  background: linear-gradient(180deg, #fdfdfd, #d9dde2);
  border: 1px solid #9aa2ac;
  box-shadow: inset 0 1px 0 #fff;
}
.segmented button + button { border-left: 0; }
.segmented button:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.segmented button:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.segmented button:hover { background: linear-gradient(180deg, #f2f4f6, #c9cfd6); }
.segmented button.on {
  background: linear-gradient(180deg, #2f66c0, #6ca1e8);
  border-color: #1f4d99; color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .3);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .3);
}
.segmented button.on + button { border-left: 1px solid #1f4d99; }

.install-box {
  display: flex; flex-wrap: wrap; gap: 10px;
  align-items: center; justify-content: center;
  margin: 0 auto 14px;
  width: fit-content; max-width: 100%;
}
.install-note { font-size: 10px; color: var(--dim); }

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

@media (max-width: 1100px) {
  main, .topbar { border-left: 0; border-right: 0; }
  /* .player.via-spotify outranks a bare .player, and a media query adds no
     specificity — every rule here must carry the via-spotify variant too, or
     the desktop's 300px-stage grid wins on phones and overflows the screen.

     Nothing shares a row with the transport buttons: five of them need
     ~190px, which a phone cannot spare next to a stage and a title. Each
     part gets a full-width row instead — only stage + title sit together. */
  .player, .player.via-spotify {
    grid-template-columns: 110px minmax(0, 1fr);
    row-gap: 8px; height: auto; padding: 10px 14px;
  }
  .player-stage { width: 110px; height: 62px; }
  /* Spotify's compact embed keeps its ~80px height but gets its own full-width
     row instead of a fixed 300px column. */
  .player.via-spotify { grid-template-columns: minmax(0, 1fr); }
  .player.via-spotify .player-stage { grid-column: 1 / -1; width: 100%; height: 80px; }
  .player-controls { grid-column: 1 / -1; justify-content: center; }
  .player-progress { grid-column: 1 / -1; }
  /* Volume, the two source links and the queue button share this row; on a
     narrow phone they wrap rather than push the bar off the screen. */
  .player-side { grid-column: 1 / -1; justify-content: flex-end; flex-wrap: wrap; }
  body { padding-bottom: 250px; }
}

@media (max-width: 860px) {
  .topbar { flex-wrap: wrap; gap: 10px; padding: 10px 14px; }
  .nav { align-self: center; }
  .nav a { margin-bottom: 0; border-radius: var(--radius); }
  .nav a.active { border-color: transparent; }
  .search { margin-left: 0; width: 100%; }
  .search input, .search input:focus { width: 100%; max-width: none; }
  .hero { grid-template-columns: 1fr; margin: 12px; padding: 16px; }
  .hero-cover { max-width: 220px; }
  .book-head { grid-template-columns: 1fr; gap: 18px; margin: 12px; padding: 14px; }
  .book-cover { max-width: 200px; }
  .wrap, .row-scroll, .grid, .result-list, .artist-chips { padding-left: 12px; padding-right: 12px; }
  .section-head, .filters { margin-left: 12px; margin-right: 12px; }
  .row-scroll { scroll-padding-left: 12px; }
  .disc { margin: 0 12px 20px; }
  .track { grid-template-columns: 30px minmax(0, 1fr) auto; }
  .track-flags { display: none; }
}
