/* pages.css — page-specific layouts for Song of the Week.
 * Rules here only layout page grids and page-scoped adjustments. Shared
 * component styling lives in components.css; tokens live in tokens.css. */

/* The .page__main element is a <main>, and some browser defaults +
 * user-agent stylesheets apply a max-width via legacy rules. Neutralise
 * the cascade here so new layouts inherit the full .page width. */
.page__main {
  max-width: none;
  margin: 0;
  padding: 0;
  padding-bottom: var(--sp-10);
}

/* ─── Small compat utilities ────────────────────────────────────
 * A few still-live partials (listen_links, mb_search_results) use the
 * pre-redesign class names `.muted` and `.art-sm`. They map cleanly to
 * the handoff palette — aliased here so those partials keep rendering
 * correctly without another template pass. `.flash` + `.cta-fab` +
 * `.readonly-input` are also used in the wild. */
.muted {
  color: var(--dim);
  font-size: var(--fs-body-sm);
}
.art-sm {
  width: 48px;
  height: 48px;
  background: var(--paper-hi);
  border: 1px solid var(--ink);
  object-fit: cover;
  flex-shrink: 0;
}
.art-box {
  background: var(--paper-hi);
  border: 1px solid var(--ink);
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.art-box img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.flash {
  padding: 10px 14px;
  border: var(--border-width) solid var(--ink);
  background: var(--paper-hi);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-sm);
  margin: var(--sp-3) 0;
}
.flash-ok    { background: var(--soft); color: var(--ink); }
.flash-error { background: var(--accent); color: var(--paper); }

/* Mobile floating CTA — visible on group detail when the viewer owes
 * an action. Big circular pink blob bottom-right. */
.cta-fab {
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  display: none;
  align-items: center;
  gap: var(--sp-2);
  padding: 12px 16px;
  background: var(--accent);
  color: var(--paper);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-body);
  z-index: 50;
}
.cta-fab:hover { color: var(--paper); text-decoration: none; }
.cta-fab-label { display: inline; }
.cta-fab-arrow { font-weight: 400; }

@media (max-width: 900px) {
  .cta-fab { display: inline-flex; }
}

/* Short inline forms without page-level padding — the old
 * `class="inline"` was a flex shim in app.css. Keep the affordance. */
.inline {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

/* Listen-link partial leftovers — the partial is still used by vote
 * cards, results cards, and listen lists. Keep a minimal baseline so
 * its <details class="listen-other"> summary + icon stay usable in
 * places we haven't bespokely restyled. */
.listen-group {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-top: 6px;
}
.listen-group .listen-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: var(--accent-2);
  color: var(--paper);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-sm);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-body-sm);
  text-decoration: none;
  border-radius: 0;
}
.listen-group .listen-btn:hover { color: var(--paper); }
.listen-group .listen-btn .svc-icon { width: 14px; height: 14px; }
.listen-other {
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
}
.listen-other > summary {
  list-style: none;
  cursor: pointer;
  color: var(--dim);
}
.listen-other > summary::-webkit-details-marker { display: none; }
.listen-other > summary::marker { content: ""; }
.listen-other[open] > summary { color: var(--accent); }
.listen-other ul {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.listen-other a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink);
  text-decoration: underline;
}
.listen-note {
  color: var(--dim);
}

/* MusicBrainz search pick list. */
.mb-search-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.mb-search-list li {
  border: 1px dotted var(--line);
  padding: var(--sp-2) var(--sp-3);
}
.mb-pick {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  color: var(--ink);
}
.mb-pick:hover { color: var(--accent); }
.mb-search-results .muted { color: var(--dim); padding: var(--sp-2); }

.spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: sotw-spin 0.8s linear infinite;
  vertical-align: middle;
}
.spinner.htmx-indicator { opacity: 0; transition: opacity 150ms; }
.spinner.htmx-request.htmx-indicator,
.htmx-request .spinner.htmx-indicator { opacity: 1; }
@keyframes sotw-spin {
  to { transform: rotate(360deg); }
}

/* The brand logo and the bell are anchors, so base.css's global
 * `a { text-decoration: underline }` lands on them. The handoff
 * strips it from `.nav__item` only; do the same for the other nav
 * anchors and the legacy header brand. Same problem for any anchor
 * styled as a button — both the handoff `.btn` family and the legacy
 * `.btn-primary` / `.btn-secondary` should never carry link underline. */
.nav__brand,
.nav__brand:hover,
.nav__bell,
.nav__bell:hover,
.brand,
.brand:hover,
.btn,
.btn:hover,
.btn-primary,
.btn-primary:hover,
.btn-secondary,
.btn-secondary:hover,
.btn-88x31,
.btn-88x31:hover,
.group-card,
.group-card:hover {
  text-decoration: none;
}

/* Base.css's `a:hover { color: var(--accent) }` is right for body links
 * but turns the text of anchor-styled buttons / cards / brand chrome
 * pink on hover, which against a pink CTA reads as "the button just
 * vanished". Pin each anchored component's hover colour to whatever
 * its base style uses so the hover state keeps contrast. */
.nav__brand:hover .nav__logo { color: var(--accent); } /* brand logo is already accent; keep it */
.nav__brand:hover .nav__tag  { color: var(--dim); }
.nav__bell:hover             { color: var(--accent); }
.btn:hover                   { color: var(--ink); }
.btn--primary:hover,
.btn--secondary:hover        { color: var(--paper); }
.btn--waiting:hover          { color: var(--dim); }
.btn-primary:hover           { color: #0b0e16; }     /* legacy app.css */
.btn-secondary:hover         { color: var(--text); } /* legacy app.css */
.group-card:hover            { color: var(--ink); }
.win-pill:hover              { color: var(--ink); }
.past-round-card:hover       { color: var(--ink); }

/* Disabled button state — keep the visual present but drop the
 * interactive affordance so the user knows it's not ready yet. */
.btn[disabled],
.btn[disabled]:hover {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  box-shadow: var(--shadow-btn);
  color: var(--ink);
}

/* ─── Dashboard ──────────────────────────────────────────────── */

.masthead {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-6);
  align-items: end;
  padding: var(--sp-6) 0 var(--sp-3);
  border-top: var(--border-width) solid var(--ink);
}
.masthead__stamp-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
/* Chip row that follows the member/started stamp on the group masthead.
 * Gives the round-state chip-marquee a little vertical breathing room so
 * it doesn't crowd the member count above it. */
.masthead__chip-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: var(--sp-2);
}
.masthead__title {
  font-size: 64px;
  line-height: 1;
  letter-spacing: var(--ls-display-tight);
  margin: 0;
}
.masthead__subcopy {
  margin-top: 6px;
}
.masthead__right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  text-align: right;
}
.masthead__right .countdown {
  letter-spacing: -0.5px;
}

