/* ════════════════════════════════════════════════════════════════════════════
   VOLONTAIRE DÉSIGNÉ — la page et la scène du tirage.

   La PAGE s'appuie sur les styles de base de volontaire.css (.bloc, .bouton, .champ,
   .liste…, et les variables --accent, --surface, --filet…) ; ce fichier n'ajoute que ce
   qui est propre au tirage.
   La SCÈNE est un autre monde, volontairement : une salle éteinte, projetée, en un seul
   thème sombre quel que soit le réglage. Ses noms et son verdict sont composés en Latin
   Modern, la police de LaTeX — celle des polycopiés de maths. La police est servie avec
   l'appli (fonts/, licence GUST) : rien n'est chargé d'ailleurs.
   ════════════════════════════════════════════════════════════════════════════ */

@font-face { font-family: "Tableau Serif"; src: url("fonts/lmroman10-regular.otf") format("opentype"); font-display: swap; }
@font-face { font-family: "Tableau Serif"; src: url("fonts/lmroman10-bold.otf") format("opentype"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Tableau Serif"; src: url("fonts/lmroman10-italic.otf") format("opentype"); font-style: italic; font-display: swap; }
/* Et sa compagne sans empattement, pour l'interface et les boutons (Maxime, 2026-10-07 :
   la police du système changeait d'un ordinateur à l'autre). Même famille, même licence. */
@font-face { font-family: "Tableau Sans"; src: url("fonts/lmsans10-regular.otf") format("opentype"); font-display: swap; }
@font-face { font-family: "Tableau Sans"; src: url("fonts/lmsans10-bold.otf") format("opentype"); font-weight: 700; font-display: swap; }

/* ══ La page ════════════════════════════════════════════════════════════════════ */

.erreur-tableau {
  color: var(--brique); background: var(--brique-t); border-radius: var(--rayon);
  padding: .7rem .9rem; margin-bottom: 1rem;
}
.erreur-tableau[hidden] { display: none; }
/* Le rappel de sauvegarde (appli publique) : visible sans crier — un aplat de la couleur
   d'accent, ses deux boutons à portée. */
.rappel {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .5rem .8rem;
  padding: .6rem .8rem; border-radius: var(--rayon);
  background: var(--accent-t); border: 1px solid var(--accent); color: var(--texte);
}
/* Le texte et ses deux boutons sur une ligne quand la place le permet. */
.rappel p { flex: 1 1 14rem; font-size: max(var(--mini), .95rem); line-height: 1.4; }
.rappel .actions { margin: 0; flex-wrap: nowrap; }
.version-appli {
  margin-top: 2.5rem; text-align: center; color: var(--pale);
  font-size: max(var(--mini), .85rem); font-variant-numeric: tabular-nums;
}
.info-tableau {
  color: var(--accent); background: var(--accent-t); border-radius: var(--rayon);
  padding: .7rem .9rem; margin-bottom: 1rem;
}

.tirer { width: 100%; min-height: 4.2rem; font-size: max(var(--mini), 1.3rem); }
.tirer:disabled { opacity: .45; cursor: not-allowed; }

.presents {
  color: var(--pale); text-align: center; margin-top: .5rem;
  font-size: max(var(--mini), .95rem); font-variant-numeric: tabular-nums;
}

/* L'appel : un bouton par élève. Pressé = absent aujourd'hui. */
.appel {
  display: grid; gap: .45rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 7.2rem), 1fr));
}
.eleve {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: .05rem; min-width: 0; min-height: 44px; padding: .45rem .65rem; cursor: pointer;
  font-family: inherit; font-size: 1rem; text-align: left; color: var(--texte);
  background: var(--surface); border: 1px solid var(--filet); border-radius: 8px;
}
.eleve-nom { font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.eleve-info { font-size: max(var(--mini), .8rem); color: var(--pale); font-variant-numeric: tabular-nums; }
.eleve[aria-pressed="true"] { background: transparent; border-style: dashed; color: var(--pale); }
.eleve[aria-pressed="true"] .eleve-nom { text-decoration: line-through; font-weight: 500; }
.eleve:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@media (hover: hover) { .eleve:hover { border-color: var(--accent); } }
/* Téléphone debout : deux colonnes, sinon l'appel d'une classe de quarante se fait en
   quarante écrans de pouce. */
@media (orientation: portrait) and (max-width: 699px) {
  .appel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.liste .vide { padding: 1rem; }
#jour + .actions .champ { flex: 1 1 10rem; }

.bascule-vue { margin-top: 0; }
.bascule-vue .bouton { flex: 1 1 0; }
.seance {
  font-size: max(var(--mini), .85rem); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); margin: 1.1rem 0 .45rem;
}
.ligne.parti { opacity: .6; }
.ligne.refus .ligne-meta { color: var(--brique); }

/* Les blocs repliés : réglages et liste de la classe, qu'on n'ouvre pas tous les jours. */
.depliant > summary {
  display: flex; align-items: center; min-height: 44px; cursor: pointer; list-style: none;
}
.depliant > summary::-webkit-details-marker { display: none; }
.depliant > summary::after { content: "▸"; margin-left: .5rem; transition: transform .2s; }
.depliant[open] > summary::after { transform: rotate(90deg); }
.depliant > .form { margin-top: .4rem; }
.form label.case {
  display: flex; align-items: center; gap: .6rem; min-height: 44px; font-weight: 500; cursor: pointer;
}
.form label.case input { width: 1.4rem; height: 1.4rem; flex-shrink: 0; accent-color: var(--accent); }
.form.essai { margin: -.4rem 0 1rem; }

/* Le vrai champ fichier est caché — son apparence ne se règle pas —, son étiquette (un
   bouton du socle) l'ouvre. Il reste focalisable : le cadre passe sur l'étiquette. */
.fichier { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.actions:has(.fichier:focus-visible) label[for="fichier-csv"] { outline: 2px solid var(--accent); outline-offset: 2px; }
.import-bilan { margin-top: .6rem; color: var(--pale); font-size: max(var(--mini), .95rem); }
.import-bilan.souci { color: var(--brique); }

/* La fiche « Format du .csv » : une notice, pas un formulaire — du texte courant, un
   exemple en chasse fixe qui défile seul s'il est trop large. */
.fiche-csv p, .fiche-csv ul { margin: .5rem 0; }
.fiche-csv ul { padding-left: 1.2rem; }
.fiche-csv li + li { margin-top: .2rem; }
.fiche-csv h3 { margin: 1.1rem 0 .3rem; font-size: 1.02rem; }
.exemple-csv {
  margin: .5rem 0 .2rem; padding: .6rem .8rem; overflow-x: auto;
  font-family: ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;
  font-size: max(var(--mini), .9rem); line-height: 1.45;
  background: var(--fond); border: 1px solid var(--filet); border-radius: 8px;
}
.aide-csv { color: var(--pale); font-size: max(var(--mini), .95rem); }
.liste-classe { margin-top: 1rem; }
.liste-classe .ligne { flex-wrap: wrap; gap: .5rem; }
.liste-classe .ligne-corps { flex: 1 1 8rem; }
.bouton.petit { flex: 0 0 auto; min-height: 44px; padding: .35rem .8rem; font-size: max(var(--mini), .9rem); }

/* Le choix de la classe dans les Paramètres : une rangée, l'étiquette contre son menu. */
.classe-choix { display: flex; align-items: center; gap: .5rem; font-weight: 600; flex: 1 1 14rem; }
.classe-choix .champ { flex: 1 1 auto; }

/* ══ ACCUEIL et TIRAGE : épurés, mais ils OCCUPENT l'écran ══
   (Maxime, 2026-10-03 : « elle est épurée mais il y a beaucoup de blanc. Occupe
   l'espace ».) Les mêmes éléments, plus grands : la colonne s'élargit avec l'écran
   (jusqu'à 56 % de sa largeur), et chaque élément prend une taille tirée de sa HAUTEUR.
   Au vidéoprojecteur tout grandit et se lit du fond de la salle ; sur un téléphone, rien
   ne change de place. Chaque taille est écrite deux fois : en `vh`, puis en `dvh` (la
   hauteur VISIBLE, barre d'adresse déduite) là où le navigateur la connaît. */
body[data-vue="accueil"], body[data-vue="tirage"] {
  --colonne: max(36rem, 56vw);
  --ecart: clamp(.75rem, 2.4vh, 1.75rem);
  --ecart: clamp(.75rem, 2.4dvh, 1.75rem);
}
body[data-vue="accueil"] .page, body[data-vue="tirage"] .page { max-width: none; }
body[data-vue="accueil"] .titre, body[data-vue="tirage"] .titre {
  text-align: center; padding-bottom: clamp(.6rem, 2vh, 1.5rem);
}
body[data-vue="accueil"] .titre h1, body[data-vue="tirage"] .titre h1 {
  font-size: clamp(1.7rem, 6vh, 4.2rem); font-size: clamp(1.7rem, 6dvh, 4.2rem);
}

/* ── ACCUEIL : le menu des classes et « Valider », au milieu de l'écran ── */
body[data-vue="accueil"] .titre label { cursor: pointer; }
.accueil { width: 100%; max-width: var(--colonne); margin: 0 auto; display: flex; flex-direction: column; gap: var(--ecart); }
/* ⚠ `flex: none` : un `flex: 1 1 …` écrit pour une rangée devient une HAUTEUR dans cette
   colonne (le menu des classes a déjà mesuré 224 px). */
/* Le menu : le nom de la classe centré, et le même « ▾ » que la pastille du TIRAGE — la
   flèche du navigateur ne grandit pas avec le reste. */
.menu-classe { position: relative; display: block; }
.menu-classe::after {
  content: "▾"; position: absolute; right: 1em; top: 50%; transform: translateY(-50%);
  pointer-events: none; color: var(--pale); font-size: clamp(var(--mini-champ), 3vh, 2rem);
}
.accueil .champ {
  flex: none; width: 100%; padding-inline: 2.2em; appearance: none; -webkit-appearance: none;
  text-align: center; text-align-last: center; font-weight: 600;
  min-height: clamp(50px, 12vh, 8rem); min-height: clamp(50px, 12dvh, 8rem);
  font-size: clamp(var(--mini-champ), 4.2vh, 2.8rem); font-size: clamp(var(--mini-champ), 4.2dvh, 2.8rem);
}
.accueil .bouton {
  border-radius: clamp(1rem, 3vh, 2rem);
  min-height: clamp(3.6rem, 14vh, 9rem); min-height: clamp(3.6rem, 14dvh, 9rem);
  font-size: clamp(1.25rem, 5vh, 3.4rem); font-size: clamp(1.25rem, 5dvh, 3.4rem);
}
.accueil .bouton:disabled { opacity: .45; cursor: not-allowed; }

/* ── TIRAGE : une colonne centrée, le bouton au milieu ──
   Elle tient sur un écran, de 1280 × 720 (le vidéoprojecteur) au téléphone. En titre, la
   classe : un clic ramène à l'accueil pour en changer (Maxime, 2026-10-03). */
/* La classe affichée, aussi présente que le bouton (Maxime, 2026-10-03 : « mets plus de
   place, comme le bouton tirer au sort, pour la classe affichée ») : une pastille de la
   largeur de la colonne, juste au-dessus du bouton et du même dessin — en creux, lui en
   plein. Un clic ramène à l'accueil pour changer de classe. */
.classe-lien {
  display: flex; align-items: center; justify-content: center; gap: .35em;
  width: 100%; max-width: var(--colonne, 36rem); margin: 0 auto; padding: .15em 1em;
  min-height: clamp(3.2rem, 13vh, 9rem); min-height: clamp(3.2rem, 13dvh, 9rem);
  border: 2px solid var(--filet); border-radius: clamp(1.2rem, 3vh, 2rem);
  background: var(--surface); color: inherit; text-decoration: none; overflow-wrap: break-word;
}
.classe-lien .chevron { font-size: .5em; color: var(--pale); }
@media (hover: hover) {
  .classe-lien:hover { border-color: var(--accent); }
  .classe-lien:hover .chevron { color: var(--accent); }
}
.classe-lien:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.jouer { width: 100%; max-width: var(--colonne, 36rem); margin: 0 auto; display: flex; flex-direction: column; gap: var(--ecart, .75rem); }
.jouer .tirer {
  border-radius: clamp(1.2rem, 3vh, 2rem);
  min-height: clamp(4rem, 20vh, 14rem); min-height: clamp(4rem, 20dvh, 14rem);
  font-size: clamp(1.6rem, 5.5vh, 3.8rem); font-size: clamp(1.6rem, 5.5dvh, 3.8rem);
}
/* Sur la page de la séance, le bouton principal ramène à l'écran d'attente : moins grand
   que ne l'était « Tirer au sort ». */
.jouer .tirer.retour { min-height: clamp(3.4rem, 10vh, 5rem); font-size: clamp(1.15rem, 3vh, 1.6rem); }
.jouer .objet {
  flex: none; width: 100%; text-align: center;
  min-height: clamp(50px, 8vh, 5.5rem); min-height: clamp(50px, 8dvh, 5.5rem);
  font-size: clamp(var(--mini-champ), 2.6vh, 1.8rem); font-size: clamp(var(--mini-champ), 2.6dvh, 1.8rem);
}
.jouer .absents > summary { font-size: clamp(1rem, 2.4vh, 1.6rem); font-size: clamp(1rem, 2.4dvh, 1.6rem); }
.jouer #ouvrir-volontaire {
  padding-inline: 1.2em;
  min-height: clamp(44px, 6.5vh, 4.5rem); min-height: clamp(44px, 6.5dvh, 4.5rem);
  font-size: clamp(.95rem, 2.2vh, 1.5rem); font-size: clamp(.95rem, 2.2dvh, 1.5rem);
}
/* Téléphone debout : moins de hauteur, et le pied y prend cinq lignes — tout se resserre
   d'un cran, pour que la page tienne encore sans défiler. */
@media (orientation: portrait) and (max-width: 699px) {
  body[data-vue="accueil"], body[data-vue="tirage"] {
    --ecart: clamp(.6rem, 1.6vh, 1rem); --ecart: clamp(.6rem, 1.6dvh, 1rem);
  }
  body[data-vue="accueil"] .titre h1, body[data-vue="tirage"] .titre h1 {
    font-size: clamp(1.5rem, 4.6vh, 2.6rem); font-size: clamp(1.5rem, 4.6dvh, 2.6rem);
  }
  .classe-lien { min-height: clamp(3rem, 9vh, 6rem); min-height: clamp(3rem, 9dvh, 6rem); }
  .accueil .champ { padding-inline: 1.8em; }
  .jouer .tirer { min-height: clamp(4rem, 14vh, 9rem); min-height: clamp(4rem, 14dvh, 9rem); }
  .jouer .objet { min-height: 50px; }
}
.jouer .actions { margin: 0; }
.actions.centre { justify-content: center; }
/* Les absents, repliés : la ligne de résumé est le bouton qui ouvre l'appel. */
.absents > summary {
  cursor: pointer; list-style: none; min-height: 44px; display: flex; align-items: center;
  justify-content: center; gap: .4rem; text-align: center; color: var(--pale);
  font-variant-numeric: tabular-nums;
}
.absents > summary::-webkit-details-marker { display: none; }
.absents > summary::after { content: "▸"; transition: transform .2s; }
.absents[open] > summary::after { transform: rotate(90deg); }
.absents .aide { text-align: center; margin: .3rem 0 .7rem; }
.aide { color: var(--pale); font-size: max(var(--mini), .95rem); margin: .3rem 0 .6rem; }

/* Le choix d'un volontaire : une feuille de boutons, un par présent. */
.modale .ligne {
  width: 100%; background: none; border: 0; border-bottom: 1px solid var(--filet);
  text-align: left; font: inherit; color: inherit; cursor: pointer;
}
@media (hover: hover) { .modale .ligne:hover { background: var(--accent-t); } }

/* ══ PARAMÉTRER : des sections nommées, un sommaire pour y sauter ══ */
.sommaire { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 1.4rem; }
.sommaire a {
  min-height: 44px; display: inline-flex; align-items: center; padding: .4rem .9rem;
  border: 1px solid var(--filet); border-radius: 999px; background: var(--surface);
  color: var(--texte); text-decoration: none; font-size: max(var(--mini), .95rem);
}
.sommaire a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.section { scroll-margin-top: 1rem; padding-top: .4rem; }
.section-titre { font-size: 1.35rem; font-weight: 700; margin: 0 0 .8rem; }
.section-titre .discret { color: var(--pale); }
body[data-vue="parametres"] #choix-classe { margin-bottom: 1.6rem; }
.ligne.courante { background: var(--accent-t); }

/* La mise en scène : onze cartes, celle qui est choisie marquée ; « Au hasard », à part,
   prend toute la ligne. */
/* Les onglets des paramètres : Réglages | Classe. */
.onglets-parametres { display: flex; gap: .3rem; margin: 0 0 1.2rem; border-bottom: 2px solid var(--filet); }
.onglet-param {
  min-height: 48px; padding: .5rem 1.3rem; margin-bottom: -2px; cursor: pointer;
  font: inherit; font-weight: 700; color: var(--pale); background: none;
  border: 0; border-bottom: 3px solid transparent;
}
.onglet-param[aria-selected="true"] { color: var(--texte); border-bottom-color: var(--accent); }
.onglet-param:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) { .onglet-param:hover { color: var(--texte); } }
.panneau[hidden] { display: none; }

