/* Quizz Master V3 — accueil et écran de jeu.
   Monde : affiche de concert surf-rock sérigraphiée. Un aplat lagon possède l'écran,
   encre noire, papier os, orange réservé au lancement de la musique, rose flamant en
   seconde passe décalée. */

html {
    -webkit-text-size-adjust: 100%;
    scrollbar-color: var(--bone-soft) var(--lagoon-deep);
}

/* Zones sûres (encoche, Dynamic Island, barre d'accueil de l'iPhone) : nulles dans un onglet Safari
   tenu droit, réelles en paysage et quand le site est ouvert depuis l'écran d'accueil. */
:root {
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --edge-left: max(var(--gutter), env(safe-area-inset-left, 0px));
    --edge-right: max(var(--gutter), env(safe-area-inset-right, 0px));
}

body {
    margin: 0;
    min-height: 100vh;
    min-height: 100dvh;
    background-color: var(--lagoon);
    color: var(--bone);
    font-family: var(--face-ui);
    font-size: 1rem;
    line-height: 1.5;
    font-variation-settings: 'wdth' 100;
    -webkit-font-smoothing: antialiased;
    caret-color: var(--flamingo);
}

/* Grain papier sur tout l'écran, sans jamais capter un clic. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    background-image: var(--grain);
    opacity: 0.16;
    mix-blend-mode: soft-light;
    pointer-events: none;
    z-index: 0;
}

/* ---------- Accueil ---------- */

.home {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    /* Le pied de page (lien Administration) reste dans la colonne de droite, sous le line-up :
       l'affiche, collée en haut de la colonne de gauche, ne peut plus le recouvrir. */
    grid-template-areas:
        "poster setup"
        "poster lineup"
        "poster foot";
    grid-template-rows: auto 1fr auto;
    column-gap: clamp(2rem, 5vw, 5rem);
    max-width: 1500px;
    margin: 0 auto;
    padding: max(clamp(1.25rem, 3vw, 2.5rem), var(--safe-top)) var(--edge-right) calc(1.5rem + var(--safe-bottom)) var(--edge-left);
    min-height: 100vh;
    min-height: 100dvh;
}

.wordmark {
    margin: 0;
    font-family: var(--face-wordmark);
    font-size: clamp(1.6rem, 2.6vw, 2.3rem);
    line-height: 1.1;
    color: var(--bone);
    text-shadow: 0.05em 0.05em 0 var(--flamingo);
    transform: rotate(-3deg);
    transform-origin: left center;
    width: fit-content;
}
.wordmark-small { font-size: clamp(1.1rem, 1.8vw, 1.6rem); }
/* Le logo du site : assets/img/Qm-logo.png sur fond clair (l'affiche), Qm-logo-clair.png (texte crème)
   sur fond foncé (l'affiche du blindtest, la vidéo du DanceFloor). */
.brand-logo { margin: 0; line-height: 0; }
.brand-logo img { display: block; width: auto; max-width: 100%; }
.poster-brand img { height: clamp(2.6rem, 4.6vw, 4.2rem); }
.stage-brand img { height: clamp(1.5rem, 2.8vw, 2.4rem); }
/* Au blindtest, le logo ramène à l'accueil, comme au DanceFloor. */
button.stage-brand { margin: -0.2rem; padding: 0.2rem; border: 0; border-radius: var(--radius); background: none; cursor: pointer; }
button.stage-brand:hover { opacity: 0.85; }
button.stage-brand:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 3px; }

/* L'affiche de la soirée : une feuille de papier os collée au mur lagon. */
.poster {
    grid-area: poster;
    align-self: start;
    position: sticky;
    top: clamp(1.25rem, 3vw, 2.5rem);
    display: flex;
    flex-direction: column;
    gap: clamp(0.8rem, 1.6vh, 1.2rem);
    height: min(calc(100dvh - 2 * clamp(1.25rem, 3vw, 2.5rem)), 54rem);
    min-height: 32rem;
    padding: clamp(1.1rem, 2.2vw, 1.8rem);
    background-color: var(--bone);
    color: var(--ink);
    isolation: isolate;
    border-radius: 3px;
    box-shadow: 0 2px 0 rgb(0 0 0 / 0.08), 0 28px 60px rgb(0 0 0 / 0.38);
    transform: rotate(-0.8deg);
}

.poster::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: var(--grain);
    opacity: 0.35;
    mix-blend-mode: multiply;
    pointer-events: none;
    border-radius: inherit;
}

/* Grand titre en deux passes d'encre : encre noire par-dessus, flamant décalé dessous. */
.poster-title {
    position: relative;
    margin: 0;
    font-family: var(--face-display);
    font-weight: 400;
    font-size: clamp(4.2rem, 9.4vw, 10rem);
    line-height: 0.86;
    letter-spacing: 0;
    text-transform: uppercase;
    color: var(--ink);
    isolation: isolate;
}
.poster-title::before {
    content: attr(data-text);
    position: absolute;
    inset: 0;
    color: var(--flamingo);
    transform: translate(0.04em, 0.035em);
    z-index: -1;
}

/* La photo de l'affiche en bichromie (encre tirée au sort par affiche.js) et noir, avec la trame d'impression. */
.poster-photo {
    position: relative;
    flex: 1;
    min-height: 12rem;
    margin: 0;
    background: var(--poster-ink, var(--flamingo));
    overflow: hidden;
    isolation: isolate;
}
/* Repli : bichromie simple (photo en gris multipliée sur l'aplat rose), le temps que la trame s'imprime. */
.poster-photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--poster-focus, center 45%);
    filter: grayscale(1) contrast(1.3) brightness(1.1);
    mix-blend-mode: multiply;
}
/* La trame d'imprimerie calculée par halftone.js, posée d'un coup de raclette. */
.poster-screen {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    animation: print-first 0.9s 0.15s var(--ease-out) both;
}

.poster-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
}
.poster .wordmark { color: var(--ink); text-shadow: 0.05em 0.05em 0 var(--flamingo); }
.poster-tagline {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 1rem;
    margin: 0;
    font-weight: 800;
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ink);
}
.poster-tagline span:last-child { flex-basis: 100%; }
.poster-tagline span:not(:last-child)::after {
    content: '';
    display: inline-block;
    width: 0.4em;
    height: 0.4em;
    margin-left: 1.25rem;
    border-radius: 50%;
    background: var(--flamingo);
    vertical-align: 0.15em;
}
/* Jamais de point en fin de ligne : la dernière phrase a sa propre ligne. */
.poster-tagline span:nth-last-child(2)::after { display: none; }

/* Réglages */
.setup {
    grid-area: setup;
    display: grid;
    gap: 1rem;
    align-content: start;
    padding-top: 0.5rem;
}