/* When a group has a custom avatar, the left column becomes a two-cell
   row (avatar + text). Collapses back to column on narrow screens so
   the image doesn't squish the title. */
/* Inline group avatar — shown next to the H1 group name in the
   masthead title row. Smaller + inline so the title itself stays the
   primary visual hook; the avatar is a familiarity anchor, not a hero. */
.masthead__title-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.masthead__title-row .avatar {
  flex-shrink: 0;
}

/* Account page — profile picture card. Lays out the current avatar
   preview on the left with the upload/remove form stack on the right. */
.account-avatar-card__body {
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
  flex-wrap: wrap;
}
.account-avatar-card__forms {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  flex: 1 1 240px;
}
.avatar-upload-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.avatar-upload-form__file {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.avatar-upload-form__remove {
  align-self: flex-start;
}

.group-list {
  padding-top: var(--sp-4);
}
.group-list__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--sp-3);
}
.group-list__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.group-list__empty {
  padding: var(--sp-6);
  text-align: center;
}
.group-list__empty p + p {
  margin-top: var(--sp-4);
}

.group-card__actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
}
.group-card__actions .btn {
  padding: 6px 12px;
  font-size: var(--fs-body-sm);
  box-shadow: var(--shadow-btn);
}
/* Time-remaining stamp next to the CTA is the only way a viewer knows
   how long they have — make it readable on phones. */
@media (max-width: 560px) {
  .group-card__actions .stamp--sm {
    font-size: 12px;
    font-weight: 700;
  }
}

/* Collapsible "more" drawer on the group page. Hides past rounds,
   shared playlist, and owner management by default so the round
   itself stays centre-stage. Owners get it open pre-expanded. */
.group-body__more { margin-top: var(--sp-5); }
.group-body__more > summary {
  cursor: pointer;
  list-style: none;
  padding: var(--sp-3) 0;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-lg);
  text-transform: uppercase;
  color: var(--dim);
}
.group-body__more > summary::-webkit-details-marker { display: none; }
.group-body__more > summary::marker { content: ""; }
.group-body__more > summary::before { content: "▸ "; }
.group-body__more[open] > summary::before { content: "▾ "; }
.group-body__more[open] > summary { color: var(--accent); }
.group-card__progress {
  margin-left: auto;
}

/* Whole-card hit area — the name anchor stretches its ::after to fill
 * the card so clicking anywhere (except the CTA button) opens the
 * group page. The CTA and the deadline/progress spans bump themselves
 * to z-index: 2 so their own clicks land distinctly. Pattern keeps
 * semantic markup simple (one main link, one action link). */
.group-card { position: relative; }
.group-card__link {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  line-height: 1.05;
  text-decoration: none;
  color: inherit;
}
.group-card__link:hover { color: var(--ink); }
.group-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.group-card:hover .group-card__link { color: var(--accent); }
.group-card__cta,
.group-card__actions [data-countdown],
.group-card__progress {
  position: relative;
  z-index: 2;
}

@media (max-width: 720px) {
  .masthead {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .masthead__right {
    align-items: flex-start;
    text-align: left;
  }
  .masthead__title {
    font-size: 44px;
  }
  .group-list__grid {
    grid-template-columns: 1fr;
  }
}

/* ─── Group detail ───────────────────────────────────────────── */

.masthead--group .masthead__title {
  font-size: var(--fs-display-xl);
}

.group-body__section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--sp-3);
  gap: var(--sp-4);
  flex-wrap: wrap;
}
/* Right-side cluster inside a section head — groups the "> N tracks"
 * stamp with secondary action buttons (e.g. "listen to all") so they
 * stay aligned to the right of the h2 and wrap as a unit on mobile. */
.group-body__section-head__right {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}

/* Prominent "your turn" banner — the viewer's state is the most
 * important thing on the page, so it sits just below the masthead
 * and takes the full width at card weight. The variant classes
 * tune the colour: urgent=pink, done=soft teal, finalised=teal,
 * idle=paper-hi. */
.status-banner {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-4);
  align-items: center;
  padding: var(--sp-4) var(--sp-5);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  margin: var(--sp-3) 0;
}
.status-banner__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.status-banner__copy {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  line-height: 1.1;
}
.status-banner__sub {
  color: var(--ink);
  opacity: 0.8;
}
.status-banner--urgent    { background: var(--accent);   color: var(--paper); }
.status-banner--urgent .status-banner__label,
.status-banner--urgent .status-banner__sub { color: var(--paper); opacity: 0.85; }
.status-banner--done      { background: var(--soft);     color: var(--ink); }
.status-banner--finalised { background: var(--accent-2); color: var(--paper); }
.status-banner--finalised .status-banner__label,
.status-banner--finalised .status-banner__sub { color: var(--paper); opacity: 0.85; }
.status-banner--idle      { background: var(--paper-hi); color: var(--ink); }

.status-banner__cta .btn { white-space: nowrap; }

/* Section wrapper for the current round — when voting is live we
 * pair the bracket grid with a voters/status aside; other states are
 * full-width. */
.round-section {
  padding-top: var(--sp-4);
}
.round-section__grid {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: var(--sp-8);
  align-items: start;
}
.round-section__aside {
  padding-left: var(--sp-6);
  border-left: var(--border-width) solid var(--line);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.bracket-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}
