/* components.css — Song of the Week
 * Shared UI components used across screens. Reference these by class name
 * from Go templates. */

/* ══════════════════════════════════════════════════════════
 * NAV
 * ══════════════════════════════════════════════════════════ */

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 0;
}
.nav__brand {
  display: flex;
  align-items: center;
  gap: 10px;
}
.nav__logo {
  font-family: var(--font-display);
  font-size: 28px;
  color: var(--accent);
  line-height: 1;
}
.nav__tag {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  color: var(--dim);
  letter-spacing: var(--ls-mono-sm);
}
.nav__links {
  display: flex;
  gap: 18px;
  align-items: center;
}
.nav__item {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--ink);
  text-decoration: underline;
  white-space: nowrap;
  /* 24px pointer-target floor (WCAG 2.2 SC 2.5.8) without changing the
     visual density — the link box grows, the glyphs don't. */
  padding: 6px 7px;
}
.nav__item.is-active {
  color: var(--accent);
  font-weight: 700;
  text-decoration: none;
}
.nav__bell {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 32px;
  padding: 6px 7px;
  text-decoration: none;
}

/* ─── Nav at phone widths ───
   The "/ song of the week /" tagline is decorative, and at <760px it wrapped
   into a five-line vertical stack that ate the entire header. Drop it and
   close the link gutter rather than letting the row wrap. Each link already
   carries 7px of inline padding, so the visual gutter stays legible at
   gap: 0. */
@media (max-width: 760px) {
  .nav__tag { display: none; }
  .nav__links { gap: 0; }
}
@media (max-width: 380px) {
  .nav__item, .nav__bell { padding-inline: 5px; }
  .nav__logo { font-size: 24px; }
}
.nav__bell-count {
  background: var(--accent);
  color: var(--paper);
  padding: 1px 5px;
  font-size: var(--fs-micro-xs);
}
.nav__theme {
  appearance: none;
  background: transparent;
  border: none;
  padding: 4px;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  cursor: pointer;
  line-height: 1;
}
.nav__theme:hover { color: var(--accent); }
.nav__theme:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.svc-icon { fill: currentColor; }
.nav__theme .svc-icon { width: 16px; height: 16px; display: block; }

/* ══════════════════════════════════════════════════════════
 * WEB RING STRIP (dashboard top bar)
 * ══════════════════════════════════════════════════════════ */

.webring {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--ink);
  color: var(--paper);
  padding: 7px var(--sp-8);
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  letter-spacing: var(--ls-mono-sm);
  margin: 0 calc(var(--sp-8) * -1);  /* escape page padding */
}
.webring__title { color: var(--tertiary); }
.webring__subtitle { opacity: 0.75; }
.webring__visitor-count {
  background: var(--accent);
  color: var(--paper);
  padding: 1px 5px;
}

/* ══════════════════════════════════════════════════════════
 * PIXEL RULE
 * ══════════════════════════════════════════════════════════ */

.pixel-rule {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: var(--sp-6) 0 var(--sp-4);
}
.pixel-rule::before,
.pixel-rule::after {
  content: "";
  flex: 1;
  height: 2px;
  background: var(--ink);
  image-rendering: pixelated;
}
.pixel-rule[data-ornament]::after,
.pixel-rule[data-ornament]::before { /* rules */ }
.pixel-rule__ornament {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  color: var(--ink);
  letter-spacing: var(--ls-mono-lg);
}

/* ══════════════════════════════════════════════════════════
 * MARQUEE CHIP << text >>
 * ══════════════════════════════════════════════════════════ */

.chip-marquee {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  border: var(--border-width) solid var(--accent);
  background: transparent;
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  letter-spacing: var(--ls-mono-sm);
  color: var(--accent);
  white-space: nowrap;
}
.chip-marquee::before { content: "<<"; }
.chip-marquee::after  { content: ">>"; }

.chip-marquee.is-filled {
  background: var(--accent);
  color: var(--paper);
}

/* ══════════════════════════════════════════════════════════
 * CARD
 * ══════════════════════════════════════════════════════════ */

.card {
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  padding: var(--sp-4);
}
.card--flat { box-shadow: none; }
.card--dashed { border-style: dashed; }
.card--inverse {
  background: var(--accent);
  color: var(--paper);
}
.card--inverse .stamp { color: rgba(255,255,255,0.85); }

