/* The ballot: map rail, song stage, criterion rows, and the masthead's clock, jokers and save state. */

.ballot {
    --rail: minmax(17rem, 21rem);
    --notice-hold: 6s;

    display: grid;
    grid-template-columns: var(--rail) minmax(0, 1fr);
    grid-template-rows: auto 1fr auto;
    min-height: calc(100dvh - var(--masthead));
}

/* Masthead additions: the clock opens the right-hand group. */
.masthead:has([data-clock]) :is(.masthead__voter, .masthead__menu) {
    margin-left: 0;
}

:where(.masthead) [data-clock] {
    --figure: var(--size-lead);
    --unit: var(--size-tier);

    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin-left: auto;
    white-space: nowrap;
}

:where(.masthead) [data-clock] .tier,
.masthead__jokers > .tier {
    color: var(--text-muted);
}

:where(.masthead) [data-clock] .tier {
    transform: translateY(calc(-1 * var(--raise)));
}

:where(.masthead) [data-clock] time {
    font-stretch: var(--narrow);
    font-weight: var(--weight-super);
}

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

.jokers {
    display: flex;
    gap: var(--space-4);
    padding: 0;
    list-style: none;
}

.jokers li {
    display: flex;
    align-items: center;
    gap: 3px;
}

.jokers .icon {
    width: 1rem;
    height: 1rem;
    margin-right: 3px;
    color: var(--text-muted);
}

.token {
    display: inline-grid;
    place-items: center;
    min-width: var(--token-width);
    height: var(--token-height);
    padding: 0 var(--space-1);
    background: var(--spotlight);
    color: var(--on-spotlight);
    font-stretch: var(--narrow);
    font-size: var(--size-token);
    font-weight: var(--weight-super);
    line-height: 1;
    transition: background-color var(--dur-quick) var(--ease-out), color var(--dur-quick) var(--ease-out), box-shadow var(--dur-quick) var(--ease-out);
}

.token[data-spent],
.token.is-landing {
    background: transparent;
    box-shadow: inset 0 0 0 var(--hairline) var(--ink-4);
    color: var(--ink-6);
}

.token--sign {
    background: var(--sign);
    color: var(--on-sign);
}

.token--count {
    display: none;
}

.masthead__save {
    display: flex;
    align-items: center;
    white-space: nowrap;
}

/* The rows' punches say what is saved; the bar speaks only when a save fails. Screen readers hear every state. */
.masthead__save:not([data-state='failed'], [data-state='offline']) {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

.masthead__save:is([data-state='failed'], [data-state='offline']) {
    padding: var(--space-1) var(--space-2);
    background: var(--vermilion);
    color: var(--on-vermilion);
    font-stretch: var(--narrow);
    font-size: var(--size-tier);
    font-weight: var(--weight-strong);
    letter-spacing: var(--track-tier);
    text-transform: uppercase;
}

.masthead__retry {
    padding: 0 var(--space-4);
}

@keyframes blink {
    from {
        opacity: 1;
    }

    to {
        opacity: 0.25;
    }
}

/* Map: the running order on a rail. */
.map {
    position: sticky;
    top: var(--masthead);
    grid-column: 1;
    grid-row: 1 / -1;
    align-self: start;
    display: grid;
    grid-template-columns: 1fr auto;
    align-content: start;
    align-items: baseline;
    min-width: 0;
    height: calc(100dvh - var(--masthead));
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--space-5) 0 var(--space-6);
    background: var(--ink-1);
    scrollbar-color: var(--ink-4) var(--ink-1);
}