.bracket-grid__cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.bracket-grid__cell .art-tile {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
}
.bracket-grid__cell.is-pending {
  opacity: 0.55;
}
.bracket-grid__cell .display-sm {
  font-size: var(--fs-display-sm);
  line-height: 1.05;
  margin-top: 4px;
  /* keep long titles from breaking the grid */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bracket-grid__cell.is-you .display-sm { color: var(--accent); }
.bracket-empty {
  padding: var(--sp-6);
  text-align: center;
}
.bracket-empty p + p {
  margin-top: var(--sp-4);
}

/* ─── Right-column phase + standings ─── */

.phase-aside {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.phase-aside__head {
  display: flex;
  justify-content: flex-start;
}
.phase-aside__head-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--sp-2);
}
.phase-aside__block {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.phase-aside__chip--finalised {
  background: var(--accent);
  color: var(--paper);
}
.phase-aside__chip--idle,
.phase-aside__chip--closed {
  background: var(--soft);
  color: var(--ink);
}

.voters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.voter {
  width: 44px;
}
.voter .avatar--md {
  width: 36px;
  height: 36px;
  font-size: var(--fs-micro-xs);
}
.voter__name {
  display: block;
  text-align: center;
  font-size: var(--fs-micro-xs);
  line-height: 1.15;
  word-break: break-word;
  margin-top: 2px;
}

/* .voters--lg is the prominent open-state roster in the main column:
   bigger avatars so identity reads at a glance, wider cells so names
   fit without wrapping, and a readable micro-sm label underneath. */
.voters--lg {
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.voters--lg .voter { width: 76px; }
.voters--lg .voter .avatar--lg {
  width: 56px;
  height: 56px;
  font-size: var(--fs-body-sm);
}
.voters--lg .voter__name {
  font-size: var(--fs-micro-sm);
  margin-top: 4px;
}
.voters--lg .voter__voted-badge {
  width: 20px;
  height: 20px;
  font-size: 12px;
  bottom: -4px;
  right: -4px;
}

/* Submissions strip: voting-state preview. One compact horizontal
   card per submitted track (art on the left, title/artist on the
   right). Submitter identity stays hidden; the viewer's own track
   is flagged with an accent border + "YOURS" corner tag so it's
   findable at a glance. Replaces the old placeholder bracket-grid
   of anonymous colored squares. */
.submissions-strip {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.submissions-strip__cta {
  margin-top: var(--sp-4);
  display: flex;
  justify-content: center;
}
.submission-card {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: center;
  padding: var(--sp-3);
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
}
.submission-card.is-mine {
  border-color: var(--accent);
  box-shadow: var(--shadow-card-accent);
}
.submission-card__art {
  width: 64px;
  height: 64px;
}
.submission-card__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.submission-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
  line-height: 1.1;
  word-break: break-word;
}
.submission-card__tag {
  position: absolute;
  top: -8px;
  right: 12px;
  background: var(--accent);
  color: var(--paper);
  border: var(--border-width) solid var(--ink);
  padding: 2px 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  letter-spacing: var(--ls-mono-lg);
  font-weight: 700;
  text-transform: uppercase;
}
@media (min-width: 720px) {
  .submissions-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Your-pick card: compact "you're set" callout at the top of the
   round body when the viewer has already submitted. Album art on the
   left (64px square), track metadata + change link on the right. The
   empty variant is the reverse nudge: no art, just a "submit now" CTA. */
.your-pick-card {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
}
.your-pick-card__art {
  width: 72px;
  height: 72px;
  flex-shrink: 0;
}
.your-pick-card__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.your-pick-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
  line-height: 1.1;
  word-break: break-word;
}
.your-pick-card__change {
  align-self: flex-start;
  margin-top: 6px;
}
.your-pick-card--empty {
  grid-template-columns: 1fr;
  padding: var(--sp-4);
  text-align: left;
}
.your-pick-card--empty .btn { align-self: flex-start; margin-top: 6px; }
.voter__voted-badge {
  width: 14px;
  height: 14px;
  font-size: 10px;
  bottom: -3px;
  right: -3px;
}

/* Standings is promoted to its own full-width section below the current
 * round on the group page. One roomy row per member with avatar, rank,
 * name, and score — the rank now gets display-md weight so the column
 * pops. A collapsible drawer below holds per-member win history. */
.standings-section {
  padding-top: var(--sp-6);
}
.standings { display: flex; flex-direction: column; gap: var(--sp-3); }
.standings__head { margin-bottom: 0; }
.standings__list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
  row-gap: var(--sp-2);
}
.standings__row {
  display: grid;
  grid-template-columns: 36px 32px 1fr auto;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px dotted var(--line);
  align-items: center;
  min-width: 0;
}
.standings__rank {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  color: var(--dim);
  line-height: 1;
  letter-spacing: 0;
}
.standings__rank.accent { color: var(--accent); }
.standings__name {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-body);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.standings__row.is-you .standings__name { font-weight: 800; color: var(--accent); }
.standings__score {
  color: var(--dim);
  letter-spacing: var(--ls-mono-sm);
  white-space: nowrap;
}
.standings__wins-drawer {
  margin-top: var(--sp-2);
}
.standings__wins-drawer > summary {
  cursor: pointer;
  list-style: none;
  display: inline-block;
  padding: 4px 0;
}
.standings__wins-drawer > summary::-webkit-details-marker { display: none; }
.standings__wins-drawer > summary::marker { content: ""; }
.standings__wins-drawer[open] > summary { color: var(--accent); }
.standings__wins-list {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.standings__wins-list li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-3);
  align-items: center;
}
.standings__wins {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.win-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 6px;
  background: var(--paper);
  border: 1px solid var(--line);
  text-decoration: none;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: var(--fs-micro-xs);
  letter-spacing: var(--ls-mono-sm);
}
.win-pill:hover {
  color: var(--ink);
  border-color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.win-pill__art {
  width: 14px;
  height: 14px;
  background-size: cover;
  background-position: center;
  border: 1px solid var(--ink);
  flex-shrink: 0;
}
.win-pill__art--blank { background: var(--accent-2); }

/* ─── Past rounds carousel ─── */

.past-rounds-strip {
  padding-top: var(--sp-4);
}
.past-rounds-strip__scroll {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding-bottom: var(--sp-2);
  scroll-snap-type: x proximity;
}
.past-round-card {
  flex: 0 0 160px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px;
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-btn);
  text-decoration: none;
  color: inherit;
  scroll-snap-align: start;
}
.past-round-card:hover { color: var(--ink); box-shadow: var(--shadow-card); transform: translate(-1px, -1px); }
.past-round-card__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.past-round-card .art-tile {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
}
.past-round-card .display-sm {
  font-size: var(--fs-display-sm);
  line-height: 1.05;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ─── Owner management cluster ─── */

.group-management__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-4);
}
.group-management__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px var(--sp-3);
  margin: 0;
}
.kv dt { font-family: var(--font-mono); color: var(--dim); font-size: var(--fs-micro-sm); }
.kv dd { margin: 0; font-family: var(--font-mono); font-size: var(--fs-micro-sm); }
.readonly-input {
  width: 100%;
  padding: 6px 10px;
  border: var(--border-width) solid var(--ink);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--fs-body-sm);
}

@media (max-width: 900px) {
  .round-section__grid {
    grid-template-columns: 1fr;
  }
  .round-section__aside {
    border-left: none;
    padding-left: 0;
    border-top: var(--border-width) solid var(--line);
    padding-top: var(--sp-4);
  }
  .bracket-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .status-banner {
    grid-template-columns: 1fr;
  }
  .status-banner__cta { justify-self: start; }
}
@media (max-width: 560px) {
  .bracket-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
}

/* ─── Vote (tournament, single matchup) ─────────────────────── */

.masthead--vote .masthead__title {
  font-size: 40px;
}

.vote-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.vote-mini-head { display: none; }  /* desktop: hidden; mobile: shown via breakpoint */

.vote-card-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 48px minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: stretch;
  margin-top: var(--sp-6);
}
.vote-card-pair .vs {
  align-self: center;
  padding-top: var(--sp-6);
  font-size: 44px;
}