/* ══════════════════════════════════════════════════════════
 * BUTTONS
 * ══════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--paper);
  color: var(--ink);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-sans);
  font-size: var(--fs-body-sm);
  font-weight: 700;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: transform 80ms ease, box-shadow 80ms ease;
  text-decoration: none;
}
.btn:hover { transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--ink); }
.btn:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--ink); }

.btn--primary   { background: var(--accent);   color: var(--paper); }
.btn--secondary { background: var(--accent-2); color: var(--paper); }
.btn--ghost {
  background: transparent;
  border-width: var(--border-width);
  box-shadow: none;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 400;
  padding: 8px 12px;
}
.btn--ghost:hover { transform: none; box-shadow: none; color: var(--accent); }

.btn--sm { padding: 6px 12px; font-size: var(--fs-body-sm); }
.btn--lg { padding: 12px 22px; font-size: var(--fs-body-lg); box-shadow: var(--shadow-card); }

.btn--full { width: 100%; }

/* Disabled / waiting */
/* "waiting" is a state, not a disabled control — it still has to be
   readable. --dim is already the de-emphasis; stacking 0.6 opacity on top
   took it to 2.4:1. */
.btn--waiting {
  background: transparent;
  color: var(--dim);
  border-style: dashed;
  cursor: default;
}

/* ══════════════════════════════════════════════════════════
 * 88×31 WEB BUTTON
 * Used in footers. Render as <a class="btn-88x31">…</a> wrapping an SVG,
 * or use a background-image if you prefer.
 * ══════════════════════════════════════════════════════════ */

.btn-88x31 {
  display: inline-block;
  width: 88px;
  height: 31px;
  position: relative;
  image-rendering: pixelated;
}
.btn-88x31 svg { display: block; width: 100%; height: 100%; }

/* ══════════════════════════════════════════════════════════
 * AVATAR (2-letter initials square)
 * ══════════════════════════════════════════════════════════ */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: var(--avatar-bg, var(--tertiary));
  /* --tertiary and --soft stay light in both themes, so text on them must
     stay dark in both. --paper flips, and put 1.5:1 light-on-light
     initials on every default avatar in dark mode. */
  color: var(--on-fill);
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  font-weight: 700;
  letter-spacing: 0;
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-sm);
  border-radius: 2px;
}
.avatar--xs { width: 14px; height: 14px; font-size: 8px; box-shadow: none; border-width: 1px; }
.avatar--sm { width: 24px; height: 24px; font-size: var(--fs-micro-xs); }
.avatar--md { width: 40px; height: 40px; font-size: 12px; box-shadow: 2px 2px 0 var(--ink); }
.avatar--lg { width: 48px; height: 48px; font-size: 14px; box-shadow: 2px 2px 0 var(--ink); }
.avatar--xl { width: 96px; height: 96px; font-size: 28px; box-shadow: 3px 3px 0 var(--ink); }

/* The accent tints DO flip with the theme, so these two keep --paper. */
.avatar--you { background: var(--accent); color: var(--paper); }
.avatar--accent-2 { background: var(--accent-2); color: var(--paper); }
.avatar--tertiary { background: var(--tertiary); color: var(--on-fill); }

/* .avatar--image replaces the initials span with a user-uploaded image
   using the same square box. object-fit: cover keeps the face/logo
   centered inside the square even if the server-side crop left any
   slack (it shouldn't, since ProcessAvatar pre-crops, but defence in
   depth is cheap here). */
.avatar--image {
  padding: 0;
  overflow: hidden;
  background: var(--tertiary);
  object-fit: cover;
  object-position: center;
}

/* ══════════════════════════════════════════════════════════
 * AVATAR + VOTED BADGE (group page voter row)
 * ══════════════════════════════════════════════════════════ */

.voter {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.voter__avatar-wrap { position: relative; }
.voter__voted-badge {
  position: absolute;
  bottom: -4px;
  right: -4px;
  width: 18px;
  height: 18px;
  border-radius: 9px;
  background: var(--soft);
  border: var(--border-width) solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-micro-sm);
  color: var(--on-fill);
  color: var(--ink);
  font-weight: 700;
}
.voter__name {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  color: var(--ink);
}
.voter--you .voter__name { font-weight: 700; }
/* Same reasoning as the standings avatars: desaturate rather than fade,
   so a pending member's initials stay legible against their own tile. */
