/* ─────────────────────────────────────────────────────────────────────────────
   C'est l'heure — le jeu.

   Un téléphone tenu à une main, dans une pièce mal éclairée, qui passe de
   personne en personne. Tout découle de là : du très grand texte, des cibles
   qu'on n'a pas besoin de viser, et rien à lire en petit.

   Les couleurs et les polices sont dans « theme.css ».
   ───────────────────────────────────────────────────────────────────────────── */

html, body { height: 100%; }

body {
  overflow: hidden;
  /* Un appui long ne doit ni sélectionner du texte, ni ouvrir la loupe d'iOS :
     le geste d'entrée en dépend, et un joueur qui appuie fort sur un gage n'a
     rien à sélectionner non plus. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* ── Les écrans ───────────────────────────────────────────────────────────── */

.ecran {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 2rem 1.25rem;
  padding-top: max(2rem, env(safe-area-inset-top));
  padding-bottom: max(2rem, env(safe-area-inset-bottom));
  /* Caché NET, pas en fondu. Deux écrans qui se fondent l'un dans l'autre
     superposent leurs textes pendant une demi-seconde, et ce qu'on lit alors
     n'est ni l'un ni l'autre. Seul l'écran qui ARRIVE est animé. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* L'écran d'entrée, décidé AVANT le premier affichage.
   
   La page déclare la façade visible : c'est le bon défaut, car dans le doute
   un appareil ne doit pas annoncer ce qu'il contient. Mais sur une
   installation réglée en avertissement, l'horloge paraissait le temps que le
   serveur réponde. « theme-tot.js » pose donc « data-entree » depuis ce que
   l'appareil a retenu, et ces deux règles rectifient le tir avant le premier
   pixel — aucun script n'a encore tourné. */
/* Ces trois règles ne valent QUE PENDANT LE DÉMARRAGE — « data-demarrage »
   est retiré dès que le jeu affiche son premier écran, et à partir de là seule
   la classe « visible » décide.
   
   Sans cette borne, la deuxième valait en permanence : une fois entré,
   l'avertissement restait affiché par-dessus l'écran de tirage et interceptait
   les gestes. L'appui long sur l'horloge n'ouvrait plus l'administration. */
:root[data-demarrage="oui"][data-entree="avertissement"] #ecran-horloge {
  opacity: 0; visibility: hidden; pointer-events: none; animation: none;
}
:root[data-demarrage="oui"][data-entree="avertissement"] #ecran-avertissement {
  opacity: 1; visibility: visible; pointer-events: auto;
}
/* Et un appareil qui a déjà accepté n'en voit rien passer du tout. */
:root[data-demarrage="oui"][data-entree="avertissement"][data-vu="oui"] #ecran-avertissement {
  opacity: 0; visibility: hidden; pointer-events: none;
}

.ecran.visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  animation: paraitre .3s ease both;
}

@keyframes paraitre {
  from { opacity: 0; transform: translateY(.5rem); }
  to   { opacity: 1; transform: none; }
}

/* Une animation d'apparition est un agrément, pas une information : qui a
   demandé moins de mouvement n'en a pas besoin. */
@media (prefers-reduced-motion: reduce) {
  .ecran.visible { animation: none; }
}

/* Sur la façade, l'enseigne est un peu plus sobre : c'est le nombre qui doit
   attirer l'œil, pas le titre. */
/* Deux classes, pas une : « .enseigne » seule a la même spécificité et, comme
   elle est déclarée plus bas, sa marge nulle écrasait celle-ci sans bruit.
   L'espace au-dessus du nombre tombait à zéro.

   Le nombre doit se trouver à égale distance du titre au-dessus et de la
   légende en dessous. Mesuré : la boîte du texte déborde ses chiffres de 10 px
   des DEUX côtés — le débord étant symétrique, égaliser les boîtes suffit à
   égaliser ce que l'œil voit. D'où 2 × le rythme ici, et deux écarts de 1,3 rem
   plus bas qui font la même somme. */
/* L'enseigne, partout : l'horloge au-dessus du nom. C'est un logo, pas une
   puce de liste — et c'est LE MÊME sur la façade et dans le jeu : ce qu'on
   voit en entrant est ce qu'on retrouve ensuite. */
.enseigne {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
}

/* En trait plutôt qu'en aplat. Sans « fill: none », le cercle se remplit et
   l'horloge devient un DISQUE NOIR — c'est ce qui est arrivé en déplaçant
   cette règle sous un seul écran : la façade, elle, l'a perdue. */