.vote-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px;
  position: relative;
  min-width: 0;
}
/* Corner tag pokes above the card border, exactly like the mockup's
 * "◆ TRACK A" notch — a thin paper-coloured pill punching through. */
.vote-card__tag {
  position: absolute;
  top: -11px;
  left: 16px;
  padding: 0 8px;
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-lg);
  color: var(--ink);
  font-weight: 700;
  line-height: 1;
}

.vote-card__head {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}
.vote-card__head .art-tile {
  width: 130px;
  height: 130px;
  flex-shrink: 0;
}
.vote-card__info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.vote-card__title {
  font-family: var(--font-display);
  font-size: 28px;
  line-height: 1.05;
  /* Wrap at natural spaces; only break mid-word if a single word
   * genuinely overflows (rare — the card is 500-600px wide on
   * desktop so most titles fit on one line). */
  overflow-wrap: break-word;
}
.vote-card__artist { margin-top: 2px; }
.vote-card__listen-row {
  margin-top: 10px;
  display: flex;
  gap: 6px;
  align-items: stretch;
}
.vote-card__also-on { margin-top: 6px; }
.vote-card__divider {
  border-top: 1px dotted var(--ink);
  margin: 2px 0;
}

/* Listen button: teal square, Nunito bold — replaces the legacy
 * rounded .listen-btn from app.css within the vote context. */
.vote-card__listen-row {
  display: flex;
  gap: 6px;
  align-items: stretch;
  flex-wrap: wrap;
}
.vote-card__listen-row .listen-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--accent-2);
  color: var(--paper);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-body-sm);
  text-decoration: none;
  border-radius: 0;
  white-space: nowrap;
  /* Don't shrink below the button's natural width — titles and
   * artist lines wrap to make room instead. */
  flex: 0 0 auto;
}
.vote-card__listen-row .listen-btn:hover { color: var(--paper); }
.vote-card__listen-row .listen-btn .svc-icon {
  width: 14px;
  height: 14px;
}
.listen-caret {
  position: relative;
}
.listen-caret > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 100%;
  min-height: 36px;
  padding: 0 10px;
  background: var(--paper);
  color: var(--ink);
  border: var(--border-width) solid var(--ink);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
}
.listen-caret > summary::-webkit-details-marker { display: none; }
.listen-caret > summary::marker { content: ""; }
.listen-caret[open] > summary { background: var(--accent-2); color: var(--paper); }
.listen-caret > ul {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 5;
  background: var(--paper);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-btn);
  min-width: 160px;
  padding: 6px 0;
  margin: 0;
  list-style: none;
}
.listen-caret > ul li { margin: 0; }
.listen-caret > ul a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  color: var(--ink);
  text-decoration: none;
  font-family: var(--font-sans);
  font-size: var(--fs-body-sm);
}
.listen-caret > ul a:hover { color: var(--ink); background: var(--paper-hi); }

/* Live pick state via CSS :has() — falls back to `.is-picked` for
 * browsers without :has() support. */
.vote-card:has(input[name="pick"]:checked),
.vote-card.is-picked {
  box-shadow: var(--shadow-card-lg-accent);
}
.vote-card:has(input[name="pick"]:checked) .vote-card__tag,
.vote-card.is-picked .vote-card__tag {
  color: var(--accent);
}

/* Pick CTA fills the card width; accent background when selected. */
.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-weight: 700;
  font-size: 15px;
  cursor: pointer;
}
.pick-cta:hover { color: var(--ink); }
.pick-cta:has(input:checked),
.pick-cta.is-picked {
  background: var(--accent);
  color: var(--paper);
}
.pick-cta:has(input:checked):hover,
.pick-cta.is-picked:hover { color: var(--paper); }
.pick-cta__bullet {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--ink);
  flex-shrink: 0;
}
.pick-cta:has(input:checked) .pick-cta__bullet,
.pick-cta.is-picked .pick-cta__bullet {
  background: var(--paper);
  box-shadow: inset 0 0 0 2px var(--accent);
}
.pick-cta__ext { display: none; }  /* desktop: short label; mobile enables the " : Track X" extension */

/* Rate + comment live on one row under the pick CTA on desktop. */
.vote-card__optional-label {
  margin: 6px 0 4px;
}
.vote-card__rate-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px;
  align-items: stretch;
}

.rating {
  display: flex;
  gap: 4px;
  align-items: center;
  flex-wrap: nowrap;
}
.rating__btn {
  cursor: pointer;
  user-select: none;
  min-width: 22px;
  height: 22px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--paper);
  color: var(--ink);
  border: var(--border-width) solid var(--ink);
  font-family: var(--font-mono);
  font-size: var(--fs-micro-sm);
  font-weight: 700;
  line-height: 1;
}
.rating__btn.is-on { background: var(--ink); color: var(--paper); }

.rating:has(.rating__btn input[value="5"]:checked) .rating__btn { background: var(--ink); color: var(--paper); }
.rating:has(.rating__btn input[value="4"]:checked) .rating__btn:nth-of-type(1),
.rating:has(.rating__btn input[value="4"]:checked) .rating__btn:nth-of-type(2),
.rating:has(.rating__btn input[value="4"]:checked) .rating__btn:nth-of-type(3),
.rating:has(.rating__btn input[value="4"]:checked) .rating__btn:nth-of-type(4) { background: var(--ink); color: var(--paper); }
.rating:has(.rating__btn input[value="3"]:checked) .rating__btn:nth-of-type(1),
.rating:has(.rating__btn input[value="3"]:checked) .rating__btn:nth-of-type(2),
.rating:has(.rating__btn input[value="3"]:checked) .rating__btn:nth-of-type(3) { background: var(--ink); color: var(--paper); }
.rating:has(.rating__btn input[value="2"]:checked) .rating__btn:nth-of-type(1),
.rating:has(.rating__btn input[value="2"]:checked) .rating__btn:nth-of-type(2) { background: var(--ink); color: var(--paper); }
.rating:has(.rating__btn input[value="1"]:checked) .rating__btn:nth-of-type(1) { background: var(--ink); color: var(--paper); }

.comment-chip {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 10px;
  border: 1px dashed var(--line);
  cursor: text;
  min-width: 0;
}
.comment-chip textarea {
  width: 100%;
  border: none;
  background: transparent;
  padding: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body-sm);
  color: var(--ink);
  resize: vertical;
  min-height: 0;
  max-height: 6em;
}
.comment-chip textarea:focus { outline: none; }
.comment-chip:focus-within { border-color: var(--accent); border-style: solid; }
/* Collapse textarea into a dashed chip until the user focuses it — matches
 * the mockup's single-line "+ add a comment (optional)" look. */
.comment-chip textarea {
  height: 0;
  padding: 0;
  display: block;
  overflow: hidden;
}
.comment-chip:focus-within textarea,
.comment-chip:has(textarea:not(:placeholder-shown)) textarea {
  height: 4em;
  padding-top: 4px;
}