.voter:not(.is-voted) .avatar { filter: saturate(0.25); }
.voter:not(.is-voted) .voter__name { color: var(--dim); }

/* ══════════════════════════════════════════════════════════
 * ART TILE — procedural album art placeholders
 * Four variants via modifier class. Override with background-image inline
 * when a real album cover is available:
 *   <div class="art-tile" style="background-image:url(/covers/xyz.jpg);">
 * ══════════════════════════════════════════════════════════ */

.art-tile {
  width: 110px;
  height: 110px;
  background: var(--paper-hi);
  background-size: cover;
  background-position: center;
  border: var(--border-width) solid var(--ink);
  position: relative;
  overflow: hidden;
}
.art-tile--sm  { width: 56px;  height: 56px; }
.art-tile--md  { width: 130px; height: 130px; }
.art-tile--lg  { width: 160px; height: 160px; }
.art-tile--xl  { width: 180px; height: 180px; }
.art-tile--xxl { width: 190px; height: 190px; }

.art-tile__label {
  position: absolute;
  bottom: 3px;
  left: 4px;
  font-family: var(--font-mono);
  font-size: 8px;
  background: var(--paper-hi);
  padding: 1px 4px;
  color: var(--ink);
}

/* Four procedural variants — only show when no background-image is set */
.art-tile--v0::before,
.art-tile--v0::after,
.art-tile--v1::before,
.art-tile--v1::after,
.art-tile--v2::before,
.art-tile--v2::after,
.art-tile--v3::before,
.art-tile--v3::after {
  content: "";
  position: absolute;
  mix-blend-mode: multiply;
  opacity: 0.85;
}

/* v0 — concentric circles */
.art-tile--v0::before { inset: 22%; border-radius: 50%; background: var(--accent); }
.art-tile--v0::after  { inset: 32%; border-radius: 50%; background: var(--accent-2); }
/* v1 — diagonal + square */
.art-tile--v1::before {
  inset: 0; background: var(--accent-2);
  clip-path: polygon(0 0, 70% 0, 100% 100%, 0 100%);
  opacity: 0.78;
}
.art-tile--v1::after { top: 22%; right: 20%; width: 45%; height: 45%; background: var(--accent); }
/* v2 — stacked bars */
.art-tile--v2::before { top: 18%; left: 20%; right: 20%; bottom: 52%; background: var(--accent); }
.art-tile--v2::after  { top: 48%; left: 18%; right: 18%; bottom: 20%; background: var(--accent-2); }
/* v3 — rotated diamonds */
.art-tile--v3::before { inset: 26%; background: var(--accent-2);  transform: rotate(45deg); }
.art-tile--v3::after  { inset: 34%; background: var(--accent);    transform: rotate(45deg); }

/* Hide procedural shapes when a real image is set */
.art-tile[style*="background-image"]::before,
.art-tile[style*="background-image"]::after { display: none; }

/* ══════════════════════════════════════════════════════════
 * THEME BAND (group page hero + vote page compact)
 * ══════════════════════════════════════════════════════════ */

.theme-band {
  background: var(--accent);
  color: var(--paper);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  padding: 14px 18px;
  display: flex;
  align-items: center;
  gap: 18px;
}
.theme-band__label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  letter-spacing: var(--ls-mono-lg);
  line-height: 1.1;
}
.theme-band__body {
  flex: 1;
  border-left: 1px solid rgba(255, 255, 255, 0.35);
  padding-left: 18px;
}
.theme-band__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-lg);
  line-height: 1;
}
.theme-band__meta {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  margin-top: 3px;
}
.theme-band__round {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  letter-spacing: var(--ls-mono-sm);
  text-align: right;
  line-height: 1.2;
}

/* Submit-next band — overlapping submit/vote: the next round's submission
   window is open while an earlier round is still being voted on. Teal
   (accent-2) to read as "submit" and stay visually distinct from the theme
   band's accent. Mirrors .theme-band's structure. */