.horloge {
  width: clamp(3.4rem, 16vw, 4.2rem);
  height: clamp(3.4rem, 16vw, 4.2rem);
  flex: 0 0 auto;
  fill: none;
  stroke: var(--accent);
  /* Le trait s'affine à mesure que le dessin grandit : à 4 rem, 1,5 px faisait
     lourd et le cercle paraissait dessiné au feutre. */
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.titre-jeu {
  font: 400 clamp(1.25rem, 5.2vw, 1.5rem)/1.15 var(--serif);
  letter-spacing: .03em;
  margin: 0;
  color: var(--encre-douce);
}
.titre-jeu span { color: var(--accent); font-weight: 600; }

.enseigne.enseigne-facade {
  --rythme: clamp(1rem, 2.6vh, 1.35rem);
  margin-bottom: calc(var(--rythme) * 2);
}

/* ── La façade : une horloge ──────────────────────────────────────────────── */

#unix {
  display: block;
  font-family: var(--mono);
  font-size: clamp(2.4rem, 13vw, 5.5rem);
  font-weight: 300;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  touch-action: manipulation;
  transition: color .25s ease, text-shadow .25s ease;
}

/* Le seul aveu de l'appui, et il n'arrive qu'après une seconde : un doigt posé
   par hasard lâche avant, et ne découvre donc jamais qu'il y avait quelque
   chose à découvrir. */
#unix.tenu {
  color: var(--accent);
  text-shadow: 0 0 2.5rem var(--accent-voile);
}

.jauge {
  /* 1,3 rem ici et autant sous le trait : les deux, plus l'épaisseur du filet,
     font la marge posée au-dessus du nombre. C'est ce qui le met à équidistance. */
  margin: 1.3rem auto 0;
  /* Le trait de l'appui. Au repos il ne doit presque pas se voir : c'est une
     jauge, pas un séparateur, et un filet trop net découpe la page en deux. */
  width: min(14rem, 60vw);
  height: 1px;
  background: var(--voile-trait);
  overflow: hidden;
}
.jauge span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width .1s linear;
}

.legende {
  margin-top: 1.3rem;
  color: var(--encre-faible);
  font-size: clamp(.8rem, 3.4vw, .95rem);
  letter-spacing: .06em;
}

.date {
  margin-top: .45rem;
  color: var(--encre-faible);
  font-size: clamp(.75rem, 3vw, .88rem);
  font-variant-numeric: tabular-nums;
}

/* ── Le bandeau des cookies ───────────────────────────────────────────────
   En bas, par-dessus tout, et il ne s'en va qu'une fois répondu. Les deux
   réponses ont le même poids : un refus qu'il faut chercher n'est pas un refus.

   Il reste sobre — un bandeau qui insiste ou qui grise le « non » se lit comme
   une porte forcée, et ce n'est pas la maison. */
.bandeau-cookies {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  padding: .6rem .8rem max(.6rem, env(safe-area-inset-bottom));
  background: var(--fond-releve);
  border-top: 1px solid var(--trait);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1rem;
  text-align: left;
}
.bandeau-cookies[hidden] { display: none; }

/* Il se pose PAR-DESSUS l'écran, et c'est voulu. J'ai essayé de lui réserver
   la place : sur un téléphone couché, ses 143 pixels ne laissaient plus rien
   au jeu, et les commandes sortaient de l'écran. Or on ne peut pas jouer sans
   avoir répondu — le bandeau reste jusqu'au clic — donc ce qu'il recouvre
   pendant ces quelques secondes n'a aucune conséquence.
   
   Ce qui a été gardé de cette tentative : le bandeau est devenu compact. */

.mot-cookies {
  margin: 0;
  flex: 1 1 11rem;
  color: var(--encre-douce);
  font-size: .78rem;
  line-height: 1.35;
}

/* Deux colonnes ÉGALES, et non deux boutons qui prennent la largeur de leur
   texte : « Accepter » est plus long que « Refuser », et les laisser libres
   faisait le refus plus petit de onze pixels. Onze pixels, c'est peu — et
   c'est exactement le genre de peu qui dit laquelle des deux réponses est
   attendue. Le contrôle l'a mesuré. */
.issues-cookies {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .4rem;
}
.issues-cookies button {
  min-height: 2.75rem;
  min-width: 5.2rem;
  padding: 0 .7rem;
  border-radius: .25rem;
  border: 1px solid var(--trait);
  background: var(--fond-creux);
  color: var(--encre);
  font: 700 .82rem/1 var(--sans);
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}
#cookies-oui {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-encre);
}
.issues-cookies button:active { filter: brightness(.92); }

/* ── L'avertissement ──────────────────────────────────────────────────────
   L'autre entrée. Elle ne cache rien : c'est tout son objet. Sobre, lisible,
   et sans mise en scène — un avertissement qui en fait trop se lit comme une
   promesse, et ce n'en est pas une. */

.colonne-avertissement {
  width: min(28rem, 100%);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: left;
  gap: 1.1rem;
}