/* Sticky submit bar. Desktop: one-line helper + prev/submit on the
 * right. Mobile swaps to a picked/rated summary on the left.         */
.vote-submit-bar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: var(--paper);
  border-top: var(--border-width) solid var(--ink);
  margin: var(--sp-4) calc(var(--sp-8) * -1) 0;
}
.vote-submit-bar__buttons {
  display: flex;
  gap: 8px;
  align-items: center;
}
.vote-submit-bar__mobile { display: none; }
.vote-submit-bar__prev { white-space: nowrap; }

.vote-empty {
  padding: var(--sp-8);
  text-align: center;
}
.vote-empty p + p { margin-top: var(--sp-4); }

/* ─── Auth / welcome — centered paper card ───────────────────── */

.auth-shell {
  max-width: 480px;
  margin: var(--sp-8) auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: 0;
}
.auth-card {
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  padding: var(--sp-6) var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  /* reset legacy app.css rules on the same class */
  border-radius: 0;
  max-width: none;
  margin: 0;
}
.auth-card__chip-row {
  display: flex;
  justify-content: flex-start;
}
.auth-card__title {
  font-family: var(--font-display);
  font-size: 40px;
  line-height: 1;
  letter-spacing: var(--ls-display);
  margin: 0;
}
.auth-card__sub {
  font-family: var(--font-hand);
  font-size: var(--fs-hand-md);
  color: var(--accent-2);
  margin: -6px 0 0;
  line-height: 1.1;
}
.auth-card__body {
  font-size: var(--fs-body);
}
.auth-card form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.auth-card label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-sm);
  color: var(--dim);
  text-transform: uppercase;
}
.auth-card label > small {
  font-family: var(--font-sans);
  font-size: var(--fs-body-sm);
  color: var(--dim);
  text-transform: none;
  letter-spacing: 0;
  margin-top: 2px;
}
.auth-card input[type="email"],
.auth-card input[type="password"],
.auth-card input[type="text"],
.auth-card select {
  padding: 10px 12px;
  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-lg);
  border-radius: 0;
  text-transform: none;
  letter-spacing: 0;
}
.auth-card input:focus,
.auth-card select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 2px 2px 0 var(--accent);
}
.auth-card button[type="submit"] {
  margin-top: var(--sp-2);
  align-self: flex-start;
}
.auth-card .error {
  background: var(--accent);
  color: var(--paper);
  padding: 8px 12px;
  border: var(--border-width) solid var(--ink);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-sm);
}
.auth-card__footer {
  border-top: 1px dotted var(--ink);
  padding-top: var(--sp-3);
  margin-top: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-sm);
  color: var(--dim);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: baseline;
}
.auth-card__footer a { color: var(--accent-2); text-decoration: underline; }
.auth-card__footer a:hover { color: var(--accent); }

/* OAuth row — big Spotify button + "or with email" divider */
.auth-oauth {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.btn-oauth {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 14px;
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  text-decoration: none;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-body);
  border-radius: 0;
}
.btn-oauth.btn-spotify {
  background: var(--accent-2);
  color: var(--paper);
}
.btn-oauth.btn-spotify:hover { color: var(--paper); text-decoration: none; }
.btn-oauth .svc-icon { width: 18px; height: 18px; }
.oauth-sep {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--dim);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-sm);
  text-transform: uppercase;
}
.oauth-sep::before,
.oauth-sep::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.form-actions {
  display: flex;
  gap: var(--sp-3);
  align-items: center;
  flex-wrap: wrap;
  margin-top: var(--sp-2);
}
.form-actions .btn-link,
.btn-link {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-sm);
  color: var(--accent-2);
  text-decoration: underline;
}
.btn-link:hover { color: var(--accent); }

/* ─── Group create / settings — shared pickers ──────────────── */

.scheme-picker {
  border: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.scheme-picker legend {
  padding: 0 0 6px;
}
.scheme-picker__option {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-3);
  align-items: start;
  padding: var(--sp-3);
  border: var(--border-width) solid var(--ink);
  background: var(--paper);
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink);
}
.scheme-picker__option:hover { background: var(--paper-hi); }
.scheme-picker__option > span {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.scheme-picker__option input[type="radio"] {
  margin-top: 6px;
  accent-color: var(--accent);
  transform: scale(1.15);
}
.scheme-picker__option:has(input:checked) {
  border-color: var(--accent);
  box-shadow: var(--shadow-btn);
  background: var(--paper-hi);
}

.toggle-label {
  display: grid !important;
  grid-template-columns: auto 1fr !important;
  gap: var(--sp-3);
  align-items: start;
  padding: var(--sp-3);
  border: 1px dashed var(--line);
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink);
}
.toggle-label input[type="checkbox"] {
  margin-top: 4px;
  accent-color: var(--accent);
  transform: scale(1.25);
}
.toggle-label > span {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.toggle-label:has(input:checked) {
  border-color: var(--accent);
  background: var(--paper-hi);
}

.invite-code-input {
  text-transform: uppercase;
  letter-spacing: 4px !important;
  font-family: var(--font-mono) !important;
  font-size: 20px !important;
  text-align: center;
}

/* ─── Group settings ─────────────────────────────────────────── */

.settings-shell {
  max-width: 720px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
}
.settings-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.settings-card {
  max-width: none;
  padding: var(--sp-5);
  margin: 0;
}
.settings-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
}
.settings-footer {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
}

@media (max-width: 560px) {
  .settings-row { grid-template-columns: 1fr; }
}

/* ─── Theme ideas pool (group show page) ───────────────────────
 * The opt-in theme idea board. Members pitch round themes into a
 * shared pool; the owner picks one when starting a round. The form
 * sits at the top of the card with a live char counter, and each
 * idea renders below as a small index-card-style chit. */

.theme-ideas {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-4);
}
.theme-ideas__form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.theme-ideas__field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.theme-ideas__field-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.theme-ideas__input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.35;
  color: var(--ink);
  background: var(--paper-hi);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  padding: var(--sp-3);
  resize: vertical;
  min-height: 5em;
}
.theme-ideas__input::placeholder {
  color: var(--dim);
  font-style: italic;
}
.theme-ideas__input:focus {
  outline: none;
  border-color: var(--accent-2);
  box-shadow: 3px 3px 0 var(--accent-2);
}
.theme-ideas__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.theme-ideas__count { font-variant-numeric: tabular-nums; }