.tickets {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.6rem;
    margin: 0;
    padding: 0;
    border: 0;
    min-width: 0;
}
.tickets legend, .setup-legend {
    padding: 0;
    margin-bottom: 0.55rem;
    font-family: var(--face-display);
    font-size: 1.35rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* Un ticket : papier os perforé, poinçonné quand il est choisi. */
.ticket {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "icon name" "note note";
    align-items: center;
    column-gap: 0.45rem;
    row-gap: 0.15rem;
    min-height: 4.75rem;
    padding: 0.7rem 0.75rem 0.65rem;
    border: 2px solid rgb(244 235 221 / 0.55);
    border-radius: var(--radius);
    cursor: pointer;
    transition: background-color 0.2s, border-color 0.2s, color 0.2s;
    -webkit-mask: radial-gradient(circle at 0 50%, transparent 0.42rem, #000 0.45rem) left / 51% 100% no-repeat,
                  radial-gradient(circle at 100% 50%, transparent 0.42rem, #000 0.45rem) right / 51% 100% no-repeat;
            mask: radial-gradient(circle at 0 50%, transparent 0.42rem, #000 0.45rem) left / 51% 100% no-repeat,
                  radial-gradient(circle at 100% 50%, transparent 0.42rem, #000 0.45rem) right / 51% 100% no-repeat;
}
.ticket input { position: absolute; opacity: 0; pointer-events: none; }
.ticket .icon { grid-area: icon; width: 1.4rem; height: 1.4rem; }
.ticket-name { grid-area: name; font-weight: 800; font-size: 1rem; line-height: 1.15; }
.ticket-note { grid-area: note; font-size: 0.8rem; line-height: 1.25; color: var(--bone-soft); }
.ticket:hover { border-color: var(--bone); }
.ticket:has(input:checked) {
    background: var(--bone);
    border-color: var(--bone);
    color: var(--ink);
}
.ticket:has(input:checked) .ticket-note { color: var(--ink-soft); }
/* Le poinçon : marque d'état, pas seulement une couleur. */
.ticket:has(input:checked)::after {
    content: '';
    position: absolute;
    top: 0.5rem;
    right: 0.55rem;
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 50%;
    background: var(--lagoon);
    box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.45);
}
.ticket:has(input:focus-visible) { outline: 3px solid var(--flamingo); outline-offset: 3px; }

.setup-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
}

.switcher {
    display: inline-flex;
    margin: 0;
    padding: 3px;
    border: 2px solid rgb(244 235 221 / 0.55);
    border-radius: calc(var(--radius) + 3px);
    min-width: 0;
}
.switcher label { position: relative; cursor: pointer; }
.switcher input { position: absolute; opacity: 0; pointer-events: none; }
.switcher span {
    display: flex;
    align-items: baseline;
    gap: 0.35em;
    min-height: 2.6rem;
    align-items: center;
    padding: 0.35rem 0.9rem;
    border-radius: var(--radius);
    font-weight: 800;
    white-space: nowrap;
}
.switcher small { font-weight: 600; font-size: 0.8em; opacity: 0.75; }
.switcher input:checked + span { background: var(--bone); color: var(--ink); }
.switcher input:focus-visible + span { outline: 3px solid var(--flamingo); outline-offset: 2px; }

.toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    min-height: 2.75rem;
    font-weight: 700;
    cursor: pointer;
}
.toggle input { position: absolute; opacity: 0; pointer-events: none; }
.toggle-track {
    position: relative;
    flex: none;
    width: 3.6rem;
    height: 1.7rem;
    border: 2px solid currentColor;
    border-radius: 1rem;
    transition: background-color 0.2s;
}
.toggle-track::after {
    content: '';
    position: absolute;
    top: 0.18rem;
    left: 0.2rem;
    width: 1.05rem;
    height: 1.05rem;
    border-radius: 50%;
    background: currentColor;
    transition: transform 0.25s var(--ease-out), background-color 0.2s;
}
/* L'état est écrit dans la piste, du côté libre : on le lit sans comparer deux interrupteurs. */
.toggle-track::before {
    content: 'NON';
    position: absolute;
    top: 50%;
    right: 0.42rem;
    transform: translateY(-50%);
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    line-height: 1;
}
.toggle input:checked + .toggle-track { background: var(--bone); border-color: var(--bone); }
.toggle input:checked + .toggle-track::before { content: 'OUI'; right: auto; left: 0.5rem; color: var(--ink); }
.toggle input:checked + .toggle-track::after { transform: translateX(1.88rem); background: var(--ink); }
.toggle input:focus-visible + .toggle-track { outline: 3px solid var(--flamingo); outline-offset: 3px; }
.toggle-light input:checked + .toggle-track { background: var(--ink); border-color: var(--ink); }
.toggle-light input:checked + .toggle-track::after { background: var(--bone); }
.toggle-light input:checked + .toggle-track::before { color: var(--bone); }

html[data-play="dance"] .only-blindtest,
html[data-play="dance"] #auto-note,
html:not([data-play="dance"]) .only-dance,
html:not([data-play="group"]) .only-group,
html:not([data-play="solo"]) .only-solo { display: none; }

.toggle-note {
    flex-basis: 100%;
    margin: -0.4rem 0 0;
    font-size: 0.85rem;
    color: var(--bone-soft);
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 2.75rem;
    padding: 0.4rem 0.95rem;
    border: 2px solid rgb(244 235 221 / 0.55);
    border-radius: 2rem;
    background: transparent;
    font-weight: 700;
}
.chip:hover, .chip[aria-expanded="true"] { border-color: var(--bone); }
.chip[data-count]:not([data-count="0"])::after {
    content: attr(data-count);
    display: grid;
    place-items: center;
    min-width: 1.6rem;
    height: 1.6rem;
    padding: 0 0.35rem;
    border-radius: 1rem;
    background: var(--flamingo);
    color: var(--ink);
    font-size: 0.85rem;
    font-weight: 800;
}

/* Panneau joueurs : une feuille de papier os posée sur l'affiche. */
.players-panel {
    padding: 1.1rem 1.2rem 1.2rem;
    background: var(--bone);
    color: var(--ink);
    border-radius: var(--radius);
    box-shadow: 0 14px 30px rgb(0 0 0 / 0.3);
}
.panel-title {
    margin: 0 0 0.25rem;
    font-family: var(--face-display);
    font-weight: 400;
    font-size: 1.6rem;
    text-transform: uppercase;
    line-height: 1.1;
}
.panel-note { margin: 0 0 0.85rem; color: var(--ink-soft); font-size: 0.95rem; }
.players-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 0.85rem;
    padding: 0;
    list-style: none;
}
.players-list:empty { display: none; }
.player-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.35rem 0.3rem 0.75rem;
    border: 2px solid var(--ink);
    border-radius: 2rem;
    font-weight: 700;
}
.player-tag button {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border: 0;
    border-radius: 50%;
    background: transparent;
}
.player-tag button:hover { background: rgb(21 20 19 / 0.1); }
.player-tag .icon { width: 1rem; height: 1rem; }
.player-add { display: flex; gap: 0.5rem; }
.player-add input {
    flex: 1;
    min-width: 0;
    min-height: 2.75rem;
    padding: 0.5rem 0.8rem;
    border: 2px solid var(--ink);
    border-radius: var(--radius);
    background: #fffaf2;
    color: var(--ink);
}
.player-add input::placeholder { color: #6f675d; }
.panel-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.85rem; }

/* Line-up : chaque playlist est une tête d'affiche qu'on touche pour lancer la soirée. */
.lineup { grid-area: lineup; margin-top: 1.6rem; outline: none; }
.lineup-title {
    margin: 0;
    font-family: var(--face-script);
    font-weight: 400;
    font-size: clamp(1.7rem, 2.6vw, 2.3rem);
    line-height: 1.2;
    color: var(--bone);
    text-shadow: 0.05em 0.05em 0 var(--flamingo);
}
.lineup-hint { margin: 0.2rem 0 0.9rem; color: var(--bone-soft); font-weight: 600; }
.lineup-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.4rem 1rem; }
.mix-toggle { min-height: 2.4rem; padding: 0.3rem 0.85rem; color: var(--bone); }
.mix-toggle .icon { width: 1.1rem; height: 1.1rem; }
.mix-toggle[aria-pressed="true"] { border-color: var(--bone); background: var(--bone); color: var(--ink); }

/* Mélange : chaque playlist se coche (disque vide, puis orange coché) au lieu de partir tout de suite. */
.act-go .icon + .icon { display: none; }
.lineup[data-mix="on"] .act-go { background: transparent; border-color: rgb(244 235 221 / 0.55); color: var(--ink); }
.lineup[data-mix="on"] .act-go .icon:first-child { display: none; }
.lineup[data-mix="on"] .act[aria-pressed="true"] .act-go { background: var(--sunset); border-color: var(--ink); }
.lineup[data-mix="on"] .act[aria-pressed="true"] .act-go .icon + .icon { display: block; margin: 0; }
.lineup[data-mix="on"] .act[aria-pressed="true"] .act-name { color: var(--bone); }
.lineup[data-mix="on"] .act:hover .act-go, .lineup[data-mix="on"] .act:focus-visible .act-go { transform: none; }
.mix-bar {
    position: sticky;
    bottom: calc(0.75rem + var(--safe-bottom));
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem 1rem;
    margin-top: 0.9rem;
    padding: 0.75rem 0.9rem;
    border: 3px solid var(--ink);
    border-radius: var(--radius);
    background: var(--bone);
    color: var(--ink);
    box-shadow: 0 14px 30px rgb(0 0 0 / 0.4);
}
.mix-summary { margin: 0; font-weight: 800; font-variant-numeric: tabular-nums; }
.mix-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.mix-bar .stamp { min-height: 2.75rem; font-size: 1.15rem; }
.mix-bar .stamp:disabled { opacity: 0.45; cursor: default; transform: rotate(-1.2deg); }

.lineup-list { margin: 0; padding: 0; list-style: none; border-top: 2px solid rgb(244 235 221 / 0.35); }