.submit-band {
  background: var(--accent-2);
  color: var(--paper);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  padding: 12px 18px;
  margin-top: 14px;
  display: flex;
  align-items: center;
  gap: 18px;
}
.submit-band__label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  letter-spacing: var(--ls-mono-lg);
  line-height: 1.1;
}
.submit-band__body {
  flex: 1;
  border-left: 1px solid rgba(255, 255, 255, 0.35);
  padding-left: 18px;
}
.submit-band__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  line-height: 1.05;
}
.submit-band__meta {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  margin-top: 3px;
}
@media (max-width: 600px) {
  .submit-band { padding: 12px 14px; gap: 8px; flex-wrap: wrap; }
  .submit-band__body { border-left: none; padding-left: 0; flex-basis: 100%; }
  .submit-band .btn { width: 100%; justify-content: center; }
}

/* Compact (vote page) */
.theme-band--compact {
  padding: 8px 14px;
  box-shadow: var(--shadow-btn);
}
.theme-band--compact .theme-band__body { border-left: none; padding-left: 0; display: flex; align-items: center; gap: 14px; }
.theme-band--compact .theme-band__title { font-size: var(--fs-display-md); }

@media (max-width: 600px) {
  .theme-band {
    padding: 12px 14px;
    gap: 8px;
    flex-wrap: wrap;
  }
  .theme-band__body { border-left: none; padding-left: 0; flex-basis: 100%; }
  .theme-band__title { font-size: var(--fs-display-md); }
  .theme-band__round { font-size: var(--fs-micro-xs); }
}

/* ══════════════════════════════════════════════════════════
 * VOTE CARD
 * ══════════════════════════════════════════════════════════ */

.vote-card {
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card-lg);
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
}
.vote-card.is-picked { box-shadow: var(--shadow-card-lg-accent); }

.vote-card__tag {
  position: absolute;
  top: -11px;
  left: 16px;
  background: var(--paper);
  padding: 0 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-lg);
  font-weight: 700;
  color: var(--ink);
}
.vote-card.is-picked .vote-card__tag { color: var(--accent); }

.vote-card__head {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 16px;
  align-items: start;
}
.vote-card__title {
  font-family: var(--font-display);
  font-size: 28px;
  line-height: 1.05;
  letter-spacing: var(--ls-display);
  margin: 0;
}
.vote-card__artist {
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  color: var(--dim);
  margin-top: 2px;
}

.vote-card__divider {
  border-top: 1px dotted var(--ink);
}

/* Pick CTA */
.pick-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 16px;
  background: var(--paper);
  color: var(--ink);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.5px;
  cursor: pointer;
  user-select: none;
}
.pick-cta__bullet {
  width: 16px;
  height: 16px;
  border: 2px solid var(--ink);
  border-radius: 8px;
  background: transparent;
}
.pick-cta.is-picked {
  background: var(--accent);
  color: var(--paper);
}
.pick-cta.is-picked .pick-cta__bullet {
  background: var(--paper);
  border-color: var(--paper);
}

/* Rating row */
.rating {
  display: flex;
  align-items: center;
  gap: 4px;
}
.rating__end {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  color: var(--dim);
  letter-spacing: var(--ls-mono-sm);
  padding: 0 4px;
}
.rating__btn {
  width: 22px;
  height: 22px;
  border: var(--border-width) solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  cursor: pointer;
  padding: 0;
}
.rating__btn.is-on { background: var(--ink); color: var(--paper); }

/* Comment chip */
.comment-chip {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--dim);
  padding: 6px 10px;
  border: 1px dashed var(--line);
  cursor: pointer;
}

/* `vs` separator between two vote cards */
.vs {
  align-self: center;
  font-family: var(--font-display);
  font-size: 48px;
  color: var(--dim);
  letter-spacing: var(--ls-mono-lg);
  transform: translateY(30px);
}

/* ══════════════════════════════════════════════════════════
 * MATCHUP PROGRESS BAR (segmented)
 * ══════════════════════════════════════════════════════════ */

.matchup-progress {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-3) 0;
  padding: var(--sp-2) 0;
}
.matchup-progress__label {
  flex-shrink: 0;
  letter-spacing: var(--ls-mono-lg);
}
.matchup-progress__list {
  display: flex;
  gap: 8px;
  list-style: none;
  margin: 0;
  /* padding-top + padding-right reserve room inside the scroll viewport
   * so the check overlay (top:-6px, right:-6px) doesn't get clipped by
   * the auto overflow-y that overflow-x:auto silently turns on. */
  padding: 8px 8px 0 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.matchup-progress__list > li { scroll-snap-align: start; }
.matchup-progress__chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: var(--paper);
  color: var(--ink);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 15px;
  text-decoration: none;
  transition: transform 60ms ease, box-shadow 60ms ease;
}
.matchup-progress__chip:hover {
  transform: translate(-1px, -1px);
  box-shadow: 4px 4px 0 var(--ink);
}
.matchup-progress__chip.is-done {
  background: var(--ink);
  color: var(--paper);
}
.matchup-progress__chip.is-current {
  background: var(--accent);
  color: var(--paper);
  transform: translate(-1px, -1px);
  box-shadow: 4px 4px 0 var(--ink);
}
/* Shared "pick check" — used on matchup chips, picked vote-cards, and
 * picked A/B tabs so the same teal corner badge means "you voted for
 * this" everywhere on the page. */