/* Les mises en scène, par famille ; chaque carte, sa vignette et son bouton ▶. */
.famille { margin: 1.3rem 0 .25rem; font-size: 1.05rem; font-weight: 700; }
.section-titre + .famille { margin-top: .4rem; }
.famille-aide { margin: 0 0 .6rem; color: var(--pale); font-size: max(var(--mini), .9rem); line-height: 1.4; }
.choix-scenes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; }
.choix-scenes + .choix-scenes { margin-top: .6rem; }
.carte-scene { position: relative; display: flex; min-width: 0; }
.choix-scene {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: .2rem; min-height: 44px;
  padding: 0 0 .75rem; overflow: hidden; text-align: left; cursor: pointer; font: inherit; color: var(--texte);
  background: var(--surface); border: 1px solid var(--filet); border-radius: var(--rayon);
}
.choix-vignette {
  display: block; width: 100%; height: auto; aspect-ratio: 560 / 217; object-fit: cover;
  margin-bottom: .45rem; background: #07080B; border-bottom: 1px solid var(--filet);
}
.choix-scene .choix-nom, .choix-scene .choix-texte { padding: 0 .9rem; }
.essayer-scene {
  position: absolute; top: .4rem; right: .4rem; width: 44px; height: 44px; display: grid; place-items: center;
  padding: 0 0 0 3px; cursor: pointer; font-size: 1rem; color: #FFFFFF;
  background: rgba(7, 8, 11, .72); border: 1.5px solid rgba(255, 255, 255, .75); border-radius: 50%;
}
.essayer-scene:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) { .essayer-scene:hover { background: var(--accent); border-color: var(--accent); } }
.essayer-scene[hidden] { display: none; }
.carte-scene.hasard { grid-column: 1 / -1; }
.carte-scene.hasard .choix-vignette { aspect-ratio: 1120 / 108; }
.choix-scene[aria-pressed="true"] { border: 2px solid var(--accent); background: var(--accent-t); }
/* Une scène choisie porte sa coche, en haut à gauche de la vignette. */
.choix-scene { position: relative; }
.choix-scene[aria-pressed="true"]::after {
  content: "✓"; position: absolute; top: .45rem; left: .45rem; width: 1.9rem; height: 1.9rem;
  display: grid; place-items: center; border-radius: 50%; font-weight: 700;
  color: #FFFFFF; background: var(--accent); box-shadow: 0 0 0 2px rgba(255, 255, 255, .85);
}
.choix-scene:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) { .choix-scene:hover { border-color: var(--accent); } }
.choix-nom { font-weight: 700; }
.choix-texte { color: var(--pale); font-size: max(var(--mini), .9rem); line-height: 1.35; }
@media (orientation: portrait) and (max-width: 699px) {
  .choix-scenes { grid-template-columns: 1fr; }
}

/* La page derrière la scène ne défile pas. */
body.scene-ouverte { overflow: hidden; }

/* ══ La scène ═══════════════════════════════════════════════════════════════════
   Un seul thème, choisi : la salle est éteinte. */

.scene {
  --encre:       #07080B;
  --craie:       #ECE7DC;
  --craie-pale:  #8E8A82;
  --lampe:       #FFD98A;
  --alerte:      #E5484D;
  --or:          #FFC94D;
  --filet-scene: #262931;

  position: fixed; inset: 0; z-index: 100; overflow: hidden;
  display: grid; grid-template-rows: auto auto minmax(0, 1fr);
  padding: clamp(.8rem, 2.5vh, 2rem) clamp(1rem, 3vw, 3rem) clamp(3.6rem, 7vh, 4.5rem);
  background: var(--encre); color: var(--craie);
  font-family: "Tableau Serif", "Latin Modern Roman", "CMU Serif", Georgia, serif;
  animation: extinction .8s ease-out;
}
.scene[hidden] { display: none; }
@keyframes extinction { from { background-color: rgba(7, 8, 11, 0); } }