/* « Par décennie » : la dernière ligne du line-up, une pastille par décennie. */
.decades { padding: 0.95rem 0.25rem 0.85rem; border-bottom: 2px solid rgb(244 235 221 / 0.35); }
.decades-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; margin-bottom: 0.75rem; }
.decades-title {
    margin: 0;
    font-family: var(--face-display);
    font-weight: 400;
    font-size: clamp(1.5rem, 2.5vw, 2rem);
    line-height: 1.05;
    text-transform: uppercase;
    color: var(--bone);
}
.decades-options { min-height: 2.4rem; padding: 0.3rem 0.85rem; color: var(--bone); }
.decades-options .icon { width: 1.1rem; height: 1.1rem; }
.decades-list { display: flex; flex-wrap: wrap; gap: 0.55rem; margin: 0; padding: 0; list-style: none; }
.decade {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    min-height: 2.75rem;
    padding: 0.45rem 1rem 0.35rem;
    border: 2px solid rgb(244 235 221 / 0.75);
    border-radius: 2rem;
    background: transparent;
    color: var(--bone);
    font-family: var(--face-display);
    font-size: 1.45rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s, transform 0.25s var(--ease-stamp);
}
.decade-count { font-family: var(--face-ui); font-size: 0.75rem; font-weight: 700; color: var(--bone-soft); font-variant-numeric: tabular-nums; }
.decade:hover, .decade:focus-visible { background: var(--bone); color: var(--ink); transform: rotate(-2deg); outline: none; }
.decade:hover .decade-count, .decade:focus-visible .decade-count { color: var(--ink-soft); }
.decade[aria-disabled="true"] { border-color: rgb(244 235 221 / 0.3); color: rgb(244 235 221 / 0.45); cursor: default; }
.decade[aria-disabled="true"]:hover, .decade[aria-disabled="true"]:focus-visible { background: transparent; color: rgb(244 235 221 / 0.6); transform: none; outline: 2px solid rgb(244 235 221 / 0.4); }
.decade[aria-disabled="true"] .decade-count { color: inherit; }
.decade[aria-busy="true"] { background: var(--sunset); border-color: var(--ink); color: var(--ink); }
.decades-hint { margin: 0.65rem 0 0; font-size: 0.85rem; font-weight: 600; color: var(--bone-soft); }
/* Volet « Décennies » : les playlists comprises. */
.decades-sheet-list { display: grid; margin: 0.6rem 0 0; padding: 0; list-style: none; }
.decades-sheet-list label {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    min-height: 2.75rem;
    padding: 0.15rem 0.2rem;
    border-bottom: 1px solid rgb(21 20 19 / 0.12);
    font-weight: 700;
    cursor: pointer;
}
.decades-sheet-list input { flex: none; width: 1.3rem; height: 1.3rem; accent-color: var(--ink); }
.decades-sheet-count { margin-left: auto; font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
.decades-sheet-note { margin-top: 0.8rem; }
.lineup-list li { border-bottom: 2px solid rgb(244 235 221 / 0.35); }

.act {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(1rem, 1fr) auto auto;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    min-height: 3.6rem;
    padding: 0.35rem 0.4rem 0.3rem 0.25rem;
    border: 0;
    background: transparent;
    color: var(--bone);
    text-align: left;
    transition: color 0.15s, background-color 0.15s;
}
.act-name {
    font-family: var(--face-display);
    font-size: clamp(1.7rem, 3vw, 2.45rem);
    line-height: 1.05;
    text-transform: uppercase;
    letter-spacing: 0.01em;
}
/* Pointillés entre le nom et le nombre de titres, comme sur une affiche de festival. */
.act-leader {
    height: 0.3rem;
    align-self: center;
    margin-top: 0.4rem;
    background-image: radial-gradient(circle, currentColor 1.4px, transparent 1.8px);
    background-size: 0.65rem 0.3rem;
    background-repeat: repeat-x;
    opacity: 0.45;
}
.act-count { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--bone-soft); white-space: nowrap; }
.act-go {
    display: grid;
    place-items: center;
    width: 2.6rem;
    height: 2.6rem;
    border: 2px solid var(--ink);
    border-radius: 50%;
    background: var(--sunset);
    color: var(--ink);
    transition: background-color 0.15s, transform 0.25s var(--ease-stamp);
}
.act-go .icon { width: 1.05rem; height: 1.05rem; margin-left: 0.12rem; }
.act-name, .act-flag { transition: transform 0.25s var(--ease-out); }
.act:hover .act-name, .act:focus-visible .act-name { transform: translateX(0.6rem); }
.act:hover, .act:focus-visible {
    color: var(--spot);
    background: rgb(7 58 66 / 0.55);
    outline: none;
}
.act:hover .act-count, .act:focus-visible .act-count { color: var(--bone); }
.act:hover .act-go, .act:focus-visible .act-go {
    background: #ff7d4d;
    transform: rotate(-8deg) scale(1.08);
}
.act:focus-visible { box-shadow: inset 0 0 0 3px var(--flamingo); }
.act[aria-busy="true"] .act-go { animation: spin 0.9s linear infinite; }
.act:disabled { opacity: 0.45; }
/* Drapeau plié : la dernière playlist jouée. */
.act-flag {
    position: absolute;
    left: -0.2rem;
    top: 50%;
    width: 0.55rem;
    height: 1.7rem;
    margin-top: -0.85rem;
    background: var(--spot);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 78%, 0 100%);
}

.lineup-skeleton {
    height: 3.6rem;
    background: linear-gradient(90deg, rgb(244 235 221 / 0.06), rgb(244 235 221 / 0.14), rgb(244 235 221 / 0.06)) 0 0 / 200% 100%;
    animation: shimmer 1.4s linear infinite;
}
.lineup-error {
    padding: 1rem 1.1rem;
    margin-top: 0.5rem;
    background: var(--alert);
    color: var(--bone);
    border-radius: var(--radius);
    font-weight: 700;
}
.lineup-error button { margin-top: 0.6rem; }

.home-foot {
    grid-area: foot;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.6rem;
    margin-top: 3rem;
    padding-top: 1.1rem;
    border-top: 2px solid rgb(244 235 221 / 0.2);
    font-size: 0.9rem;
    color: var(--bone-soft);
}
.home-foot a { color: var(--bone); font-weight: 700; text-underline-offset: 0.2em; }
/* Sources des années (Discogs demande d'être cité, et qu'on dise que le site n'en dépend pas). */
.home-credit { flex-basis: 100%; margin: 0; font-size: 0.78rem; line-height: 1.45; opacity: 0.75; }
.home-credit a { font-weight: 600; }
.home-foot a:hover { color: var(--flamingo); }

/* ---------- Écran de jeu ---------- */

/* Partie ouverte : l'accueil disparaît de la page. Sur iPhone, les barres flottantes de Safari
   laissent voir la page derrière elles et l'écran de jeu fixe ne passe pas dessous : il n'y reste
   que le fond, à la couleur du bord de l'écran de jeu (lagon foncé sous l'affiche ou la pause,
   encre sous la vidéo). */
html[data-view="stage"] .home { display: none; }
html[data-view="stage"],
html[data-view="stage"] body {
    overflow: hidden;
    background-color: var(--ink);
    transition: background-color 0.3s var(--ease-out);
}
html[data-view="stage"]:has(.stage-cover:not([hidden]), .stage-message[data-kind="pause"]:not([hidden])),
html[data-view="stage"]:has(.stage-cover:not([hidden]), .stage-message[data-kind="pause"]:not([hidden])) body {
    background-color: var(--lagoon-deep);
}
html[data-view="stage"] body::before { z-index: 3; opacity: 0.1; }

.stage {
    position: fixed;
    inset: 0;
    z-index: 2;
    background: var(--ink);
    overflow: hidden;
    overflow: clip;
    touch-action: none;
    user-select: none;
    -webkit-touch-callout: none; /* pas de menu iOS sur l'appui long d'un score */
}
.stage[data-idle="true"] { cursor: none; }
/* Commandes masquées (inactivité) : un voile transparent couvre la vidéo. Sans lui, un mouvement de
   souris au-dessus de la vidéo partirait vers YouTube et le jeu ne le verrait pas : les poignées ne
   reviendraient pas. Le premier mouvement le retire (stage.js, wake) ; il cache aussi le curseur. */
.stage[data-idle="true"]::after { content: ""; position: absolute; inset: 0; z-index: 2; }

.stage-video, .stage-video iframe, #yt-player, #yt-player-b {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}
/* Deux platines l'une sur l'autre : celle qui joue est devant, l'autre attend derrière, invisible.
   En mix, celle qui arrive passe devant et apparaît en fondu (durée posée par le moteur). */
.stage-video > * { z-index: 1; transition: opacity 0.35s var(--ease-out); }
.stage-video > .is-standby { z-index: 0; opacity: 0; pointer-events: none; }
.stage-video > .is-entering { z-index: 2; opacity: 1; transition: opacity 3s linear; }

/* L'affiche qui cache la vidéo pendant la recherche. Le compteur et la question forment un bloc ;
   la publicité est centrée entre la question et les talons de scores (ou le bas de l'écran) :
   l'espace libre se partage à parts égales au-dessus du compteur, sous la question et sous la pub. */
.stage-cover {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto auto auto minmax(1.5rem, 1fr) auto minmax(1.5rem, 1fr);
    justify-items: center;
    padding: max(clamp(1rem, 2.5vw, 2rem), var(--safe-top)) var(--edge-right) calc(2.5rem + var(--safe-bottom)) var(--edge-left);
    background-color: var(--lagoon);
    background-image:
        radial-gradient(ellipse at 50% 55%, rgb(11 85 96 / 0) 35%, rgb(7 58 66 / 0.9) 100%),
        var(--halftone);
    background-size: auto, 7px 7px;
    clip-path: inset(0 0 0 0);
}

/* Place réservée aux talons de scores, à leur hauteur réelle (ils passent sur deux lignes avec
   beaucoup de joueurs sur un écran étroit) : le bas de l'affiche s'arrête au ras des talons. */
.stage:has(.scoreboard:not([hidden])) .stage-cover { padding-bottom: calc(var(--board-h, 3.6rem) + 1.2rem + var(--safe-bottom)); }
.stage-top { grid-row: 1; }
.countdown { grid-row: 3; }
.stage-question { grid-row: 4; }
.stage-hints { grid-row: 5; }
.ad-slot { grid-row: 7; }

/* Le tirage à la raclette : l'affiche s'efface de gauche à droite, une barre d'encre en tête. */
.stage-cover.is-pulling {
    animation: pull-cover 0.85s var(--ease-out) forwards;
}
.stage-cover.is-pulling::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 1.1rem;
    background: var(--spot);
    box-shadow: 0 0 0 4px var(--ink);
    animation: squeegee 0.85s var(--ease-out) forwards;
}

.stage-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    width: 100%;
}
.stage-where {
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    font-family: var(--face-display);
    font-size: clamp(1.3rem, 2.4vw, 2rem);
    text-transform: uppercase;
    color: var(--spot);
    text-align: right;
}
.stage-count {
    font-family: var(--face-ui);
    font-weight: 700;
    font-size: 0.55em;
    color: var(--bone-soft);
    font-variant-numeric: tabular-nums;
    text-transform: none;
}