.pick-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  background: var(--accent-2);
  color: var(--paper);
  border: 1px solid var(--ink);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
}
.matchup-progress__check {
  position: absolute;
  top: -6px;
  right: -6px;
}

/* ══════════════════════════════════════════════════════════
 * GROUP CARD (dashboard)
 * ══════════════════════════════════════════════════════════ */

.group-card {
  position: relative;
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 14px;
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: inherit;
}
.group-card.is-urgent {
  box-shadow: var(--shadow-card-accent);
  border-color: var(--accent);
}
/* Pinned "ACTION" notch in the ink-stamp family, mirroring .vote-card__tag.
   Sits above the card's hit-area overlay via z-index so it stays clickable
   and doesn't capture the card's own click target. */
.group-card.is-urgent::before {
  content: "ACTION";
  position: absolute;
  top: -9px;
  left: 12px;
  z-index: 3;
  background: var(--accent);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  font-weight: 700;
  letter-spacing: var(--ls-mono-lg);
  padding: 2px 7px;
  border: var(--border-width) solid var(--ink);
  text-transform: uppercase;
  pointer-events: none;
}

.group-card__avatar {
  width: 64px; height: 64px;
  background: var(--accent-2);
  color: var(--paper);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-size: 26px;
  border: var(--border-width) solid var(--ink);
}
.group-card.is-urgent .group-card__avatar { background: var(--accent); }
/* Image variant used when the group has uploaded a custom avatar — same
   64x64 square, but the <img> fills the box edge-to-edge. Urgent-state
   background isn't needed here because the image fully covers it. */
.group-card__avatar--image {
  padding: 0;
  overflow: hidden;
  object-fit: cover;
  object-position: center;
}

.group-card__meta { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.group-card__name-row {
  display: flex; align-items: baseline; gap: 8px;
}
.group-card__name {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
}
.group-card__gloss {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--dim);
}
.group-card__actions {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-top: 4px;
}
.group-card__progress {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  color: var(--dim);
  margin-left: auto;
}

/* ══════════════════════════════════════════════════════════
 * MATCHUP THREAD (round results page)
 * ══════════════════════════════════════════════════════════ */

.matchup-thread {
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  padding: 14px;
  margin-bottom: 16px;
}
.matchup-thread__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 8px;
}
.matchup-thread__tag {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  letter-spacing: var(--ls-mono-lg);
  color: var(--accent);
  font-weight: 700;
}
.matchup-thread__tracks {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 10px;
}
.matchup-thread__track {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 10px;
}
.matchup-thread__track.is-loser { opacity: 0.55; }
.matchup-thread__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
  line-height: 1;
}
.badge-won {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 8px;
  background: var(--soft);
  color: var(--on-fill);
  padding: 1px 5px;
  letter-spacing: var(--ls-mono-sm);
  font-weight: 700;
}

/* Pick-split bar */
.pick-split {
  display: flex;
  height: 8px;
  border: 1px solid var(--ink);
  margin-bottom: 12px;
}
.pick-split__seg { height: 100%; }
.pick-split__seg--winner { background: var(--accent); }
.pick-split__seg--loser  { background: var(--line); border-left: 1px solid var(--ink); }

/* Thread comments */
.thread {
  border-top: 1px dotted var(--ink);
  padding-top: 10px;
}
.thread__head {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  letter-spacing: var(--ls-mono-lg);
  color: var(--dim);
  margin-bottom: 8px;
}
.thread__comment {
  display: grid;
  grid-template-columns: 32px 1fr auto;
  gap: 10px;
  margin-bottom: 10px;
  align-items: start;
}
.thread__comment-name-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.thread__you-tag {
  font-family: var(--font-mono);
  font-size: 8px;
  color: var(--accent);
  margin-left: 4px;
}
.thread__pick-line {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  letter-spacing: var(--ls-mono-sm);
  color: var(--dim);
}
.thread__pick-line.is-winner { color: var(--accent); }
.thread__text {
  font-size: var(--fs-body-sm);
  margin-top: 2px;
  line-height: 1.35;
  color: var(--ink);
}
.thread__time {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  color: var(--dim);
}