.map__heading {
    padding: 0 var(--space-3) var(--space-3) var(--space-5);
    font-stretch: var(--wide);
    font-size: var(--size-small);
    font-weight: var(--weight-super);
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.map__progress {
    padding: 0 var(--space-5) var(--space-3) 0;
    color: var(--text-muted);
    font-stretch: var(--narrow);
    font-size: var(--size-small);
    font-weight: var(--weight-strong);
}

.map__meter {
    grid-column: 1 / -1;
    width: auto;
    height: 3px;
    margin: 0 var(--space-5) var(--space-4);
    border: 0;
    background: var(--ink-3);
    -webkit-appearance: none;
    appearance: none;
}

.map__meter::-webkit-progress-bar {
    background: var(--ink-3);
}

.map__meter::-webkit-progress-value {
    background: var(--ink-10);
}

.map__meter::-moz-progress-bar {
    background: var(--ink-10);
}

.map__list {
    grid-column: 1 / -1;
    padding: 0;
    list-style: none;
}

.map__entry {
    display: grid;
    grid-template-columns: 1.75rem minmax(0, 1fr) auto;
    column-gap: var(--space-3);
    align-items: center;
    min-height: var(--control);
    padding: var(--space-2) var(--space-5);
    text-decoration: none;
    transition: background-color var(--dur-quick) var(--ease-out);
}

.map__entry:focus-visible {
    outline-offset: -3px;
}

.map__entry[aria-current] {
    background: var(--edition);
    color: var(--on-edition);
}

.map__number {
    grid-row: span 2;
    color: var(--ink-6);
    font-stretch: var(--narrow);
    font-size: var(--size-lead);
    font-weight: var(--weight-strong);
}

.map__song {
    overflow: hidden;
    font-size: var(--size-small);
    font-weight: var(--weight-strong);
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.map__year {
    grid-column: 2;
    color: var(--text-muted);
    font-stretch: var(--narrow);
    font-size: var(--size-tier);
    font-weight: var(--weight-medium);
    letter-spacing: 0.04em;
    line-height: 1.3;
}

.map__entry[aria-current] :is(.map__number, .map__year) {
    color: var(--on-edition-soft);
}

.map__extra {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    box-shadow: inset 0 var(--hairline) 0 var(--rule);
}

.map__extra .map__number {
    font-size: var(--size-small);
}

/* Punches: one per criterion (or prediction), the state of each cell at a glance. */
.punches {
    grid-column: 3;
    grid-row: 1 / span 2;
    display: flex;
    gap: 3px;
}

.punch {
    width: var(--punch);
    height: var(--punch);
    box-shadow: inset 0 0 0 1.5px var(--ink-5);
    transition: background-color var(--dur-quick) var(--ease-out), box-shadow var(--dur-quick) var(--ease-out);
}

.punch:is([data-state='done'], [data-state='joker']) {
    background: var(--ink-8);
    box-shadow: none;
}

.punch[data-state='joker']:not(.is-landing) {
    background: var(--spotlight);
}

.punch[data-state='none'] {
    align-self: center;
    height: 1.5px;
    background: var(--ink-4);
    box-shadow: none;
}

.map__entry[aria-current] .punch {
    box-shadow: inset 0 0 0 1.5px var(--on-edition-soft);
}

.map__entry[aria-current] .punch:is([data-state='done'], [data-state='joker']) {
    background: var(--on-edition);
    box-shadow: none;
}

.map__entry[aria-current] .punch[data-state='joker']:not(.is-landing) {
    background: var(--spotlight);
}

.map__entry[aria-current] .punch[data-state='none'] {
    background: var(--on-edition-soft);
    box-shadow: none;
}

/* Notices: the joker that moved, the refused or late vote. A ticker held at the bottom of the screen,
   wiped away after a while so it never sits on a cell; screen readers already heard it. */
.ballot__notice {
    position: sticky;
    bottom: 0;
    z-index: 1;
    grid-column: 2;
    grid-row: 3;
    justify-self: center;
    max-width: 46rem;
    margin: 0 var(--gutter) var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--ink-10);
    color: var(--ink-0);
    pointer-events: none;
    animation: wipe var(--dur-wipe) var(--ease-out) backwards, unwipe var(--dur-wipe) var(--ease-out) var(--notice-hold) forwards;
}

.ballot__notice:empty {
    display: none;
}

/* A joker that changed hands: the criterion's icon, then who gave the joker up and where it drops to. */
.joker-notice {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.joker-notice + .joker-notice {
    margin-top: var(--space-2);
}

.joker-notice .token {
    margin-inline: 0.1em;
    vertical-align: 0.08em;
}

.ballot__closed {
    grid-column: 2;
    grid-row: 1;
    padding: var(--space-3) var(--gutter);
    background: var(--ink-10);
    color: var(--ink-0);
}

/* Stage: one song, then the Pronostics. */
.stage {
    grid-column: 2;
    grid-row: 2;
    scroll-margin-top: var(--masthead);
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
        'media'
        'player'
        'hint'
        'rows'
        'nav';
    align-content: start;
    gap: var(--space-4);
    justify-self: center;
    width: 100%;
    max-width: calc(46rem + 2 * var(--gutter));
    padding: var(--space-6) var(--gutter) var(--space-7);
}

/* Media: the cover stands over the video until the clip is revealed. */
.media {
    grid-area: media;
    position: relative;
    isolation: isolate;
    container-type: inline-size;
    aspect-ratio: 16 / 9;
    margin-bottom: var(--space-6);
    background: var(--ink-1);
}

.media__player {
    position: absolute;
    inset: 0;
}

.media__player iframe {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

/* Opaque, and above the player: no frame of the clip can show through before the reveal. */
.media__art {
    position: absolute;
    inset: 0;
    z-index: 1;
    overflow: hidden;
    background: var(--ink-1);
    clip-path: inset(0);
    transition: clip-path var(--dur-rise) var(--ease-out), visibility 0s linear var(--dur-rise);
}

.media__cover {
    position: absolute;
    inset: 0 0 0 auto;
    width: auto;
    height: 100%;
    aspect-ratio: 1;
    object-fit: cover;
}

.media__year {
    position: absolute;
    top: 3cqw;
    left: 3cqw;
    color: var(--ink-2);
    font-stretch: var(--wide);
    font-size: 12.5cqw;
    font-weight: var(--weight-super);
    letter-spacing: -0.03em;
    line-height: 1;
}

.media__pending .media__year {
    top: auto;
    left: auto;
    right: -0.04em;
    bottom: -0.2em;
    font-size: 24cqw;
}

.media__pending .tier {
    position: absolute;
    top: var(--space-4);
    left: var(--space-4);
    color: var(--ink-6);
}

/* The reveal: the art wipes off left to right, the clip stands behind it. */
.stage[data-revealed] .media:not([data-embed='unavailable']) .media__art {
    clip-path: inset(0 0 0 100%);
    visibility: hidden;
}

.media__error {
    position: absolute;
    top: var(--space-4);
    left: var(--space-4);
    z-index: 2;
    max-width: min(26rem, calc(100% - 9rem));
    padding: var(--space-2) var(--space-3);
    background: var(--ink-0);
    color: var(--text);
    font-size: var(--size-small);
    line-height: 1.4;
}

.media__bug {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    z-index: 2;
    padding: var(--space-1) var(--space-2);
    background: var(--ink-0);
    color: var(--text-muted);
}

.media__bug b {
    color: var(--text);
    font-weight: inherit;
}

/* Lower third: the nominee graphic, overhanging the frame's bottom-left corner. */
.lower-third {
    position: absolute;
    left: calc(-1 * var(--space-4));
    bottom: calc(-1 * var(--space-5));
    z-index: 2;
    display: grid;
    justify-items: start;
    max-width: calc(100% + var(--space-4) - var(--space-6));
}

.lower-third__name {
    font-stretch: var(--wide);
    font-size: min(var(--size-name), 7cqw);
    font-weight: var(--weight-super);
    letter-spacing: var(--track-super);
    line-height: 1.12;
    text-transform: uppercase;
    text-wrap: balance;
}

.lower-third__name span {
    padding: 0.06em 0.3em 0.04em;
    background: var(--edition);
    color: var(--on-edition);
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    animation: wipe var(--dur-wipe) var(--ease-out) backwards;
}

/* Revealed, the name wipes away so the clip shows; the year · artist tier stays under the frame. */
.stage[data-revealed] .lower-third__name span {
    animation: unwipe var(--dur-wipe) var(--ease-out) forwards;
}

.lower-third__tier {
    padding: var(--space-1) var(--space-3);
    background: var(--ink-10);
    color: var(--ink-0);
    animation: wipe var(--dur-wipe) var(--ease-out) backwards;
    animation-delay: calc(2 * var(--stagger));
}

/* Player: our own controls; the video never takes a tap. */
.player {
    grid-area: player;
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.player__play {
    display: grid;
    place-items: center;
    flex: none;
    width: var(--control);
    height: var(--control);
    border: 0;
    background: var(--edition);
    color: var(--on-edition);
    transition: background-color var(--dur-quick) var(--ease-out), opacity var(--dur-quick) var(--ease-out);
}

.player__play .icon {
    width: 1.25rem;
    height: 1.25rem;
}

.player__play[data-playing] .icon:first-child,
.player__play:not([data-playing]) .icon:last-child {
    display: none;
}

.player__play:disabled {
    background: var(--ink-2);
    color: var(--ink-6);
    cursor: progress;
}

.media[data-embed='unavailable'] ~ .player .player__play:disabled {
    cursor: not-allowed;
}

/* Seek: a 3px line with a 3×15px head; the played part is the head's image run out to the left. */
.player__seek {
    flex: 1;
    min-width: 0;
    height: var(--control);
    margin: 0;
    overflow: hidden;
    background: transparent;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.player__seek:disabled {
    cursor: default;
    opacity: 0.5;
}

.player__seek::-webkit-slider-runnable-track {
    height: 3px;
    background: var(--ink-3);
}

.player__seek::-webkit-slider-thumb {
    width: 3px;
    height: 3px;
    background: var(--ink-10);
    box-shadow: 0 -6px var(--ink-10), 0 -3px var(--ink-10), 0 3px var(--ink-10), 0 6px var(--ink-10);
    border-image: linear-gradient(var(--ink-10) 0 0) fill 0 / 0 / 0 0 0 100vw;
    -webkit-appearance: none;
    appearance: none;
}

.player__seek::-moz-range-track {
    height: 3px;
    background: var(--ink-3);
}

.player__seek::-moz-range-progress {
    height: 3px;
    background: var(--ink-10);
}

.player__seek::-moz-range-thumb {
    width: 3px;
    height: 15px;
    border: 0;
    border-radius: 0;
    background: var(--ink-10);
}

.player__seek:focus-visible {
    outline-offset: -2px;
}

.player__time {
    flex: none;
    min-width: 4.5rem;
    color: var(--text-muted);
    font-stretch: var(--narrow);
    font-weight: var(--weight-medium);
    text-align: right;
}

.stage__hint {
    grid-area: hint;
    color: var(--text-muted);
    font-size: var(--size-small);
}

.stage[data-revealed] .stage__hint {
    display: none;
}

/* Previous and next: the next song is the primary key, at the end of the rows. */
.stage__nav {
    grid-area: nav;
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.stage__step {
    gap: var(--space-2);
    max-width: calc(50% - var(--space-2));
    padding: var(--space-2) var(--space-4);
    line-height: 1.2;
    text-align: left;
}

.stage__step--next {
    margin-left: auto;
    text-align: right;
}

/* Criterion rows. */
.rows {
    grid-area: rows;
    display: grid;
    align-content: start;
    margin-top: var(--space-2);
}

/* A segment per criterion, apart under a hairline; its gate (Paroles, the clip reveal) opens it. */
.segment {
    display: grid;
    gap: var(--space-4);
}

.segment + .segment {
    margin-top: var(--space-5);
    padding-top: var(--space-5);
    box-shadow: inset 0 var(--hairline) 0 var(--rule);
}

.crit {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 3px;
    min-width: 0;
    padding: 0;
    border: 0;
    transition: opacity var(--dur-wipe) var(--ease-out);
}

/* Floated, the legend is a grid item like the rest of the row. */
.crit__head {
    float: left;
    grid-column: 1 / -1;
    grid-row: 1;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    padding: 0;
    font-weight: var(--weight-strong);
}

.crit__head .icon {
    width: 1.125rem;
    height: 1.125rem;
}

.crit__head .icon:first-child {
    color: var(--text-muted);
}

.crit__head .icon:not(:first-child) {
    width: 1rem;
    height: 1rem;
    color: var(--text-muted);
}

.crit:not([data-locked]) .crit__head .icon:not(:first-child) {
    display: none;
}

.crit__status {
    grid-column: 1 / -1;
    grid-row: 1;
    justify-self: end;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    color: var(--text-muted);
    font-size: var(--size-small);
    white-space: nowrap;
}

/* The row's punch, as in the map. */
.crit__status::before {
    content: '';
    flex: none;
    width: var(--punch);
    height: var(--punch);
    box-shadow: inset 0 0 0 1.5px var(--ink-5);
    transition: background-color var(--dur-rise) var(--ease-in-out), box-shadow var(--dur-rise) var(--ease-in-out);
}

:is(.crit, .pick)[data-state='saved'] > .crit__status::before {
    background: var(--ink-8);
    box-shadow: none;
}

.crit[data-state='saved']:has(.sign--joker :checked) > .crit__status::before {
    background: var(--spotlight);
}

/* Lit at once while it saves; cools down to its saved colour, so even a quick save reads as a pulse. */
:is(.crit, .pick)[data-state='saving'] > .crit__status::before {
    background: var(--edition-hover);
    box-shadow: none;
    transition-duration: var(--dur-quick);
    animation: blink 1s steps(2, jump-none) infinite;
}

.crit[data-state='locked'] > .crit__status::before {
    display: none;
}

/* The punch is the witness: a row keeps only its punch, its words (still read out) showing only when
   the row needs the voter (a failed save, the locked Clip). */
:is(.crit, .pick):not([data-state='failed'], [data-state='locked']) > .crit__status {
    overflow: hidden;
    width: var(--punch);
    gap: 0;
    text-indent: 100%;
}

:is(.crit, .pick)[data-state='failed'] > .crit__status {
    padding: 2px var(--space-2);
    background: var(--vermilion);
    color: var(--on-vermilion);
    font-stretch: var(--narrow);
    font-size: var(--size-tier);
    font-weight: var(--weight-strong);
    letter-spacing: var(--track-tier);
    text-transform: uppercase;
}

:is(.crit, .pick)[data-state='failed'] > .crit__status::before {
    display: none;
}

.crit__holder {
    grid-column: 1 / -1;
    margin-top: var(--space-1);
    color: var(--text-muted);
    font-weight: var(--weight-body);
}

.crit__holder cite {
    color: var(--text);
}

.crit__holder:empty {
    display: none;
}

/* Scale cells: −3 … +3, coloured by the sign of the vote once selected. */
.cell {
    position: relative;
    display: grid;
    place-items: center;
    height: var(--cell);
    background: var(--ink-2);
    cursor: pointer;
    transition: background-color var(--dur-quick) var(--ease-out), color var(--dur-quick) var(--ease-out);
    -webkit-tap-highlight-color: transparent;
}

.cell input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: inherit;
}

.cell > span {
    pointer-events: none;
}

.cell:has(:focus-visible) {
    z-index: 1;
    outline: var(--edge) solid var(--focus);
    outline-offset: 2px;
}

.cell__number {
    font-stretch: var(--narrow);
    font-size: var(--size-cell);
    font-weight: var(--weight-strong);
}

.cell__mark {
    position: absolute;
    right: 0;
    bottom: 4px;
    left: 0;
    color: var(--ink-7);
    font-stretch: var(--narrow);
    font-size: var(--size-mark);
    font-weight: var(--weight-strong);
    letter-spacing: 0.06em;
    line-height: 1;
    text-align: center;
}

.cell.sign--joker .cell__number {
    color: var(--spotlight);
}

.cell.sign--joker[data-held] .cell__number {
    color: var(--ink-6);
}

.cell:has(:checked) {
    background: var(--sign);
    color: var(--on-sign);
}

.cell:has(:checked) :is(.cell__number, .cell__mark) {
    color: inherit;
}

/* Held while a joker flies in: it fills when the token lands. */
.cell.is-landing {
    background: var(--ink-2);
}

.cell.is-landing .cell__number {
    color: var(--spotlight);
}

.crit:disabled .cell {
    cursor: default;
}

/* Closed: the votes stand, the cells around them recede. */
[data-phase='closed'] :is(.cell, .pick__option):not(:has(:checked)) {
    background: var(--ink-1);
    color: var(--ink-5);
}

[data-phase='closed'] .cell.sign--joker:not(:has(:checked)) .cell__number {
    color: var(--ink-5);
}

.crit[data-locked] .cell {
    opacity: 0.4;
    cursor: not-allowed;
}

/* The clip reveal: the focal tap of each song. */
.reveal {
    position: relative;
    display: grid;
    grid-template-columns: 3.5rem minmax(0, 1fr) auto;
    column-gap: var(--space-4);
    align-items: center;
    width: 100%;
    min-height: 3.5rem;
    padding: 0 var(--space-4) 0 0;
    border: 0;
    background: var(--ink-2);
    text-align: left;
    transition: background-color var(--dur-quick) var(--ease-out);
}

/* Out of the flow, so the icon square runs the full height of however many lines the label takes. */
.reveal > .icon:first-child {
    position: absolute;
    inset: 0 auto 0 0;
    width: 3.5rem;
    height: 100%;
    padding: 0 1rem;
    background: var(--ink-10);
    color: var(--ink-0);
}

.reveal > b {
    grid-column: 2;
    padding-top: var(--space-2);
    font-stretch: var(--narrow);
    font-weight: var(--weight-super);
    letter-spacing: var(--track-tier);
    line-height: 1.2;
    text-transform: uppercase;
}

.reveal > span {
    grid-column: 2;
    padding-bottom: var(--space-2);
    color: var(--text-muted);
    font-size: var(--size-small);
    line-height: 1.35;
}

.reveal > .icon:last-child {
    grid-column: 3;
    grid-row: 1 / span 2;
}

.reveal:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.no-clip {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--ink-1);
    color: var(--text-muted);
}

.no-clip b {
    color: var(--text);
}

/* Paroles: a quiet tab that opens the Storytelling segment, lighter than the clip reveal. Open, it joins
   its panel: the themes, then the lyrics with each French line under its original, in a frame short
   enough to keep the Storytelling row close. */
.lyrics__toggle {
    display: grid;
    grid-template-columns: auto auto;
    align-items: center;
    column-gap: var(--space-3);
    width: fit-content;
    min-height: var(--control);
    padding: var(--space-2) var(--space-4);
    box-shadow: inset 0 0 0 var(--hairline) var(--rule);
    list-style: none;
    font-stretch: var(--narrow);
    font-size: var(--size-tier);
    font-weight: var(--weight-super);
    letter-spacing: var(--track-tier);
    line-height: 1.2;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color var(--dur-quick) var(--ease-out);
    -webkit-tap-highlight-color: transparent;
}

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

.lyrics__toggle:focus-visible {
    outline-offset: -2px;
}

.lyrics__toggle .icon {
    color: var(--text-muted);
    transition: transform var(--dur-quick) var(--ease-out);
}

.lyrics[open] .lyrics__toggle {
    background: var(--ink-1);
    box-shadow: none;
}

.lyrics[open] .lyrics__toggle .icon {
    transform: rotate(180deg);
}

.lyrics__body {
    display: grid;
    justify-items: start;
    gap: var(--space-4);
    padding: var(--space-4);
    background: var(--ink-1);
    animation: settle var(--dur-rise) var(--ease-out) backwards;
}

.lyrics__themes {
    max-width: 65ch;
}

.lyrics__verses {
    display: grid;
    gap: var(--space-5);
    justify-self: stretch;
    max-height: min(30rem, 60dvh);
    padding: var(--space-4) var(--space-3) var(--space-4) 0;
    overflow-y: auto;
    box-shadow: inset 0 var(--hairline) 0 var(--rule), inset 0 calc(-1 * var(--hairline)) 0 var(--rule);
    scrollbar-color: var(--ink-4) var(--ink-1);
}

.lyrics__verses:focus-visible {
    outline-offset: -2px;
}

.stanza {
    display: grid;
    justify-items: start;
    max-width: 65ch;
}

.lyrics__verses--translated .stanza {
    row-gap: var(--space-3);
}

.stanza br {
    display: none;
}

.stanza__label {
    margin-bottom: var(--space-2);
    color: var(--text-muted);
}

.lyrics__verses--translated .stanza__label {
    margin-bottom: 0;
}

.verse {
    display: grid;
    line-height: 1.35;
}

.verse__original {
    font-weight: var(--weight-medium);
}

.verse__translation {
    margin-top: 2px;
    color: var(--text-muted);
    font-size: var(--size-small);
    font-style: italic;
}

.lyrics__pending {
    color: var(--text-muted);
}

/* Pronostics: pick the two winners among every song. */
.stage--pronostics {
    grid-template-areas: none;
    row-gap: var(--space-5);
}

.stage--pronostics .stage__nav {
    grid-area: auto;
}

.pronostics__title {
    justify-self: start;
}

.pronostics__lead {
    color: var(--text-muted);
}

.pick {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 2px;
    min-width: 0;
    padding: 0;
    border: 0;
}

.pick__head {
    float: left;
    grid-column: 1;
    grid-row: 1;
    justify-self: start;
    margin-bottom: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--edition);
    color: var(--on-edition);
}

.pick .crit__status {
    grid-column: 2;
}

.pick__option {
    position: relative;
    grid-column: 1 / -1;
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    min-height: var(--control);
    padding: var(--space-3) var(--space-4);
    background: var(--ink-1);
    cursor: pointer;
    transition: background-color var(--dur-quick) var(--ease-out), color var(--dur-quick) var(--ease-out);
    -webkit-tap-highlight-color: transparent;
}

.pick__option input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: inherit;
}

.pick__option > span {
    pointer-events: none;
}

.pick__option:has(:focus-visible) {
    z-index: 1;
    outline: var(--edge) solid var(--focus);
    outline-offset: 2px;
}

.pick__song {
    font-weight: var(--weight-strong);
}

.pick__year {
    margin-left: auto;
    color: var(--text-muted);
    font-stretch: var(--narrow);
    font-size: var(--size-small);
    font-weight: var(--weight-medium);
}

.pick__option:has(:checked) {
    background: var(--edition);
    color: var(--on-edition);
}

.pick__option:has(:checked) .pick__year {
    color: var(--on-edition-soft);
}

.pick:disabled .pick__option {
    cursor: default;
}

/* A joker in flight between the masthead, the map and the scale. */
.joker-flight {
    position: fixed;
    z-index: 10;
    display: grid;
    place-items: center;
    background: var(--spotlight);
    color: var(--on-spotlight);
    font-family: var(--font);
    font-stretch: var(--narrow);
    font-weight: var(--weight-super);
    line-height: 1;
    pointer-events: none;
    transform-origin: 0 0;
}

@media (hover: hover) {
    .map__entry:not([aria-current]):hover,
    .pick__option:not(:has(:checked)):hover {
        background: var(--ink-2);
    }

    .lyrics__toggle:hover {
        background: var(--ink-2);
    }

    .cell:not(:has(:checked)):hover,
    .reveal:not(:disabled):hover {
        background: var(--ink-3);
    }

    .crit:is(:disabled, [data-locked]) .cell:not(:has(:checked)):hover {
        background: var(--ink-2);
    }

    .player__play:not(:disabled):hover {
        background: var(--edition-hover);
    }
}

/* Wide: the song beside its rows. */
@media (min-width: 80rem) {
    .stage {
        grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
        grid-template-rows: auto auto auto auto 1fr;
        grid-template-areas:
            'media rows'
            'player rows'
            'hint rows'
            'nav rows'
            '. rows';
        column-gap: var(--space-7);
        max-width: 82rem;
    }

    .rows {
        margin-top: 0;
    }

    .stage--pronostics {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-rows: none;
        grid-template-areas: none;
        align-items: start;
    }

    .stage--pronostics > :not(.pick) {
        grid-column: 1 / -1;
    }

    .ballot__notice {
        max-width: 82rem;
    }
}

/* A failed save needs the room: the token list gives way to the count. */
.masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) .jokers {
    display: none;
}

.masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) .token--count {
    display: inline-grid;
}