/* Le décompte : deux passes d'encre, chaque chiffre est tamponné. */
.countdown {
    display: grid;
    place-items: center;
    align-self: center;
    font-family: var(--face-display);
    font-size: clamp(7rem, 30vh, 19rem);
    line-height: 0.8;
    font-variant-numeric: tabular-nums;
    isolation: isolate;
}
.countdown-pass, .reveal-pass { grid-area: 1 / 1; position: relative; }
/* La première passe reste toujours devant, même quand seule la seconde est décalée. */
[data-pass="first"] { z-index: 2; }
[data-pass="second"] { z-index: 1; }
.countdown-pass[data-pass="first"] { color: var(--bone); }
.countdown-pass[data-pass="second"] { color: var(--spot); transform: translate(0.035em, 0.03em); }
.countdown.is-stamped .countdown-pass[data-pass="first"] { animation: stamp 0.45s var(--ease-stamp); }
.countdown.is-stamped .countdown-pass[data-pass="second"] { animation: misregister 0.45s var(--ease-out); }
/* Les 5 dernières secondes : les encres s'inversent. */
.countdown[data-urgent="true"] .countdown-pass[data-pass="first"] { color: var(--flamingo); }
.countdown[data-urgent="true"] .countdown-pass[data-pass="second"] { color: var(--bone); }

.stage-question {
    margin: 0.3em 0 0;
    font-family: var(--face-script);
    font-size: clamp(2rem, 6.5vh, 4.4rem);
    line-height: 1.1;
    color: var(--bone);
    text-shadow: 0.06em 0.06em 0 var(--flamingo);
    transform: rotate(-2.5deg);
}

/* Indices pendant la recherche, sous la question : la 1re lettre de chaque mot, puis la 2e. Leur
   place est réservée dès le début quand les indices sont actifs : rien ne bouge quand ils tombent. */
.stage-hints { display: grid; justify-items: center; align-content: start; margin-top: 0.6rem; text-align: center; }
.stage[data-hints="on"] .stage-hints { min-height: clamp(2.2rem, 6vh, 3.4rem); }
.hint-letters {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.15em 1.1em;
    margin: 0;
    font-family: var(--face-display);
    font-size: clamp(1.4rem, 4.4vh, 2.6rem);
    line-height: 1.1;
    letter-spacing: 0.05em;
    color: var(--bone);
    text-shadow: 0.05em 0.05em 0 var(--flamingo);
}
.hint-word { white-space: nowrap; }
.hint-letters.is-stamped { animation: stamp-hint 0.45s var(--ease-stamp) both; }
@keyframes stamp-hint {
    0% { transform: scale(1.15); opacity: 0; }
    60% { opacity: 1; }
    100% { transform: none; opacity: 1; }
}