.titre-avertissement {
  margin: 0;
  font: 900 clamp(1.5rem, 7vw, 2rem)/1.1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--encre);
}

.sous-avertissement {
  margin: -.75rem 0 0;
  font: 900 clamp(.8rem, 3.6vw, .95rem)/1.2 var(--sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}

.texte-avertissement {
  display: flex;
  flex-direction: column;
  gap: .85rem;
  color: var(--encre-douce);
  font-size: clamp(.92rem, 4vw, 1rem);
  line-height: 1.5;
}
.texte-avertissement p { margin: 0; }

/* Les deux issues au même poids : une porte qu'on referme doit se voir aussi
   bien que celle qu'on franchit. Ce n'est pas une politesse — quelqu'un qui
   arrive là par erreur doit trouver la sortie du premier coup d'œil. */
.issues {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .6rem;
  margin-top: .4rem;
}

#entrer, .quitter {
  min-height: 3.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: .3rem;
  font: 900 clamp(1rem, 4.4vw, 1.15rem)/1 var(--sans);
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  border: 2px solid var(--trait);
}

#entrer {
  background: var(--accent);
  color: var(--accent-encre);
  border-color: var(--accent);
}
#entrer:active { filter: brightness(.92); }

.quitter {
  background: var(--fond-releve);
  color: var(--encre);
}
.quitter:active { filter: brightness(1.15); }

/* ── La roue : l'accès visible à l'administration ──────────────────────────
   Elle n'existe qu'en mode avertissement. En mode façade, un engrenage sur
   l'écran de jeu dirait qu'il y a quelque chose à ouvrir — c'est exactement ce
   que la façade est censée taire.

   Discrète : elle est là pour qui la cherche, pas pour attirer l'œil pendant
   une partie. */
.roue {
  position: absolute;
  top: max(.5rem, env(safe-area-inset-top));
  right: .5rem;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  opacity: .45;
  transition: opacity .16s ease;
}
.roue[hidden] { display: none; }
.roue:active { opacity: .9; }
.roue svg { width: 1.45rem; height: 1.45rem; fill: var(--encre-faible); }

/* ── Le tirage ────────────────────────────────────────────────────────────── */

/* L'écran est une enseigne : le nom en haut, les trois tubes debout, et le
   bouton qui les allume. Rien n'est posé à côté de rien — chaque pièce occupe
   la largeur entière, et c'est l'alignement qui fait l'ordre. */
#ecran-tirage > .colonne {
  /* « 100% », et non « 94vw » : les unités de fenêtre ignorent le rembourrage
     de l'écran, et la colonne débordait de seize pixels à droite. Elle n'était
     donc plus centrée, et l'interrupteur tombait à côté de l'axe. */
  width: min(26rem, 100%);
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* L'horloge d'abord, en grand et sur l'axe ; le nom dessous, sur deux lignes.
   C'est l'ordre dans lequel on lit une enseigne : le signe, puis ce qu'il
   annonce. Ce bloc PREND la place que les colonnes lui laissent — sans le
   flex, l'espace rendu retombait en bas et remontait le bouton Tirer. */
#ecran-tirage .enseigne {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.1rem;
  padding: .4rem 0 1.2rem;
  margin: 0;
}

/* En trait plutôt qu'en aplat : un dessin plein devient une tache dès qu'il
   rapetisse, et c'est la même horloge que celle de la façade — ce qu'on voit
   en entrant est ce qu'on retrouve ici. Bornée en largeur d'écran pour qu'un
   petit téléphone la rétrécisse au lieu de pousser le nom hors du cadre. */
/* En trait plutôt qu'en aplat : un dessin plein devient une tache dès qu'il
   rapetisse. Sans « fill: none », le cercle se remplit et l'horloge devient un
   disque noir — c'est ce qui est arrivé en déplaçant cette règle. */
#ecran-tirage .horloge {
  width: min(7.4rem, 30vw);
  height: min(7.4rem, 30vw);
  flex: 0 1 auto;
  min-height: 0;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

#ecran-tirage .titre-jeu {
  font: 900 clamp(1.5rem, 8.6vw, 2.15rem)/1.12 var(--sans);
  letter-spacing: .22em;
  text-align: center;
  margin: 0;
  color: var(--encre);
  text-transform: uppercase;
}
/* Deux lignes voulues, pas deux lignes subies : « L'HEURE » passe dessous
   parce qu'on le décide, et non parce que la largeur de l'écran l'y force. */
#ecran-tirage .titre-jeu span {
  display: block;
  color: var(--accent);
  font-weight: 900;
}

/* ── Les trois colonnes ───────────────────────────────────────────────────── */