/* Reactions */
.reactions {
  display: flex;
  gap: 6px;
  margin-top: 4px;
}
.reaction {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--dim);
  cursor: pointer;
}
.reaction__symbol { color: var(--accent); }
.reaction.is-mine { background: var(--paper-hi); border-color: var(--accent); }

.add-take {
  margin-top: 6px;
  padding: 8px 10px;
  border: 1px dashed var(--line);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--dim);
  cursor: pointer;
}

/* ══════════════════════════════════════════════════════════
 * COUNTDOWN
 * ══════════════════════════════════════════════════════════ */

.countdown {
  font-family: var(--font-display);
  font-size: 48px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: 0;
}
.countdown--md { font-size: 38px; }
.countdown--sm { font-size: var(--fs-display-md); }

/* ══════════════════════════════════════════════════════════
 * MOBILE VOTE
 * ══════════════════════════════════════════════════════════ */

@media (max-width: 600px) {
  .page { padding: 0 var(--sp-3); }
  .vote-layout { display: flex; flex-direction: column; }
  .vote-card__head { grid-template-columns: 1fr; }
  .vote-card { box-shadow: var(--shadow-card); }
  .vs { display: none; }
}

/* AB tabs (mobile vote) */
.ab-tabs {
  display: flex;
  gap: 6px;
  padding: 10px 0 6px;
}
.ab-tabs__btn {
  flex: 1;
  padding: 9px 8px;
  background: var(--paper-hi);
  color: var(--ink);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
  font-weight: 700;
  letter-spacing: var(--ls-mono-lg);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.ab-tabs__btn.is-active {
  background: var(--ink);
  color: var(--paper);
  box-shadow: none;
}
.ab-tabs__pick-pill {
  background: var(--accent);
  color: var(--paper);
  font-size: 8px;
  padding: 1px 4px;
  letter-spacing: var(--ls-mono-sm);
}

/* ══════════════════════════════════════════════════════════
 * FOOTER
 * ══════════════════════════════════════════════════════════ */

.footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-top: var(--border-width) solid var(--ink);
}
.footer__note {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  color: var(--dim);
}
.footer__buttons { display: flex; gap: 6px; }

/* Geocities 88×31 buttons are a retro artifact but unreadable on phones.
   At narrow widths they scale up so the tap targets meet platform minimums
   — but a flat 132px each put three buttons plus gaps at 408px, which was
   wider than a 390px phone and made *every* page scroll sideways. Sizing
   them as a share of the row keeps the intent without the overflow; the
   SVG viewBox handles the rest. */
@media (max-width: 560px) {
  .btn-88x31 {
    width: min(132px, calc((100% - 20px) / 3));
    height: auto;
    aspect-ratio: 88 / 31;
  }
  .footer__buttons { gap: 10px; width: 100%; justify-content: center; }
  .footer {
    flex-wrap: wrap;
    gap: var(--sp-3);
    justify-content: center;
  }
}

/* ══════════════════════════════════════════════════════════
 * PUSH BANNER
 * "Enable notifications" nudge rendered above the main page
 * body. Hidden by default; push.js reveals it based on the
 * current permission + subscription state.
 * ══════════════════════════════════════════════════════════ */
.push-banner[hidden] { display: none; }
.push-banner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-3) var(--sp-4);
  margin: var(--sp-3) 0;
  border: var(--border-width) solid var(--ink);
  background: var(--paper-hi);
  box-shadow: var(--shadow-card);
}
.push-banner__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.push-banner__title { font-family: var(--font-display); font-size: var(--fs-display-sm); }
.push-banner__copy  { color: var(--ink); opacity: 0.85; font-size: var(--fs-body-lg); }
.push-banner__actions { display: flex; gap: var(--sp-2); align-items: center; flex-shrink: 0; }
.push-banner__dismiss {
  background: transparent;
  border: 0;
  color: var(--dim);
  padding: 6px 8px;
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  cursor: pointer;
}
.push-banner__dismiss:hover { color: var(--accent); }