.ad-slot {
    display: grid;
    justify-items: center;
    gap: 0.25rem;
    padding: 0.35rem 0.4rem 0.4rem;
    background: var(--bone);
    color: var(--ink-soft);
    border-radius: 4px;
    box-shadow: 0 10px 24px rgb(0 0 0 / 0.3);
    max-width: 100%;
}
.ad-label { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
/* Entre deux recherches, la bannière reste en place mais invisible : rien ne saute à son retour. */
.ad-slot.is-off { visibility: hidden; }
/* Petit téléphone : le liseré s'amincit pour que la bannière de 320 px tienne en entier. */
@media (max-width: 380px) {
    .ad-slot { padding-inline: 0.1rem; }
}
.ad-frame iframe { display: block; border: 0; max-width: 100%; }

/* Révélation : bandeau d'encre en haut, titre imprimé en deux passes. */
.reveal {
    position: absolute;
    z-index: 3;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    padding: max(clamp(0.8rem, 2vh, 1.4rem), var(--safe-top)) var(--edge-right) clamp(0.8rem, 2vh, 1.4rem) var(--edge-left);
    background: rgb(21 20 19 / 0.94);
    box-shadow: 0 12px 30px rgb(0 0 0 / 0.4);
    transition: background-color 0.3s var(--ease-out);
}
/* En pause, le bandeau prend le lagon foncé du fond : sur iPhone, la bande sous la barre de Safari
   et le haut de l'écran restent de la même couleur. */
.stage:has(.stage-message[data-kind="pause"]:not([hidden])) .reveal { background-color: rgb(7 58 66 / 0.94); }
.reveal-title {
    position: relative;
    flex: 0 1 auto;
    min-width: 0;
    display: grid;
    margin: 0;
    overflow-wrap: anywhere;
    font-family: var(--face-display);
    font-weight: 400;
    font-size: clamp(1.8rem, 6vh, 4rem);
    line-height: 1.05;
    text-transform: uppercase;
    text-wrap: balance;
    isolation: isolate;
}
.reveal-pass[data-pass="first"] { color: var(--bone); }
.reveal-pass[data-pass="second"] { color: var(--spot); transform: translate(0.04em, 0.035em); }
.reveal.is-printing .reveal-pass[data-pass="second"] { animation: print-second 0.7s var(--ease-out) both; }
.reveal.is-printing .reveal-pass[data-pass="first"] { animation: print-first 0.75s 0.18s var(--ease-out) both; }
/* L'année du morceau, tamponnée à côté du titre une fois celui-ci imprimé. */
.reveal-year {
    flex: none;
    margin: 0;
    padding: 0.12em 0.38em 0.04em;
    border: 3px solid var(--spot);
    border-radius: var(--radius);
    font-family: var(--face-display);
    font-size: clamp(1.4rem, 4.4vh, 2.8rem);
    line-height: 1;
    color: var(--spot);
    font-variant-numeric: tabular-nums;
    transform: rotate(-1.2deg);
}
.reveal.is-printing .reveal-year { animation: stamp-year 0.45s 0.8s var(--ease-stamp) both; }

/* La colonne de droite ne rétrécit jamais sous son plus large élément (sinon « Suivant dans » ou un
   bouton déborderait à gauche, sur l'année) : c'est le titre, long, qui passe à la ligne. */
.reveal-side { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 0.9rem; flex: 0 1 auto; min-width: min-content; margin-left: auto; }
.reveal-side .stamp, .reveal-side .button-quiet-light { white-space: nowrap; }
/* Grand écran tenu droit (tablette, écran pivoté) : à côté de l'année et des boutons, un titre long
   n'aurait plus qu'une colonne étroite et sortirait par le bas ; l'année et les boutons passent dessous. */
@media (orientation: portrait) {
    html[data-screen="large"] .reveal { flex-direction: column; align-items: stretch; gap: 0.6rem; }
    html[data-screen="large"] .reveal-year { align-self: flex-start; }
}
.reveal-next {
    margin: 0;
    font-weight: 700;
    font-size: clamp(1rem, 2.4vh, 1.4rem);
    color: var(--bone-soft);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.reveal-next strong { color: var(--bone); font-family: var(--face-display); font-weight: 400; font-size: 1.4em; }
.solo-score { display: flex; align-items: center; gap: 0.6rem; }
/* Tampon os : marquer un point ne lance pas de musique, l'orange ne lui revient pas. */
.stamp-bone { background: var(--bone); }
.stamp-bone:hover { background: #fffaf2; }
.solo-score .button-quiet-light { color: var(--bone); min-height: 3rem; }

.stage-message {
    position: absolute;
    z-index: 4;
    inset: 0;
    display: grid;
    place-items: center;
    padding: max(var(--gutter), var(--safe-top)) var(--edge-right) max(var(--gutter), var(--safe-bottom)) var(--edge-left);
    pointer-events: none;
}
.stage-message > * { pointer-events: auto; }
.message-plate {
    display: grid;
    justify-items: center;
    gap: 0.9rem;
    max-width: 34rem;
    padding: 1.6rem 1.8rem;
    background: var(--bone);
    color: var(--ink);
    border: 3px solid var(--ink);
    border-radius: var(--radius);
    box-shadow: 0 22px 50px rgb(0 0 0 / 0.45);
    text-align: center;
    transform: rotate(-1deg);
    animation: stamp 0.4s var(--ease-stamp);
}
.message-plate h2 {
    margin: 0;
    font-family: var(--face-display);
    font-weight: 400;
    font-size: clamp(2.2rem, 7vh, 4rem);
    line-height: 1;
    text-transform: uppercase;
}
.message-plate p { margin: 0; font-weight: 600; color: var(--ink-soft); }
.message-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; }
/* Une alerte change de matière : plaque rouge pleine. */
.message-plate.is-alert { background: var(--alert); color: var(--bone); }
.message-plate.is-alert p { color: var(--bone); }
.message-plate.is-alert .button-quiet { color: var(--bone); }
/* Écran de pause : l'affiche recouvre le lecteur (YouTube y afficherait sinon « Plus de vidéos »).
   Il passe sous le bandeau du titre et les scores, qui restent visibles ; un toucher relance la lecture. */
.stage-message[data-kind="pause"] {
    z-index: 2;
    background-color: var(--lagoon);
    background-image:
        radial-gradient(ellipse at 50% 55%, rgb(11 85 96 / 0) 35%, rgb(7 58 66 / 0.9) 100%),
        var(--halftone);
    background-size: auto, 7px 7px;
}
.message-plate.is-pause { background: transparent; border: 0; box-shadow: none; pointer-events: none; }
.message-plate.is-pause h2 {
    font-size: clamp(4rem, 16vh, 9rem);
    color: var(--bone);
    text-shadow: 0.05em 0.05em 0 var(--spot);
}

/* Tableau des scores : des talons de tickets en bas de l'écran, au-dessus de la zone sensible du
   curseur (sinon toucher le bas d'un talon déplacerait la vidéo au lieu de marquer le point). */
.scoreboard {
    position: absolute;
    z-index: 5;
    left: 0;
    right: 0;
    bottom: calc(1.2rem + var(--safe-bottom));
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin: 0;
    padding: 0 var(--edge-right) 0 var(--edge-left);
    list-style: none;
    pointer-events: none;
}
.stub {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.3rem 0.9rem 0.3rem 0.75rem;
    background: var(--bone);
    color: var(--ink);
    border-radius: 4px;
    box-shadow: 0 8px 20px rgb(0 0 0 / 0.35);
    pointer-events: auto;
    -webkit-mask: radial-gradient(circle at 0 50%, transparent 0.32rem, #000 0.35rem);
            mask: radial-gradient(circle at 0 50%, transparent 0.32rem, #000 0.35rem);
}
.stub button { all: unset; display: flex; align-items: center; gap: 0.7rem; cursor: pointer; }
.stub-key {
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    border: 2px solid var(--ink);
    border-radius: 50%;
    font-size: 0.75rem;
    font-weight: 800;
}
.stub-name { font-weight: 800; font-size: clamp(0.95rem, 2.2vh, 1.3rem); }
.stub-score {
    font-family: var(--face-display);
    font-size: clamp(1.5rem, 4vh, 2.4rem);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.stub.is-leading { background: var(--flamingo); }
.stub.is-bumped { animation: stamp 0.4s var(--ease-stamp); }

.progress {
    position: absolute;
    z-index: 4;
    left: 0;
    right: 0;
    bottom: 0;
    height: 6px;
    background: rgb(21 20 19 / 0.65);
    transition: height 0.15s var(--ease-out), left 0.4s var(--ease-out);
}
.progress:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 6px; }
.progress-fill {
    height: 100%;
    width: 100%;
    background: var(--spot);
    transform-origin: left;
    transform: scaleX(0);
}
/* Curseur : quand la barre montre la position dans la vidéo, on peut cliquer ou glisser dessus.
   La zone sensible dépasse la barre (28px), pour le doigt comme pour la souris de loin. */
.progress[aria-disabled="false"] { cursor: pointer; }
.progress[aria-disabled="false"]::before { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 28px; }
.progress[aria-disabled="false"]:hover, .progress.is-scrubbing { height: 10px; }
.progress-thumb {
    position: absolute;
    top: 50%;
    left: var(--x, 0%);
    width: 18px;
    height: 18px;
    margin: -9px 0 0 -9px;
    border: 3px solid var(--ink);
    border-radius: 50%;
    background: var(--spot);
    box-shadow: 0 2px 6px rgb(0 0 0 / 0.45);
    opacity: 0;
    transform: scale(0.6);
    transition: opacity 0.15s, transform 0.15s var(--ease-out);
    pointer-events: none;
}
.progress[aria-disabled="false"]:hover .progress-thumb, .progress.is-scrubbing .progress-thumb, .progress:focus-visible .progress-thumb { opacity: 1; transform: none; }
/* Le temps visé, au-dessus du pouce pendant qu'on glisse ; aux deux bords, la bulle reste entière. */
.progress-time {
    position: absolute;
    bottom: calc(100% + 0.9rem);
    left: clamp(2.6rem, var(--x, 0%), calc(100% - 2.6rem));
    display: none;
    padding: 0.2rem 0.5rem;
    border-radius: 3px;
    background: var(--ink);
    color: var(--bone);
    font-family: var(--face-ui);
    font-size: 0.95rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    transform: translateX(-50%);
}
.progress.is-scrubbing .progress-time { display: block; }
html[data-screen="mobile"] .progress[aria-disabled="false"]:hover, html[data-screen="mobile"] .progress.is-scrubbing { height: 12px; }
/* Téléphone : la barre reste au-dessus de l'indicateur d'accueil et de la bande de geste du système,
   et sa zone sensible fait la taille d'un doigt. */
html[data-screen="mobile"] .progress { bottom: var(--safe-bottom); }
html[data-screen="mobile"] .progress[aria-disabled="false"]::before { height: 44px; }

/* Les commandes : une barre verticale au bord droit, repliée derrière une languette fléchée.
   Ouverte, elle reste jusqu'à ce qu'on la referme (son dernier bouton). */
.dock {
    position: absolute;
    z-index: 5;
    top: 50%;
    right: max(0.75rem, env(safe-area-inset-right, 0px));
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.4rem;
    background: var(--ink);
    border: 2px solid rgb(244 235 221 / 0.18);
    border-radius: 1.2rem;
    box-shadow: -10px 14px 34px rgb(0 0 0 / 0.45);
    opacity: 0;
    visibility: hidden;
    transform: translate(calc(100% + 1.5rem), -50%);
    transition: opacity 0.25s, transform 0.4s var(--ease-out), visibility 0s 0.4s;
}
.stage[data-dock="open"] .dock {
    opacity: 1;
    visibility: visible;
    transform: translate(0, -50%);
    transition: opacity 0.25s, transform 0.4s var(--ease-out), visibility 0s;
}
.dock-close::before {
    content: '';
    position: absolute;
    top: -0.2rem;
    left: 0.6rem;
    right: 0.6rem;
    border-top: 1.5px solid rgb(244 235 221 / 0.18);
}

/* La languette : collée au bord droit, à mi-hauteur. */
.dock-handle {
    position: absolute;
    z-index: 5;
    top: 50%;
    right: 0;
    display: grid;
    place-items: center;
    width: calc(2.75rem + env(safe-area-inset-right, 0px));
    height: 4.4rem;
    padding: 0 env(safe-area-inset-right, 0px) 0 0;
    border: 2px solid rgb(244 235 221 / 0.18);
    border-right: 0;
    border-radius: 1rem 0 0 1rem;
    background: var(--ink);
    color: var(--bone);
    box-shadow: -8px 10px 26px rgb(0 0 0 / 0.4);
    cursor: pointer;
    transform: translateY(-50%);
    transition: opacity 0.25s, transform 0.4s var(--ease-out);
}
.dock-handle .icon { width: 1.6rem; height: 1.6rem; }
.dock-handle:hover { background: var(--ink-soft); }
.dock-handle:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 2px; }
.stage[data-dock="open"] .dock-handle { opacity: 0; transform: translate(100%, -50%); pointer-events: none; }

/* ---------- DanceFloor ---------- */

.stage { --dance-w: min(25rem, 88vw); }

/* La languette musique, en miroir de celle des commandes, au bord gauche. */
.dance-handle {
    position: absolute;
    z-index: 5;
    top: 50%;
    left: 0;
    display: grid;
    place-items: center;
    width: calc(2.75rem + env(safe-area-inset-left, 0px));
    height: 4.4rem;
    padding: 0 0 0 env(safe-area-inset-left, 0px);
    border: 2px solid rgb(244 235 221 / 0.18);
    border-left: 0;
    border-radius: 0 1rem 1rem 0;
    background: var(--ink);
    color: var(--bone);
    box-shadow: 8px 10px 26px rgb(0 0 0 / 0.4);
    cursor: pointer;
    transform: translateY(-50%);
    transition: opacity 0.25s, transform 0.4s var(--ease-out);
}
.dance-handle .icon { width: 1.5rem; height: 1.5rem; }
.dance-handle:hover { background: var(--ink-soft); }
.dance-handle:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 2px; }
.stage[data-panel="open"] .dance-handle { opacity: 0; transform: translate(-100%, -50%); pointer-events: none; }
.stage[data-idle="true"] .dance-handle { opacity: 0; pointer-events: none; }

/* Le volet : papier os, comme les options. Sur grand écran il pousse la vidéo au lieu de la couvrir. */
.dance-panel {
    position: absolute;
    z-index: 7;
    top: 0;
    bottom: 0;
    left: 0;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    width: var(--dance-w);
    overflow: auto;
    overscroll-behavior: contain;
    padding: max(1rem, var(--safe-top)) 1rem calc(1rem + var(--safe-bottom)) max(1rem, env(safe-area-inset-left, 0px));
    background: var(--bone);
    color: var(--ink);
    box-shadow: 18px 0 44px rgb(0 0 0 / 0.45);
    scrollbar-color: var(--ink-soft) transparent;
    visibility: hidden;
    transform: translateX(-100%);
    transition: transform 0.4s var(--ease-out), visibility 0s 0.4s;
}
.stage[data-panel="open"] .dance-panel { visibility: visible; transform: none; transition: transform 0.4s var(--ease-out), visibility 0s; }
/* Grand écran assez large : le volet pousse la vidéo (qui garde au moins 200 px), le carton et les messages. */
@media (min-width: 40.0625rem) {
    html[data-screen="large"] .stage-video { width: auto; transition: left 0.4s var(--ease-out); }
    html[data-screen="large"] .stage[data-panel="open"] .stage-video { left: var(--dance-w); }
    html[data-screen="large"] .stage[data-panel="open"] .dance-caption {
        left: calc(var(--dance-w) + var(--edge-left));
        max-width: min(44rem, calc(100% - var(--dance-w) - var(--edge-left) - 5rem));
    }
    html[data-screen="large"] .stage[data-panel="open"] .stage-message { padding-left: var(--dance-w); }
    html[data-screen="large"] .stage[data-panel="open"] .progress { left: var(--dance-w); }
}
/* Ailleurs (téléphone, fenêtre étroite), le volet passe par-dessus : un voile capte le toucher qui le referme. */
.dance-scrim {
    position: absolute;
    z-index: 6;
    inset: 0;
    display: none;
    background: rgb(0 0 0 / 0.35);
}
html[data-screen="mobile"] .stage[data-panel="open"] .dance-scrim { display: block; }
@media (max-width: 40rem) {
    .stage[data-panel="open"] .dance-scrim { display: block; }
}
.dance-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.dance-title { margin: 0; font-family: var(--face-display); font-weight: 400; font-size: 2rem; line-height: 1; text-transform: uppercase; }
.dance-panel .icon-button { display: inline-grid; place-items: center; padding: 0; color: var(--ink); cursor: pointer; }
/* « Réduire » : chevron et mot, pour que le geste soit lisible de loin. */
.dance-close {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-height: 2.75rem;
    padding: 0 0.9rem 0 0.6rem;
    border: 2px solid var(--ink);
    border-radius: var(--radius);
    background: transparent;
    color: var(--ink);
    font-family: var(--face-ui);
    font-size: 1rem;
    font-weight: 800;
    cursor: pointer;
}
.dance-close:hover { background: rgb(21 20 19 / 0.08); }
.dance-close:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 2px; }
.dance-panel .icon-button:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 2px; }
.dance-field { display: grid; gap: 0.3rem; }
.dance-label, .dance-subtitle { font-weight: 800; }
.dance-subtitle { display: flex; align-items: baseline; gap: 0.4rem; margin: 0 0 0.45rem; font-size: 0.95rem; }
.dance-count { color: var(--ink-soft); font-weight: 700; }
.dance-panel select,
.dance-search input {
    width: 100%;
    min-height: 2.75rem;
    padding: 0.4rem 0.7rem;
    border: 2px solid var(--ink);
    border-radius: var(--radius);
    background: #fffaf2;
    color: var(--ink);
    font: inherit;
}
.dance-search { position: relative; display: block; margin-bottom: 0.6rem; }
.dance-search .icon { position: absolute; left: 0.7rem; top: 50%; width: 1.1rem; height: 1.1rem; transform: translateY(-50%); pointer-events: none; }
.dance-search input { padding-left: 2.3rem; }
.dance-section { min-width: 0; }
.dance-queue, .dance-list { display: grid; gap: 0.35rem; margin: 0; padding: 0; list-style: none; }
.dance-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.4rem 0.4rem 0.65rem;
    border: 1.5px solid rgb(21 20 19 / 0.22);
    border-radius: var(--radius);
    background: #fffaf2;
}
.dance-queue .dance-row { grid-template-columns: auto minmax(0, 1fr) auto; cursor: grab; }
.dance-grip { min-width: 1.4rem; font-family: var(--face-display); font-size: 1.2rem; color: var(--flamingo); text-align: center; font-variant-numeric: tabular-nums; }
.dance-text { display: grid; gap: 0.1rem; min-width: 0; }
.dance-name { font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.dance-meta { display: flex; flex-wrap: wrap; gap: 0.15rem 0.6rem; font-size: 0.8rem; color: var(--ink-soft); }
.dance-state { font-weight: 800; }
.dance-actions { display: inline-flex; gap: 0.25rem; }
.dance-actions .icon-button { width: 2.4rem; height: 2.4rem; border: 1.5px solid currentColor; border-radius: var(--radius); background: transparent; }
.dance-actions .icon-button:hover:not(:disabled) { background: rgb(21 20 19 / 0.08); }
.dance-actions .icon-button:disabled { opacity: 0.3; cursor: default; }
.dance-row.is-played { opacity: 0.5; }
.dance-row.is-played:hover, .dance-row.is-played:focus-within { opacity: 0.85; }
.dance-row.is-current { border-color: var(--lagoon); box-shadow: 0 0 0 2px var(--lagoon); }
.dance-row.is-current .dance-state { color: var(--lagoon); }
.dance-row.is-dragging { opacity: 0.4; }
.dance-row.is-over { box-shadow: 0 -3px 0 var(--flamingo); }
.dance-empty { margin: 0; font-size: 0.88rem; color: var(--ink-soft); }
/* Le morceau en cours, avec de quoi passer au suivant. */
.dance-now { flex-shrink: 0; }
.dance-now .dance-actions { align-items: center; }
.dance-skip { min-height: 2.4rem; padding: 0.35em 0.8em 0.35em 0.6em; font-weight: 800; cursor: pointer; }
.dance-skip .icon { width: 1.1rem; height: 1.1rem; }
.dance-skip:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 2px; }
.dance-foot { margin-top: auto; padding-top: 0.4rem; }