.scene-tete { text-align: center; margin-bottom: clamp(.5rem, 2vh, 1.4rem); }
.scene-titre {
  font-size: clamp(1.35rem, min(3.6vw, 5.6vh), 3rem); letter-spacing: .26em; text-transform: uppercase; text-wrap: balance;
  color: var(--craie-pale); animation: souffle 2.4s ease-in-out infinite;
}
@keyframes souffle { 50% { color: var(--craie); } }
.scene-objet { font-style: italic; font-size: clamp(1rem, 2vw, 1.4rem); color: var(--craie-pale); margin-top: .2rem; }
.scene-objet:empty { display: none; }

.scene-plateau { position: relative; min-height: 0; transition: opacity .6s, filter .6s; }
.scene.revelee .scene-plateau { opacity: .28; filter: blur(2px); }

/* Les phrases, sous le titre. Deux lignes réservées : une phrase longue qui passe à la
   ligne ne doit pas rogner le plateau en plein tirage (les grilles y sont calibrées au
   pixel). */
.scene-legende {
  text-align: center; font-style: italic; min-height: 2.6em; line-height: 1.3; margin: 0 0 .6rem;
  font-size: clamp(1.2rem, min(3vw, 4.4vh), 2.4rem); color: var(--craie); text-wrap: balance;
  opacity: 0; transition: opacity .45s;
}
.scene-legende.visible { opacity: 1; }
.scene-legende.voix-off { font-style: italic; color: var(--craie-pale); }
.scene-legende.replique { font-style: normal; color: var(--craie); }
/* L'étiquette qui suit : le nom en grand, là où les noms de la scène sont trop petits. */
.etiquette-suit {
  position: absolute; z-index: 37; margin: 0; padding: .15em .6em; border-radius: .4em; white-space: nowrap;
  font-weight: 700; color: #1A1D22; background: var(--craie); box-shadow: 0 .2em .8em rgba(0, 0, 0, .45);
  pointer-events: none;
}

.scene-coin { position: absolute; right: 1rem; bottom: 1rem; z-index: 5; display: flex; gap: .5rem; }
.scene-discret {
  min-height: 44px; padding: .4rem .95rem; cursor: pointer; opacity: .5;
  font-family: var(--texte-police); font-size: 15px; color: var(--craie-pale);
  background: none; border: 1px solid var(--filet-scene); border-radius: 999px;
}
.scene-discret:hover, .scene-discret:focus-visible { opacity: 1; }
.scene-discret[hidden] { display: none; }
.scene-discret:focus-visible { outline: 2px solid var(--lampe); outline-offset: 2px; }

/* ── Les tuiles (élimination, projecteur) ── */
.scene-grille {
  position: absolute; inset: 0; display: grid;
  grid-template-columns: repeat(var(--colonnes), minmax(0, 1fr)); grid-auto-rows: 1fr;
  gap: clamp(.3rem, .8vw, .7rem); font-size: var(--fs);
}
.tuile {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 0; padding: .2em .35em; text-align: center; line-height: 1.1; overflow-wrap: anywhere;
  border: 1px solid var(--filet-scene); border-radius: 6px;
  transition: opacity .5s, transform .6s cubic-bezier(.3, .6, .3, 1), filter .5s,
              background-color .12s, border-color .12s, color .12s, box-shadow .2s;
}
/* `--echelle` : posée par scene.js sur la tuile dont le nom ne tient pas au corps commun. */
.tuile { font-size: calc(1em * var(--echelle, 1)); }
.tuile-nom { font-weight: 700; }
.tuile-proba { margin-top: .2em; font-size: .5em; color: var(--craie-pale); font-variant-numeric: tabular-nums; }
/* Le trait rouge qui raye un nom tombé. */
.tuile::after {
  content: ""; position: absolute; left: 8%; right: 8%; top: 50%; height: 3px;
  background: var(--alerte); transform: scaleX(0); transform-origin: left; transition: transform .25s ease-out;
}
.tuile.out { opacity: .13; transform: translateY(.35em) rotate(var(--rot)); }
.tuile.out::after { transform: scaleX(1); }
.tuile.tremble { border-color: var(--alerte); animation: tremble .09s linear infinite; }
@keyframes tremble {
  25% { transform: translate(-2px, 1px) rotate(-.8deg); }
  75% { transform: translate(2px, -1px) rotate(.8deg); }
}
.tuile.vise { background: var(--craie); color: var(--encre); border-color: var(--craie); box-shadow: 0 0 2em rgba(255, 217, 138, .35); }
.tuile.vise .tuile-proba { color: var(--encre); }
.tuile.elu {
  z-index: 3; background: var(--or); color: var(--encre); border-color: var(--or);
  transform: scale(1.08); box-shadow: 0 0 3em rgba(255, 201, 77, .55);
}
.tuile.elu .tuile-proba { color: var(--encre); }
/* La surprise du duel : une tuile qui chancelle — rayée, penchée, mais encore là. */
.tuile.chancelle { opacity: .45; transform: translateY(.35em) rotate(var(--rot)); border-color: var(--alerte); }
.tuile.chancelle::after { transform: scaleX(1); }

/* Les six derniers se rassemblent au centre, en grand. */
.scene-grille.finale {
  display: flex; flex-wrap: wrap; justify-content: center; align-content: center;
  gap: clamp(.6rem, 1.6vw, 1.4rem); font-size: clamp(26px, 4.4vw, 68px);
}
.scene-grille.finale .tuile.out { display: none; }
.scene-grille.finale .tuile { min-width: 5.5em; padding: .45em .9em; border-width: 2px; }

/* ── Projecteur : un voile noir percé d'un rond de lumière ── */
.mode-projecteur .tuile { border-color: transparent; }
.nuit {
  position: absolute; inset: -2px; z-index: 2; pointer-events: none;
  opacity: 0; transition: opacity .9s ease-in;
}
.nuit.eteinte { opacity: 1; }

/* ── Machine à sous : trois cases visibles, celle du milieu fait foi ──
   Le corps des noms est ajusté par scene.js (`--echelle`) : chaque nom tient entre les
   deux repères. Le texte ne passe jamais sous un repère : le retrait le leur réserve. */