/* ══════════════════════════════════════════════════════════
 * GLOBAL EVENT — "The Song of the Week" spotlight & winner card
 * Shown above the group grid on the dashboard, and on the
 * public landing for "last week's winner".
 * ══════════════════════════════════════════════════════════ */
.global-spotlight {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-4);
  margin: var(--sp-3) 0;
  border: var(--border-width) solid var(--ink);
  background: var(--paper-hi);
  box-shadow: var(--shadow-card);
}
.global-spotlight.is-urgent {
  box-shadow: var(--shadow-card-accent, var(--shadow-card));
  border-color: var(--accent);
}
.global-spotlight__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-3);
}
.global-spotlight__theme {
  margin: 0;
  font-style: italic;
}
.global-spotlight__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  align-items: flex-start;
}
.global-spotlight__copy { margin: 0; }
.global-spotlight__foot {
  border-top: 1px dashed var(--ink-soft, var(--dim));
  padding-top: var(--sp-2);
}
.global-spotlight--muted {
  display: flex;
  gap: var(--sp-3);
  justify-content: space-between;
  align-items: center;
  padding: var(--sp-2) var(--sp-3);
  margin: var(--sp-2) 0;
  border: 1px dashed var(--ink-soft, var(--dim));
  background: transparent;
  box-shadow: none;
}

/* Winner card used on public landing + spotlight + /sotw page. */
.global-winner-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3);
}
.global-winner-card__body {
  display: flex;
  gap: var(--sp-3);
  align-items: center;
}
.global-winner-card__art {
  flex-shrink: 0;
  width: 96px;
  height: 96px;
}
.global-winner-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
}
.global-winner-card__artist { margin: 0; }
.global-winner-card__theme  { margin: 0; font-style: italic; }
.global-winner-card__submitter { margin: 0; }

/* /sotw page sections */
.sotw-last,
.sotw-standings,
.landing-sotw,
.landing-sotw-winner {
  margin: var(--sp-4) 0;
}
.sotw-submit {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
}
.sotw-submit input[type="url"] {
  padding: var(--sp-2);
  border: var(--border-width) solid var(--ink);
  background: var(--paper);
  font-family: var(--font-mono);
}

/* Vote grid mirrors the per-group vote screen layout. */
.vote-form { margin: var(--sp-4) 0; }
.vote-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: 1fr;
}
@media (min-width: 720px) {
  .vote-grid { grid-template-columns: 1fr 1fr; }
}
.vote-form__submit {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-4);
}

/* ═══════════════════════════════════════════════════════════════════
 * Pointer-target floor — WCAG 2.2 SC 2.5.8
 *
 * Links styled as plain text are only as tall as their line box (14–17px
 * at our mono sizes), which is a miss on a phone. Padding grows the hit
 * box without moving the glyphs, so this costs nothing visually.
 *
 * Links sitting inline inside a sentence are exempt by the spec — you
 * can't pad those without wrecking the line box, and the surrounding
 * prose gives them context. Everything below is a standalone control.
 * ═══════════════════════════════════════════════════════════════════ */
.footer__legal a,
.auth-card__footer a,
.settings-footer .btn-link,
.btn-link,
.masthead__right a.mono-sm,
.vote-mini-head__back,
.group-card__link,
.win-pill,
.stamp > a {
  display: inline-block;
  padding-block: 5px;
}
.win-pill { min-height: 24px; }

/* Native controls scale with font-size, not layout, so they need an
   explicit floor. accent-color keeps the checked state on-brand. */
input[type="checkbox"],
input[type="radio"] {
  width: 24px;
  height: 24px;
  accent-color: var(--accent);
  flex: 0 0 auto;
  margin: 0;
  cursor: pointer;
}
/* …except the ones that are only a form value: .pick-cta and .rating
   wrap their radio in a label that *is* the target, and the input itself
   is visually hidden. */
input.sr-only[type="radio"],
input.sr-only[type="checkbox"] { width: 1px; height: 1px; }

input[type="file"] { padding-block: 6px; }
input[type="url"],
input[type="email"],
input[type="password"],
input[type="text"],
input[type="search"] { min-height: 24px; }

details > summary { min-height: 24px; padding-block: 4px; }
.theme-idea__delete-btn { min-height: 24px; min-width: 28px; }