/* Le carton « En ce moment » / « À suivre », en bas à gauche, façon chaîne musicale. */
.dance-caption {
    position: absolute;
    z-index: 4;
    left: var(--edge-left);
    bottom: calc(1.6rem + var(--safe-bottom));
    max-width: min(44rem, calc(100% - var(--edge-left) - 5rem));
    padding: 0.65rem 1.1rem 0.75rem;
    border-radius: var(--radius);
    background: rgb(21 20 19 / 0.88);
    box-shadow: 0 12px 30px rgb(0 0 0 / 0.4);
    pointer-events: none;
    transition: left 0.4s var(--ease-out);
}
.dance-caption-label { margin: 0 0 0.15rem; font-weight: 800; font-size: 0.85rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--flamingo); }
.dance-caption-year { color: var(--bone); font-variant-numeric: tabular-nums; }
.dance-caption-title {
    margin: 0;
    font-family: var(--face-display);
    font-weight: 400;
    font-size: clamp(1.4rem, 3.4vw, 2.6rem);
    line-height: 1.05;
    text-transform: uppercase;
    color: var(--bone);
    text-shadow: 0.04em 0.035em 0 var(--flamingo);
    overflow-wrap: anywhere;
}
.dance-caption.is-printing { animation: print-first 0.75s var(--ease-out) both; }
.stage[data-idle="true"] .dock,
.stage[data-idle="true"] .dock-handle { opacity: 0; pointer-events: none; }
.dock-button {
    display: grid;
    place-items: center;
    width: 3.4rem;
    height: 3.4rem;
    border: 0;
    border-radius: 0.85rem;
    background: transparent;
    color: var(--bone);
}
.dock-button .icon { width: 1.55rem; height: 1.55rem; }
.dock-button:hover { background: rgb(244 235 221 / 0.12); }
.dock-main { background: var(--bone); color: var(--ink); }
.dock-main:hover { background: #fff; }
.dock-button[hidden] { display: none; }
.dock-close { position: relative; color: var(--bone-soft); }
.dock-close:hover { color: var(--bone); }

/* Barre ouverte : le titre, ses boutons et les messages se rangent à sa gauche. */
.stage { --dock-room: calc(max(0.75rem, env(safe-area-inset-right, 0px)) + 5rem); }
.stage[data-dock="open"] .reveal,
.stage[data-dock="open"] .stage-message { padding-right: var(--dock-room); }

/* DanceFloor : le logo du site, toujours visible en haut à droite de la vidéo (comme celui d'une
   chaîne de télé) ; un clic ramène à l'accueil. */
.dance-brand {
    position: absolute;
    z-index: 5;
    top: max(0.9rem, var(--safe-top));
    right: var(--edge-right);
    display: none;
    margin: 0;
    padding: 0.2rem;
    border: 0;
    border-radius: var(--radius);
    background: none;
    opacity: 0.92;
    cursor: pointer;
}
/* Le logo (assets/img/Qm-logo.png, fond transparent) : une ombre douce le garde lisible sur un clip clair. */
.dance-brand img {
    display: block;
    width: auto;
    height: clamp(1.4rem, 2.4vw, 2.1rem);
    filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.55)) drop-shadow(0 0 6px rgb(0 0 0 / 0.35));
}
.dance-brand:hover { opacity: 1; }
.dance-brand:focus-visible { outline: 3px solid var(--flamingo); outline-offset: 3px; }
html[data-play="dance"] .dance-brand { display: block; }
/* Barre de commandes ouverte (bord droit) : le logo se place à sa gauche. */
.stage[data-dock="open"] .dance-brand { right: var(--dock-room); }

/* ---------- Feuilles (popover) ---------- */

.sheet {
    margin: 0;
    inset: auto max(1rem, env(safe-area-inset-right, 0px)) calc(1rem + var(--safe-bottom)) auto;
    width: min(26rem, calc(100% - 2rem));
    max-height: calc(100% - 2rem - var(--safe-top) - var(--safe-bottom));
    overflow: auto;
    padding: 1.2rem 1.25rem 1.3rem;
    background: var(--bone);
    color: var(--ink);
    border: 3px solid var(--ink);
    border-radius: var(--radius);
    box-shadow: 0 24px 60px rgb(0 0 0 / 0.5);
    scrollbar-color: var(--ink-soft) transparent;
    /* Au clavier, le bouton qui prend le focus ne passe pas sous l'en-tête collant (titre et croix). */
    scroll-padding-top: 4rem;
}
.sheet:popover-open { animation: sheet-in 0.3s var(--ease-out); }
.sheet::backdrop { background: rgb(7 58 66 / 0.35); }
.sheet-title {
    margin: 0 0 0.9rem;
    font-family: var(--face-display);
    font-weight: 400;
    font-size: 1.8rem;
    text-transform: uppercase;
    line-height: 1;
}
/* En-tête du volet : le titre et la croix qui le ferme. Il reste en haut quand le volet défile
   (top négatif : l'accroche se mesure depuis l'intérieur de la marge du volet, pas depuis son bord). */