.theme-ideas__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--sp-3);
}
.theme-idea {
  position: relative;
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-3);
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-sm);
}
.theme-idea__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 0;
}
.theme-idea__text {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body-sm);
  line-height: 1.4;
  color: var(--ink);
  word-break: break-word;
}
.theme-idea__author {
  color: var(--dim);
  letter-spacing: var(--ls-mono-sm);
}
.theme-idea__delete {
  margin: 0;
  flex-shrink: 0;
}
.theme-idea__delete-btn {
  padding: 2px 8px;
  min-width: 0;
  font-size: 16px;
  line-height: 1;
  color: var(--dim);
}
.theme-idea__delete-btn:hover { color: var(--accent); }

.theme-ideas__empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4);
  border: 1px dashed var(--line);
  text-align: center;
}
.theme-ideas__empty p { margin: 0; }
/* HTMX prepends new ideas above the server-rendered empty state
 * rather than replacing the list, so hide the empty stamp once a
 * real idea lands in the same list. */
.theme-ideas__list:has(.theme-idea) .theme-ideas__empty { display: none; }

@media (max-width: 560px) {
  .theme-ideas__list { grid-template-columns: 1fr; }
  .theme-ideas__footer { justify-content: flex-end; }
  .theme-ideas__footer .theme-ideas__count { margin-right: auto; }
}

/* ─── Ranked ballot ─────────────────────────────────────────── */

.ranked-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
}
.ballot-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.ballot-item {
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  padding: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.ballot-item--dragging { opacity: 0.6; }
.ballot-item__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--sp-3);
  align-items: center;
}
.ballot-item__rank-grab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding-right: var(--sp-2);
  border-right: 1px dotted var(--ink);
}
.drag-handle {
  font-family: var(--font-mono);
  font-size: 18px;
  color: var(--dim);
  cursor: grab;
  user-select: none;
  line-height: 1;
}
.drag-handle:active { cursor: grabbing; color: var(--accent); }
.ballot-rank {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  color: var(--accent);
  line-height: 1;
}
.ballot-item__track {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: var(--sp-3);
  min-width: 0;
}
.ballot-item__track .art-tile {
  width: 64px;
  height: 64px;
}
.ballot-item__meta { min-width: 0; }
.ballot-item__meta .display-sm {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
  line-height: 1.05;
}
.ballot-item__nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ballot-item__nav .btn {
  min-width: 36px;
  padding: 4px 8px;
  font-size: 12px;
}
.ballot-item__optional-label {
  margin: 0;
  padding-top: var(--sp-2);
  border-top: 1px dotted var(--ink);
}
.ballot-item__rate-row {
  padding-top: var(--sp-1);
}
.ballot-item__comment {
  margin-top: 0;
}

@media (max-width: 640px) {
  .ballot-item__head { grid-template-columns: 1fr; }
  .ballot-item__rank-grab { flex-direction: row; border-right: none; border-bottom: 1px dotted var(--ink); padding: 0 0 var(--sp-2); gap: var(--sp-3); justify-content: space-between; }
  .ballot-item__nav { flex-direction: row; }
}

/* ─── Submit a song ──────────────────────────────────────────── */

.submit-shell {
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
}
.submit-shell__footer {
  justify-content: center;
  text-align: center;
}
.submit-form-card {
  /* use auth-card styling but don't centre its container */
  max-width: none;
}
.submit-current {
  padding: var(--sp-4);
}
.submit-current__body {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: var(--sp-3);
  margin-top: var(--sp-2);
  align-items: center;
}
.submit-current__body .art-tile { width: 56px; height: 56px; }

.mb-search-primary .mb-search-results {
  margin-top: var(--sp-3);
  max-height: 40vh;
  overflow-y: auto;
  border: 1px dotted var(--ink);
  padding: var(--sp-2);
}
.mb-search-primary .mb-search-results:empty {
  display: none;
}
.manual-entry {
  margin-top: var(--sp-2);
  border: 1px dashed var(--line);
  padding: var(--sp-3);
}
.manual-entry > summary {
  cursor: pointer;
  list-style: none;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-sm);
  color: var(--dim);
  text-transform: uppercase;
}
.manual-entry > summary::-webkit-details-marker { display: none; }
.manual-entry > summary::marker { content: ""; }
.manual-entry[open] > summary { color: var(--accent); margin-bottom: var(--sp-3); }
.manual-entry-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

/* ─── Account ────────────────────────────────────────────────── */

.account-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  max-width: 720px;
  margin: 0 auto;
  padding-top: var(--sp-4);
}
.account-card {
  max-width: none;
  padding: var(--sp-5);
}
.account-card__body {
  margin-top: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.oauth-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--sp-3);
  align-items: center;
}
.oauth-row__meta { min-width: 0; }
.oauth-row .display-sm {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.oauth-row .display-sm .svc-icon { width: 16px; height: 16px; }

@media (max-width: 640px) {
  .oauth-row { grid-template-columns: 1fr; }
}

/* ─── Notifications / inbox ──────────────────────────────────── */

.inbox-body {
  max-width: 720px;
  margin: 0 auto;
  padding-top: var(--sp-4);
}
.inbox-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
/* Inbox rows mirror the .group-card shape: a leading tile on the left,
 * meta in the middle, timestamp on the right. Unread rows get the accent
 * left-border and the full card shadow so they read as louder than
 * already-seen items. */
.inbox-row {
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
}
.inbox-row.is-unread {
  border-left: 4px solid var(--accent);
}
.inbox-row__link {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  gap: var(--sp-3);
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  text-decoration: none;
  color: var(--ink);
}
.inbox-row__link:hover { color: var(--ink); background: var(--paper); }
.inbox-row__icon {
  width: 40px;
  height: 40px;
  background: var(--accent-2);
  color: var(--paper);
  border: var(--border-width) solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1;
}
.inbox-row.is-unread .inbox-row__icon { background: var(--accent); }
.inbox-row__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.inbox-row__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
}
.inbox-row__body {
  font-size: var(--fs-body-sm);
  color: var(--dim);
}
.inbox-row__stamp {
  white-space: nowrap;
  align-self: center;
}
@media (max-width: 560px) {
  .inbox-row__link {
    grid-template-columns: 36px minmax(0, 1fr);
    row-gap: 4px;
  }
  .inbox-row__icon { width: 36px; height: 36px; font-size: 20px; }
  .inbox-row__stamp { grid-column: 2 / -1; }
}
.inbox-empty {
  padding: var(--sp-8);
  text-align: center;
}
.inbox-empty p + p { margin-top: var(--sp-3); }

/* ─── Landing (unauthenticated) ───────────────────────────────
   Elevator-pitch hero: giant display headline, one-line premise,
   one big primary CTA. No feature enumeration — the landing is
   advertising, not documentation. */