/* TROIS TUBES DEBOUT. Celles qui sont DANS la pioche sont allumées : leur
   teinte en aplat, leur encre dessus. Les autres restent éteintes. Le curseur
   est cumulatif — choisir « Feu » ouvre aussi les deux d'avant — et la
   différence entre un cran et trois se voit d'un mètre, sans lire.

   Plafonnées à 44 % de la hauteur : elles restaient lisibles bien avant
   d'occuper tout l'écran, et ce quart-là sert mieux au nom du jeu. */
.curseur {
  flex: 1 1 auto;
  max-height: 44dvh;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .38rem;
  width: 100%;
}

.curseur button {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: .85rem;
  padding: 0 0 1.2rem;
  border: 2px solid var(--trait);
  border-radius: .2rem;
  color: var(--encre-faible);
  background: var(--fond-creux);
  font: 900 clamp(.72rem, 3.6vw, .92rem)/1 var(--sans);
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
  /* Sec et court : rien ne glisse, tout bascule. */
  transition: background .12s linear, color .12s linear, border-color .12s linear;
}

.curseur button svg { width: 3rem; height: 2.25rem; fill: currentColor; }

.curseur button[data-allume="oui"] {
  background: var(--cat-tube);
  border-color: var(--cat-tube);
  color: var(--cat-encre);
}

/* Chaque colonne porte SA teinte, prise dans l'habillage courant. Aucune
   couleur n'est écrite ici : le contrôle des thèmes refuse tout ce qui n'est
   pas un « var() », et il a raison. */
.curseur button[data-palier="nuages"] { --cat-tube: var(--cat-nuages); --cat-encre: var(--cat-nuages-encre); }
.curseur button[data-palier="baiser"] { --cat-tube: var(--cat-baiser); --cat-encre: var(--cat-baiser-encre); }
.curseur button[data-palier="feu"]    { --cat-tube: var(--cat-feu);    --cat-encre: var(--cat-feu-encre); }

/* Sous les colonnes, et discret : c'est une indication, pas une commande. */
.reste {
  flex: 0 0 auto;
  margin: .65rem 0 .5rem;
  text-align: center;
  color: var(--encre-faible);
  font-size: .78rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

/* ── Le bouton, et il est énorme ──────────────────────────────────────────── */

/* Il porte les couleurs de ce qu'il va tirer : à un cran, un aplat ; à trois,
   les trois bandes. Il EST la pioche, pas un déclencheur posé à côté d'elle. */
.agir { flex: 0 0 auto; width: 100%; }

#bouton-tirer {
  width: 100%;
  min-height: 8.6rem;
  display: block;
  font: 900 clamp(2.2rem, 12vw, 3rem)/1 var(--sans);
  letter-spacing: .01em;
  text-transform: uppercase;
  color: var(--cat-encre, var(--accent-encre));
  background: var(--cat-tube, var(--accent));
  border: 0;
  border-radius: .2rem;
  cursor: pointer;
  transition: filter .16s ease;
}

#bouton-tirer[data-bandes="1"] { background: var(--bande-1); }
#bouton-tirer[data-bandes="2"] {
  background: linear-gradient(90deg, var(--bande-1) 0 50%, var(--bande-2) 50% 100%);
}
#bouton-tirer[data-bandes="3"] {
  background: linear-gradient(90deg,
    var(--bande-1) 0 33.34%, var(--bande-2) 33.34% 66.67%, var(--bande-3) 66.67% 100%);
}

#bouton-tirer:hover { filter: brightness(1.06); }
#bouton-tirer:active { filter: brightness(.9); }

#bouton-tirer:disabled {
  background: var(--fond-releve);
  color: var(--encre-faible);
  cursor: default;
  filter: none;
}

/* ── Le registre : un interrupteur, et rien d'autre ───────────────────────── */

/* Trois colonnes, dont celle du milieu tient juste l'interrupteur : c'est LUI
   qui est sur l'axe de l'écran, pas l'ensemble « étiquette + bascule + état ».
   Centrer le bloc entier aurait posé la bascule à droite du milieu. */
.axes { flex: 0 0 auto; width: 100%; padding-top: .9rem; }
/* Caché, il ne doit pas non plus laisser son rembourrage derrière lui :
   l'écran se recomposerait autour d'un vide qui ne dit rien. */
.axes[hidden] { display: none; }
.axes .axe {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: .9rem;
}
/* Sans « min-width: 0 », une piste « 1fr » s'élargit pour contenir son texte :
   l'étiquette, plus longue que l'état, poussait l'interrupteur de huit pixels
   hors de l'axe. Mesuré, pas supposé. */
.axes .etiquette, .axes .etat { min-width: 0; }
.axes .etiquette {
  justify-self: end;
  display: flex; align-items: center; gap: .45rem;
  white-space: nowrap;
  font: 900 .7rem/1 var(--sans);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--encre-faible);
}
.axes .etiquette svg { width: 1.1rem; height: .85rem; fill: currentColor; }