.sheet-head {
    position: sticky;
    z-index: 2;
    top: -1.2rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    margin: -1.2rem -1.25rem 0.6rem;
    padding: 1.2rem 1.25rem 0.3rem;
    background: var(--bone);
}
.sheet-head .sheet-title { margin: 0; }
.sheet-close {
    flex: none;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    margin: -0.4rem -0.45rem -0.4rem 0;
    border: 2px solid var(--ink);
    border-radius: var(--radius);
    background: transparent;
    color: var(--ink);
}
.sheet-close:hover { background: rgb(21 20 19 / 0.08); }
.sheet-subtitle { margin: 1.2rem 0 0.6rem; font-size: 1rem; font-weight: 800; }
.sheet-group { display: grid; gap: 0.6rem; }
.sheet-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.1rem; }
.sheet-note { margin: 0; font-size: 0.85rem; font-weight: 600; color: var(--ink-soft); }
.stage[data-dock="open"] ~ .sheet { right: calc(max(0.75rem, env(safe-area-inset-right, 0px)) + 5.3rem); }

.volume { display: flex; align-items: center; gap: 0.75rem; font-weight: 700; }
.volume input { flex: 1; accent-color: var(--ink); min-height: 2.5rem; }
.volume output { min-width: 2.5rem; text-align: right; font-variant-numeric: tabular-nums; }
/* Volume et coupure du son sur la même ligne. À côté du curseur, l'icône suffit (le texte reste lu
   par les lecteurs d'écran) ; sur iPhone et iPad, où le curseur n'existe pas, le texte revient. */