.landing-hero {
  min-height: calc(100vh - 220px);
  max-width: 780px;
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-4);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--sp-4);
}
.landing-hero__chip {
  margin-bottom: var(--sp-4);
}
.landing-hero__headline {
  font-family: var(--font-display);
  font-size: clamp(68px, 14vw, 132px);
  line-height: 0.88;
  letter-spacing: var(--ls-display-tight);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.landing-hero__headline-row { display: block; }
.landing-hero__headline-kicker {
  display: block;
  text-shadow: 4px 4px 0 var(--ink);
}
.landing-hero__pitch {
  font-family: var(--font-sans);
  font-size: var(--fs-body-lg);
  line-height: 1.5;
  max-width: 44ch;
  margin: var(--sp-4) 0 0;
}
.landing-hero__pitch em {
  font-family: var(--font-hand);
  font-style: normal;
  font-size: 1.5em;
  line-height: 0.9;
  color: var(--accent);
  letter-spacing: 0;
}
.landing-hero__cta {
  margin-top: var(--sp-5);
  font-size: 20px;
  padding: 14px 28px;
}
.landing-hero__alt {
  margin-top: var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-lg);
  text-transform: uppercase;
  color: var(--dim);
}
.landing-hero__alt a {
  color: var(--accent-2);
  font-weight: 700;
  text-decoration: underline;
}
.landing-hero__alt a:hover { color: var(--accent); }

@media (max-width: 560px) {
  .landing-hero {
    min-height: calc(100vh - 260px);
    padding: var(--sp-6) var(--sp-3);
  }
  .landing-hero__headline { font-size: clamp(56px, 18vw, 104px); }
  .landing-hero__pitch { font-size: var(--fs-body); }
  .landing-hero__headline-kicker { text-shadow: 3px 3px 0 var(--ink); }
}

/* ─── Listen page ────────────────────────────────────────────── */

.listen-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
  max-width: 960px;
  margin: 0 auto;
}
.listen-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--sp-4);
  align-items: center;
  padding: var(--sp-4) var(--sp-5);
}
.listen-card--ok { background: var(--soft); }
.listen-card .display-sm {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
  line-height: 1.1;
  margin-top: 4px;
}
.listen-card .svc-icon { width: 16px; height: 16px; }
.listen-missing-drawer {
  border: 1px dashed var(--line);
  padding: var(--sp-3) var(--sp-4);
}
.listen-missing-drawer > summary {
  cursor: pointer;
  list-style: none;
}
.listen-missing-drawer > summary::-webkit-details-marker { display: none; }
.listen-missing-drawer > summary::marker { content: ""; }
.listen-missing-drawer[open] > summary { color: var(--accent); }
.listen-missing {
  list-style: none;
  margin: var(--sp-3) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.listen-missing li {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: center;
}
.listen-missing .art-tile { width: 56px; height: 56px; }
.listen-missing__meta { min-width: 0; }
.listen-missing-card {
  padding: var(--sp-4) var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

@media (max-width: 640px) {
  .listen-card { grid-template-columns: 1fr; align-items: flex-start; }
  .listen-card form, .listen-card .btn { width: 100%; }
}

/* ─── Round results ──────────────────────────────────────────── */

.masthead--results .masthead__title {
  font-size: 44px;
}
/* Results masthead byline: avatar + "submitted by" stamp on one line. */
.masthead__byline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--sp-2);
  flex-wrap: wrap;
}
.masthead--results .masthead__right {
  gap: 8px;
}
.masthead--results .masthead__right .btn { white-space: nowrap; }

.results-body {
  display: grid;
  grid-template-columns: 0.9fr 1.3fr;
  gap: var(--sp-8);
  align-items: start;
  padding-top: var(--sp-4);
}
.results-body__left {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.results-body__right {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

/* Winner spotlight — inverse (accent) card with art, title, submitter,
 * listen CTA. Cheer-y centrepiece of the page. */
.winner-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: var(--sp-5);
}
.winner-card__art {
  width: 180px;
  height: 180px;
}
.winner-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-display-lg);
  line-height: 1;
  margin-top: 6px;
}
.winner-card__artist { opacity: 0.9; }
.winner-card__submitter {
  opacity: 0.95;
  margin-top: var(--sp-2);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
.winner-card__submitter .submitted-by {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-lg);
  text-transform: uppercase;
  opacity: 0.85;
}
.ranking-thread__submitter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
}
/* Celebratory "WINNER" heading — display-xl with an ink drop-shadow so
   the word itself feels like a victory stamp. Dropped one notch on
   mobile so it doesn't clip the 375px viewport. */
.winner-heading {
  font-family: var(--font-display);
  font-size: var(--fs-display-xl);
  line-height: 0.95;
  color: var(--accent);
  letter-spacing: var(--ls-display-tight);
  margin: 0 0 var(--sp-3);
  text-shadow: 3px 3px 0 var(--ink);
}
@media (max-width: 560px) {
  .winner-heading { font-size: 44px; text-shadow: 2px 2px 0 var(--ink); }
}
.winner-card__listen {
  margin-top: var(--sp-3);
  background: var(--paper);
  color: var(--ink);
  border-color: var(--ink);
}
.winner-card__listen:hover { color: var(--ink); }
.winner-card__also-on { opacity: 0.9; margin-top: 6px; }

.results-stats .stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
.stats-grid__cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
}
.stats-grid__num {
  font-family: var(--font-display);
  font-size: 28px;
  line-height: 1;
  color: var(--accent);
}
.stats-grid__num small {
  font-size: 16px;
  margin-left: 2px;
}

.winner-rating__stars {
  font-family: var(--font-display);
  font-size: var(--fs-display-md);
  margin-top: 6px;
}