/* Pas un cran parmi quatre : un objet à deux états. Fermé, il porte une
   promesse ; ouvert, il porte le violet du registre — qui ne peint jamais un
   gage, mais qui porte toute sa commande. */
.bascule {
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: .5rem .6rem;
  min-height: 2.75rem; min-width: 2.75rem;
  cursor: pointer; font: inherit;
}
.bascule .glissiere {
  position: relative; width: 3.9rem; height: 2.15rem; flex: 0 0 auto;
  border: 2px solid var(--trait); border-radius: .15rem;
  background: var(--fond-creux);
  transition: border-color .14s steps(2);
}
.bascule .pion {
  position: absolute; top: .19rem; left: .19rem;
  width: 1.5rem; height: 1.5rem;
  background: var(--encre-faible);
  transition: transform .14s steps(2), background .14s steps(2);
}
.bascule[aria-checked="true"] .glissiere { border-color: var(--cat-collier); }
.bascule[aria-checked="true"] .pion {
  transform: translateX(1.75rem);
  background: var(--cat-collier);
}

/* « Dans la pioche » est le plus long des deux états, et la grille donne aux
   deux colonnes latérales la largeur du plus large : à .78 rem il passait à la
   ligne et déséquilibrait la rangée. On le resserre plutôt que de raccourcir
   le mot — « Éteint » / « Dans la pioche » DIT la promesse, et c'est ce qui
   compte ici. */
.axe .etat {
  justify-self: start;
  font: 900 .7rem/1 var(--sans);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--encre-faible);
  white-space: nowrap;
}
.axe:has(.bascule[aria-checked="true"]) .etat { color: var(--cat-collier); }

/* ── Le panneau : le gage, et le minuteur ─────────────────────────────────── */

/* Les deux écrans sont LE MÊME OBJET dans deux états. Un panneau de couleur
   pleine, cerné de nuit, qui porte le nom du jeu à gauche et ce que le gage
   EST à droite. On ne change pas d'endroit, on change d'état. */