/* Below 112rem the bar needs the room: the pages, the voter and the sign-out fold into the menu. */
@media (max-width: 112rem) {
    .masthead:has(.masthead__jokers) .masthead__menu {
        display: inline-flex;
    }

    .masthead:has(.masthead__jokers) .masthead__pages:not(:popover-open) {
        display: none;
    }
}

/* Off the ballot (the opening's countdown), the clock alone joins the bar: it folds under 60rem. */
@media (max-width: 60rem) {
    .masthead:has([data-clock]) .masthead__menu {
        display: inline-flex;
    }

    .masthead:has([data-clock]) .masthead__pages:not(:popover-open) {
        display: none;
    }
}

/* Below 82rem the bar no longer fits: the token list gives way to the count, the clock to its figures. */
@media (max-width: 82rem) {
    .jokers {
        display: none;
    }

    .token--count {
        display: inline-grid;
    }

    .masthead:has(.masthead__jokers) [data-clock] .tier {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* Off the ballot, the opening's clock keeps its tier until the folded bar runs out of room. */
@media (max-width: 44rem) {
    :where(.masthead) [data-clock] .tier {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* Tablets: a failed save takes the wordmark's place. */
@media (max-width: 64rem) {
    .masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) .masthead__mark {
        display: none;
    }

    .masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) [data-clock] {
        margin-left: 0;
    }
}

/* Phones: the map is a strip of numbers and punches stuck under the masthead. */
@media (max-width: 48rem) {
    .ballot {
        --cell: 3.25rem;
        --punch: 0.375rem;

        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto auto 1fr auto;
    }

    .masthead:has(.masthead__jokers) {
        gap: var(--space-3);
    }

    .masthead:has(.masthead__jokers) .masthead__mark,
    .masthead__jokers > .tier {
        display: none;
    }

    .masthead:has(.masthead__jokers) [data-clock] {
        margin-left: 0;
    }

    :where(.masthead) [data-clock] {
        --figure: var(--size-body);
    }

    .masthead__jokers {
        margin-left: auto;
    }

    /* A failure takes a second row of the masthead, edge to edge, and the map strip moves down under it. */
    .masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) {
        flex-wrap: wrap;
        row-gap: 0;
    }

    .masthead__save:is([data-state='failed'], [data-state='offline']) {
        order: 1;
        flex: 1 0 calc(100% - 8rem);
        min-height: var(--control);
        margin-left: calc(-1 * var(--gutter));
        padding: 0 var(--gutter);
    }

    .masthead__retry {
        order: 2;
        margin-right: calc(-1 * var(--gutter));
        background: var(--ink-0);
        color: var(--text);
    }

    .masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) .masthead__pages:popover-open {
        top: calc(var(--masthead) + var(--control));
    }

    .masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) ~ main .map {
        top: calc(var(--masthead) + var(--control));
    }

    .masthead:has(.masthead__save:is([data-state='failed'], [data-state='offline'])) ~ main .stage {
        scroll-margin-top: calc(var(--masthead) + var(--control));
    }

    .map {
        z-index: 1;
        grid-row: 1;
        grid-template-columns: minmax(0, 1fr);
        height: auto;
        overflow: visible;
        padding: 0;
        box-shadow: inset 0 calc(-1 * var(--hairline)) 0 var(--rule);
    }

    .map__heading,
    .map__progress,
    .map__meter {
        display: none;
    }

    .map__list {
        display: grid;
        grid-auto-columns: minmax(1.5rem, 1fr);
        grid-auto-flow: column;
        overflow-x: auto;
        scrollbar-width: none;
    }

    .map__entry {
        grid-template-columns: auto;
        justify-items: center;
        row-gap: 5px;
        min-height: 0;
        padding: var(--space-2) 0;
    }

    .map__song,
    .map__year {
        display: none;
    }

    .map__number {
        grid-row: auto;
        font-size: var(--size-tier);
    }

    .map__entry:not([aria-current]) .map__number {
        color: var(--ink-8);
    }

    .map__extra {
        margin-top: 0;
        padding-top: 0;
        box-shadow: inset var(--hairline) 0 0 var(--rule);
    }

    .map__extra .map__number {
        font-size: var(--size-tier);
    }

    .punches {
        grid-column: 1;
        grid-row: auto;
        display: grid;
        grid-template-columns: repeat(2, var(--punch));
        gap: 2px;
    }

    .punch[data-state='none'] {
        align-self: center;
        height: 1.5px;
    }

    .ballot__closed {
        grid-column: 1;
        grid-row: 2;
    }

    .stage {
        grid-column: 1;
        grid-row: 3;
        gap: var(--space-3);
        padding: 0 0 var(--space-7);
    }

    .stage > :not(.media) {
        margin-inline: var(--gutter);
    }

    .stage--pronostics {
        padding-top: var(--space-6);
    }

    .media {
        margin-bottom: var(--space-7);
    }

    .lower-third {
        left: var(--gutter);
        bottom: calc(-1 * var(--space-6));
        max-width: calc(100% - 2 * var(--gutter));
    }

    .media__error {
        max-width: calc(100% - 7rem);
    }

    .rows {
        margin-top: var(--space-4);
    }

    .ballot__notice {
        grid-column: 1;
        grid-row: 4;
        margin-inline: var(--gutter);
    }
}

@media (max-width: 30rem) {
    .stage__step {
        padding: var(--space-2) var(--space-3);
    }
}