/* Ranking thread cards — one per submission, rank + track + comments. */
.ranking-threads {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: 0;
  margin: 0;
  list-style: none;
}
.ranking-thread {
  background: var(--paper-hi);
  border: var(--border-width) solid var(--ink);
  box-shadow: var(--shadow-card);
  padding: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.ranking-thread.is-winner { box-shadow: var(--shadow-card-accent); }
.ranking-thread__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
}
.ranking-thread__track {
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: start;
}
.ranking-thread__track .art-tile {
  width: 80px;
  height: 80px;
}
.ranking-thread__meta { min-width: 0; }
.ranking-thread__meta .display-sm {
  font-family: var(--font-display);
  font-size: var(--fs-display-sm);
  line-height: 1.05;
}
.ranking-thread__listen {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  background: var(--accent-2);
  color: var(--paper);
  border: var(--border-width-thick) solid var(--ink);
  box-shadow: var(--shadow-btn);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-micro);
  text-decoration: none;
  border-radius: 0;
  margin-top: 6px;
}
.ranking-thread__listen:hover { color: var(--paper); }
.ranking-thread__comments {
  border-top: 1px dotted var(--ink);
  padding-top: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.ranking-thread__comments ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.thread__comment {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: var(--sp-3);
  align-items: start;
}
.thread__comment-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.thread__comment-name { font-weight: 700; }
.thread__text {
  font-size: var(--fs-body-sm);
  line-height: 1.35;
}
.ranking-thread__empty {
  border-top: 1px dotted var(--ink);
  padding-top: var(--sp-3);
}

/* Bottom actions — matches the handoff footer pattern on results. */
.results-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
  flex-wrap: wrap;
}
.results-actions__buttons {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

@media (max-width: 900px) {
  .results-body {
    grid-template-columns: 1fr;
  }
  .masthead--results .masthead__right {
    flex-direction: row;
    flex-wrap: wrap;
  }
}

/* Done-state card — rendered after the viewer submits their last
 * matchup. Soft teal background so it reads as "done / peaceful" and
 * not as another action. The progress bar above stays interactive
 * so voters can jump back into any matchup to review. */
.vote-done {
  padding: var(--sp-8) var(--sp-6);
  text-align: center;
  background: var(--soft);
  margin-top: var(--sp-6);
}
.vote-done__title {
  font-family: var(--font-display);
  font-size: 44px;
  line-height: 1;
  margin-top: var(--sp-3);
}
.vote-done__sub {
  margin-top: var(--sp-3);
  color: var(--ink);
  opacity: 0.85;
  max-width: 48ch;
  margin-left: auto;
  margin-right: auto;
}
.vote-done__buttons {
  margin-top: var(--sp-5);
  display: flex;
  justify-content: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.vote-done__hint {
  margin-top: var(--sp-5);
}

/* A/B tabs: hidden on desktop, shown on mobile — clicking toggles
 * which card is visible via data-ab-active on .vote-card-pair.
 * !important is belt-and-braces against components.css which defines
 * its own unconditional `.ab-tabs { display: flex }`. */
.ab-tabs { display: none !important; }
@media (max-width: 600px) {
  .ab-tabs { display: flex !important; }
}

@media (max-width: 600px) {
  /* Hide the big masthead and replace with the compact mini-head.
   * Two rows: context (back link · round info · countdown), then a
   * prominent "listen to all" button so engaging with the tracks is
   * one tap away on mobile. */
  .masthead--vote { display: none; }
  .vote-mini-head {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "back meta countdown"
      "listen listen listen";
    align-items: center;
    padding: var(--sp-2) var(--sp-3);
    margin: 0 calc(var(--sp-4) * -1);
    border-bottom: var(--border-width) solid var(--ink);
    gap: var(--sp-2) var(--sp-3);
  }
  .vote-mini-head__back     { grid-area: back; }
  .vote-mini-head__meta     { grid-area: meta; text-align: center; }
  .vote-mini-head__countdown { grid-area: countdown; }
  .vote-mini-head__listen {
    grid-area: listen;
    justify-self: stretch;
    margin-top: var(--sp-2);
  }

  .ab-tabs {
    display: flex;
    gap: 8px;
    margin-top: var(--sp-3);
  }
  .ab-tabs__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex: 1;
    padding: 10px 12px;
    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-micro);
    letter-spacing: var(--ls-mono-lg);
    font-weight: 700;
    cursor: pointer;
  }
  .ab-tabs__btn.is-active {
    background: var(--ink);
    color: var(--paper);
    box-shadow: none;
  }
  .ab-tabs__pick-pill {
    background: var(--accent);
    color: var(--paper);
    padding: 1px 6px;
    font-size: var(--fs-micro-xs);
    letter-spacing: var(--ls-mono-sm);
  }

  .vote-card-pair {
    grid-template-columns: 1fr;
    margin-top: var(--sp-3);
  }
  .vote-card-pair .vs { display: none; }
  .vote-card-pair[data-ab-active="a"] .vote-card--b,
  .vote-card-pair[data-ab-active="b"] .vote-card--a {
    display: none;
  }

  /* Stack card contents vertically, centred, like the mockup.
   * The corner tag is redundant on mobile — the active A/B tab
   * already labels which track is showing. */
  .vote-card__tag { display: none; }
  .vote-card {
    gap: 12px;
    padding: 16px 14px;
  }
  .vote-card__head {
    grid-template-columns: 1fr;
    gap: 12px;
    justify-items: center;
    text-align: center;
  }
  .vote-card__head .art-tile {
    width: 190px;
    height: 190px;
  }
  .vote-card__info {
    align-items: center;
    text-align: center;
    width: 100%;
  }
  .vote-card__title {
    font-size: 26px;
  }
  .vote-card__listen-row {
    width: 100%;
    justify-content: stretch;
  }
  .vote-card__listen-row .listen-btn { flex: 1; justify-content: center; }

  .pick-cta { padding: 14px 12px; font-size: 15px; }
  .pick-cta__ext { display: inline; }

  /* RATE buttons stretch full-width like the mockup. */
  .vote-card__rate-row {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .rating { width: 100%; }
  .rating__btn {
    flex: 1;
    min-width: 0;
    height: 32px;
    font-size: 13px;
  }

  /* Mobile submit bar: picked/rated summary on the left, big CTA right. */
  .vote-submit-bar {
    margin: var(--sp-4) calc(var(--sp-4) * -1) 0;
    align-items: center;
  }
  .vote-submit-bar__desktop { display: none; }
  .vote-submit-bar__mobile  { display: inline; }
  .vote-submit-bar__prev    { display: none; }
  .vote-submit-bar__buttons .btn { flex: 1; white-space: normal; }
}

/* ─── Prose pages (privacy, terms, contact, unsubscribe) ────────────────── */

.prose-page {
  max-width: 780px;
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  font-family: var(--font-sans);
  line-height: 1.6;
}
.prose-page h1,
.prose-page h2 {
  font-family: var(--font-display);
  letter-spacing: var(--ls-display-tight);
  margin: 0;
}
.prose-page__title {
  font-size: clamp(44px, 8vw, 72px);
  line-height: 0.95;
}
.prose-page h2 {
  font-size: clamp(22px, 3vw, 28px);
  margin-top: var(--sp-4);
}
.prose-page__sub {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mono-lg);
  text-transform: uppercase;
  color: var(--dim);
  margin: 0;
}
.prose-page p,
.prose-page ul {
  margin: 0;
}
.prose-page ul {
  padding-left: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.prose-page a {
  color: var(--accent-2);
  text-decoration: underline;
}
.prose-page a:hover { color: var(--accent); }
.prose-page__contact {
  font-family: var(--font-mono);
  font-size: var(--fs-body-lg);
  padding: var(--sp-3) 0;
}
.consent-row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  margin: var(--sp-3) 0;
  line-height: 1.4;
}
.consent-row input[type="checkbox"] {
  margin-top: 3px;
}
.oauth-consent {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--dim);
  margin: var(--sp-2) 0 0;
  text-align: center;
}
.footer__legal {
  display: inline;
}
.footer__legal a {
  color: inherit;
  text-decoration: underline;
}