.panneau {
  /* À GAUCHE, comme dans la maquette. Les écrans du jeu sont centrés — c'est
     une règle globale — mais un gage en capitales énormes centré se lit mal :
     chaque ligne commence ailleurs, et l'œil doit chercher son départ à chaque
     retour. Le panneau est un panneau : tout y est calé sur la marge. */
  text-align: left;
  position: absolute;
  inset: .6rem;
  padding-top: max(0px, env(safe-area-inset-top));
  padding-bottom: max(0px, env(safe-area-inset-bottom));
  border-radius: .25rem;
  background: var(--cat-tube);
  color: var(--cat-encre);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.panneau[data-cat="nuages"] {
  --cat-tube: var(--cat-nuages); --cat-encre: var(--cat-nuages-encre);
  --cat-douce: var(--cat-nuages-douce);
}
.panneau[data-cat="baiser"] {
  --cat-tube: var(--cat-baiser); --cat-encre: var(--cat-baiser-encre);
  --cat-douce: var(--cat-baiser-douce);
}
.panneau[data-cat="feu"] {
  --cat-tube: var(--cat-feu); --cat-encre: var(--cat-feu-encre);
  --cat-douce: var(--cat-feu-douce);
}

/* ── Le haut du panneau ───────────────────────────────────────────────────── */

.panneau-haut {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .9rem 1rem 0;
  min-height: 2.9rem;
}

/* Quand la rangée est pleine — deux marques et une catégorie au nom long —
   quelque chose doit céder. C'est le nom du jeu : lui seul ne porte aucune
   information sur le gage. La catégorie et les marques, elles, disent ce que
   le gage EST, et ne se laissent jamais rogner. */
.panneau-haut[data-charge="1"] { gap: .38rem; }
.panneau-haut[data-charge="1"] .nom-ici { font-size: .72rem; letter-spacing: .03em; }
.panneau-haut[data-charge="1"] .marques { margin-right: .38rem; }
.panneau-haut[data-charge="1"] .marque { padding: .3rem .44rem; letter-spacing: .06em; }
.panneau-haut[data-charge="1"] .nom-cat { font-size: .8rem; letter-spacing: .08em; }

.panneau-haut[data-charge="2"] { gap: .3rem; }
.panneau-haut[data-charge="2"] .nom-ici { font-size: .6rem; letter-spacing: 0; }
.panneau-haut[data-charge="2"] .marques { margin-right: .3rem; gap: .25rem; }
.panneau-haut[data-charge="2"] .marque {
  padding: .28rem .32rem; letter-spacing: .04em; font-size: .62rem;
}
.panneau-haut[data-charge="2"] .cartouche { gap: .3rem; }
.panneau-haut[data-charge="2"] .nom-cat { font-size: .75rem; letter-spacing: .04em; }
.panneau-haut[data-charge="2"] .blason { width: 1.55rem; height: 1.2rem; }

.nom-ici {
  font: 900 .875rem/1 var(--sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cat-douce);
  white-space: nowrap;
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cartouche {
  margin-left: auto;
  display: flex; align-items: center; gap: .5rem;
  flex: 0 0 auto;
}

.blason { width: 1.9rem; height: 1.45rem; fill: var(--cat-douce); flex: 0 0 auto; }

.nom-cat {
  font: 900 .875rem/1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--cat-douce);
  white-space: nowrap;
  flex: 0 0 auto;
}

.marques {
  margin-left: auto; margin-right: .6rem;
  display: flex; gap: .38rem; flex: 0 0 auto;
}
.marques:empty { margin-right: 0; }

.marque {
  font: 900 .69rem/1 var(--sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: .3rem .56rem;
  border-radius: .12rem;
  background: var(--cat-encre);
  color: var(--cat-tube);
}
/* Le Collier ne peint pas le panneau : il s'y accroche. Le violet reste le
   violet du registre, quelle que soit la température de ce qui est sorti. */
.marque[data-marque="collier"] { color: var(--cat-collier); }

/* ── Le corps : le gage, en capitales ─────────────────────────────────────── */

.panneau-corps {
  flex: 1 1 auto;
  min-height: 0;
  padding: .75rem 1rem 0;
  overflow: hidden;
}

#texte-gage {
  margin: 0;
  font: 900 2.6rem/1.02 var(--sans);
  letter-spacing: -.01em;
  text-transform: uppercase;
  color: var(--cat-encre);
}

/* Pendant le défilé, le texte est FLOUTÉ. Lisible, il se lisait comme un
   résultat — et le résultat était faux une image sur deux. */
.panneau[data-etat="defile"] #texte-gage { filter: blur(.5rem); opacity: .55; }
.panneau[data-etat="defile"] .marques { visibility: hidden; }
.panneau[data-etat="defile"] .panneau-bas { opacity: .3; pointer-events: none; }

/* ── Le bas : les durées, puis « Un autre » ───────────────────────────────── */

.panneau-bas {
  flex: 0 0 auto;
  padding: 0 .75rem .75rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

/* Six cases, deux rangs. « Sans minuteur » y prend une case comme les autres,
   ni plus petite ni reléguée — ne pas vouloir de minuteur est un choix comme
   un autre. */
.durees { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
.durees[hidden] { display: none; }

.titre-durees {
  grid-column: 1 / -1;
  font: 900 .75rem/1 var(--sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--cat-douce);
}

.durees button {
  min-height: 3.6rem;
  border: 0;
  border-radius: .2rem;
  background: var(--cat-encre);
  color: var(--cat-tube);
  font: 900 1.35rem/1 var(--sans);
  letter-spacing: .01em;
  cursor: pointer;
}
.durees button.sans {
  font-size: .875rem; line-height: 1.1;
  letter-spacing: .06em; text-transform: uppercase;
}
.durees button:active { opacity: .82; }

/* « Un autre » garde la largeur qu'il aurait eue s'ils étaient deux : ni étiré
   sur toute la carte — il se lirait comme l'issue attendue — ni rétréci en
   petit lien discret, qui dirait sans le dire que le refus se fait tout petit.
   Rien n'est compté, rien n'est affiché (D21, D22). */
.rechange { display: flex; justify-content: center; padding-top: .62rem; }
.rechange[hidden] { display: none; }
.rechange button {
  width: calc(50% - .25rem);
  min-height: 3.9rem;
  border: 0;
  border-radius: .2rem;
  background: var(--cat-encre);
  color: var(--cat-tube);
  font: 900 1.3rem/1.05 var(--sans);
  letter-spacing: .02em;
  text-transform: uppercase;
  cursor: pointer;
}
.rechange button:active { opacity: .82; }

/* ── Le minuteur ──────────────────────────────────────────────────────────── */

/* Le gage n'est pas un sous-titre du minuteur : c'est ce qu'on est en train de
   faire. Il occupe TOUJOURS trois lignes — la boîte ne bouge pas d'un gage à
   l'autre, et c'est la taille du texte qui s'y ajuste. Un écran dont le bloc
   du haut change de hauteur à chaque tirage ne se lit pas : il saute.

   Les deux pixels de grâce évitent qu'un texte faisant pile trois lignes à la
   taille maximale soit rogné d'un cheveu par les arrondis. */
/* Ces deux valeurs sont AUSSI écrites dans jeu.js, qui part de la même taille
   maximale pour chercher celle qui tient. Un contrôle les compare : le jour où
   l'une bouge sans l'autre, la boîte et le texte ne parlent plus de la même
   chose, et le défaut ne se voit qu'à l'écran. */
#panneau-minuteur { --rappel-max: 2.75rem; --rappel-inter: 1.06; }

.rappel {
  flex: 0 0 auto;
  margin: .75rem 0 0;
  height: calc(3 * var(--rappel-max) * var(--rappel-inter) + 2px);
  font: 900 var(--rappel-max)/var(--rappel-inter) var(--sans);
  letter-spacing: -.005em;
  text-transform: uppercase;
  color: var(--cat-encre);
  padding: 0 1rem;
  overflow: hidden;
}
/* Le texte vit dans un bloc À LUI : la hauteur d'une boîte fixe ne dit plus
   rien du texte qu'elle contient, et « scrollHeight » ne descend jamais sous
   elle. Sans ce bloc, la mesure comptait le contenant. */
.rappel > span { display: block; }

#chiffres {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  font: 900 8rem/1 var(--sans);
  letter-spacing: -.045em;
  font-variant-numeric: tabular-nums;
  color: var(--cat-encre);
}
#chiffres.libre { font-size: 5.25rem; letter-spacing: -.01em; text-transform: uppercase; }

/* Le bas du minuteur reprend la hauteur qu'il lui faut. Lui imposer la réserve
   taillée pour les six durées poussait son chiffre cent pixels au-dessus du
   centre — et rien ne le mesurait. */
#panneau-minuteur .panneau-bas { padding-top: .75rem; }

/* La sonnerie se VOIT autant qu'elle s'entend : dans le bruit d'une soirée, le
   son ne suffit pas. Le panneau bat, il ne clignote pas en boucle. */
@keyframes battre-fin {
  0%, 100% { opacity: 1; }
  50% { opacity: .2; }
}
.panneau.sonne { animation: battre-fin .26s steps(1, end) 5; }

/* ── Un mot quand quelque chose manque ────────────────────────────────────── */

.souci {
  color: var(--encre-douce);
  max-width: 32ch;
  margin: 0 auto;
  line-height: 1.5;
}
.souci strong { color: var(--encre); display: block; margin-bottom: .75rem; }

/* ── La porte de l'administration ─────────────────────────────────────────── */
/*
   L'horloge de l'enseigne s'ouvre sur l'administration après trois secondes
   d'appui. Deux précautions tactiles, et ce ne sont pas des détails : sans
   « touch-action: none », un appui maintenu sur un téléphone fait défiler la
   page ou ouvre le menu du navigateur, et le geste ne va jamais au bout.
*/
#porte-admin {
  touch-action: none;
  -webkit-touch-callout: none;
  cursor: default;
}

/* L'anneau qui se remplit. Il tourne de -90° pour partir de midi, comme une
   aiguille — 57.8 est la circonférence du cercle de rayon 9,2. */
#porte-admin .anneau {
  /* Pas la couleur du cercle qu'il recouvre : deux traits dorés l'un sur
     l'autre ne font qu'un trait qui épaissit, et on ne lit plus où en est le
     remplissage. En clair, il se détache et la progression se voit d'un coup
     d'œil. */
  stroke: var(--encre);
  stroke-width: 2.4;
  stroke-linecap: round;
  /* Posées ici pour l’état de repos ; le script les recalcule sur la longueur
     réelle du tracé dès le premier appui. */
  stroke-dasharray: 57.8;
  stroke-dashoffset: 57.8;
  transform: rotate(-90deg);
  transform-origin: 12px 12px;
  opacity: 0;
}

