/*
 * Shared component vocabulary.
 *
 * Everything here is theme-agnostic: components only ever reference --fg,
 * --line, --mut, --surf, --mark, --acc and --score-fg, never a brand colour
 * directly. That is what lets the same roster or countdown sit on the amber
 * drop screen and the crimson reveal screen without a variant class.
 *
 * The deliberate exception is .btn--spotify, which carries Spotify's brand
 * colour wherever it lands. The personal Spotify
 * playlist card is a screen-specific third exception in screens.css.
 */

@layer components {
  /* ══ Eyebrow ═══════════════════════════════════════════════════════════════
     The label strip at the top of every screen body: where you are on the left,
     a counter or step index on the right. */
  .eyebrow {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: var(--track-label-wide);
    text-transform: uppercase;
    color: var(--mut);
  }

  .eyebrow__index {
    margin-inline-start: auto;
  }

  .eyebrow__live {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--fg);
  }

  @media (max-width: 55.999rem) {
    .eyebrow--deadline .eyebrow__live {
      white-space: nowrap;
    }

    .eyebrow--deadline .eyebrow__index {
      display: none;
    }
  }

  /* ══ Live dot ══════════════════════════════════════════════════════════════
     A square, not a circle — nothing in this design is round. Steps rather than
     eases so it reads as a hard blink, like a recording light. */
  .live-dot {
    inline-size: 0.375rem;
    block-size: 0.375rem;
    background: var(--mark);
    display: inline-block;
    flex-shrink: 0;
    animation: blink 1.1s steps(1) infinite;
  }

  .live-dot--lg {
    inline-size: 0.4375rem;
    block-size: 0.4375rem;
  }

  @keyframes blink {
    50% {
      opacity: 0.25;
    }
  }

  /* A blinking dot is decorative; if it also conveys "live", the text says so.
     Reduced-motion readers get a solid dot rather than a frozen half-faded one. */
  @media (prefers-reduced-motion: reduce) {
    .live-dot {
      animation: none;
      opacity: 1;
    }
  }

  /* ══ Section head ══════════════════════════════════════════════════════════ */
  .section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-block-start: var(--space-7);
    margin-block-end: var(--space-3);
  }

  .section-head:first-child {
    margin-block-start: 0;
  }

  /* ══ Button ════════════════════════════════════════════════════════════════
     The primary action. Full-width thumb bar on phones, contained on laptops
     (see layout.css). Square dot on the left, arrow on the right — the dot is
     what makes it read as an instrument panel rather than a web button. */
  .btn {
    inline-size: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    min-block-size: var(--tap-target);
    padding: var(--space-6) var(--space-6);
    border: 0;
    border-radius: var(--radius);
    font-family: var(--font-sans);
    font-weight: 700;
    font-size: var(--text-xl);
    letter-spacing: -0.01em;
    text-align: start;
    transition: filter var(--dur-fast) ease;
  }

  .btn:hover {
    filter: brightness(0.94);
  }

  .btn:active {
    filter: brightness(0.88);
  }

  .btn:disabled {
    cursor: not-allowed;
    filter: none;
  }

  .btn__label {
    display: flex;
    align-items: center;
    gap: var(--space-4);
  }

  .btn__dot {
    inline-size: 0.5625rem;
    block-size: 0.5625rem;
    flex-shrink: 0;
    background: currentColor;
  }

  .btn__arrow {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-2xl);
    flex-shrink: 0;
  }

  /* Phase fills. Each pairs the phase's mid tone with its darkest ink so the
     label clears contrast on the fill, not on the page. */
  .btn--drop {
    background: var(--drop-mid);
    color: var(--drop-deep);
  }

  .btn--vote {
    background: var(--vote-mid);
    color: var(--vote-dark);
  }

  .btn--reveal {
    background: var(--reveal-mid);
    color: #32130d;
  }

  .btn--prof {
    background: var(--prof-mid);
    color: var(--prof-dark);
  }

  .btn--ink {
    background: var(--neutral-fg);
    color: var(--neutral-bg);
  }

  .btn--ink .btn__dot {
    background: var(--drop-mid);
  }

  /* Completed state: you have done the thing, the button stays as a way back in
     but stops competing for attention. */
  .btn--done {
    background: var(--beton);
    color: var(--ink);
  }

  .btn--done .btn__arrow {
    font-size: var(--text-lg);
  }

  /* Not yet available — visible, legible, obviously inert. */
  .btn--disabled {
    background: transparent;
    border: var(--hairline) solid var(--line);
    color: var(--mut);
  }

  .btn--ghost {
    background: transparent;
    border: var(--hairline) solid var(--fg);
    color: var(--fg);
  }

  .btn--danger {
    background: transparent;
    border: var(--hairline) solid var(--fail);
    color: var(--fail);
  }

  /* Third-party brands keep their own colour in every theme. Connection
     buttons and primary mobile listening actions use the brand fill;
     secondary outbound listening links use an outline. */
  .btn--spotify {
    background: var(--spotify);
    color: var(--spotify-ink);
  }

  a.btn--spotify:not(.btn--spotify-filled) {
    padding-block: var(--space-4);
    border: var(--hairline) solid var(--spotify);
    background: transparent;
    color: var(--fg);
  }

  /* A full-bleed thumb bar makes no sense with a mouse, so on laptops the CTA
     shrinks to a contained button.

     This lives in the components layer rather than next to the rest of the
     shell in layout.css on purpose: layout is an EARLIER layer, so a rule there
     would lose to `.btn { inline-size: 100% }` above no matter how specific it
     was. Overrides of a component belong in the component's layer. */
  @media (min-width: 56rem) {
    .screen__cta .btn {
      inline-size: auto;
      min-inline-size: 15.5rem;
      flex: 0 0 auto;
      padding: var(--space-5) var(--space-6);
    }

    .screen--desktop-action-pinned .screen__cta .btn {
      inline-size: 100%;
      min-inline-size: 0;
      flex: 1 1 auto;
    }
  }

  .share-copy-status {
    display: block;
    flex-basis: 100%;
    margin-block-start: var(--space-2);
    color: var(--mut);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
  }

  /* Drop actions belong beside the game content on laptops, not in a
     floating bar. The phone keeps the same full-width, thumb-reachable CTA. */
  .drop-action--desktop {
    display: none;
  }

  .drop-bonus {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-1) var(--space-4);
    margin-block-start: var(--space-6);
    padding: var(--space-3) var(--space-4);
    border: var(--hairline) solid var(--fg);
    border-inline-start: 4px solid var(--mark);
    background: var(--surf);
  }

  .drop-bonus__label,
  .drop-bonus__count {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .drop-bonus__count {
    text-align: end;
  }

  .drop-bonus__title {
    grid-column: 1 / -1;
    display: block;
    margin-block-start: var(--space-1);
    font-size: var(--text-lg);
    color: var(--fg);
  }

  .drop-slot-label {
    margin-block-start: var(--space-6);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg);
  }

  @media (min-width: 56rem) {
    .screen__cta:has(.drop-action--mobile) {
      display: none;
    }

    .drop-action--desktop {
      display: block;
      margin-block-start: var(--space-5);
    }

    .drop-action--desktop .btn {
      inline-size: min(100%, 20rem);
      padding: var(--space-4) var(--space-5);
      font-size: var(--text-md);
    }
  }

  /* The live playlist stays thumb-reachable while someone builds their ballot.
     Its existing playlist-card action takes over on laptop screens. */
  .vote-playlist-action--desktop {
    display: none;
  }

  @media (min-width: 56rem) {
    .screen__cta:has(.vote-playlist-action--mobile) {
      display: none;
    }

    .vote-playlist-action--desktop {
      display: block;
    }
  }

  /* Library playlists stay thumb-reachable in the phone shell. On laptops the
     same action moves below the title, before a long track list can push it out
     of sight. */
  .library-playlist-action--desktop {
    display: none;
  }

  @media (min-width: 56rem) {
    .screen__cta:has(.library-playlist-action--mobile) {
      display: none;
    }

    .library-playlist-action--desktop {
      display: block;
      margin-block-start: var(--space-5);
    }

    .library-playlist-action--desktop .btn {
      inline-size: auto;
      min-inline-size: 15.5rem;
    }

    .library-playlist-action--desktop + .tabs {
      margin-block-start: var(--space-5);
    }
  }

  /* Secondary action under the primary one. */
  .btn-sub {
    display: block;
    inline-size: 100%;
    min-block-size: var(--tap-target);
    margin-block-start: var(--space-3);
    padding: var(--space-2);
    text-align: center;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .btn-sub:hover {
    color: var(--fg);
  }

  .btn-sub b {
    color: var(--fg);
    border-block-end: var(--hairline) solid var(--fg);
    padding-block-end: 1px;
  }

  /* ══ Embed ═════════════════════════════════════════════════════════════════
     Spotify iframes. aspect-ratio rather than the padding-top hack, and the
     iframe fills the box so the ratio is the only thing to maintain. */
  .embed {
    margin-block-start: var(--space-5);
    border: var(--hairline) solid var(--fg);
  }

  .embed iframe {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    border: 0;
  }

  .embed--square {
    aspect-ratio: 1;
  }

  .embed--playlist {
    block-size: 5rem;
  }

  @media (min-width: 56rem) {
    .embed--playlist {
      block-size: 9.5rem;
    }
  }

  /* A single track's player: Spotify's compact embed is a fixed 152px tall. */
  .embed--track {
    block-size: 9.5rem;
  }

  /* ══ Code block ════════════════════════════════════════════════════════════
     Invite links and codes. Wraps rather than scrolls: a URL you can't see all
     of is a URL you can't check before sending. */
  .codeblock {
    border: var(--hairline) solid var(--fg);
    background: var(--surf);
    padding: var(--space-4) var(--space-5);
    font-family: var(--font-mono);
    font-size: var(--text-md);
    color: var(--fg);
    overflow-wrap: anywhere;
    user-select: all;
  }

  .codeblock--lg {
    font-size: var(--text-2xl);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-align: center;
  }

  /* ══ Pill ══════════════════════════════════════════════════════════════════ */
  .pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
    border: var(--hairline) solid var(--fg);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg);
  }

  .pill--accent {
    background: var(--acc);
    border-color: var(--acc);
    color: var(--on-acc);
  }

  /* Phase badges use the phase's DARK tone as a fill with white text, so they
     stay legible on any of the light phase backgrounds. */
  .pill--drop {
    background: var(--drop-dark);
    border-color: var(--drop-dark);
    color: #fff;
  }

  .pill--vote {
    background: var(--vote-dark);
    border-color: var(--vote-dark);
    color: #fff;
  }

  .pill--reveal {
    background: var(--reveal-dark);
    border-color: var(--reveal-dark);
    color: #fff;
  }

  .pill--pause {
    background: var(--fg);
    border-color: var(--fg);
    color: var(--bg);
  }

  /* The optional title/theme is game-level context. It appears in every phase
     and keeps the owner's edit control beside the value instead of burying it
     in the flon's settings. */
  .game-theme {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    margin-block-start: var(--space-5);
    padding: var(--space-4);
    border: var(--hairline) solid var(--line);
    background: var(--surf);
  }

  .game-theme__copy {
    min-inline-size: 0;
  }

  .game-theme__title,
  .game-theme__empty {
    margin-block-start: var(--space-2);
    line-height: 1.35;
  }

  .game-theme__title {
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--fg);
  }

  .game-theme__empty {
    color: var(--mut);
  }

  .game-theme__edit {
    min-block-size: var(--tap-target);
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg);
  }

  /* ══ Countdown ═════════════════════════════════════════════════════════════
     The default phase deadline sits beside the page title. The banner variant
     gives imminent transitions their own full-width, high-contrast beat. */
  .phase-title {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--space-4);
  }

  .phase-title > .u-display {
    min-inline-size: 0;
  }

  .countdown {
    display: flex;
    flex-direction: column;
    align-items: end;
    gap: var(--space-1);
    flex-shrink: 0;
    font-family: var(--font-mono);
    text-align: end;
    white-space: nowrap;
  }

  .countdown__value {
    font-size: var(--text-lg);
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.02em;
    color: var(--fg);
    font-variant-numeric: tabular-nums;
  }

  .countdown__meta {
    font-size: var(--text-3xs);
    line-height: 1.2;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .countdown--banner {
    flex-flow: row wrap;
    align-items: baseline;
    justify-content: flex-start;
    gap: var(--space-4);
    inline-size: 100%;
    margin-block-start: var(--space-6);
    padding: var(--space-3) var(--space-5);
    border: var(--hairline) solid var(--fg);
    background: var(--acc);
    color: var(--on-acc);
    text-align: center;
    white-space: normal;
  }

  .countdown--banner .countdown__value {
    font-size: var(--text-2xl);
    color: currentColor;
  }

  .countdown--banner .countdown__meta {
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: none;
    color: currentColor;
  }

  /* ══ Vote status ═══════════════════════════════════════════════════════════
     A full-width answer to the ballot's only urgent question: is anything
     still missing? It updates with the Turbo-framed ranking. */
  .vote-status {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    inline-size: 100%;
    margin-block-start: var(--space-3);
    padding: var(--space-3) var(--space-5);
    border: var(--hairline) solid currentColor;
    font-family: var(--font-mono);
  }

  .vote-status--complete {
    color: color-mix(in srgb, var(--pass) 75%, var(--fg));
  }

  .vote-status--incomplete {
    color: color-mix(in srgb, var(--fail) 80%, var(--fg));
  }

  .vote-status__mark {
    display: grid;
    place-items: center;
    inline-size: 1.5rem;
    block-size: 1.5rem;
    flex-shrink: 0;
    border: var(--hairline) solid currentColor;
    font-size: var(--text-lg);
    font-weight: 800;
    line-height: 1;
  }

  .vote-status__copy {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    min-inline-size: 0;
    white-space: nowrap;
  }

  .vote-status__title {
    font-size: var(--text-md);
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  .vote-status__detail {
    font-size: var(--text-xs);
    font-weight: 600;
  }

  .voting-progress {
    margin-block-start: var(--space-6);
  }

  .result-card-frame {
    display: block;
  }

  /* ══ Roster ════════════════════════════════════════════════════════════════
     Who has posted / who has voted. Social pressure, rendered as a list. */
  .roster {
    display: flex;
    flex-direction: column;
    margin-block-start: var(--space-3);
  }

  .roster__row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding-block: var(--space-4);
    border-block-start: var(--hairline) solid var(--line);
  }

  .roster__row:last-child {
    border-block-end: var(--hairline) solid var(--line);
  }

  .roster__index {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: var(--text-xs);
    color: var(--mut);
    inline-size: 1.125rem;
    flex-shrink: 0;
  }

  .roster__name {
    flex: 1;
    min-inline-size: 0;
    font-weight: 600;
    font-size: var(--text-lg);
    letter-spacing: -0.01em;
    color: var(--fg);
  }

  .roster__you {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.1em;
    color: var(--mut);
    margin-inline-start: var(--space-2);
  }

  .roster__status {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--fg);
  }

  .roster__status::before {
    content: "";
    inline-size: 0.375rem;
    block-size: 0.375rem;
    background: currentColor;
  }

  /* Waiting reads quieter, and its marker is an outline rather than a fill —
     so the state survives being printed, or seen without colour. */
  .roster__status--waiting {
    color: var(--mut);
    font-weight: 500;
  }

  .roster__status--waiting::before {
    background: transparent;
    box-shadow: inset 0 0 0 1px currentColor;
  }

  /* ══ Ranking ═══════════════════════════════════════════════════════════════ */
  .ranking {
    display: flex;
    flex-direction: column;
    margin-block-start: var(--space-3);
  }

  .ranking__player {
    border-block-start: var(--hairline) solid var(--line);
  }

  .ranking__player:last-child {
    border-block-end: var(--hairline) solid var(--line);
  }

  /* Every row carries the same inline padding, including the ones with no
     highlight. Otherwise the reader's own row indents its text by the width of
     its accent rail and stops lining up with the rows above and below. */
  .ranking__row {
    display: flex;
    align-items: baseline;
    gap: var(--space-4);
    padding-block: var(--space-3);
    padding-inline: var(--space-4);
    cursor: pointer;
    list-style: none;
  }

  .ranking__row::-webkit-details-marker {
    display: none;
  }

  .ranking__position {
    font-weight: 800;
    font-size: var(--text-xl);
    inline-size: 1rem;
    flex-shrink: 0;
    color: var(--fg);
  }

  .ranking__name {
    flex: 1;
    min-inline-size: 0;
    font-weight: 600;
    font-size: var(--text-base);
    color: var(--fg);
  }

  .ranking__meta {
    display: block;
    margin-block-start: var(--space-1);
    overflow: hidden;
    text-overflow: ellipsis;
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 500;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .ranking__points {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-sm);
    color: var(--score-fg);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
  }

  .ranking__toggle {
    inline-size: 1rem;
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: var(--text-lg);
    text-align: center;
    color: var(--mut);
  }

  .ranking__details[open] .ranking__toggle {
    rotate: 45deg;
  }

  .ranking__ballot {
    padding: var(--space-2) var(--space-4) var(--space-6) calc(var(--space-4) + 1rem + var(--space-4));
  }

  .ranking__ballot-title {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
    margin-block-end: var(--space-3);
  }

  .ranking__drops {
    margin-block-end: var(--space-6);
  }

  .ranking__drop {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-3);
    padding-block: var(--space-3);
    border-block-start: var(--hairline) solid var(--line);
  }

  .ranking__drop-status {
    display: block;
    margin-block-start: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    color: var(--mut);
  }

  .ranking__drop--uncounted .ranking__points {
    color: var(--mut);
  }

  .ranking__points--uncounted {
    text-decoration-thickness: 0.1em;
  }

  .ranking__votes {
    display: flex;
    flex-direction: column;
  }

  .ranking__vote {
    display: grid;
    grid-template-columns: 1.5rem minmax(0, 1fr);
    gap: var(--space-3);
    padding-block: var(--space-3);
    border-block-start: var(--hairline) solid var(--line);
  }

  .ranking__vote-position {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 700;
    color: var(--score-fg);
  }

  .ranking__vote-track,
  .ranking__vote-name,
  .ranking__vote-artists {
    display: block;
    min-inline-size: 0;
  }

  .ranking__vote-name {
    font-size: var(--text-base);
    font-weight: 650;
    color: var(--fg);
  }

  .ranking__vote-artists {
    margin-block-start: var(--space-1);
    font-size: var(--text-sm);
    color: var(--mut);
  }

  .ranking__vote-comment {
    display: block;
    margin-block-start: var(--space-3);
    padding-inline-start: var(--space-3);
    border-inline-start: 2px solid var(--line);
    font-size: var(--text-sm);
    font-style: italic;
    line-height: 1.45;
    color: var(--fg);
  }

  .ranking__ballot-note {
    margin-block-start: var(--space-3);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--mut);
  }

  /* The reader's own row.
     Marked with a fill and an accent rule rather than the mockup's full-bleed
     pull-out: that relied on a negative margin exactly matching the body
     padding, which only held on phones (--space-6). On a laptop, or nested in
     the group home's frame, it left the row sticking out past every block
     around it. */
  .ranking__row--you {
    background: var(--surf);
    box-shadow: inset 3px 0 0 var(--acc);
  }

  /* ══ Callout ═══════════════════════════════════════════════════════════════
     A sentence that matters, marked with a rule rather than a box. */
  .callout {
    border-inline-start: 2px solid var(--mark);
    padding: var(--space-1) 0 var(--space-1) var(--space-5);
    margin-block-start: var(--space-6);
    font-size: var(--text-lg);
    line-height: 1.4;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--fg);
  }

  .callout--warn {
    border-color: var(--warn);
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
  }

  .callout--warn::before {
    content: "⚠";
    color: var(--warn);
    font-weight: 800;
    flex-shrink: 0;
  }

  /* The ballot is complete. The tick carries the meaning; the text stays on
     --fg so it reads on every theme. */
  .callout--done {
    border-color: var(--pass);
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
  }

  .callout--done::before {
    content: "✓";
    color: var(--pass);
    font-weight: 800;
    flex-shrink: 0;
  }

  /* ══ Tile ══════════════════════════════════════════════════════════════════
     A bordered row that navigates somewhere. */
  .tile {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    inline-size: 100%;
    min-block-size: var(--tap-target);
    padding: var(--space-5);
    border: var(--hairline) solid var(--fg);
    background: transparent;
    color: var(--fg);
    margin-block-start: var(--space-3);
  }

  .tile:hover {
    background: var(--surf);
  }

  .tile--filled {
    background: var(--surf);
  }

  .tile--accent {
    border-color: var(--acc);
  }

  .tile--dashed {
    display: grid;
    place-items: center;
    border-style: dashed;
    text-align: center;
    color: var(--mut);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }

  .tile__icon {
    inline-size: 1.875rem;
    block-size: 1.875rem;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: var(--hairline) solid var(--fg);
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-sm);
  }

  .tile__text {
    flex: 1;
    min-inline-size: 0;
    text-align: start;
  }

  .tile__name {
    display: block;
    font-weight: 700;
    font-size: var(--text-lg);
    letter-spacing: var(--track-tight);
    color: var(--fg);
  }

  .tile__sub {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-start: var(--space-1);
  }

  .tile__arrow {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-lg);
    color: var(--mut);
    flex-shrink: 0;
  }

  /* ══ Disclosure ════════════════════════════════════════════════════════════
     Built on <details>, so it opens without JavaScript and is announced
     correctly by screen readers for free. */
  .disclosure {
    border: var(--hairline) solid var(--fg);
    background: var(--surf);
    margin-block-start: var(--space-4);
  }

  .disclosure__summary {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-block-size: var(--tap-target);
    padding: var(--space-5);
    font-family: var(--font-mono);
    font-size: var(--text-md);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg);
    cursor: pointer;
    list-style: none;
  }

  /* Kill both the WebKit and the standards-track default marker. */
  .disclosure__summary::-webkit-details-marker {
    display: none;
  }

  .disclosure__summary::marker {
    content: "";
  }

  .disclosure__label {
    flex: 1;
    min-inline-size: 0;
  }

  .disclosure__count {
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    border: var(--hairline) solid var(--mark);
    color: var(--score-fg);
    padding: var(--space-1) var(--space-2);
    white-space: nowrap;
  }

  .disclosure__chevron {
    font-family: var(--font-mono);
    font-size: var(--text-md);
    color: var(--fg);
    transition: rotate var(--dur-fast) ease;
  }

  .disclosure[open] .disclosure__chevron {
    rotate: 180deg;
  }

  .disclosure__body {
    border-block-start: var(--hairline) solid var(--line);
  }

  .disclosure__item {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-5);
    border-block-start: var(--hairline) solid var(--line);
  }

  .disclosure__item:first-child {
    border-block-start: 0;
  }

  .disclosure__item--track {
    align-items: flex-start;
  }

  .disclosure__item--track .track-card__cover {
    inline-size: 2.5rem;
    block-size: 2.5rem;
  }

  .disclosure__track {
    display: flex;
    flex: 1;
    min-inline-size: 0;
    flex-direction: column;
    gap: var(--space-2);
  }

  .disclosure__note {
    font-size: var(--text-sm);
    font-style: italic;
    line-height: 1.4;
    color: var(--mut);
  }

  .disclosure__note--empty {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-style: normal;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.7;
  }

  /* ══ Sheet ═════════════════════════════════════════════════════════════════
     A native <dialog>: bottom sheet on phones, centred modal on laptops. Using
     the element rather than a div means focus trapping, Esc-to-close, inertness
     of the page behind and the top layer all come from the platform. */
  .sheet {
    /* dialog is display:none until open; the modal styles live in [open] so the
       transition has something to animate from. */
    position: fixed;
    inset: auto 0 0;
    inline-size: 100%;
    max-block-size: 82dvh;
    margin: 0;
    background: var(--surf);
    color: var(--fg);
    border-block-start: var(--hairline) solid var(--fg);
    flex-direction: column;
    translate: 0 100%;
    transition:
      translate var(--dur-base) var(--ease-sheet),
      overlay var(--dur-base) allow-discrete,
      display var(--dur-base) allow-discrete;
  }

  .sheet[open] {
    display: flex;
    translate: 0 0;
  }

  /* The entry keyframe: @starting-style is what lets a display:none element
     animate in without a JS double-rAF. */
  @starting-style {
    .sheet[open] {
      translate: 0 100%;
    }
  }

  .sheet::backdrop {
    background: rgb(24 19 14 / 50%);
    opacity: 0;
    transition:
      opacity var(--dur-fast) ease,
      overlay var(--dur-fast) allow-discrete,
      display var(--dur-fast) allow-discrete;
  }

  .sheet[open]::backdrop {
    opacity: 1;
  }

  @starting-style {
    .sheet[open]::backdrop {
      opacity: 0;
    }
  }

  .sheet__grab {
    display: flex;
    justify-content: center;
    padding: var(--space-3) 0 var(--space-1);
    flex-shrink: 0;
  }

  .sheet__grab::before {
    content: "";
    inline-size: 2.5rem;
    block-size: 4px;
    background: var(--mut);
  }

  .sheet__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-1) var(--space-6) var(--space-4);
    border-block-end: var(--hairline) solid var(--line);
    flex-shrink: 0;
  }

  .sheet__title {
    font-weight: 800;
    font-size: var(--text-3xl);
    letter-spacing: -0.03em;
    color: var(--fg);
  }

  .sheet__close {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mut);
    min-block-size: var(--tap-target);
    padding-inline: var(--space-2);
  }

  .sheet__body {
    padding: var(--space-5) var(--space-6) var(--space-6);
    padding-block-end: calc(var(--space-6) + env(safe-area-inset-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  @media (min-width: 56rem) {
    .sheet {
      inset: 50% auto auto 50%;
      inline-size: 27rem;
      max-inline-size: 92vw;
      max-block-size: 84dvh;
      border: var(--hairline) solid var(--fg);
      box-shadow: 0 30px 80px rgb(12 10 7 / 50%);
      translate: -50% -50%;
      scale: 0.96;
      opacity: 0;
      transition:
        opacity var(--dur-fast) ease,
        scale var(--dur-fast) var(--ease-out),
        overlay var(--dur-fast) allow-discrete,
        display var(--dur-fast) allow-discrete;
    }

    .sheet[open] {
      translate: -50% -50%;
      scale: 1;
      opacity: 1;
    }

    @starting-style {
      .sheet[open] {
        scale: 0.96;
        opacity: 0;
      }
    }

    .sheet__grab {
      display: none;
    }
  }

  /* ══ Track submission ══════════════════════════════════════════════════════
     Keeps the inline drop form visually distinct from the game status and
     supporting information that follow it. */
  .track-submission {
    margin-block-start: var(--space-6);
    padding: var(--space-5);
    border: var(--hairline) solid var(--line);
    background: var(--surf);
  }

  .track-submission > .drop-slot-label {
    margin-block-start: 0;
    margin-block-end: var(--space-5);
  }

  /* ══ Field ═════════════════════════════════════════════════════════════════ */
  .field {
    margin-block-end: var(--space-6);
  }

  .field__label {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-end: var(--space-3);
  }

  .field__required {
    color: var(--fail);
    margin-inline-start: var(--space-1);
  }

  .field__input {
    inline-size: 100%;
    min-block-size: var(--tap-target);
    padding: var(--space-5);
    border: var(--hairline) solid var(--fg);
    border-radius: var(--radius);
    background: var(--surf);
    color: var(--fg);
    font-weight: 600;
    font-size: var(--text-lg);
  }

  textarea.field__input {
    min-block-size: 3.625rem;
    resize: vertical;
    font-size: var(--text-base);
    font-weight: 400;
    line-height: 1.4;
  }

  /* Readable on phones and touch tablets; 16px also prevents iOS focus zoom.
     Include textarea explicitly: its more-specific rule otherwise wins. */
  @media (any-pointer: coarse), (width < 56rem) {
    .field__input,
    textarea.field__input {
      font-size: max(1rem, var(--text-lg));
    }
  }

  .field__input::placeholder {
    color: var(--mut);
    font-weight: 400;
  }

  .field__input:focus-visible {
    outline: 2px solid var(--acc);
    outline-offset: -2px;
  }

  .field__input[aria-invalid="true"] {
    border-color: var(--fail);
  }

  .field__hint {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.04em;
    color: var(--mut);
    margin-block-start: var(--space-3);
  }

  .field__error {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.04em;
    color: var(--fail);
    margin-block-start: var(--space-3);
  }

  .field-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
  }

  .field-pair .field {
    margin-block-end: 0;
  }

  /* ══ Tabs ══════════════════════════════════════════════════════════════════
     A segmented control. Real links or radios in the markup — never a div with
     a click handler. */
  .tabs {
    display: flex;
    border: var(--hairline) solid var(--fg);
    margin-block-start: var(--space-6);
  }

  .tabs__tab {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    min-block-size: var(--tap-target);
    padding: var(--space-3) var(--space-1);
    line-height: 1.2;
    border-inline-end: var(--hairline) solid var(--fg);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-align: center;
    color: var(--mut);
  }

  .tabs__tab:last-child {
    border-inline-end: 0;
  }

  .tabs__tab:hover {
    color: var(--fg);
  }

  .tabs__tab[aria-selected="true"],
  .tabs__tab[aria-current="page"] {
    background: var(--fg);
    color: var(--bg);
  }

  /* ══ Switch ════════════════════════════════════════════════════════════════
     A checkbox styled as a hard-edged toggle. The input stays in the markup so
     it is focusable, labellable and submits with the form. */
  .switch {
    position: relative;
    inline-size: 2.5rem;
    block-size: 1.4375rem;
    flex-shrink: 0;
    border: var(--hairline) solid var(--fg);
    background: transparent;
    appearance: none;
    cursor: pointer;
    transition: background var(--dur-fast) ease;
  }

  .switch::after {
    content: "";
    position: absolute;
    inset-block-start: 2px;
    inset-inline-start: 2px;
    inline-size: 1.0625rem;
    block-size: 1.0625rem;
    background: var(--fg);
    transition: translate var(--dur-fast) steps(2);
  }

  .switch:checked,
  .switch.is-on {
    background: var(--fg);
  }

  .switch:checked::after,
  .switch.is-on::after {
    translate: 1.0625rem 0;
    background: var(--surf);
  }

  .pause-toggle {
    flex-shrink: 0;
  }

  /* ══ Setting row ═══════════════════════════════════════════════════════════
     A labelled toggle. The switch is the real checkbox (see .switch above), so
     it stays focusable and submits with the form. */
  .setting {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    padding-block: var(--space-5);
    border-block-start: var(--hairline) solid var(--line);
  }

  .setting:last-of-type {
    border-block-end: var(--hairline) solid var(--line);
  }

  .setting__text {
    flex: 1;
    min-inline-size: 0;
  }

  .setting__name {
    display: block;
    font-weight: 600;
    font-size: var(--text-lg);
    letter-spacing: -0.01em;
    color: var(--fg);
  }

  .setting__sub {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.04em;
    color: var(--mut);
    margin-block-start: var(--space-1);
  }

  /* ══ Setup progress and installation guidance ══════════════════════════════ */
  .setup-stepper {
    display: flex;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
    padding: 0;
    list-style: none;
  }

  .setup-stepper__step {
    flex: 1;
    block-size: 3px;
    background: var(--line);
  }

  .setup-stepper__step--done,
  .setup-stepper__step--current {
    background: var(--fg);
  }

  .setup-label,
  .masthead-context {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .masthead-context {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    min-block-size: var(--masthead-control);
    white-space: nowrap;
  }

  .setup-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 4.375rem;
    block-size: 4.375rem;
    margin-block-start: var(--space-6);
    border: var(--hairline) solid var(--fg);
    font-family: var(--font-mono);
    font-size: var(--text-2xl);
    font-weight: 700;
  }

  .install-app {
    display: flex;
    align-items: center;
    gap: var(--space-4);
  }

  .install-app__icon {
    border-radius: 22%;
  }

  .install-app__caption {
    display: block;
    margin-block-start: var(--space-1);
    font-size: var(--text-sm);
    color: var(--mut);
  }

  .install-instructions {
    margin-block-start: var(--space-6);
    border: var(--hairline) solid var(--line);
    border-radius: var(--radius);
    background: var(--surf);
    overflow: hidden;
  }

  .install-guide + .install-guide {
    border-block-start: var(--hairline) solid var(--line);
  }

  .install-guide__heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-block-size: 3.5rem;
    padding: var(--space-4);
    cursor: pointer;
    list-style: none;
    font-weight: 700;
  }

  .install-guide__heading::-webkit-details-marker {
    display: none;
  }

  .install-guide__browser {
    margin-inline-start: var(--space-2);
    font-weight: 400;
    font-size: var(--text-sm);
    color: var(--mut);
  }

  .install-guide__toggle {
    font-family: var(--font-mono);
    font-size: var(--text-xl);
  }

  .install-guide[open] .install-guide__toggle {
    transform: rotate(45deg);
  }

  .install-guide__steps {
    counter-reset: install-step;
    list-style: none;
    margin: 0;
    padding: 0 var(--space-4) var(--space-4);
  }

  .install-guide__steps li {
    counter-increment: install-step;
    display: grid;
    grid-template-columns: 1rem 2.5rem minmax(0, 1fr);
    align-items: center;
    gap: var(--space-3);
    padding-block: var(--space-3);
    border-block-start: var(--hairline) solid var(--line);
    font-size: var(--text-base);
  }

  .install-guide__steps li::before {
    content: counter(install-step);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--mut);
  }

  .install-icon {
    inline-size: 2.5rem;
    block-size: 2.5rem;
    padding: var(--space-2);
    border: var(--hairline) solid var(--line);
    border-radius: var(--radius);
  }

  .install-guide__steps small {
    display: block;
    margin-block-start: var(--space-1);
    font-size: var(--text-md);
    line-height: 1.5;
    color: var(--mut);
  }

  .install-guide__finish {
    margin-block-start: var(--space-4);
    font-size: var(--text-sm);
    color: var(--mut);
  }

  /* ══ Stat grid ═════════════════════════════════════════════════════════════ */
  .stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
    border: var(--hairline) solid var(--fg);
    margin-block-start: var(--space-6);
  }

  .stat-grid__cell {
    padding: var(--space-5);
    border-inline-end: var(--hairline) solid var(--line);
  }

  .stat-grid__cell:last-child {
    border-inline-end: 0;
  }

  .stat-grid__value {
    font-weight: 800;
    font-size: var(--display-sm);
    letter-spacing: -0.03em;
    line-height: 1;
    color: var(--fg);
  }

  .stat-grid__value--accent {
    color: var(--score-fg);
  }

  .stat-grid__label {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-start: var(--space-3);
    line-height: 1.4;
  }

  .stat-grid--three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /* ══ Champions ═════════════════════════════════════════════════════════════ */
  .champions {
    border: var(--hairline) solid var(--fg);
  }

  .champions__row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
    border-block-start: var(--hairline) solid var(--line);
  }

  .champions__row:first-child {
    border-block-start: 0;
  }

  .champions__scope,
  .champions__wins {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  .champions__scope {
    flex: 0 0 6.5rem;
    color: var(--mut);
  }

  .champions__name {
    flex: 1;
    min-inline-size: 0;
    font-size: var(--text-md);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .champions__wins {
    color: var(--score-fg);
    white-space: nowrap;
  }

  /* ══ Track card ════════════════════════════════════════════════════════════
     A submitted track: artwork, title, artists. Used on the drop screen for
     your own entry and in the library for everyone's. */
  .track-card {
    border: var(--hairline) solid var(--fg);
    background: var(--surf);
    margin-block-start: var(--space-6);
  }

  .track-card--pending {
    border: 2px solid var(--warn);
  }

  .track-card--rejected {
    border: 2px solid var(--fail);
  }

  .track-card--pending .track-card__head {
    border-color: var(--warn);
  }

  .track-card--rejected .track-card__head,
  .track-card--rejected .track-card__status {
    border-color: var(--fail);
  }

  .track-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-5);
    border-block-end: var(--hairline) solid var(--fg);
  }

  .track-card__key {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg);
  }

  .track-card__working {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg);
  }

  .track-card__change {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg);
    border-block-end: var(--hairline) solid currentColor;
    padding-block-end: 1px;
    white-space: nowrap;
  }

  .track-card__body {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    padding: var(--space-5);
  }

  .track-card__cover {
    inline-size: 3rem;
    block-size: 3rem;
    flex-shrink: 0;
    background: var(--mark);
    object-fit: cover;
  }

  /* No artwork yet (the track is still being enriched): a hatched placeholder
     that reads as "pending" rather than as a broken image. */
  .track-card__cover--empty {
    position: relative;
    overflow: hidden;
  }

  .track-card__cover--empty::after {
    content: "";
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(
      135deg,
      rgb(0 0 0 / 16%) 0 4px,
      transparent 4px 8px
    );
  }

  .track-card__meta {
    min-inline-size: 0;
  }

  .track-card__name {
    font-weight: 700;
    font-size: var(--text-xl);
    letter-spacing: var(--track-tight);
    color: var(--fg);
  }

  .track-card__artists {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-start: var(--space-2);
  }

  .track-card__note {
    padding: 0 var(--space-5) var(--space-5);
    font-size: var(--text-md);
    line-height: 1.45;
    color: var(--fg);
  }

  .track-card__note span {
    display: block;
    margin-block-end: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .track-card__status {
    padding: var(--space-3) var(--space-5);
    border-block-start: var(--hairline) solid var(--line);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .track-card__status--invalid {
    color: var(--fail);
  }

  /* ══ Vote slots ════════════════════════════════════════════════════════════
     Your podium, one slot per position. An empty slot is a button that opens
     the track picker; a filled one shows the track and takes a note.

     A completed ranking is reordered by dragging the card itself: everything
     but the remove button and the comment field is the grip. Pointer events
     make the same interaction work with touch or a mouse (touch needs a short
     press, so a swipe still scrolls); the grip also takes arrow keys so
     dragging is never the only option. */
  turbo-frame#vote-ranking {
    display: block;
    scroll-margin-block-start: var(--space-5);
  }

  .vote-ranking {
    margin-block-start: var(--space-7);
  }

  .vote-ranking__head {
    align-items: baseline;
    margin-block-end: var(--space-4);
  }

  .vote-ranking__title {
    color: var(--fg);
    font-size: var(--text-3xl);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.03em;
  }

  .vote-slots {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-block-start: var(--space-5);
  }

  .vote-slot {
    border: var(--hairline) solid var(--fg);
  }

  /* While dragging (class names are SortableJS options):
     --ghost        the lifted copy that follows the pointer. SortableJS sets
                    it to 0.8 opacity inline; the card should read as solid.
     --placeholder  the gap in the list where it will land. */
  .vote-slot--ghost {
    background: var(--bg);
    box-shadow: 0.375rem 0.375rem 0 var(--fg);
    opacity: 1 !important;
    cursor: grabbing;
  }

  .vote-slot--placeholder {
    border-style: dashed;
    background: var(--surf);
  }

  .vote-slot--placeholder > * {
    visibility: hidden;
  }

  .vote-slot__head {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    inline-size: 100%;
    min-block-size: var(--tap-target);
    padding: var(--space-5);
    color: var(--fg);
  }

  .vote-slot__position,
  .podium__position {
    font-weight: 800;
    font-size: var(--display-md);
    letter-spacing: -0.05em;
    line-height: 0.8;
    inline-size: 2.375rem;
    flex-shrink: 0;
    color: var(--fg);
    font-variant-numeric: tabular-nums;
  }

  .vote-slot--filled .vote-slot__position {
    /* Position is meaningful text, so it needs the theme's readable foreground
       rather than the decorative mark colour (1.73:1 on the vote surface). */
    color: var(--fg);
  }

  .vote-slot__text {
    flex: 1;
    min-inline-size: 0;
    text-align: start;
  }

  .vote-slot__empty {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .vote-slot__name {
    display: block;
    font-weight: 700;
    font-size: var(--text-lg);
    letter-spacing: var(--track-tight);
    color: var(--fg);
  }

  .vote-slot__artists {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-start: var(--space-1);
  }

  .vote-slot__chevron {
    display: inline-grid;
    place-items: center;
    min-inline-size: var(--tap-target);
    min-block-size: var(--tap-target);
    flex-shrink: 0;
    color: var(--mut);
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-md);
  }

  /* The grip takes over the head's padding so the whole card surface, not
     just its text, picks it up. */
  .vote-slot__head:has(> .vote-slot__grip) {
    padding: 0;
    padding-inline-end: var(--space-3);
  }

  .vote-slot__grip {
    display: flex;
    flex: 1;
    align-items: center;
    gap: var(--space-5);
    min-inline-size: 0;
    align-self: stretch;
    padding: var(--space-5);
  }

  .vote-slot__grip--draggable {
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
  }

  .vote-slot__grip--draggable:active {
    cursor: grabbing;
  }

  .vote-slot__grip--draggable:focus-visible {
    outline: 3px solid var(--acc);
    outline-offset: -3px;
  }

  .vote-slot__note {
    display: flex;
    border-block-start: var(--hairline) solid var(--line);
  }

  .vote-slot__note input {
    flex: 1;
    min-inline-size: 0;
    border: 0;
    background: var(--surf);
    padding: var(--space-3) var(--space-5);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--fg);
  }

  /* Match other mobile controls and prevent iOS focus zoom. */
  @media (any-pointer: coarse), (width < 56rem) {
    .vote-slot__note input {
      font-size: 1rem;
    }
  }

  .vote-slot__note input::placeholder {
    color: var(--mut);
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  /* ══ Track picker ══════════════════════════════════════════════════════════
     The list inside the pick-a-track sheet. Tracks you can't choose (your own,
     or one you've already ranked) stay visible but dimmed and inert — seeing
     the whole playlist is part of deciding. */
  .picklist {
    display: flex;
    flex-direction: column;
  }

  .picklist__row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    inline-size: 100%;
    min-block-size: var(--tap-target);
    padding: var(--space-4) var(--space-1);
    border-block-start: var(--hairline) solid var(--line);
    text-align: start;
    color: var(--fg);
  }

  .picklist__row:first-child {
    border-block-start: 0;
  }

  /* button_to wraps its button in a form. display:contents removes that form
     from the layout so the button behaves as a direct child of .picklist. */
  .picklist .contents {
    display: contents;
  }

  .picklist__index {
    font-weight: 800;
    font-size: var(--text-3xl);
    inline-size: 1.625rem;
    flex-shrink: 0;
    color: var(--mut);
  }

  .picklist__text {
    flex: 1;
    min-inline-size: 0;
    text-align: start;
  }

  .picklist__name {
    display: block;
    font-weight: 700;
    font-size: var(--text-lg);
    letter-spacing: var(--track-tight);
    color: var(--fg);
  }

  .picklist__meta {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-start: var(--space-1);
  }

  /* Unavailable choices stay readable: dim artwork, not the reason why the
     track cannot be picked. Text also has to clear contrast on dark sheets. */
  .picklist__row--taken .picklist__name {
    color: var(--mut);
  }

  .picklist__row--taken .track-card__cover {
    opacity: 0.45;
  }

  /* The sheet rows are denser than a track card, so the artwork shrinks to match. */
  .picklist__row .track-card__cover {
    inline-size: 2.5rem;
    block-size: 2.5rem;
  }

  /* ══ Reveal row & cinema ═══════════════════════════════════════════════════
     The results list: one row per track, ranked, expanding to show who voted
     for it and what they said. Built on <details> so it works without JS.

     On a first visit Stimulus stages these same rows behind a full-screen
     spotlight. The server-rendered list remains the source of truth, so repeat
     visits, no-JS browsers and reduced-motion users get the complete result.

     Rows outside the podium are dimmed rather than hidden — the point of the
     reveal is seeing where everything landed, including last. */
  .reveal-cinema {
    position: fixed;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    margin: 0;
    z-index: var(--z-scrim);
    align-items: center;
    justify-content: center;
    padding:
      calc(var(--space-8) + env(safe-area-inset-top))
      calc(var(--space-6) + env(safe-area-inset-right))
      calc(var(--space-8) + env(safe-area-inset-bottom))
      calc(var(--space-6) + env(safe-area-inset-left));
    background: color-mix(in srgb, var(--bg) 90%, transparent);
    overflow: hidden;
  }

  .reveal-cinema[open] {
    display: flex;
  }

  .reveal-cinema::backdrop {
    background: transparent;
  }

  .reveal-cinema::before,
  .reveal-cinema::after {
    content: "";
    position: absolute;
    inset: 8%;
    pointer-events: none;
    opacity: 0;
    scale: 0.25;
    background:
      radial-gradient(circle at 12% 32%, var(--score) 0 0.22rem, transparent 0.25rem),
      radial-gradient(circle at 25% 15%, var(--mark) 0 0.18rem, transparent 0.21rem),
      radial-gradient(circle at 38% 38%, var(--fg) 0 0.2rem, transparent 0.23rem),
      radial-gradient(circle at 62% 18%, var(--score) 0 0.2rem, transparent 0.23rem),
      radial-gradient(circle at 75% 42%, var(--mark) 0 0.22rem, transparent 0.25rem),
      radial-gradient(circle at 88% 24%, var(--fg) 0 0.18rem, transparent 0.21rem),
      radial-gradient(circle at 18% 72%, var(--mark) 0 0.2rem, transparent 0.23rem),
      radial-gradient(circle at 42% 84%, var(--score) 0 0.22rem, transparent 0.25rem),
      radial-gradient(circle at 68% 76%, var(--fg) 0 0.18rem, transparent 0.21rem),
      radial-gradient(circle at 86% 68%, var(--score) 0 0.2rem, transparent 0.23rem);
  }

  .reveal-cinema::after {
    rotate: 24deg;
  }

  .reveal-cinema.is-celebrating::before {
    animation: reveal-fireworks 1.25s var(--ease-out) both;
  }

  .reveal-cinema.is-celebrating::after {
    animation: reveal-fireworks 1.25s 0.14s var(--ease-out) both;
  }

  @keyframes reveal-fireworks {
    0% {
      opacity: 0;
      scale: 0.25;
    }
    28% { opacity: 1; }
    100% {
      opacity: 0;
      scale: 1.2;
    }
  }

  .reveal-cinema__skip {
    position: absolute;
    inset-block-start: calc(var(--space-5) + env(safe-area-inset-top));
    inset-inline-end: calc(var(--space-6) + env(safe-area-inset-right));
    min-block-size: var(--tap-target);
    border: var(--hairline) solid var(--line);
    padding-inline: var(--space-4);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fg);
    background: var(--bg);
  }

  .reveal-cinema__card {
    inline-size: min(100%, 36rem);
    text-align: center;
    opacity: 0;
    scale: 0.82;
    translate: 0 var(--space-4);
    transition:
      opacity 0.28s ease,
      scale var(--dur-slow) var(--ease-out),
      translate var(--dur-slow) var(--ease-out);
  }

  .reveal-cinema.is-visible .reveal-cinema__card {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }

  .reveal-cinema__rank,
  .reveal-cinema__song,
  .reveal-cinema__by,
  .reveal-cinema__points {
    display: block;
  }

  .reveal-cinema__rank {
    font-weight: 800;
    font-size: clamp(7rem, 32vw, 11rem);
    line-height: 0.78;
    letter-spacing: -0.06em;
    color: var(--mark);
    font-variant-numeric: tabular-nums;
    transition: font-size var(--dur-slow) var(--ease-out), color var(--dur-fast) ease;
  }

  .reveal-cinema__song {
    margin-block-start: var(--space-6);
    font-weight: 800;
    font-size: clamp(var(--text-3xl), 8vw, var(--display-md));
    line-height: 1.02;
    letter-spacing: -0.03em;
    color: var(--fg);
    text-wrap: balance;
  }

  .reveal-cinema__by {
    margin-block-start: var(--space-4);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .reveal-cinema__points {
    margin-block-start: var(--space-6);
    font-family: var(--font-mono);
    font-size: var(--text-2xl);
    font-weight: 700;
    text-transform: uppercase;
    color: var(--score);
    font-variant-numeric: tabular-nums;
  }

  .reveal-cinema.is-winner .reveal-cinema__rank {
    font-size: clamp(9rem, 40vw, 14rem);
    color: var(--score);
  }

  .reveal-cinema.is-winner .reveal-cinema__song {
    font-size: var(--display-lg);
  }

  .reveal-cinema.is-your-track .reveal-cinema__card {
    filter: drop-shadow(0 0 2rem color-mix(in srgb, var(--score) 35%, transparent));
  }

  .reveal-share-action {
    inline-size: 100%;
  }

  .reveal-followups {
    margin-block: var(--space-6) var(--space-7);
  }

  @media (min-width: 56rem) {
    .screen__cta:has(.reveal-share-action) {
      padding-inline: var(--space-6);
    }

    .reveal-share-action .btn {
      inline-size: 100%;
      min-inline-size: 0;
    }
  }

  .reveal-standings-divider {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin-block: var(--space-6);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .reveal-standings-divider::before,
  .reveal-standings-divider::after {
    content: "";
    flex: 1;
    border-block-start: 2px dotted currentColor;
  }

  .reveal-standings-divider--podium {
    color: var(--score);
  }

  .reveal-row {
    border-block-start: var(--hairline) solid var(--line);
    transition: opacity 0.3s ease, translate var(--dur-slow) var(--ease-out);
  }

  .reveal-standings-divider + .reveal-row {
    border-block-start: 0;
  }

  .reveal-row.is-waiting {
    opacity: 0;
    translate: 0 calc(-1 * var(--space-4));
  }

  @media (prefers-reduced-motion: reduce) {
    .reveal-cinema {
      display: none !important;
    }

    .reveal-row.is-waiting {
      opacity: 1;
      translate: none;
    }
  }

  .reveal-row:last-of-type {
    border-block-end: var(--hairline) solid var(--line);
  }

  .reveal-row__head {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    inline-size: 100%;
    padding: var(--space-5) var(--space-1);
    cursor: pointer;
    list-style: none;
  }

  .reveal-row__head::-webkit-details-marker {
    display: none;
  }

  .reveal-row__head::marker {
    content: "";
  }

  .reveal-row__rank {
    align-self: flex-start;
    font-weight: 800;
    font-size: var(--display-lg);
    letter-spacing: -0.05em;
    line-height: 0.78;
    inline-size: 3rem;
    flex-shrink: 0;
    color: var(--mark);
    font-variant-numeric: tabular-nums;
  }

  .reveal-row__meta {
    flex: 1;
    min-inline-size: 0;
  }

  .reveal-row__song {
    display: block;
    font-weight: 700;
    font-size: var(--text-xl);
    letter-spacing: var(--track-tight);
    line-height: 1.05;
    color: var(--fg);
  }

  .reveal-row__by {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-start: var(--space-2);
  }

  .reveal-row__artist {
    display: block;
    margin-block-start: var(--space-1);
    font-size: var(--text-base);
    line-height: 1.2;
    color: var(--mut);
  }

  .reveal-row__attribution {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin-block-start: var(--space-3);
    color: var(--mut);
  }

  .reveal-row__poster {
    color: var(--fg);
    font-size: var(--text-lg);
    font-weight: 700;
    line-height: 1.1;
  }

  .reveal-row__attribution .pool-badge {
    margin-inline-start: 0;
  }

  .winner-bonus-badge {
    border: var(--hairline) solid var(--score);
    padding: var(--space-1) var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--score);
  }

  .reveal-row__comments {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  .reveal-row__comments::before {
    content: "·";
    margin-inline-end: var(--space-2);
  }

  .reveal-row__points {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-xl);
    color: var(--score);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
  }

  .reveal-row__points--penalized {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-2);
  }

  .reveal-row__points-original {
    color: var(--mut);
    font-size: var(--text-sm);
    text-decoration-thickness: 0.1em;
  }

  /* Keep non-podium tracks visually quiet without fading the whole subtree:
     opacity blended the already-muted byline into the crimson background and
     pushed every value below WCAG contrast. */
  .reveal-row--faded .reveal-row__rank,
  .reveal-row--faded .reveal-row__song,
  .reveal-row--faded .reveal-row__by,
  .reveal-row--faded .reveal-row__poster,
  .reveal-row--faded .reveal-row__points {
    color: var(--mut);
  }

  .reveal-row--winner .reveal-row__rank {
    color: var(--score);
  }

  .reveal-row__detail {
    /* Indented to clear the rank column, so the detail reads as belonging to
       the row above rather than as a new top-level block. */
    padding: 0 var(--space-1) var(--space-6) 3.8rem;
  }

  .reveal-row__block {
    margin-block-start: var(--space-5);
  }

  .reveal-row__key {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
    margin-block-end: var(--space-3);
  }

  .voters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
  }

  .voters__voter {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    letter-spacing: 0.04em;
    border: var(--hairline) solid var(--line);
    padding: var(--space-1) var(--space-3);
    color: var(--fg);
    white-space: nowrap;
  }

  .voters__voter b {
    color: var(--mark);
  }

  .comment {
    font-size: var(--text-md);
    line-height: 1.45;
    color: var(--fg);
    padding-block-start: var(--space-3);
    border-block-start: var(--hairline) solid var(--line);
    margin-block-start: var(--space-1);
  }

  .comment--poster {
    border-block-start: 0;
    border-inline-start: 2px solid var(--score);
    background: color-mix(in srgb, var(--score) 12%, transparent);
    padding: var(--space-4) var(--space-5);
    margin-block-start: 0;
  }

  .comment--poster .comment__who {
    color: var(--score);
  }

  .comment__who {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mut);
    margin-block-end: var(--space-1);
  }

  .comment__rank {
    color: var(--mark);
    font-weight: 700;
  }

  /* ══ Podium ════════════════════════════════════════════════════════════════ */
  .podium {
    border: var(--hairline) solid var(--fg);
    margin-block-start: var(--space-5);
  }

  .podium__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-5);
    border-block-end: var(--hairline) solid var(--fg);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .podium__row {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
    border-block-start: var(--hairline) solid var(--line);
  }

  .podium__row:first-of-type {
    border-block-start: 0;
  }

  .podium__entry {
    flex: 1;
    min-inline-size: 0;
  }

  .podium__name {
    display: block;
    min-inline-size: 0;
    font-weight: 600;
    font-size: var(--text-base);
    color: var(--fg);
  }

  .podium__artists {
    display: block;
    margin-block-start: var(--space-1);
    color: var(--mut);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  .podium__comment {
    display: block;
    margin-block-start: var(--space-2);
    padding-inline-start: var(--space-3);
    border-inline-start: 2px solid var(--mark);
    color: var(--mut);
    font-size: var(--text-md);
    line-height: 1.45;
  }

  .podium__points {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-sm);
    color: var(--score-fg);
    flex-shrink: 0;
  }

  /* ══ Playlist card ═════════════════════════════════════════════════════════ */
  .playlist-card {
    border: var(--hairline) solid var(--fg);
    background: var(--surf);
    margin-block-start: var(--space-5);
  }

  .playlist-card__head {
    padding: var(--space-4) var(--space-5);
    border-block-end: var(--hairline) solid var(--fg);
  }

  .playlist-card--embedded .playlist-card__head {
    padding-block-end: var(--space-2);
    border-block-end: 0;
  }

  .playlist-card__embed {
    padding: 0 var(--space-3) var(--space-3);
  }

  .playlist-card__share {
    padding: var(--space-4) var(--space-5);
  }

  .playlist-card__embed .embed {
    margin-block-start: 0;
    border: 0;
  }

  .playlist-card__key {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  @media (min-width: 56rem) {
    .playlist-card__period {
      display: none;
    }
  }

  .playlist-card__title {
    font-weight: 700;
    font-size: var(--text-2xl);
    letter-spacing: var(--track-tight);
    color: var(--fg);
    margin-block-start: var(--space-2);
  }

  /* ══ State block ═══════════════════════════════════════════════════════════
     The centrepiece of the group home: what this flon wants from you this week,
     in one bordered panel that carries the phase accent on its left edge.

     The `--turn` variant is the one place the design shouts — a ring plus a
     filled header — because "it's your turn" is the single most important thing
     the app ever has to say. */
  /* The accent rail is an inset shadow, not a fat left border: a 5px border on
     one side and 1px on the other three made the panel look lopsided. This
     keeps every edge a hairline and paints the rail inside. */
  .state-block {
    display: block;
    inline-size: 100%;
    border: var(--hairline) solid var(--fg);
    box-shadow: inset 4px 0 0 var(--acc);
    background: var(--surf);
    color: inherit;
    margin-block-start: var(--space-3);
  }

  .state-block__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-5);
    border-block-end: var(--hairline) solid var(--fg);
  }

  .state-block__label {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg);
  }

  .state-block__clock {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    color: var(--fg);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
  }

  /* These are spans inside an <a> (a link can't contain block elements in the
     markup we want), so display:block is doing real work here — without it the
     headline and the detail run together on one line. */
  .state-block__mid {
    display: block;
    padding: var(--space-6) var(--space-5) var(--space-1);
  }

  .state-block__headline {
    display: block;
    font-weight: 800;
    font-size: var(--display-md);
    line-height: 0.94;
    letter-spacing: -0.04em;
    color: var(--fg);
  }

  .state-block__detail {
    display: block;
    font-size: var(--text-md);
    line-height: 1.4;
    color: var(--mut);
    margin-block-start: var(--space-3);
  }

  .state-block__tracks {
    display: grid;
    gap: var(--space-3);
    margin-block-start: var(--space-5);
  }

  .state-block__track {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-inline-size: 0;
    padding: var(--space-3);
    border: var(--hairline) solid var(--line);
    background: var(--bg);
  }

  .state-block__track-cover {
    inline-size: 3rem;
    block-size: 3rem;
    flex-shrink: 0;
    object-fit: cover;
    background: var(--mark);
  }

  .state-block__track-cover--empty {
    background: repeating-linear-gradient(
      135deg,
      rgb(0 0 0 / 16%) 0 4px,
      var(--mark) 4px 8px
    );
  }

  .state-block__track-meta,
  .state-block__track-key,
  .state-block__track-name,
  .state-block__track-artists {
    display: block;
  }

  .state-block__track-meta {
    min-inline-size: 0;
  }

  .state-block__track-key {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .state-block__track-name,
  .state-block__track-artists {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .state-block__track-name {
    margin-block-start: var(--space-1);
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--fg);
  }

  .state-block__track-artists {
    margin-block-start: var(--space-1);
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .state-block__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
  }

  .state-block__enter {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: var(--text-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--fg);
  }

  .state-block--turn {
    border-color: var(--acc);
    box-shadow:
      inset 4px 0 0 var(--acc),
      0 0 0 2px var(--acc);
  }

  .state-block--turn .state-block__top {
    background: var(--acc);
    border-block-end-color: rgb(31 26 20 / 28%);
  }

  .state-block--turn .state-block__top .state-block__label,
  .state-block--turn .state-block__top .state-block__clock,
  .state-block--turn .state-block__top .countdown__value,
  .state-block--turn .state-block__top .countdown__meta {
    color: var(--on-acc);
  }

  .state-block--turn .state-block__top .live-dot {
    background: var(--on-acc);
  }

  /* Progress squares: one per player, filled when they've done their bit.
     A count of squares reads faster than "4/6" and still carries the number. */
  .progress-squares {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
  }

  .progress-squares__square {
    inline-size: 0.8125rem;
    block-size: 0.8125rem;
    border: var(--hairline) solid var(--fg);
    flex-shrink: 0;
  }

  .progress-squares__square--done {
    background: var(--fg);
  }

  .progress-squares__square--you {
    box-shadow: inset 0 0 0 2px var(--acc);
    border-color: var(--acc);
  }

  .progress-squares__count {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mut);
    margin-inline-start: var(--space-2);
  }

  /* ══ Result block ══════════════════════════════════════════════════════════
     Last week's outcome, promoted above the live phase when it needs attention. */
  .result-block {
    display: block;
    inline-size: 100%;
    border: var(--hairline) solid var(--fg);
    background: var(--surf);
    color: inherit;
    margin-block-start: var(--space-3);
    transition: translate 140ms var(--ease-out), box-shadow 140ms var(--ease-out);
  }

  .result-block__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-6) 0;
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .result-block__mid {
    display: block;
    padding: var(--space-3) var(--space-6) var(--space-2);
  }

  .result-block__winner {
    display: block;
    font-weight: 750;
    font-size: var(--display-sm);
    line-height: 1.05;
    letter-spacing: var(--track-tight);
    color: var(--fg);
  }

  .result-block__sub {
    display: block;
    font-size: var(--text-sm);
    line-height: 1.3;
    color: var(--mut);
    margin-block-start: var(--space-1);
  }

  .result-block__action {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: 0 var(--space-6) var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--fg);
  }

  @media (hover: hover) {
    .result-block:hover {
      translate: 0 -2px;
      box-shadow: 0 4px 0 color-mix(in srgb, var(--fg) 18%, transparent);
    }
  }

  .result-block:active {
    translate: 0 1px;
  }

  .result-block:focus-visible {
    outline: 3px solid var(--acc);
    outline-offset: 3px;
  }

  /* Fresh results get a reveal-coloured edge and surface without spoiling them. */
  .result-block--hot {
    border-color: var(--result-edge);
    border-inline-start-width: 4px;
    background: color-mix(in srgb, var(--result-tint) 32%, var(--surf));
  }

  .result-block--hot .result-block__top,
  .result-block--hot .result-block__action {
    color: var(--result-edge);
  }

  .result-block--your-win {
    border-color: var(--result-edge);
    border-inline-start-width: 4px;
    background:
      linear-gradient(135deg, color-mix(in srgb, var(--result-tint) 42%, var(--surf)), var(--surf));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--reveal-mid) 18%, transparent);
  }

  /* ══ Group switcher ════════════════════════════════════════════════════════
     Masthead chip that opens the flon picker. Replaces the offcanvas burger. */
  .group-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    block-size: var(--masthead-control);
    padding-inline: var(--space-3);
    color: var(--fg);
  }

  /* Match the other masthead controls: a compact visible box with the full
     iOS-size target extending invisibly around it. */
  .group-switch::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-start: 50%;
    translate: 0 -50%;
    block-size: var(--tap-target);
  }

  .group-switch__chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    block-size: var(--masthead-control);
    border: var(--hairline) solid var(--fg);
    padding-inline: var(--space-3);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    max-inline-size: 9rem;
  }

  .group-switch__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .group-switch__caret {
    color: var(--mut);
    flex-shrink: 0;
  }

  /* ══ Table ═════════════════════════════════════════════════════════════════
     Real tables for real tabular data (the scoring ladder, points breakdowns).
     Numeric columns get .is-num on both the th and the td. */
  .scoretable {
    inline-size: 100%;
    border-collapse: collapse;
    border: var(--hairline) solid var(--fg);
    margin-block-start: var(--space-3);
  }

  .scoretable th,
  .scoretable td {
    padding: var(--space-4) var(--space-5);
    text-align: start;
    border-block-start: var(--hairline) solid var(--line);
  }

  .scoretable thead th {
    border-block-start: 0;
    border-block-end: var(--hairline) solid var(--fg);
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--mut);
  }

  .scoretable tbody th {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg);
  }

  .scoretable .is-num {
    text-align: end;
    font-weight: 800;
    font-size: var(--display-sm);
    letter-spacing: -0.03em;
    color: var(--score-fg);
    font-variant-numeric: tabular-nums;
  }

  .scoretable thead .is-num {
    font-weight: 600;
    font-size: var(--text-2xs);
    color: var(--mut);
  }

  /* ══ Settings, pseudonyms and track pool ═══════════════════════════════════ */
  .field-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
  }

  .pool-hero {
    max-inline-size: 37rem;
  }

  .pool-guide {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-block-start: var(--space-7);
    border: var(--hairline) solid var(--fg);
    background: var(--surf);
  }

  .pool-guide__step {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-4);
    padding: var(--space-5);
  }

  .pool-guide__step + .pool-guide__step {
    border-inline-start: var(--hairline) solid var(--line);
  }

  .pool-guide__number,
  .pool-guide__copy > span,
  .pool-empty__copy > span {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.04em;
    color: var(--mut);
  }

  .pool-guide__number {
    align-self: center;
    min-inline-size: 2.25rem;
    color: var(--fg);
    font-size: var(--text-xl);
    font-weight: 800;
    line-height: 1;
    text-align: center;
  }

  .pool-guide__copy,
  .pool-empty__copy {
    display: flex;
    min-inline-size: 0;
    flex-direction: column;
    gap: var(--space-2);
  }

  .pool-guide__copy strong,
  .pool-empty__copy strong {
    font-size: var(--text-md);
  }

  .pool-guide__copy > span,
  .pool-empty__copy > span {
    line-height: 1.5;
  }

  .pool-empty,
  .pool-add-card {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-5);
    padding: var(--space-6);
    border: var(--hairline) dashed var(--fg);
    background: var(--surf);
    color: var(--fg);
  }

  .pool-empty {
    display: grid;
  }

  .pool-add-card {
    display: none;
    margin-block-end: var(--space-3);
  }

  .pool-empty:hover,
  .pool-add-card:hover {
    border-style: solid;
    background: var(--bg);
  }

  .pool-empty__mark {
    display: grid;
    place-items: center;
    inline-size: 3rem;
    block-size: 3rem;
    border: var(--hairline) solid var(--fg);
    font-family: var(--font-mono);
    font-size: var(--text-2xl);
    font-weight: 700;
  }

  .pool-empty__arrow {
    font-family: var(--font-mono);
    font-size: var(--text-2xl);
    font-weight: 700;
  }

  @media (min-width: 56rem) {
    .screen__cta:has(.pool-add-action--mobile) {
      display: none;
    }

    .pool-add-card {
      display: grid;
    }
  }

  .settings-list,
  .pseudonym-list,
  .pool-card {
    border: var(--hairline) solid var(--fg);
  }

  .settings-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    min-block-size: var(--tap-target);
    padding: var(--space-4) var(--space-5);
    border-block-start: var(--hairline) solid var(--line);
    color: var(--fg);
  }

  .settings-row:first-child,
  .pseudonym-row:first-child,
  .pool-row:first-of-type {
    border-block-start: 0;
  }

  .settings-row__text,
  .pool-row__track {
    display: flex;
    flex: 1;
    min-inline-size: 0;
    flex-direction: column;
    gap: var(--space-1);
  }

  .settings-row__text strong,
  .pool-row__track strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .settings-row__text span,
  .settings-row__meta,
  .settings-row__arrow,
  .pool-row__track > span,
  .pool-card__empty {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.04em;
    color: var(--mut);
  }

  .settings-row__meta,
  .settings-row__arrow {
    flex-shrink: 0;
    text-transform: uppercase;
  }

  .settings-chat-link {
    color: var(--fg);
    text-decoration: underline;
    overflow-wrap: anywhere;
  }

  .setting--button {
    inline-size: 100%;
    text-align: start;
    color: var(--fg);
  }

  .pseudonym-row {
    display: grid;
    grid-template-columns: minmax(4.5rem, 0.7fr) minmax(0, 1.3fr) auto;
    align-items: center;
    gap: var(--space-3);
    min-block-size: var(--tap-target);
    padding: var(--space-3) var(--space-4);
    border-block-start: var(--hairline) solid var(--line);
  }

  .pseudonym-row__group,
  .pseudonym-row__hint,
  .pseudonym-row__save,
  .pool-card__head,
  .pool-row__position,
  .pool-row__adjust,
  .pool-row__remove,
  .pool-row__scope {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  .pseudonym-row__group,
  .pseudonym-row__hint,
  .pool-row__position,
  .pool-row__scope {
    color: var(--mut);
  }

  .pool-coverage {
    margin-block: var(--space-6);
  }

  .pool-coverage .pool-coverage__warning {
    font-family: var(--font-sans);
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1.5;
    color: var(--fg);
  }

  .pool-row__eligibility,
  .pool-row__track > .pool-row__eligibility {
    display: grid;
    gap: var(--space-1);
    margin-block-start: var(--space-2);
    font-size: var(--text-xs);
    line-height: 1.5;
    color: var(--fg);
    overflow-wrap: anywhere;
  }

  .pool-row__eligibility strong {
    overflow: visible;
    white-space: normal;
  }

  .pseudonym-row__input {
    min-inline-size: 0;
    border: 0;
    border-block-end: var(--hairline) solid var(--line);
    padding: var(--space-2) 0;
    color: var(--fg);
  }

  .pseudonym-row__input:focus {
    outline: 0;
    border-color: var(--fg);
  }

  .pseudonym-row__save,
  .pool-row__remove {
    color: var(--fg);
  }

  .pool-row__adjust {
    color: var(--mut);
  }

  .pool-row__adjust:hover,
  .pool-row__adjust:focus-visible {
    color: var(--fg);
  }

  .pool-row__main {
    display: grid;
    grid-template-columns: 2rem 2.75rem minmax(0, 1fr);
    align-items: center;
    gap: var(--space-3);
    min-inline-size: 0;
    align-self: stretch;
    padding: var(--space-4);
  }

  .pool-row__grip {
    color: var(--fg);
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
  }

  .pool-row__grip:active {
    cursor: grabbing;
  }

  .pool-row__grip:focus-visible {
    outline: 3px solid var(--acc);
    outline-offset: -3px;
  }

  .pool-row__actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
  }

  /* "Remove" is a button_to: take its wrapping form out of the row layout so
     the button itself occupies the action column. */
  .pool-row__actions form {
    display: contents;
  }

  .pool-row__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--tap-target);
    min-block-size: var(--tap-target);
    padding: 0;
    border: var(--hairline) solid var(--line);
    font-family: var(--font-sans);
    font-size: var(--text-xl);
    font-weight: 500;
    line-height: 1;
  }

  .pool-row__remove:hover {
    border-color: var(--fg);
    background: var(--surf);
  }

  .pool-card__head {
    display: flex;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--fg);
    color: var(--bg);
  }

  .pool-card__head a {
    color: inherit;
  }

  .pool-row {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    border-block-start: var(--hairline) solid var(--line);
  }

  .pool-row--managed {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0;
    padding: 0;
  }

  .pool-row--managed .pool-row__actions {
    padding-inline-end: var(--space-4);
  }

  .pool-row--ghost {
    background: var(--bg);
    box-shadow: 0.375rem 0.375rem 0 var(--fg);
    opacity: 1 !important;
    cursor: grabbing;
  }

  .pool-row--placeholder {
    background: var(--surf);
    outline: var(--hairline) dashed var(--fg);
    outline-offset: calc(-1 * var(--hairline));
  }

  .pool-row--placeholder > * {
    visibility: hidden;
  }

  .pool-row .track-card__cover {
    inline-size: 2.75rem;
    block-size: 2.75rem;
  }

  .pool-card__empty {
    padding: var(--space-5);
  }

  @media (max-width: 35rem) {
    .pool-guide {
      grid-template-columns: 1fr;
    }

    .pool-guide__step + .pool-guide__step {
      border-inline-start: 0;
      border-block-start: var(--hairline) solid var(--line);
    }

    .pool-row__main {
      grid-template-columns: 1.25rem 3.5rem minmax(0, 1fr);
    }
  }

  .field-group {
    margin: 0;
    padding: 0;
    border: 0;
  }

  .check-list {
    display: grid;
    gap: var(--space-2);
    margin-block-start: var(--space-4);
  }

  .check-row {
    display: grid;
    grid-template-columns: 1.5rem minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-4);
    min-block-size: var(--tap-target);
    padding: var(--space-4);
    border: var(--hairline) solid var(--line);
    background: var(--surf);
    color: var(--fg);
    cursor: pointer;
    transition: border-color var(--dur-fast) ease, background var(--dur-fast) ease;
  }

  .check-row:hover {
    border-color: var(--fg);
    background: var(--bg);
  }

  .check-row:has(.check-row__input:checked) {
    border-color: var(--fg);
    box-shadow: inset 3px 0 0 var(--fg);
  }

  .check-row__input {
    display: grid;
    place-content: center;
    appearance: none;
    inline-size: 1.5rem;
    block-size: 1.5rem;
    margin: 0;
    border: var(--hairline) solid var(--fg);
    background: var(--bg);
    color: var(--fg);
    cursor: pointer;
  }

  .check-row__input::before {
    content: "";
    inline-size: 0.65rem;
    block-size: 0.35rem;
    border-inline-start: 2px solid currentcolor;
    border-block-end: 2px solid currentcolor;
    transform: rotate(-45deg) scale(0);
    transition: transform var(--dur-fast) var(--ease-out);
  }

  .check-row__input:checked {
    background: var(--fg);
    color: var(--bg);
  }

  .check-row__input:checked::before {
    transform: rotate(-45deg) scale(1);
  }

  .check-row__input:focus-visible {
    outline: 2px solid var(--mark);
    outline-offset: 3px;
  }

  .check-row__name {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 700;
  }

  .check-row__state::before {
    content: "Choose";
  }

  .check-row:has(.check-row__input:checked) .check-row__state::before {
    content: "Chosen";
  }

  .check-row__state {
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .pool-badge {
    display: inline-flex;
    margin-inline-start: var(--space-2);
    padding: 1px var(--space-2);
    border: var(--hairline) solid currentcolor;
    font-family: var(--font-mono);
    font-size: var(--text-3xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  @media (max-width: 24rem) {
    .field-grid {
      grid-template-columns: 1fr;
    }
  }

  /* ══ Release tour & feedback ══════════════════════════════════════════════ */
  .release-tour {
    inline-size: min(44rem, calc(100% - 1.5rem));
    max-block-size: calc(100dvh - 2rem - env(safe-area-inset-top) - env(safe-area-inset-bottom));
    margin: auto;
    border: var(--hairline) solid var(--line);
    overflow: hidden;
  }

  .release-tour[open] { display: flex; flex-direction: column; }
  .release-tour::backdrop { background: rgb(0 0 0 / 60%); }

  .release-tour__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding-inline: var(--space-6);
    flex: none;
  }

  .release-tour__dismiss {
    min-block-size: var(--tap-target);
    text-decoration: underline;
    font-size: var(--text-md);
  }

  .release-tour__slides { overflow-y: auto; overscroll-behavior: contain; }
  .release-slide { display: grid; gap: var(--space-6); padding: var(--space-7); }
  .release-slide[hidden] { display: none; }
  .release-slide__title { margin-block: var(--space-4); font-size: var(--display-sm); line-height: 1.1; letter-spacing: var(--track-display); }
  .release-slide__preview { inline-size: min(100%, 13rem); margin-inline: auto; }
  .release-slide__preview img {
    inline-size: 100%;
    block-size: clamp(10rem, 25dvh, 16rem);
    object-fit: cover;
    object-position: top;
    border: var(--hairline) solid var(--line);
  }
  .release-slide__preview figcaption { margin-block-start: var(--space-2); text-align: center; font-size: var(--text-xs); color: var(--mut); }
  .release-tour__footer { padding: var(--space-5) var(--space-6); border-block-start: var(--hairline) solid var(--line); flex: none; }
  .release-tour__navigation { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--space-4); }
  .release-tour__navigation .btn {
    inline-size: auto;
    padding: var(--space-3) var(--space-5);
    font-size: var(--text-md);
  }
  .release-tour__navigation .release-tour__progress { text-align: center; }
  .release-tour__progress { font-family: var(--font-mono); font-size: var(--text-xs); }
  .release-notes { display: grid; gap: var(--space-6); }
  .help-address { margin-block: var(--space-6); overflow-wrap: anywhere; }
  .help-checklist { padding-inline-start: var(--space-7); }
  .help-checklist li + li { margin-block-start: var(--space-4); }

  @media (min-width: 40rem) {
    .release-slide { grid-template-columns: 1fr 1fr; align-items: center; padding: var(--space-8); }
    .release-slide__preview { inline-size: min(100%, 15rem); }
    .release-slide__preview img { block-size: auto; }
    .release-slide__title { font-size: var(--display-md); }
  }

  /* ══ Rules footer ══════════════════════════════════════════════════════════ */
  .rules-foot {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-block-start: var(--space-8);
    padding-block: var(--space-4) var(--space-3);
    border-block-start: var(--hairline) solid var(--line);
  }

  .rules-foot a {
    font-family: var(--font-mono);
    font-size: var(--text-2xs);
    font-weight: 600;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--mut);
  }

  .rules-foot a:hover {
    color: var(--fg);
  }
}