.volume-line { display: flex; align-items: center; gap: 0.5rem 1rem; min-width: 0; }
.volume-line .volume { flex: 1; min-width: 0; }
.volume-line .volume input { min-width: 0; }
.mute-toggle { flex: none; gap: 0.45rem; }
.volume-line:has(> .volume[hidden]) .mute-icon { display: none; }
.volume-line:has(> .volume:not([hidden])) .mute-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* Une action qu'on ne peut pas défaire se confirme par un bouton qui apparaît juste à sa droite. */
.button-confirm {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    min-height: 2.75rem;
    padding: 0.5em 0.75em;
    border: 2px solid var(--alert);
    border-radius: var(--radius);
    background: var(--alert);
    color: var(--bone);
    font-weight: 700;
}
.button-confirm:hover { background: #9e180b; border-color: #9e180b; }
@media (prefers-reduced-motion: no-preference) {
    .button-confirm { animation: confirm-in 0.2s var(--ease-out); }
}
@keyframes confirm-in { from { opacity: 0; transform: translateX(-0.4rem); } }

.report-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.report {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 3rem;
    padding: 0.5rem 0.7rem;
    border: 2px solid var(--ink);
    border-radius: var(--radius);
    background: transparent;
    font-weight: 700;
    text-align: left;
    line-height: 1.2;
}
.report:hover { background: rgb(21 20 19 / 0.08); }
.report.is-sent { background: var(--ink); color: var(--bone); }
.report-alert { border-color: var(--alert); color: var(--alert); }
.report-alert:hover { background: var(--alert); color: var(--bone); }

.scores-edit { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.4rem; }
.scores-edit li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto auto auto;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.3rem 0.3rem 0.7rem;
    border: 2px solid var(--ink);
    border-radius: var(--radius);
}
.scores-edit .score-value { font-family: var(--face-display); font-size: 1.6rem; min-width: 2.2rem; text-align: center; font-variant-numeric: tabular-nums; }
.scores-edit button {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border: 2px solid var(--ink);
    border-radius: 50%;
    background: transparent;
}
.scores-edit button:hover { background: rgb(21 20 19 / 0.1); }
.scores-edit .score-name {
    display: block;
    width: auto;
    height: auto;
    min-height: 2.75rem;
    padding: 0 0.4rem;
    border: 0;
    border-radius: var(--radius);
    font-weight: 800;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: text;
}
.scores-edit .score-key { min-width: 1.3rem; font-family: var(--face-display); font-size: 1.15rem; color: var(--flamingo); text-align: center; font-variant-numeric: tabular-nums; }
.scores-edit .score-remove { width: 2.4rem; height: 2.4rem; border-width: 1.5px; border-radius: var(--radius); opacity: 0.75; }
.scores-edit .score-remove:hover { opacity: 1; }
.scores-edit .score-remove .icon { width: 1rem; height: 1rem; }
/* Retrait d'un joueur à confirmer : les boutons de points s'effacent le temps de la question. */
.scores-edit li.is-confirming { grid-template-columns: auto minmax(0, 1fr) auto auto auto; }
.scores-edit li.is-confirming [data-role="minus"],
.scores-edit li.is-confirming [data-role="plus"] { display: none; }
.scores-edit .button-confirm { display: inline-flex; width: auto; height: auto; min-height: 2.4rem; padding: 0.3em 0.75em; border-color: var(--alert); border-radius: var(--radius); background: var(--alert); color: var(--bone); }
.scores-edit .button-confirm:hover { background: #9e180b; border-color: #9e180b; }
.score-rename {
    min-width: 0;
    min-height: 2.75rem;
    padding: 0.3rem 0.5rem;
    border: 2px solid var(--ink);
    border-radius: var(--radius);
    background: #fffaf2;
    color: var(--ink);
    font: inherit;
    font-weight: 800;
}
.scores-add { margin-top: 0.7rem; }
.scores-edit:empty { display: none; }
#scores-note { margin-top: 0.6rem; }
.solo-summary { margin: 0; font-family: var(--face-display); font-size: 2rem; line-height: 1.1; text-transform: uppercase; }

/* Partage d'un morceau : le titre, puis les façons de l'envoyer. */
.share-track { margin: 0 0 0.35rem; font-weight: 800; font-size: 1.05rem; line-height: 1.3; overflow-wrap: anywhere; }
.share-url {
    width: 100%;
    min-height: 2.5rem;
    margin-top: 0.7rem;
    padding: 0.4rem 0.6rem;
    border: 2px solid rgb(21 20 19 / 0.35);
    border-radius: var(--radius);
    background: #fffaf2;
    color: var(--ink);
    font: inherit;
    font-size: 0.85rem;
}
.share-grid { margin-top: 0.9rem; }
a.report { color: inherit; text-decoration: none; }
.share-note { margin-top: 0.9rem; }

/* Raccourcis : la colonne des touches prend au plus 45 % de la largeur et passe à la ligne au besoin
   (jamais au milieu d'une touche) ; la description garde toujours sa place. */
.sheet-help { width: min(34rem, calc(100% - 2rem)); }
.shortcuts { display: grid; grid-template-columns: fit-content(45%) minmax(0, 1fr); gap: 0.55rem 1rem; margin: 0; align-items: baseline; }
.shortcuts dt { font-weight: 700; }
.shortcuts kbd { white-space: nowrap; }
.shortcuts dd { margin: 0; overflow-wrap: break-word; }
html:not([data-input="touch"]) #shortcuts-touch,
html[data-input="touch"] #shortcuts-keys { display: none; }

/* ---------- Type d'écran (détecté) ---------- */

/* Grand écran (ordinateur, TV, tablette) : tout se lit de loin, le bandeau et les scores grossissent. */
html[data-screen="large"] .reveal-title { font-size: clamp(2.2rem, 7.5vh, 5rem); }
html[data-screen="large"] .stub { padding: 0.45rem 1.2rem 0.45rem 1rem; gap: 0.9rem; }
html[data-screen="large"] .stub button { gap: 0.9rem; }
html[data-screen="large"] .stub-name { font-size: clamp(1.4rem, 3.6vh, 2.2rem); }
html[data-screen="large"] .stub-score { font-size: clamp(2.6rem, 7.5vh, 4.5rem); }
html[data-screen="large"] .stub-key { width: 2rem; height: 2rem; font-size: 1rem; }
html[data-screen="large"] .stage:has(.scoreboard:not([hidden])) .stage-cover { padding-bottom: calc(var(--board-h, 6rem) + 1.2rem + var(--safe-bottom)); }
/* Smartphone : décompte et commandes à la taille de la main. */
html[data-screen="mobile"] .countdown { font-size: clamp(6rem, 27vh, 13rem); }
/* La question tient entre la poignée des commandes (à droite) et le bord gauche. */
html[data-screen="mobile"] .stage-question { font-size: clamp(1.8rem, 10vw, 2.8rem); }
html[data-screen="mobile"] .hint-letters { font-size: clamp(1.15rem, 6.2vw, 1.7rem); gap: 0.1em 0.8em; }
html[data-screen="mobile"] .stage[data-hints="on"] .stage-hints { min-height: 2.3rem; }
html[data-screen="mobile"] .dock-button { width: 3.1rem; height: 3.1rem; }

/* ---------- Petits écrans ---------- */

@media (max-width: 980px) {
    .home {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "poster" "setup" "lineup" "foot";
        grid-template-rows: none;
    }
    .poster { position: static; height: auto; min-height: 0; transform: rotate(-0.6deg); }
    .poster-title { font-size: clamp(4rem, 18vw, 9rem); }
    .poster-photo { flex: none; aspect-ratio: 16 / 8; }
    .setup { margin-top: 1.8rem; }
}

@media (max-width: 640px) {
    .poster { margin-inline: -0.25rem; gap: 0.55rem; }
    .poster-title { font-size: clamp(3rem, 15vw, 3.6rem); }
    .poster-photo { aspect-ratio: 2.4 / 1; min-height: 0; }
    .setup { margin-top: 1.2rem; gap: 0.7rem; }
    .tickets legend { font-size: 1.15rem; margin-bottom: 0.4rem; }
    .tickets { gap: 0.45rem; }
    .ticket {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "icon" "name" "note";
        justify-items: start;
        min-height: 3.6rem;
        padding: 0.5rem 0.55rem 0.5rem;
        -webkit-mask: none;
                mask: none;
    }
    .ticket-name { font-size: 0.9rem; }
    .ticket-note { font-size: 0.72rem; }
    .lineup { margin-top: 1.1rem; }
    /* La phrase d'aide reste lue par les lecteurs d'écran, sans repousser le line-up. */
    .lineup-hint { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
    .lineup-title { margin-bottom: 0.4rem; }
    .setup-row { gap: 0.5rem 1rem; }
    .poster-tagline { font-size: 0.8rem; }
    .act { grid-template-columns: auto minmax(0.5rem, 1fr) auto auto; gap: 0.55rem; min-height: 3.4rem; }
    .act-name { font-size: clamp(1.45rem, 7.5vw, 2rem); }
    .act-go { width: 2.3rem; height: 2.3rem; }
    .reveal { flex-direction: column; align-items: stretch; gap: 0.6rem; }
    .reveal-year { align-self: flex-start; }
    .reveal-side { justify-content: space-between; flex-wrap: wrap; }
    .stage { --dock-room: calc(max(0.75rem, env(safe-area-inset-right, 0px)) + 4.4rem); }
    .stage[data-dock="open"] .reveal { padding-right: var(--edge-right); }
    .stage[data-dock="open"] .reveal-side { padding-right: calc(var(--dock-room) - var(--edge-right)); }
    .stamp { font-size: 1.15rem; }
    .dock { gap: 0.15rem; padding: 0.3rem; }
    .dock-button { width: 2.95rem; height: 2.95rem; }
    .sheet, .stage[data-dock="open"] ~ .sheet { inset: auto max(0.5rem, env(safe-area-inset-right, 0px)) calc(0.5rem + var(--safe-bottom)) max(0.5rem, env(safe-area-inset-left, 0px)); width: auto; }
    .stub { padding: 0.2rem 0.7rem 0.2rem 0.6rem; }
    .stub-key { display: none; }
}

/* Téléphone tenu droit, au blindtest : la vidéo en haut (cadre 16:9 entier, rien ne la recouvre),
   le titre juste dessous, et les boutons qu'on touche le plus en bas, sous le pouce. */
@media (orientation: portrait) {
    html[data-screen="mobile"]:not([data-play="dance"]) .stage-video {
        inset: var(--safe-top) 0 auto 0;
        height: auto;
        aspect-ratio: 16 / 9;
    }
    html[data-screen="mobile"]:not([data-play="dance"]) .reveal {
        top: calc(var(--safe-top) + 100vw * 9 / 16);
        bottom: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 1rem;
        padding: 1.1rem var(--edge-right) calc(1.6rem + var(--safe-bottom)) var(--edge-left);
        background: var(--ink);
        box-shadow: none;
    }
    /* Les talons peuvent passer sur deux lignes : la place réservée suit leur hauteur réelle (--board-h). */
    html[data-screen="mobile"]:not([data-play="dance"]) .stage:has(.scoreboard:not([hidden])) .reveal { padding-bottom: calc(var(--board-h, 3.6rem) + 2rem + var(--safe-bottom)); }
    html[data-screen="mobile"]:not([data-play="dance"]) .reveal-title { flex: 0 0 auto; font-size: clamp(2.2rem, 11vw, 3.4rem); }
    html[data-screen="mobile"]:not([data-play="dance"]) .reveal-title.is-long { font-size: clamp(1.6rem, 7.5vw, 2.4rem); }
    html[data-screen="mobile"]:not([data-play="dance"]) .reveal-year { align-self: flex-start; font-size: clamp(1.5rem, 7.5vw, 2.2rem); }
    html[data-screen="mobile"]:not([data-play="dance"]) .stage[data-dock="open"] .reveal-title { margin-right: calc(var(--dock-room) - var(--edge-right)); }
    /* En pause après la révélation, « Pause » s'affiche sur la vidéo, au-dessus du titre. */
    html[data-screen="mobile"]:not([data-play="dance"]) .stage:has(#reveal:not([hidden])) .stage-message[data-kind="pause"] { bottom: auto; height: calc(var(--safe-top) + 100vw * 9 / 16); }
    html[data-screen="mobile"]:not([data-play="dance"]) .stage:has(#reveal:not([hidden])) .message-plate.is-pause h2 { font-size: clamp(3rem, 14vw, 5rem); }
    html[data-screen="mobile"]:not([data-play="dance"]) .reveal-side {
        flex-direction: column;
        align-items: stretch;
        gap: 0.8rem;
        margin-top: auto;
    }
    html[data-screen="mobile"]:not([data-play="dance"]) .reveal-next { white-space: normal; }
    html[data-screen="mobile"]:not([data-play="dance"]) .reveal-side .stamp { justify-content: center; min-height: 3.4rem; }
    html[data-screen="mobile"]:not([data-play="dance"]) .solo-score { display: grid; grid-template-columns: 1fr auto; }
    html[data-screen="mobile"]:not([data-play="dance"]) .solo-score[hidden] { display: none; }
    html[data-screen="mobile"]:not([data-play="dance"]) .solo-score .stamp { min-height: 3.8rem; font-size: 1.45rem; }
    html[data-screen="mobile"]:not([data-play="dance"]) .solo-score .button-quiet-light { min-height: 3.8rem; padding-inline: 1.4rem; }
}

@media (max-height: 520px) and (orientation: landscape) {
    .countdown, html[data-screen="mobile"] .countdown { font-size: clamp(4.5rem, 30vh, 9rem); }
    .stage-question { font-size: clamp(1.4rem, 7vh, 2.4rem); }
    .stage-cover { grid-template-rows: auto minmax(0, 1fr) auto auto auto minmax(0.6rem, 1fr) auto minmax(0.6rem, 1fr); }
    .hint-letters { font-size: clamp(1.05rem, 6vh, 1.5rem); }
    .stage[data-hints="on"] .stage-hints { min-height: 1.9rem; margin-top: 0.3rem; }
    .stage-cover { padding-bottom: calc(1.2rem + var(--safe-bottom)); }
    /* Écran bas : la barre verticale doit tenir entre les barres du navigateur. */
    .dock { gap: 0.1rem; padding: 0.25rem; }
    .dock-button, html[data-screen="mobile"] .dock-button {
        width: 2.6rem;
        height: min(2.6rem, calc((100vh - 1.5rem) / 7));
        height: min(2.6rem, calc((100dvh - 1.5rem) / 7));
    }
    .stage { --dock-room: calc(max(0.75rem, env(safe-area-inset-right, 0px)) + 3.8rem); }
    .stage[data-dock="open"] .stage-top,
    .stage[data-dock="open"] .scoreboard { padding-right: var(--dock-room); }
    .dock-button .icon { width: 1.3rem; height: 1.3rem; }
}

/* ---------- Mouvements ---------- */

@keyframes stamp {
    0% { transform: scale(1.18) rotate(-3deg); opacity: 0.8; }
    60% { opacity: 1; }
    100% { transform: scale(1) rotate(0); opacity: 1; }
}
@keyframes misregister {
    0% { transform: translate(0.12em, 0.09em); opacity: 0; }
    100% { transform: translate(0.035em, 0.03em); opacity: 1; }
}
@keyframes pull-cover {
    0% { clip-path: inset(0 0 0 0); }
    100% { clip-path: inset(0 0 0 100%); }
}
@keyframes squeegee {
    0% { transform: translateX(-1.5rem); }
    100% { transform: translateX(calc(100vw + 1rem)); }
}
@keyframes print-second {
    0% { clip-path: inset(0 100% 0 0); transform: translate(0.16em, 0.12em); }
    60% { clip-path: inset(0 0 0 0); }
    100% { clip-path: inset(0 0 0 0); transform: translate(0.04em, 0.035em); }
}
@keyframes print-first {
    0% { clip-path: inset(0 100% 0 0); }
    100% { clip-path: inset(0 0 0 0); }
}
@keyframes stamp-year {
    0% { transform: scale(1.18) rotate(-4deg); opacity: 0; }
    60% { opacity: 1; }
    100% { transform: rotate(-1.2deg); opacity: 1; }
}
@keyframes sheet-in {
    from { opacity: 0; transform: translateY(1rem); }
    to { opacity: 1; transform: none; }
}
@keyframes shimmer { to { background-position: -200% 0; } }
@keyframes spin { to { transform: rotate(360deg); } }



@media (prefers-reduced-motion: reduce) {
    .stage-cover.is-pulling { animation: none; visibility: hidden; }
}

/* Très petits téléphones (320 px) : le nom « DanceFloor » tient dans son ticket. */
@media (max-width: 359px) {
    .ticket { padding-inline: 0.45rem; }
    .ticket-name { font-size: 0.8rem; }
}