#porte-admin.tenu .anneau { opacity: 1; }

/* ── Le défilé, dans le panneau du gage ────────────────────────────────────
   Le tirage se déroule À L'ENDROIT où le gage sera lu : le panneau hésite
   — les couleurs et les fragments passent vite — puis il s'arrête net. On
   n'attend pas : six cent vingt millisecondes.

   Le texte reste FLOUTÉ pendant tout le défilé. Lisible, il se lisait comme un
   résultat, et le résultat était faux une image sur deux : on croyait avoir
   tiré ce qui n'était qu'une image de passage. */

.panneau[data-etat="defile"] {
  animation: hesiter .1s steps(1, end) infinite;
}

@keyframes hesiter {
  0%, 100% { filter: none; }
  50% { filter: brightness(1.12); }
}

/* Le panneau se pose : un battement unique, sec, qui dit « c'est celui-là ».
   Pas une apparition en fondu — un fondu ferait douter qu'il soit arrivé. */
.panneau[data-etat="pose"] {
  animation: poser .18s steps(2, end) 1;
}

@keyframes poser {
  0% { filter: brightness(1.3); }
  100% { filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  .panneau[data-etat="defile"],
  .panneau[data-etat="pose"],
  .panneau.sonne { animation: none; }
  .bascule .pion, .bascule .glissiere { transition: none; }
  .curseur button { transition: none; }
}

/* ── Quand l'écran est couché ─────────────────────────────────────────────
   En paysage, un téléphone n'a plus que 390 pixels de haut : le nom en deux
   lignes sous une horloge de 118 pixels poussait le bouton et les commandes
   HORS DE L'ÉCRAN, à deux cents pixels sous le bord. On n'y touchait plus.

   Le logo se couche à son tour — horloge et nom côte à côte, sur une ligne —
   et tout se resserre. Le seuil porte sur la HAUTEUR et non sur l'orientation :
   ce qui manque n'est pas d'être debout, c'est de la place verticale, et un
   petit téléphone en souffre autant qu'un grand couché. */
/* Posé À LA FIN de la feuille, et c'est essentiel : une règle de même poids
   écrite plus bas l'emporte. Placé plus haut, ce bloc voyait la moitié de ses
   lignes écrasées en silence — celles à sélecteur de classe passaient à la
   trappe, celles à sélecteur d'identifiant tenaient, et le résultat n'était
   ni l'un ni l'autre. */
/* 680 et non 560 : un iPhone SE fait 568 pixels de haut et passait juste au
   travers, si bien que l'interrupteur du registre sortait de l'écran. Le
   seuil ne vise pas une orientation mais un manque de place verticale, et un
   petit téléphone debout en manque autant qu'un grand couché. */
@media (max-height: 680px) {
  #ecran-tirage {
    padding-top: max(.5rem, env(safe-area-inset-top));
    padding-bottom: max(.5rem, env(safe-area-inset-bottom));
  }

  /* Le logo cesse de prendre la place qui reste : il n'en garde que ce qu'il
     lui faut, et la rend aux colonnes et au bouton. */
  #ecran-tirage .enseigne {
    flex: 0 0 auto;
    flex-direction: row;
    justify-content: center;
    gap: .55rem;
    padding: .1rem 0 .5rem;
  }
  #ecran-tirage .horloge { width: 2.1rem; height: 2.1rem; }
  #ecran-tirage .titre-jeu {
    font-size: 1.05rem;
    letter-spacing: .16em;
  }
  /* Sur une ligne, les deux moitiés du nom se remettent côte à côte. */
  #ecran-tirage .titre-jeu span { display: inline; }

  .curseur { max-height: none; gap: .3rem; }
  .curseur button {
    gap: .3rem;
    padding-bottom: .45rem;
    font-size: .62rem;
    letter-spacing: .08em;
  }
  .curseur button svg { width: 1.7rem; height: 1.3rem; }

  .reste { margin: .3rem 0 .3rem; font-size: .66rem; }

  #bouton-tirer { min-height: 3.4rem; font-size: 1.8rem; }

    .axes { padding-top: .35rem; }
  /* La glissière rétrécit, la CIBLE non : 44 pixels restent 44 pixels, écran
     couché comme debout. Un doigt ne rapetisse pas avec l'écran — et le
     contrôle l'a attrapé ici, à 38 pixels. */
  .bascule { min-height: 2.75rem; padding: .25rem .6rem; }
  .bascule .glissiere { width: 3.1rem; height: 1.7rem; }
  .bascule .pion { width: 1.15rem; height: 1.15rem; top: .16rem; left: .16rem; }
  .bascule[aria-checked="true"] .pion { transform: translateX(1.4rem); }
  .axes .etiquette, .axe .etat { font-size: .62rem; }

  /* La carte du gage : les six durées passent sur UN rang. Deux rangs plus le
     bouton de rechange ne laissaient rien au gage lui-même. */
  .panneau-bas { height: auto; padding-bottom: .5rem; }
  /* On garde TROIS colonnes : à 844 pixels de large, six cases côte à côte
     seraient plus étroites que le pouce. Seule la hauteur se resserre. */
  .durees { gap: .3rem; }
  .titre-durees { font-size: .62rem; }
  .durees button { min-height: 2.9rem; font-size: .95rem; }
  .durees button.sans { font-size: .62rem; }
  .rechange { padding-top: .35rem; }
  .rechange button { min-height: 2.9rem; font-size: .95rem; }
  .panneau-haut { padding-top: .5rem; min-height: 2.2rem; }
  #texte-gage { font-size: 1.7rem; }

  /* Le minuteur : la boîte du rappel garde ses trois lignes, plus petites. */
  #panneau-minuteur { --rappel-max: 1.35rem; }
  #chiffres { font-size: 4.2rem; }
  #chiffres.libre { font-size: 2.8rem; }
}