.rouleau {
  --h: clamp(3.2rem, min(13vh, 17vw), 7.5rem);
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(100%, 60rem); height: calc(var(--h) * 3); overflow: hidden;
  border: 2px solid var(--filet-scene); border-radius: 14px;
  background: linear-gradient(#0C0E13, #171A21 50%, #0C0E13);
}
.rouleau::before {                    /* les cases du haut et du bas s'enfoncent dans le noir */
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(var(--encre), transparent 32%, transparent 68%, var(--encre));
}
.rouleau::after {                     /* la case qui compte */
  content: ""; position: absolute; left: 0; right: 0; top: var(--h); height: var(--h); z-index: 2;
  border-block: 2px solid var(--or); background: rgba(255, 201, 77, .05); pointer-events: none;
}
.rouleau-bande { will-change: transform; }
.rouleau-nom {
  display: flex; align-items: baseline; justify-content: center; gap: .45em; height: var(--h);
  padding: 0 calc(var(--h) * .5); font-size: calc(var(--h) * .46 * var(--echelle, 1));
  font-weight: 700; line-height: var(--h); white-space: nowrap; overflow: hidden;
}
/* Filet de sécurité, si une mesure se trompait : des points de suspension, pas une coupe. */
.rouleau-nom span, .lecteur span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.rouleau-nom small { flex-shrink: 0; font-size: .42em; font-weight: 400; color: var(--craie-pale); font-variant-numeric: tabular-nums; }
/* Un nom très long passe sur deux lignes plutôt que de rapetisser jusqu'à l'illisible. */
.rouleau-nom.deux-lignes, .lecteur.deux-lignes { align-items: center; white-space: normal; line-height: 1.08; }
/* Sans coupe propre au nom : à cet interligne, les accents de Latin Modern dépassent la
   ligne, et c'est la case, plus haute que les deux lignes, qui les contient. */
.rouleau-nom.deux-lignes span, .lecteur.deux-lignes span { text-align: center; overflow: visible; }
.rouleau-nom.elu { color: var(--or); text-shadow: 0 0 .6em rgba(255, 201, 77, .6); }
.rouleau-repere {
  position: absolute; top: 50%; z-index: 3; transform: translateY(-50%);
  color: var(--or); font-size: calc(var(--h) * .3); line-height: 1;
}
.rouleau-repere.gauche { left: .6rem; }
.rouleau-repere.droite { right: .6rem; }
.rouleau.arretee { border-color: var(--or); }

/* ── Roue et fléchette : un disque de parts, à la taille des chances ──
   Positions et tailles posées par scene.js, en px du plateau. */
.roue, .cible { position: absolute; inset: 0; }
.roue-socle, .cible-disque { position: absolute; }
/* Le disque tourne dans son socle : c'est le socle qui tremble à l'impact. */
.roue-disque { position: absolute; inset: 0; will-change: transform; }
.roue-disque > svg, .cible-disque > svg { display: block; width: 100%; height: 100%; overflow: visible; }
.parts text { font-weight: 700; fill: var(--craie); }
.parts .part { transition: opacity .5s; }
.parts.arretee .part:not(.elue) { opacity: .35; }
.part .fond { transition: fill .3s; }
.part.elue .fond { fill: var(--or); }
.part.touchee .fond { fill: var(--lampe); }
.part.elue text, .part.touchee text { fill: var(--encre); }

.roue-jante { fill: #1A1C22; stroke: var(--filet-scene); stroke-width: 4; }
.roue .fond { stroke: #0D0F13; stroke-width: 2; }
.roue-taquets circle { fill: #D8D2C4; }
.roue-moyeu { fill: #14161B; stroke: var(--or); stroke-width: 6; }
.roue-axe { fill: var(--or); }
/* La languette pivote sur sa vis : scene.js la couche quand un taquet la pousse. */
.roue-languette { position: absolute; overflow: visible; z-index: 2; }
.roue-languette path { fill: var(--or); stroke: #7A5A12; stroke-width: 3; stroke-linejoin: round; }
.roue-languette circle { fill: #3A2A08; }

/* La cible : parts noires et crème, l'anneau des doubles rouge sur les noires, vert sur
   les crème, comme une vraie. */
.cible-bord { fill: #111216; stroke: var(--filet-scene); stroke-width: 4; }
.cible .fond { fill: #1C1D21; }
.cible .claire .fond { fill: #E9DFC7; }
.cible .anneau { fill: #B3302B; }
.cible .claire .anneau { fill: #2E7D4F; }
.cible text { fill: #E9DFC7; }
.cible .claire text { fill: #1C1D21; }
.cible .part.elue .fond { fill: var(--or); }
.cible .part.touchee .fond { fill: var(--lampe); }
.cible .part.elue text, .cible .part.touchee text { fill: var(--encre); }
.cible-bull-ext { fill: #2E7D4F; }
.cible-bull { fill: #B3302B; }
.cible-fils path, .cible-fils circle { fill: none; stroke: #C9CCD1; stroke-width: 1.6; opacity: .75; }
.viseur { position: absolute; left: 0; top: 0; z-index: 2; pointer-events: none; overflow: visible; transition: opacity .25s; }
.viseur circle, .viseur path { fill: rgba(229, 72, 77, .08); stroke: var(--alerte); stroke-width: 4; }
.viseur path { fill: none; }
.viseur .viseur-point { fill: var(--alerte); stroke: none; }
.viseur.lache { opacity: 0; }
.flechette { position: absolute; left: 0; top: 0; z-index: 3; pointer-events: none;
             filter: drop-shadow(.25rem .4rem .2rem rgba(0, 0, 0, .65)); }
.flechette svg { display: block; width: 100%; height: 100%; overflow: visible; }
.ailette { fill: var(--alerte); stroke: var(--craie); stroke-width: 2; stroke-linejoin: round; }
.fut { fill: #2B2D33; stroke: #9AA0A8; stroke-width: 2; }
.flechette.plantee svg { animation: vibre .55s ease-out; }
/* Plantée dans la roue, elle tourne avec elle : une ombre sans direction. */
.roue-disque .flechette { filter: drop-shadow(0 0 .2rem rgba(0, 0, 0, .75)); }
@keyframes vibre {
  20% { transform: translate(2px, -2px); } 40% { transform: translate(-2px, 1px); }
  60% { transform: translate(1px, -1px); } 80% { transform: translate(-1px, 0); }
}

/* Le lecteur : le nom désigné, en grand, entre deux filets d'or — la case du rouleau. */
.lecteur {
  position: absolute; box-sizing: border-box; display: flex; align-items: baseline;
  justify-content: center; gap: .45em; font-weight: 700; white-space: nowrap; overflow: hidden;
  line-height: var(--hl); border-block: 2px solid var(--or); background: rgba(255, 201, 77, .05);
}
.lecteur small { flex-shrink: 0; font-size: .42em; font-weight: 400; color: var(--craie-pale); font-variant-numeric: tabular-nums; }
.lecteur.elu span { color: var(--or); text-shadow: 0 0 .6em rgba(255, 201, 77, .6); }

/* ── Grappin : une machine à pinces de fête foraine, illuminée dans la salle éteinte ──
   Positions et tailles posées par scene.js, en px du plateau. Superposition : fond 1,
   billes 2, capsules 10 et plus (le rang de devant au-dessus), capsule tenue 30, la cage
   de la pince 33, vitre 35, capsule de l'élu 40. */
.grappin { position: absolute; inset: 0; }
.vitrine {
  position: absolute; top: 0; border-radius: 18px;
  background: linear-gradient(#2E4258, #1B2836); box-shadow: 0 0 3rem rgba(120, 170, 220, .25);
}
.ampoule {
  position: absolute; width: calc(var(--bord) * .5); height: calc(var(--bord) * .5);
  transform: translate(-50%, -50%); border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #FFF6D0, #FFC94D 55%, #C98A16);
  box-shadow: 0 0 .6em rgba(255, 201, 77, .8);
  animation: clignote 1.2s steps(1) infinite; animation-delay: calc(var(--i) * -.4s);
}
@keyframes clignote { 0% { opacity: 1; } 33% { opacity: .3; } }
.grappin.gagne .ampoule { animation-duration: .36s; }
.vitrine-fond {
  position: absolute; z-index: 1; border-radius: 10px;
  /* La vitrine, de nuit (revue UI du 2026-10-07 : en salle éteinte, le fond clair éblouissait). */
  background: radial-gradient(ellipse at 50% 12%, #4A6F96 0%, #22384F 48%, #101C29 100%);
}
.bille {
  position: absolute; z-index: 2; border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, #CFE3F5 0%, #4F8FC9 45%, #2C5F8F 100%);
}
.bille.blanche { background: radial-gradient(circle at 32% 28%, #FFFFFF 0%, #E3ECF4 50%, #AFC3D6 100%); }

/* La capsule : une sphère de verre, un médaillon (les initiales, à la place d'un
   portrait), un bandeau de papier avec le nom — dans la police de la scène, en encre. */
.capsule {
  position: absolute; border-radius: 50%; will-change: transform;
  background: radial-gradient(circle at 34% 26%, rgba(255, 255, 255, .95) 0%, rgba(255, 255, 255, .55) 22%,
              rgba(220, 234, 246, .55) 60%, rgba(150, 180, 210, .75) 100%);
  box-shadow: inset 0 -.4em 1em rgba(40, 70, 100, .25), 0 .3em .8em rgba(10, 25, 40, .35);
  transition: opacity .5s;
}
.capsule-medaillon {
  position: absolute; left: 50%; top: 20%; width: 24%; height: 24%; transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center; border-radius: 50%;
  background: var(--teinte); color: #1C2733; font-weight: 700; letter-spacing: .02em;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .7);
}
.capsule-bandeau {
  position: absolute; left: 50%; top: 35%; width: 94%; height: 48%;
  transform: translateX(-50%) rotate(var(--penche));
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 0 3%; border-radius: .35em .35em 45% 45% / .35em .35em 30% 30%;
  background: linear-gradient(#FFFDF6, #EDE6D6); color: #1C2733;
  box-shadow: 0 .08em .25em rgba(30, 40, 50, .35);
  text-align: center; line-height: 1.1; overflow-wrap: break-word;
}
.capsule-nom { font-weight: 700; }
.capsule-bandeau small { margin-top: .15em; font-size: .62em; color: #55606B; font-variant-numeric: tabular-nums; }
/* Survolée par la pince : un tiers plus grosse, devant ses voisines (`!important` : le
   rang de la capsule est posé en ligne). */
.capsule { transition: opacity .5s, scale .25s ease-out; }
.capsule.visee { scale: 1.33; z-index: 29 !important; box-shadow: 0 0 0 .12em #FFFFFF, 0 .4em 1.2em rgba(10, 25, 40, .5); }
.grappin.gagne .capsule:not(.elue), .grappin.gagne .bille { opacity: .35; }
.bille { transition: opacity .5s; }
.capsule.elue {
  box-shadow: 0 0 0 .18em var(--or), 0 0 2.5em rgba(255, 201, 77, .7), inset 0 -.4em 1em rgba(40, 70, 100, .25);
}
.capsule.elue .capsule-bandeau { transform: translateX(-50%); }

/* La pince : un rail, un chariot, un câble, et la pince qui balance au bout. */
.grappin-cage { position: absolute; z-index: 33; overflow: hidden; border-radius: 10px; pointer-events: none; }
.grappin-rail { position: absolute; left: 0; right: 0; height: 8px; border-radius: 4px;
                background: linear-gradient(#9AA6B2, #4E5B68); }
.grappin-chariot { position: absolute; left: 0; height: 18px; border-radius: 5px;
                   background: linear-gradient(#5C6B7A, #2E3A46); border: 1px solid #8C99A6; }
.grappin-bras { position: absolute; left: 0; width: 0; height: 0; transform-origin: 0 0; }
.grappin-cable { position: absolute; left: -2.5px; top: 0; width: 5px; background: linear-gradient(90deg, #2A2F35, #59626B, #2A2F35); }
.grappin-pince { position: absolute; overflow: visible; filter: drop-shadow(0 .3rem .4rem rgba(0, 0, 0, .45)); }
.machoire path { fill: none; stroke: #C9CED6; stroke-width: 9; stroke-linecap: round; stroke-linejoin: round; }
.machoire path.bout { stroke: #2F86D6; stroke-width: 11; }
.moyeu { fill: #E9EDF1; stroke: #9AA6B2; stroke-width: 2; }
.moyeu-pastille { fill: #2F86D6; }
.moyeu-etoile { fill: #FFFFFF; }

/* ── Trappes : un plancher en perspective, un bonhomme par élève (scene.js pose tout en
   px du plateau) ── */
.trappes { position: absolute; inset: 0; }
.plancher { position: absolute; left: 0; top: 0; overflow: visible; }
.plancher .trou { fill: #1B2026; }
.plancher .paroi { fill: #4E565F; }
.plancher .trappe { fill: hsl(210 6% 91%); }
.plancher .joint { fill: none; stroke: #9AA3AC; stroke-width: 1.4; stroke-linejoin: round; }
.plancher .tranche { fill: #7E8790; stroke: #9AA3AC; stroke-width: 1.4; }
/* `!important` : scene.js pose la teinte de chaque trappe en ligne, selon son angle. */
.plancher .case.restant .trappe { fill: #F3E2AE !important; }
.plancher .case.elue .trappe { fill: var(--or) !important; }
.gens-fenetre { position: absolute; overflow: hidden; pointer-events: none; }
.gens-fenetre.tombe { visibility: hidden; }
.gens-corps { position: absolute; will-change: transform; }
.bonhomme { display: block; width: 100%; height: 100%; overflow: visible; }
.bonhomme .halo * { fill: none; stroke: var(--craie); stroke-width: 7.5; stroke-linecap: round; stroke-linejoin: round; }
.bonhomme .halo .tete { fill: var(--craie); }
.bonhomme .encre * { fill: none; stroke: #1A1D22; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
.bonhomme .encre .tete { fill: #FFFFFF; }
.bonhomme .encre .fin { stroke-width: 1.8; }
.bonhomme .encre .oeil { fill: #1A1D22; stroke: none; }
.bonhomme .encre .bouche-sourire { stroke-width: 2; }
.bonhomme .encre .bouche-o { fill: #1A1D22; stroke: none; }
.bonhomme .bras-haut, .bonhomme .bouche-o, .bonhomme .signe-chute { display: none; }
.bonhomme.panique .bras-repos, .bonhomme.joie .bras-repos, .bonhomme.panique .bouche-sourire { display: none; }
.bonhomme.panique .bras-haut, .bonhomme.joie .bras-haut, .bonhomme.panique .bouche-o,
.bonhomme.panique .signe-chute { display: inline; }
.signe-chute .fleche { fill: none; stroke: var(--alerte); stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }
.signe-chute .vitesse { fill: none; stroke: #6FA8DC; stroke-width: 2.4; stroke-linecap: round; }
.bonhomme.tremble { animation: tremble .09s linear infinite; }
.bonhomme.joie { filter: drop-shadow(0 0 .5rem rgba(255, 201, 77, .9)); }
/* La plaque du nom, aux pieds : une étiquette de papier, qui s'éteint quand il tombe. */
.plaque {
  position: absolute; display: flex; flex-direction: column; align-items: center;
  padding: .12em .3em; border-radius: .3em; text-align: center; line-height: 1.08;
  background: rgba(255, 253, 246, .93); color: #1A1D22; font-weight: 700; overflow-wrap: break-word;
  box-shadow: 0 .1em .3em rgba(0, 0, 0, .35); transition: opacity .35s, background-color .3s;
}
.plaque small { font-size: .62em; font-weight: 400; color: #55606B; font-variant-numeric: tabular-nums; }
.plaque.eteinte { opacity: 0; }
.plaque.restant { background: #F6E3A6; }
.plaque.elue { background: var(--or); box-shadow: 0 0 1.2em rgba(255, 201, 77, .7); }

/* ── Poursuite : le tableau noir court après la classe (scene.js pose tout en px) ── */
.poursuite { position: absolute; inset: 0; }
.sol { position: absolute; left: 0; right: 0; height: 3px; background: var(--craie-pale); }
.sol::after {                         /* les traits qui filent : la course */
  content: ""; position: absolute; left: 0; right: 0; top: 10px; height: 3px; opacity: .45;
  background: repeating-linear-gradient(90deg, var(--craie-pale) 0 26px, transparent 26px 70px);
}
.sol.defile::after { animation: defile .35s linear infinite; }
@keyframes defile { to { background-position: -70px 0; } }
/* Le bonhomme en haut de sa case, le nom juste sous ses pieds : les pieds sont à la même
   hauteur pour tous, que le nom tienne sur une ligne ou sur deux. */
.fuyard { position: absolute; transform-origin: 50% 100%; will-change: transform; }
.fuyard.parti { visibility: hidden; }
.fuyard-corps { position: absolute; left: 50%; top: 0; transform: translateX(-50%); }
.fuyard .plaque { left: 50%; top: var(--sous-pieds); transform: translateX(-50%); max-width: 100%; }
.coureur { display: block; width: 100%; height: 100%; overflow: visible; }
.coureur .halo * { fill: var(--craie); stroke: var(--craie); stroke-width: 7.5; stroke-linecap: round; stroke-linejoin: round; }
.coureur .halo .membres { fill: none; }
.coureur .encre * { fill: none; stroke: #1A1D22; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
.coureur .encre .tete { fill: #FFFFFF; }
.coureur .encre .maillot { fill: var(--maillot); stroke-width: 2.6; }
.coureur .visage circle { fill: #1A1D22; }
.coureur .visage .sourire { fill: none; stroke: #1A1D22; stroke-width: 2; stroke-linecap: round; }
.coureur .sueur path { fill: #6FA8DC; }
.coureur .etoiles path { fill: var(--or); }
.coureur .pose, .coureur .cri, .coureur .sueur, .coureur .etoiles { display: none; }
.coureur .pose-repos { display: inline; }
.coureur.panique .pose-repos, .coureur.trebuche .pose-repos { display: none; }
.coureur.panique .pose-haut, .coureur.trebuche .pose-haut { display: inline; }
.coureur.court .pose-repos, .coureur.court .pose-haut { display: none; }
.coureur.court .pose-a, .coureur.court .pose-b { display: inline; animation: foulee .26s steps(1) infinite; }
.coureur.court .pose-b { animation-delay: -.13s; }
@keyframes foulee { 0% { opacity: 1; } 50% { opacity: 0; } }
.coureur.panique .cri, .coureur.court .cri, .coureur.trebuche .cri { display: inline; }
.coureur.panique .sourire, .coureur.court .sourire, .coureur.trebuche .sourire { display: none; }
.coureur.panique .sueur, .coureur.court .sueur, .coureur.trebuche .sueur { display: inline; }
.coureur.panique { animation: tremble .09s linear infinite; }
.coureur.trebuche { transform: rotate(78deg); transform-origin: 50% 96%; transition: transform .25s ease-in; }
/* Écrasé : le bonhomme à plat (les étoiles, elles, gardent leur forme et descendent). */
.coureur.ecrase g.pose, .coureur.ecrase .visage { transform: scale(1.35, .22); transform-origin: 50% 96.5%; }
.coureur.ecrase .etoiles { display: inline; transform: translateY(72px); }
.coureur.ecrase .cri, .coureur.ecrase .sueur { display: none; }
.coureur.ecrase .sourire { display: inline; }

/* Le tableau : l'ardoise sur ses jambes. --bascule : 0 debout → 90° à plat, sur le coin
   bas-droit ; --rentre : les jambes rentrent et l'ardoise descend au sol. */
.tableau-noir { position: absolute; left: 0; z-index: 60; --bascule: 0deg; --rentre: 0; will-change: transform; }
.tn-corps {
  position: absolute; left: 0; top: 0; width: 100%; height: var(--corps); transform-origin: 100% 100%;
  transform: translateY(calc(var(--rentre) * var(--jambes, 0px))) rotate(var(--bascule));
}
.tn-corps > svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 .4rem .6rem rgba(0, 0, 0, .5)); }
.tn-cadre { fill: #8B5A2B; stroke: #5E3B1A; stroke-width: 2; }
.tn-ardoise { fill: #2F5141; }
.tn-auget { fill: #A0693A; }
.tn-craie { fill: #F4F1E8; }
.tn-trait * { fill: none; stroke: #F4F1E8; stroke-width: 2.6; stroke-linecap: round; opacity: .92; }
.tn-trait .pupille { fill: #F4F1E8; stroke: none; }
.tn-formule { fill: #F4F1E8; opacity: .55; font-size: 9px; font-style: italic; }
.tn-trait, .tn-formule { transition: opacity .4s; }
/* Le nom de l'élu, écrit à la craie à la fin de la poursuite. */
.tn-nom text { fill: #F4F1E8; font-style: italic; font-weight: 700; text-anchor: middle; }
.tn-alerte {
  position: absolute; right: -.2em; top: -1.1em; font: 700 clamp(1.6rem, 5vh, 3.4rem) / 1 var(--texte-police);
  color: var(--alerte); opacity: 0; transform: rotate(12deg); transition: opacity .2s;
}
.tableau-noir.furieux .tn-alerte { opacity: 1; }
.tn-jambes { position: absolute; left: 0; top: var(--corps); width: 100%; height: calc(100% - var(--corps));
             overflow: visible; opacity: calc(1 - var(--rentre)); }
.tn-jambes path { fill: none; stroke: #5E3B1A; stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
.tn-jambes .foulee-b { display: none; }
.tableau-noir.court .tn-jambes .foulee-a, .tableau-noir.court .tn-jambes .foulee-b { display: inline; animation: foulee .26s steps(1) infinite; }
.tableau-noir.court .tn-jambes .foulee-b { animation-delay: -.13s; }
.tableau-noir.court .tn-corps > svg { animation: sautille .26s ease-in-out infinite; }
@keyframes sautille { 50% { translate: 0 -4px; } }
.poussiere {
  position: absolute; z-index: 61; pointer-events: none; border-radius: 50%; opacity: 0;
  background: radial-gradient(ellipse, rgba(236, 231, 220, .9), rgba(236, 231, 220, 0) 70%);
}
.poussiere.souffle { animation: souffle-craie .9s ease-out; }
@keyframes souffle-craie { 0% { opacity: .95; transform: scale(.6); } 100% { opacity: 0; transform: scale(2.2, 1.6); } }

/* ── Galton : une planche de bois éclairée, des clous, des cases à la largeur des
   chances (scene.js pose tout en px du plateau) ── */
.galton { position: absolute; inset: 0; }
.galton-planche { position: absolute; left: 0; top: 0; overflow: visible; }
/* Bois foncé et clous de laiton (revue UI du 2026-10-07 : le bois clair éblouissait). */
.galton-planche .cadre { fill: #4A2E1A; stroke: #2B1A0E; stroke-width: 2; filter: drop-shadow(0 0 2rem rgba(255, 200, 120, .12)); }
.galton-planche .fond { fill: #1F1A16; }
.galton-planche .rail { fill: #8E6A2A; }
.galton-planche .entonnoir { fill: #B8862F; opacity: .9; }
.galton-planche .clou { fill: #D4AE5C; stroke: #7A5A1E; stroke-width: 1.2; }
.galton-planche .bac { fill: #2E2016; }
.galton-planche .cloison, .galton-planche .bord-cases { fill: #9C7A3C; stroke: #6B4E1E; stroke-width: 1; }
.galton-planche .case-elue { fill: rgba(255, 201, 77, .55); }
/* Le nom, au dos de la case : à la verticale, lu de bas en haut. */
.galton-nom { position: absolute; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.galton-nom span {
  writing-mode: vertical-rl; transform: rotate(180deg); display: flex; align-items: center; gap: .3em;
  color: #EDE3CF; line-height: 1.05; text-align: center; max-height: 100%;
}
.galton-nom b { font-weight: 700; }
.galton-nom small { font-size: .62em; color: #B9AE98; font-variant-numeric: tabular-nums; }
.galton.arretee .galton-nom:not(.elue) { opacity: .4; }
/* Sur la case dorée de l'élu, l'encre sombre. */
.galton-nom.elue span, .galton-nom.elue small { color: #1A1D22; }
.galton-billes .bille-grise {
  position: absolute; left: 0; top: 0; border-radius: 50%; opacity: 0; will-change: transform;
  background: radial-gradient(circle at 35% 30%, #FFFFFF, #AEB6BF 55%, #6E7882);
}
.galton-billes.passe .bille-grise { opacity: .45 !important; transition: opacity .5s; }
.bille-or {
  position: absolute; left: 0; top: 0; z-index: 5; border-radius: 50%; will-change: transform;
  background: radial-gradient(circle at 35% 30%, #FFF6D0, #FFC94D 50%, #B9821A);
  box-shadow: 0 0 1.2em rgba(255, 201, 77, .8);
}
.galton-elu {
  position: absolute; z-index: 6; margin: 0; padding: .15em .6em; border-radius: .4em; white-space: nowrap;
  font-weight: 700; color: #1A1D22; background: var(--or); box-shadow: 0 0 1.5em rgba(255, 201, 77, .7);
}
/* Pendant la descente : l'étiquette suit la bille, en craie ; la case sous elle s'éclaire. */
.galton-elu.suit { color: #1A1D22; background: var(--craie); box-shadow: 0 .2em .8em rgba(0, 0, 0, .45); }
.galton-planche .case-visee { fill: rgba(255, 255, 255, .16); }

/* ── Arbre de probabilités : tout est dessiné dans un canevas (scene.js) ── */
.arbre { position: absolute; inset: 0; }
/* Les bords s'estompent : la caméra coupe l'arbre, et un nom coupé net se lirait mal. */
.arbre canvas {
  position: absolute; left: 0; top: 0;
  --fondu: linear-gradient(90deg, transparent, #000 3.5%, #000 96.5%, transparent),
           linear-gradient(transparent, #000 7%);
  -webkit-mask-image: var(--fondu); -webkit-mask-composite: source-in;
  mask-image: var(--fondu); mask-composite: intersect;
}

/* ── Pluie de Monte-Carlo : des territoires de craie de couleur (scene.js pose tout en
   px du plateau), la pluie dans un canevas par-dessus ── */
.monte-carlo { position: absolute; inset: 0; }
.mc-case {
  position: absolute; z-index: 1; overflow: hidden; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; line-height: 1.1; color: var(--craie);
  font-family: "Tableau Serif", "Latin Modern Roman", Georgia, serif;
  background: var(--teinte); border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .1), inset 0 0 2em rgba(0, 0, 0, .35);
  transition: background .6s, filter .6s, box-shadow .6s;
}
.mc-case b { font-weight: 700; }
.mc-compte { font-weight: 700; font-size: 1.05em; font-variant-numeric: tabular-nums; color: #F6EED8; }
.mc-chance { display: none; font-size: .6em; color: rgba(236, 231, 220, .75); font-variant-numeric: tabular-nums; }
.monte-carlo.frequences .mc-chance { display: block; }
.mc-case.muette .mc-compte { visibility: hidden; }
.monte-carlo.eteinte .mc-case:not(.elue) { filter: brightness(.5) saturate(.7); }
.mc-case.elue {
  z-index: 2; color: #1A1D22; background: var(--or); filter: none;
  box-shadow: 0 0 2.4em rgba(255, 201, 77, .8);
}
.mc-case.elue .mc-compte, .mc-case.elue .mc-chance { color: #1A1D22; }
.mc-pluie { position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none; }
.mc-total {
  position: absolute; left: 0; right: 0; margin: 0; display: flex; align-items: center;
  justify-content: center; gap: .25em; color: var(--craie-pale);
  font-family: "Tableau Serif", "Latin Modern Roman", Georgia, serif; font-variant-numeric: tabular-nums;
}
.mc-total span { color: var(--craie); font-weight: 700; }

/* La vitre, devant tout le reste : deux reflets obliques. */
.vitre {
  position: absolute; z-index: 35; border-radius: 10px; pointer-events: none;
  background: linear-gradient(115deg, rgba(255, 255, 255, .16) 0 9%, transparent 9% 58%,
              rgba(255, 255, 255, .09) 58% 62%, transparent 62%);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .25);
}

/* ── L'écran d'attente : le cœur qui bat, à laisser au vidéoprojecteur ── */
.scene-attente {
  position: absolute; inset: 0; z-index: 20; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: min(2.4vh, 1.4rem);
  padding: 2rem 0 4.5rem; text-align: center; overflow: hidden;
  background: radial-gradient(ellipse at 50% 58%, #240707 0%, #0E0405 38%, var(--encre) 70%);
}
.scene-attente[hidden] { display: none; }
.attente-titre {
  display: flex; flex-direction: column; font-weight: 400; line-height: 1.12; text-transform: uppercase;
  font-size: clamp(1.8rem, min(6.4vw, 9vh), 5.6rem); letter-spacing: .24em; color: var(--craie);
  padding-left: .24em;                 /* l'espacement des lettres décentre sinon le titre */
}
.attente-titre span { color: #E8574D; text-shadow: 0 0 .45em rgba(229, 72, 77, .55); }
.attente-sous-titre {
  font-family: var(--texte-police); text-transform: uppercase; letter-spacing: .32em;
  font-size: clamp(.8rem, min(1.4vw, 2.2vh), 1.15rem); color: var(--craie-pale);
}
.attente-classe:not(:empty) { color: var(--craie); }
.attente-scene { position: relative; width: 100%; height: min(42vh, 36vw); flex: none; }
.attente-ecg { position: absolute; left: 0; top: 50%; width: 100%; height: 34%; transform: translateY(-50%); overflow: visible; }
.ecg-fond { fill: none; stroke: rgba(229, 72, 77, .32); stroke-width: 2; vector-effect: non-scaling-stroke; }
.ecg-trace {
  fill: none; stroke: #FF5B50; stroke-width: 3; stroke-linejoin: round; vector-effect: non-scaling-stroke;
  stroke-dasharray: 70 1000; animation: ecg 5s linear infinite;
  filter: drop-shadow(0 0 6px rgba(255, 59, 48, .9));
}
@keyframes ecg { from { stroke-dashoffset: 1000; } to { stroke-dashoffset: -70; } }
.attente-coeur {
  position: absolute; left: 50%; top: 50%; height: 100%; transform: translate(-50%, -50%); overflow: visible;
  filter: drop-shadow(0 0 1.6rem rgba(235, 40, 40, .55));
}
.attente-coeur.bat { animation: pouls .6s ease-out; }
/* Toum-toum : deux coups, le second plus faible — comme le son. */
@keyframes pouls { 0% { scale: 1; } 10% { scale: 1.08; } 24% { scale: .99; } 36% { scale: 1.05; } 100% { scale: 1; } }
/* Le cœur redessiné : des chairs sombres aux contours qui brillent, des tubes (les
   vaisseaux) bordés de lumière, et des coronaires dorées. */
.attente-coeur .chair { fill: url(#attente-chair); stroke: #FF6A4A; stroke-width: 2.6; stroke-linejoin: round; }
.attente-coeur .tube use { fill: none; stroke-linecap: butt; }
.attente-coeur .tube .bord { stroke: #FF5A3C; stroke-width: 20; }
.attente-coeur .tube .dedans { stroke: #7E0A0A; stroke-width: 15; }
.attente-coeur .tube .bord.large { stroke-width: 28; }
.attente-coeur .tube .dedans.large { stroke-width: 23; }
.attente-coeur .tube .bord.fin { stroke-width: 13; }
.attente-coeur .tube .dedans.fin { stroke-width: 9; }
.attente-coeur .bouche ellipse { fill: #3A0202; stroke: #FF7A5A; stroke-width: 2; }
.attente-coeur .coronaires { fill: none; stroke: #FFB37A; stroke-width: 1.8; stroke-linecap: round; opacity: .85; }
/* Les paramètres, en haut à droite : discrets, comme le coin du bas. */
.attente-menu {
  position: absolute; top: max(.8rem, env(safe-area-inset-top, 0px)); right: 1rem; z-index: 3;
  width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--craie-pale); border-radius: 10px;
}
.attente-menu svg { width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.attente-menu:hover, .attente-menu:focus-visible { color: var(--craie); background: rgba(236, 231, 220, .1); outline: none; }
.attente-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem; }
.attente-tuile {
  display: inline-flex; align-items: center; gap: .6em; min-height: 50px; padding: .65em 2.4em;
  font: 700 clamp(1.1rem, min(2vw, 3vh), 1.6rem) / 1 var(--texte-police);
}
/* LA famille de boutons de tout ce qui est projeté — l'écran d'attente, la barre de fin,
   le refus : la tuile, fond sombre, liseré rouge, halo. Le rouge est la couleur du
   suspense ; l'or est réservé à l'élu (Maxime, 2026-10-07, revue UI). */
.attente-tuile, .scene-bouton {
  cursor: pointer; color: var(--craie); background: rgba(45, 8, 8, .7);
  border: 1.5px solid var(--alerte); border-radius: 1rem;
  box-shadow: 0 0 1.4em rgba(229, 72, 77, .3), inset 0 0 .8em rgba(229, 72, 77, .12);
}
.attente-tuile[hidden] { display: none; }
.attente-tuile span { color: #FF5B50; font-size: 1.2em; }
.attente-tuile:hover, .attente-tuile:focus-visible, .scene-bouton:hover, .scene-bouton:focus-visible {
  box-shadow: 0 0 2.2em rgba(229, 72, 77, .6); outline: none;
}
.attente-message { font-family: var(--texte-police); color: #FF9A8F; font-size: 1.05rem; }
.attente-message.succes { color: var(--or); font-size: clamp(1.05rem, min(1.8vw, 2.8vh), 1.5rem); }
/* La feuille du volontaire, par-dessus l'écran d'attente. */
.attente-feuille {
  position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; align-items: center;
  gap: min(2vh, 1.1rem); padding: 2.2rem 1rem 4.8rem; background: var(--encre);
}
.attente-feuille[hidden] { display: none; }
.attente-feuille-titre {
  margin: 0; color: var(--craie); font: italic clamp(1.6rem, min(4vw, 6vh), 3rem) / 1.15
  "Tableau Serif", "Latin Modern Roman", Georgia, serif;
}
.attente-noms {
  flex: 1 1 auto; min-height: 0; width: min(100%, 72rem); overflow-y: auto; padding: .2rem;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  gap: .6rem; align-content: start;
}
.attente-nom {
  min-height: 52px; padding: .5em .9em; cursor: pointer; text-align: left;
  display: flex; flex-direction: column; justify-content: center; gap: .15em;
  font: 700 clamp(1.05rem, min(1.7vw, 2.6vh), 1.5rem) / 1.15 "Tableau Serif", "Latin Modern Roman", Georgia, serif;
  color: var(--craie); background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(236, 231, 220, .22); border-radius: .7rem;
}
.attente-nom small { font: 400 .62em / 1.2 var(--texte-police); color: var(--craie-pale); }
.attente-nom:hover, .attente-nom:focus-visible { border-color: var(--or); background: rgba(255, 201, 77, .12); outline: none; }
.attente-vide { color: var(--craie-pale); font-family: var(--texte-police); }
/* L'appel : un absent est rayé, éteint, liseré de rouge. */
.attente-appel-compte { margin: 0; color: var(--craie-pale); font: 400 clamp(15px, min(1.4vw, 2.2vh), 1.2rem) var(--texte-police); }
.noms-appel .attente-nom[aria-pressed="true"] {
  color: var(--craie-pale); text-decoration: line-through; text-decoration-color: var(--alerte);
  border-color: var(--alerte); background: rgba(45, 8, 8, .45);
}
.noms-appel .attente-nom[aria-pressed="true"] small { text-decoration: none; color: #FF9A8F; }
/* Dans le coin : « Quitter » n'existe que sur l'écran d'attente, « Passer » que pendant un tirage. */
.scene-coin { z-index: 25; }
.scene [data-action="quitter"], .scene [data-action="plein-ecran"] { display: none; }
.scene.en-attente [data-action="quitter"], .scene.en-attente:not(.plein-ecran) [data-action="plein-ecran"] { display: inline-block; }
.scene.en-attente [data-action="passer"] { display: none; }

/* ── Le verdict : un énoncé ── */
.scene-verdict {
  position: absolute; inset: 0; z-index: 10;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 2rem 1rem; text-align: center; overflow-y: auto;
  background: radial-gradient(ellipse at center, rgba(7, 8, 11, .78), rgba(7, 8, 11, .95) 72%);
  animation: apparition .55s ease-out;
}
.scene-verdict[hidden] { display: none; }
.scene-verdict::before {              /* l'éclair du gong */
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: var(--or); opacity: 0; animation: eclair .8s ease-out;
}
@keyframes apparition { from { opacity: 0; transform: scale(1.05); } }
@keyframes eclair { from { opacity: .55; } to { opacity: 0; } }

.verdict-surtitre { font-weight: 700; font-size: clamp(1.1rem, min(2.6vw, 4vh), 2rem); }
/* « Volontaire désigné », juste au-dessus du nom. */
.verdict-designe { margin-top: .3em; font-size: clamp(1rem, min(2.8vw, 4.2vh), 2.2rem); letter-spacing: .22em;
                   text-transform: uppercase; color: var(--craie); }
.verdict-surtitre::after { content: "."; }
.verdict-nom {
  margin: .12em 0 .08em; font-weight: 700; line-height: 1; overflow-wrap: anywhere;
  font-size: clamp(2.6rem, min(11vw, 15vh), 9rem); color: var(--or); text-shadow: 0 0 .5em rgba(255, 201, 77, .3);
}
.verdict-enonce { font-style: italic; font-size: clamp(1.3rem, min(3.4vw, 5vh), 2.6rem); }
.verdict-objet { margin-top: .3rem; font-style: italic; font-size: clamp(1.1rem, min(2.4vw, 3.6vh), 1.8rem); color: var(--craie-pale); }
/* « Pour quoi ? », à écrire au moment où l'élève est désigné. */
.verdict-champ {
  margin-top: .5rem; width: min(34rem, 90%); min-height: 48px; padding: .4rem 1.2rem; text-align: center;
  font: italic max(16px, min(2.2vw, 3.4vh)) / 1.3 "Tableau Serif", "Latin Modern Roman", Georgia, serif;
  color: var(--craie); background: #16181D;
  border: 1px solid var(--craie-pale); border-radius: 999px;
}
.verdict-champ::placeholder { color: var(--craie-pale); }
.verdict-champ:focus { outline: 2px solid var(--craie); outline-offset: 2px; }
.verdict-chiffres {
  margin-top: 1rem; font-family: var(--texte-police); font-variant-numeric: tabular-nums;
  font-size: clamp(15px, 1.6vw, 1.2rem); color: var(--craie-pale);
}
.verdict-preuve { margin-top: min(1.1rem, 1.6vh); font-size: clamp(1.1rem, min(2.2vw, 3.4vh), 1.6rem); }
.verdict-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .8rem; margin-top: min(2rem, 3vh); }
.scene-bouton { min-height: 50px; padding: .6rem 1.4rem; font-family: var(--texte-police); font-size: 1.05rem; font-weight: 700; }
/* L'action principale : la même tuile, pleine. */
.scene-bouton.fort { color: #FFF4F0; background: rgba(150, 22, 28, .92); border-color: #FF6B60; }
.verdict-note { width: 100%; font-family: var(--texte-police); font-size: 15px; color: var(--craie-pale); }

/* ── L'ANNONCE (pilote du 2026-10-07 : machine à sous, poursuite, arbre) : chaque scène
   annonce l'élu dans son propre monde ; le verdict se réduit à la BARRE des commandes,
   toujours au même endroit — en haut, à la place du titre et des phrases, qui s'effacent.
   Elle ne cache rien de la scène. ── */
.scene.annonce .scene-tete, .scene.annonce .scene-legende { opacity: 0; transition: opacity .4s; }
.scene-verdict.barre {
  inset: auto; top: max(.7rem, env(safe-area-inset-top, 0px)); left: 50%; transform: translateX(-50%);
  width: min(calc(100% - 2rem), 66rem); display: block; padding: .65rem .9rem; overflow: visible;
  background: rgba(12, 13, 17, .92); border: 1px solid var(--filet-scene); border-radius: 14px;
  box-shadow: 0 .6rem 1.6rem rgba(0, 0, 0, .5); animation: barre .45s ease-out;
}
.scene-verdict.barre::before { display: none; }
@keyframes barre { from { opacity: 0; transform: translate(-50%, -.8rem); } }
.barre .verdict-actions { margin: 0; justify-content: center; align-items: center; gap: .6rem; }
.barre .verdict-champ, .barre .verdict-objet { margin: 0; flex: 1 1 14rem; width: auto; min-width: 0; text-align: left; }
.barre .scene-bouton { font-size: clamp(1rem, min(1.2vw, 2vh), 1.35rem); min-height: max(50px, 2.4em); }
.barre .verdict-chiffres { margin-top: .4rem; font-size: clamp(13px, min(1.1vw, 1.7vh), 1.15rem); }
.lecteur-ecran {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* Sur un écran étroit, la barre se fait compacte — le haut de la scène y est plus proche
   du titre : le champ sur toute la ligne, les trois boutons côte à côte, sans la ligne
   des chances (elles sont dans la scène). */
@media (max-width: 600px) {
  .scene-verdict.barre { padding: .45rem .5rem; }
  .barre .verdict-actions { gap: .4rem; }
  .barre .verdict-champ, .barre .verdict-objet { flex-basis: 100%; min-height: 44px; }
  .barre .scene-bouton { flex: 1 1 0; min-width: 0; min-height: 46px; padding: .3rem .35rem; font-size: 14px; line-height: 1.15; }
  .barre .verdict-chiffres { display: none; }
}

/* La machine à sous : des ampoules en chenillard autour du rouleau — une sur trois
   allumée, qui tourne —, un fronton de fête foraine qui s'allume en grésillant, la ligne
   gagnante qui clignote. */
.jackpot { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.ampoule-j {
  position: absolute; width: var(--d); height: var(--d); transform: translate(-50%, -50%); border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #FFF6D0, #FFC94D 55%, #C98A16);
  box-shadow: 0 0 .9em rgba(255, 201, 77, .85); opacity: 0;
}
.jackpot.allume .ampoule-j { animation: chenillard .48s steps(1) infinite; animation-delay: calc(var(--i) * -.16s); }
@keyframes chenillard { 0% { opacity: 1; } 33.3% { opacity: .18; } }
.fronton {
  position: absolute; margin: 0; padding: .3em 1.1em; white-space: nowrap;
  font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: #FFE7A3;
  text-shadow: 0 0 .35em rgba(255, 201, 77, .9), 0 0 1em rgba(255, 140, 40, .6);
  background: linear-gradient(#4A0E0E, #250606); border: 3px solid var(--or); border-radius: .5em;
  box-shadow: 0 0 1.4em rgba(255, 170, 60, .55), inset 0 0 .8em rgba(255, 120, 40, .35); opacity: 0;
}
.jackpot.allume .fronton { animation: neon .8s linear forwards; }
@keyframes neon { 0% { opacity: 0; } 12% { opacity: .9; } 18% { opacity: .1; } 30% { opacity: 1; }
                  38% { opacity: .35; } 52%, 100% { opacity: 1; } }
.rouleau-nom.gagnant { animation: gagne .34s steps(1) 5; }
@keyframes gagne { 50% { color: var(--craie); text-shadow: none; } }

/* La poursuite : une bulle de bande dessinée, qui éclate au-dessus du tableau. */
.bulle {
  position: absolute; z-index: 70; margin: 0; padding: .45em .9em; text-align: center; line-height: 1.05;
  font: 900 italic 1em / 1.05 var(--texte-police); text-transform: uppercase; letter-spacing: .02em;
  color: #1A1D22; background: #FFFDF5; border: .14em solid #1A1D22; border-radius: 48% / 42%;
  box-shadow: .18em .2em 0 #1A1D22; transform-origin: 15% 100%; opacity: 0;
}
/* La pointe, vers le tableau : un triangle encre, et par-dessus un triangle papier qui
   efface le bord de la bulle à sa racine. */
.bulle::before, .bulle::after { content: ""; position: absolute; clip-path: polygon(0 0, 100% 0, 8% 100%); }
.bulle::before { left: 16%; bottom: -1.02em; width: 1.15em; height: 1.1em; background: #1A1D22; }
.bulle::after { left: calc(16% + .16em); bottom: -.74em; width: .82em; height: .82em; background: #FFFDF5; }
.bulle.eclate { animation: eclate .45s cubic-bezier(.2, 1.7, .4, 1) forwards; }
@keyframes eclate { from { opacity: 0; transform: scale(.2) rotate(-8deg); } to { opacity: 1; transform: scale(1) rotate(-3deg); } }

/* Les pièces partagées par les annonces : le texte à la craie (le grain est posé par
   scene.js, en --craie-blanche et --craie-jaune) ; un texte à écrire garde sa place. */
.craie {
  margin: 0; color: transparent; font-style: italic;
  background-image: var(--craie-blanche); -webkit-background-clip: text; background-clip: text;
}
.craie.jaune { background-image: var(--craie-jaune); }
.craie[hidden] { display: block !important; visibility: hidden; }
@keyframes apparait { from { opacity: 0; } }

/* L'élimination : les éliminés gisent au sol, rayés ; la tuile de l'élu grandit au centre. */
.sol-tuiles { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.tuile.tombee {
  position: absolute; white-space: nowrap; padding: .2em .45em; background: #101218; opacity: 0;
  transform: translate(-50%, -50%) rotate(var(--rot)); animation: au-sol .45s cubic-bezier(.5, 0, .75, 0) forwards;
}
@keyframes au-sol {
  from { opacity: 0; transform: translate(-50%, -260%) rotate(0deg); }
  to { opacity: .55; transform: translate(-50%, -50%) rotate(var(--rot)); }
}
.tuile.grande {
  position: absolute; z-index: 6; padding: .25em .7em .3em; border-width: 3px; border-radius: .18em;
  transform: none; white-space: nowrap; line-height: 1.05; box-shadow: 0 0 .6em rgba(255, 201, 77, .55);
}
.tuile-titre { margin-bottom: .3em; font-size: .24em; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; }
.tuile.grande .tuile-proba { font-size: .24em; }

/* Le projecteur : le reste retombe dans le noir, le nom s'écrit dans le rond de lumière. */
.scene-grille.dans-le-noir { opacity: 0; transition: opacity .6s; }
.faisceau {
  position: absolute; inset: 0; z-index: 3; pointer-events: none; text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.faisceau-titre, .faisceau-nom { margin: 0; opacity: 0; transform: scale(.92); transition: opacity .7s, transform .9s; }
.faisceau-titre { letter-spacing: .24em; text-transform: uppercase; color: #E9D8B0; }
.faisceau-nom {
  font-weight: 700; line-height: 1.05; color: #FFF3D6;
  text-shadow: 0 0 .25em rgba(255, 226, 160, .55), 0 0 1em rgba(255, 200, 120, .35);
}
.faisceau.allume .faisceau-titre, .faisceau.allume .faisceau-nom { opacity: 1; transform: none; }
.poussiere-f {
  position: absolute; width: var(--g); height: var(--g); border-radius: 50%; opacity: 0;
  background: rgba(255, 240, 210, .75); box-shadow: 0 0 4px rgba(255, 235, 200, .8);
  animation: poussiere var(--t) ease-in-out infinite;
}
@keyframes poussiere {
  0% { opacity: 0; transform: translate(0, 0); } 30% { opacity: .9; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)); }
}

/* La roue : le panneau devient un panneau de fête foraine, le nom en lettres d'ampoules. */
.lecteur.panneau-ampoules {
  z-index: 3; border: 3px solid var(--or); border-radius: 12px; transition: top .5s, height .5s, font-size .5s;
  background: linear-gradient(#3A0C0C, #1E0505);
  box-shadow: 0 0 1.6em rgba(255, 170, 60, .45), inset 0 0 1.2em rgba(255, 120, 40, .3);
}
.lettres-ampoules {
  color: transparent !important; text-shadow: none !important;
  background: radial-gradient(circle, #FFF8DC 0 32%, #FFD36A 44%, transparent 52%) 0 0 / .075em .075em,
              linear-gradient(#9A6A17, #9A6A17);
  -webkit-background-clip: text; background-clip: text;
  filter: drop-shadow(0 0 .06em rgba(255, 201, 77, .9)) drop-shadow(0 0 .3em rgba(255, 150, 40, .45));
}
.panneau-flechette { flex-shrink: 0; align-self: center; width: .9em; height: .36em; margin-right: .15em; overflow: visible; }
.panneau-flechette .fut { stroke: #E9DFC7; stroke-width: 5; }
.panneau-flechette .pointe { stroke: #C9CED6; stroke-width: 4; }
.panneau-flechette .empennage { fill: #B3302B; stroke: #7A1F1B; stroke-width: 2; }

/* La cible : l'ardoise des scores du café, le nom écrit à la craie. */
.ardoise-scores {
  position: absolute; z-index: 3; box-sizing: border-box; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .35em; padding: .6em .8em; text-align: center;
  font-family: "Tableau Serif", "Latin Modern Roman", Georgia, serif;
  background: radial-gradient(ellipse at 40% 30%, #2E3E35, #1A251F 72%);
  border: .5em solid #7A4E26; border-radius: .35em; animation: apparait .35s ease-out;
  box-shadow: inset 0 0 1.5em rgba(0, 0, 0, .6), 0 .4em 1.2em rgba(0, 0, 0, .5);
}
.ardoise-titre { letter-spacing: .12em; }
.ardoise-trait { width: 70%; height: .12em; border-radius: .1em; -webkit-background-clip: border-box; background-clip: border-box; }
.ardoise-nom { font-weight: 700; line-height: 1.1; }
.ardoise-chance { font-size: .8em; }

/* Le grappin : la goulotte à lots, la capsule qui s'ouvre, le ticket qui se déroule. */
.grappin-trappe {
  position: absolute; z-index: 36; box-sizing: border-box; display: flex; justify-content: center; pointer-events: none;
  border: 2px solid rgba(220, 240, 255, .55); border-bottom: none; border-radius: .4em .4em 0 0;
  background: linear-gradient(rgba(200, 225, 245, .12), rgba(200, 225, 245, .3));
  box-shadow: inset 0 0 1em rgba(255, 255, 255, .15); animation: apparait .4s ease-out;
}
.grappin-trappe span {
  align-self: flex-start; margin-top: -1.4em; padding: .1em .6em; border: 2px solid var(--or); border-radius: .4em;
  font: 700 1em var(--texte-police); letter-spacing: .15em; text-transform: uppercase; color: #FFE7A3; background: #3A0C0C;
}
.grappin-trappe.allume span { box-shadow: 0 0 1em rgba(255, 201, 77, .9); animation: neon .6s linear; }
.coque {
  position: absolute; z-index: 41; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 34% 26%, rgba(255, 255, 255, .95) 0%, rgba(255, 255, 255, .55) 22%,
              rgba(220, 234, 246, .55) 60%, rgba(150, 180, 210, .75) 100%);
  box-shadow: inset 0 -.4em 1em rgba(40, 70, 100, .25), 0 0 2em rgba(255, 201, 77, .5);
}
.coque.haut { z-index: 43; clip-path: inset(0 0 50% 0); transform-origin: 0% 50%; }
.coque.bas { clip-path: inset(50% 0 0 0); }
.ticket {
  position: absolute; z-index: 42; box-sizing: border-box; overflow: hidden; padding: 0 .8em; text-align: center;
  font-family: "Tableau Serif", "Latin Modern Roman", Georgia, serif; color: #1C2733;
  background: linear-gradient(var(--teinte) 0 .3em, #FFFDF6 .3em calc(100% - .3em), var(--teinte) calc(100% - .3em));
  border-inline: .16em dashed var(--teinte); border-radius: .12em; box-shadow: 0 .4em 1.2em rgba(0, 0, 0, .45);
}
.ticket-titre { margin: .9em 0 0; font-size: .3em; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: #55606B; }
.ticket-nom { margin: .1em 0 .15em; font-weight: 700; line-height: 1.1; }
.ticket-chance { margin: 0 0 .9em; font-size: .3em; color: #55606B; }
.ticket-nom:last-child { margin-bottom: .45em; }

/* Les trappes : le plateau de télévision — le studio s'assombrit, deux faisceaux de
   couleur balaient le fond, un projecteur tombe sur le dernier debout. */
.studio { position: absolute; inset: 0; z-index: 250; pointer-events: none; opacity: 0; transition: opacity .5s; }
.studio.allume { opacity: 1; }
.studio-nuit, .studio-cone { position: absolute; inset: 0; }
.studio-cone { background: linear-gradient(rgba(255, 245, 215, .4), rgba(255, 240, 200, .1)); }
.studio-sol { position: absolute; border-radius: 50%; background: radial-gradient(ellipse, rgba(255, 240, 200, .6), rgba(255, 240, 200, 0) 70%); }
.studio-balai {
  position: absolute; bottom: -10%; width: 22%; height: 130%; opacity: .35; transform-origin: 50% 100%;
  clip-path: polygon(45% 100%, 55% 100%, 100% 0, 0 0);
}
.studio-balai.gauche { left: 2%; background: linear-gradient(to top, rgba(90, 160, 255, .75), rgba(90, 160, 255, 0)); animation: balai 2.4s ease-in-out infinite alternate; }
.studio-balai.droite { right: 2%; background: linear-gradient(to top, rgba(255, 110, 200, .75), rgba(255, 110, 200, 0)); animation: balai 2.4s ease-in-out infinite alternate-reverse; }
@keyframes balai { from { transform: rotate(-22deg); } to { transform: rotate(22deg); } }

/* Galton : la plaque de laiton gravée, vissée sur le cadre. */
.plaque-laiton {
  position: absolute; z-index: 8; box-sizing: border-box; padding: .35em 1.4em .4em; text-align: center; white-space: nowrap;
  font-family: "Tableau Serif", "Latin Modern Roman", Georgia, serif; color: #3A2709;
  background: linear-gradient(160deg, #F3D98B 0%, #C9A04A 35%, #E9C873 55%, #A97E2C 100%);
  border: 2px solid #7A5A1E; border-radius: .25em;
  box-shadow: inset 0 0 0 .12em rgba(255, 240, 190, .5), inset 0 -.15em .3em rgba(90, 60, 10, .4), 0 .3em .8em rgba(0, 0, 0, .45);
  text-shadow: 0 1px 0 rgba(255, 245, 210, .7), 0 -1px 0 rgba(80, 50, 10, .45);
}
.laiton-titre { margin: 0; font-size: .3em; font-weight: 700; letter-spacing: .25em; text-transform: uppercase; }
.laiton-nom { margin: .05em 0; font-weight: 700; line-height: 1.05; }
.laiton-chance { margin: 0; font-size: .28em; font-style: italic; }
.vis {
  position: absolute; width: .26em; height: .26em; border-radius: 50%; transform: scale(0);
  background: radial-gradient(circle at 35% 35%, #F6E6B0, #8E6A22); box-shadow: inset 0 0 0 1px #6B4E16;
  transition: transform .2s cubic-bezier(.2, 1.6, .4, 1);
}
.vis::after { content: ""; position: absolute; left: 15%; right: 15%; top: 45%; height: 12%; background: #5A400F; }
.vis:nth-child(1) { left: .22em; top: .22em; }
.vis:nth-child(2) { right: .22em; top: .22em; }
.vis:nth-child(3) { left: .22em; bottom: .22em; }
.vis:nth-child(4) { right: .22em; bottom: .22em; }
.vis.vissee { transform: scale(1) rotate(200deg); }

/* Monte-Carlo : la caméra plonge dans le territoire doré, le nom s'y écrit à la craie. */
.mc-case.elue.plongee { background: radial-gradient(ellipse at 50% 45%, #6E5418, #3B2C0A 75%); box-shadow: none; }
.mc-case.plongee > * { opacity: 0; }
.mc-craie {
  position: absolute; inset: 0; z-index: 8; pointer-events: none; text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .35em;
  font-family: "Tableau Serif", "Latin Modern Roman", Georgia, serif;
}
.mc-craie-titre { letter-spacing: .14em; }
.mc-craie-nom { font-weight: 700; line-height: 1.05; }

/* Le refus : le nom en craie (pas d'or : il ne passe pas), la chance qui grimpe en rouge,
   puis tombe comme un tampon. */
.verdict-nom.refuse { color: var(--craie); text-shadow: none; }
.doublement {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: .1em .5em;
  margin: .4em 0 .3em; font-size: clamp(2rem, 6vw, 4.5rem); font-variant-numeric: tabular-nums;
}
.doublement .avant { color: var(--craie-pale); text-decoration: line-through; text-decoration-color: var(--alerte); }
.doublement .vers { color: var(--craie-pale); }
.doublement .compteur { color: var(--alerte); font-weight: 700; }
.compteur.tampon { display: inline-block; animation: tampon .35s cubic-bezier(.2, 1.6, .4, 1); }
@keyframes tampon { from { transform: scale(1.7) rotate(-8deg); opacity: .4; } }

@media (prefers-reduced-motion: reduce) {
  .scene, .scene-titre, .scene-verdict, .scene-verdict::before, .tuile.tremble, .compteur.tampon,
  .flechette.plantee svg, .ampoule, .bonhomme.tremble, .coureur.panique, .sol.defile::after,
  .tableau-noir.court .tn-corps > svg, .attente-coeur.bat, .ecg-trace { animation: none; }
  .tuile, .scene-plateau, .scene-legende, .nuit { transition: none; }
  /* Les annonces : allumées d'emblée, sans clignoter. */
  .jackpot.allume .ampoule-j, .jackpot.allume .fronton, .bulle.eclate { animation: none; opacity: 1; }
  .tuile.tombee { animation: none; opacity: .55; }
  .poussiere-f, .studio-balai, .grappin-trappe.allume span { animation: none; }
  .rouleau-nom.gagnant { animation: none; }
}
