/* ============================================================================
   LE LABORATOIRE · interface B · ÉTAPE 2 : PAR-DESSUS
   ----------------------------------------------------------------------------
   Feuille de la page d'essai public/pupitre.html, chargée APRÈS pupitre/socle.css.
   Elle porte la mise en page soignée, et seulement elle, de ce qui se pose
   par-dessus les écrans (SPECS 2.12, « Étape 2 ») :
     1. les voiles        #bandeau-pause, #bandeau-ailleurs (.voile-pupitre)
     2. les bandeaux      #bandeau-demo, #bandeau-reseau, #bandeau-version (leur
                          emplacement, .bandeaux), et leur règle de priorité.
                          PAS ceux de la question (#bandeau-tutoriel,
                          -spectateur, -mode) : ils vivent dans #ecran-jeu,
                          manche.css les dessine et leur fait une place. PAS
                          « Quitter le tutoriel » (#btn-quitter-tuto), rangé dans
                          le même emplacement : il est à tutoriel.css
     3. le message bref   #toast
     4. les fenêtres      <dialog> : menu, confirmation, notifications, « Nos
                          règles ont évolué », documents légaux
     5. les liens légaux  #liens-legaux (.pied)
   Maquette : data/maquettes-2026-10-07/B-suite/voiles.html.
   Plan : docs/interface-b/plan-de-bascule.md, partie 3, « Ce qui se pose par-dessus ».

   CE QUE CETTE FEUILLE DÉCIDE (le détail est dans SPECS 2.12)
     - Un voile couvre les cadrans et la scène : jamais la barre du haut (menu,
       son et « Quitter » restent à portée), ni les bandeaux, ni le professeur
       et sa bulle (l'équipe peut prendre la parole pendant une pause).
     - Un voile ne couvre que les écrans de la partie : profil, statistiques,
       connexion et tutoriel se lisent sans lui.
     - Deux voiles montrés ensemble : « un seul écran » passe devant et masque
       la pause.
     - Les bandeaux : la démonstration d'abord, toujours ; sur téléphone, deux
       bandeaux au plus (la panne de connexion fait attendre « Nouvelle
       version »), pour que la question et ses réponses gardent leur place.
     - Le message bref s'affiche EN HAUT, sur la barre du titre : il ne couvre
       ni la bulle du professeur, ni une réponse, ni la case des 18 ans.

   Règles (les mêmes pour toutes les feuilles, gardées par
   test/pupitre-feuilles.test.js) : ne retouche pas socle.css ; CHAQUE
   sélecteur s'accroche à une pièce de cette étape (.voile-pupitre, .bandeaux,
   dialog, #toast, .pied, ou un de leurs identifiants) : jamais de sélecteur nu
   (« .reponse { … } ») ni de réglage posé sur :root, qui changeraient les
   écrans des autres étapes sans que rien le dise ; le nom d'une animation
   (@keyframes) commence par « par-dessus- » ; tout en « u », couleurs du
   thème ; pas de color-mix(), pas de :has(), pas de « inset: », pas de dvh
   hors de @supports ; aucune ressource en ligne.
   Mesurer : « npm run pupitre:mesurer -- --ecrans=par-dessus » (mode d'emploi
   en tête de outils/mesurer-le-pupitre.mjs), sans retoucher l'outil : les états
   de cette étape sont dans outils/parcours-du-pupitre/par-dessus.mjs. Monte le
   « ?v= » de cette feuille, sur sa ligne de pupitre.html, quand tu la modifies.
   ========================================================================== */


/* ============================================================================
   1. LES VOILES : pause, « Partie suivie ailleurs », « Partie sans écran »
   ----------------------------------------------------------------------------
   Un panneau de verre sombre posé sur le pupitre, sa carte au milieu.
   Ce qu'il couvre, dans les trois rangements : la rampe de cadrans, les
   étiquettes, la scène (et, sur téléphone, les liens légaux).
   Ce qu'il ne couvre JAMAIS :
     - la barre du haut : le menu, le son et « Quitter » restent à portée ;
     - les bandeaux : « DÉMONSTRATION » et « Signal perdu » se lisent encore ;
     - le professeur et sa bulle : pendant une pause, l'équipe peut prendre la
       parole, et sa phrase s'écrit dans la bulle (sous le voile, elle était
       perdue).
   ========================================================================== */

/* ---------- téléphone debout : des cadrans aux liens légaux ---------- */
.voile-pupitre {
  grid-row: 3 / 8; grid-column: 1 / -1;
  /* une seule case, de la hauteur du voile : la carte ne la dépasse jamais */
  grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr);
  top: calc(3 * var(--u)); right: calc(-7 * var(--u)); bottom: calc(-2 * var(--u)); left: calc(-7 * var(--u));
  padding: calc(12 * var(--u));
  border-radius: calc(18 * var(--u));
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7), inset 0 0 0 max(1px, calc(1.2 * var(--u))) rgba(var(--metal-clair-rvb), 0.35);
}
/* (Assemblage des étapes.) À L'ACCUEIL DU JOUEUR (le salon), sur téléphone
   debout, le professeur n'a plus sa rangée sous les liens légaux : il est au
   pied de l'écran lui-même (hors-partie.css). La dernière rangée de la page est
   alors celle des liens légaux, et le voile, qui descend de 2 u dans l'écart
   qui la suit d'ordinaire, sortait de la page (elle défilait de 2 px sous
   « Partie suivie ailleurs »). Il s'y arrête au bas de la page ; le professeur,
   rangé dans l'écran, est alors sous le voile comme le reste de l'accueil. */
body[data-ecran="salon"] .voile-pupitre { bottom: 0; }
/* ---------- téléphone couché : les étiquettes et la scène ---------- */
@media (orientation: landscape) and (max-height: 560px) {
  .voile-pupitre { grid-row: 3 / 5; top: calc(3 * var(--u)); padding: calc(8 * var(--u)); border-radius: calc(14 * var(--u)); }
  /* (le professeur y garde sa rangée sous la scène, hors partie aussi : le voile reprend son bord) */
  body[data-ecran="salon"] .voile-pupitre { bottom: calc(-2 * var(--u)); }
}
/* ---------- ordinateur : la colonne centrale, des cadrans à la scène ---------- */
@media (min-width: 900px) and (min-aspect-ratio: 21/20) and (min-height: 561px) {
  .voile-pupitre {
    grid-area: 2 / 2 / 4 / 7;
    top: calc(6 * var(--u)); right: calc(-6 * var(--u)); bottom: calc(-1 * var(--u)); left: calc(-6 * var(--u));
    padding: calc(14 * var(--u));
    border-radius: calc(22 * var(--u));
  }
  body[data-ecran="salon"] .voile-pupitre { bottom: calc(-1 * var(--u)); }
}

/* Un voile ne couvre que les écrans de la PARTIE. Hors du jeu (connexion,
   profil, statistiques, tutoriel), il ne couvre rien : ces écrans se lisent
   sur n'importe quel appareil, et pendant une pause. Il revient avec l'écran
   de la partie (« Retour au jeu » redemande l'écran courant au serveur).
   body.en-tutoriel : le tutoriel se joue, sur l'écran de la question ou des
   résultats (posé par pupitre.js, qui voit son bouton de sortie ; c'est le
   seul repère de la leçon, le même pour toutes les feuilles). */
body[data-ecran="auth"] .voile-pupitre,
body[data-ecran="profil"] .voile-pupitre,
body[data-ecran="stats"] .voile-pupitre,
body[data-ecran="tuto"] .voile-pupitre,
body.en-tutoriel .voile-pupitre { display: none; }

/* DEUX VOILES À LA FOIS. Le programme ne les montre pas ensemble (la page qui
   perd la main retire sa pause, app.js, « partie:ailleurs ») ; si cela arrivait
   quand même, un seul se lit : « un seul écran » passe devant, et son verre
   devient opaque pour que la carte de la pause ne transparaisse pas dessous. */
#bandeau-ailleurs { z-index: 11; }
#bandeau-pause:not([hidden]) ~ #bandeau-ailleurs { background: rgb(var(--verre-bas)); }

/* ---------- La carte ---------- */
.voile-pupitre .voile-carte { align-self: center; justify-self: center; max-height: 100%; }
.voile-pupitre .voile-carte > * { flex: none; }
/* le symbole de la pause : deux barres qui luisent, et qui respirent */
.voile-pupitre .pause-symbole {
  display: flex; gap: calc(9 * var(--u));
  width: auto; height: auto; border-radius: 0; background: none;
}
.voile-pupitre .pause-symbole::before, .voile-pupitre .pause-symbole::after {
  content: ''; width: calc(11 * var(--u)); height: calc(36 * var(--u)); border-radius: calc(3 * var(--u));
  background: linear-gradient(180deg, var(--accent-vif), var(--accent) 55%, var(--accent-sombre));
  box-shadow: 0 0 calc(16 * var(--u)) rgba(var(--accent-rvb), 0.6), 0 0 0 1px rgba(0, 0, 0, 0.7);
  animation: par-dessus-pouls 2.2s ease-in-out infinite;
}
@keyframes par-dessus-pouls { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
/* ce que dit le voile : la phrase du jeu, ou le message écrit par l'équipe
   (500 caractères au plus). Trop long pour la carte, il défile à l'intérieur. */
#pause-message, #ailleurs-message {
  max-width: 34em; margin: 0;
  font-size: var(--taille-texte); line-height: 1.42; color: var(--texte); text-wrap: pretty; overflow-wrap: anywhere;
}
#bandeau-pause #pause-message {
  flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: var(--metal-sombre) transparent;
}
#ailleurs-note { max-width: 34em; }
/* « Reprendre la partie ici » : toute la largeur de la carte sur téléphone */
#btn-reprendre-ici { align-self: stretch; margin-top: calc(4 * var(--u)); }
@media (orientation: landscape) and (max-height: 560px) {
  .voile-pupitre .pause-symbole { display: none; }
  #btn-reprendre-ici { align-self: center; margin-top: 0; }
  /* la hauteur manque : la carte s'élargit avec son texte, jusqu'à la largeur du
     voile. Un message de pause de 500 caractères s'y lit alors en entier ; dans
     une carte étroite il défilait, sans que rien dise qu'il avait une suite. */
  .voile-pupitre .voile-carte {
    width: auto; min-width: min(100%, calc(560 * var(--u))); max-width: 100%;
    padding-top: calc(10 * var(--u)); padding-bottom: calc(10 * var(--u));
  }
  #pause-message, #ailleurs-message, #ailleurs-note { max-width: none; }
}
@media (min-width: 900px) and (min-aspect-ratio: 21/20) and (min-height: 561px) {
  #btn-reprendre-ici { align-self: center; }
}


/* ============================================================================
   2. LES BANDEAUX DU HAUT : démonstration, connexion, nouvelle version
   ----------------------------------------------------------------------------
   Leur emplacement est sous la barre du haut (téléphone) ou dans le coin en
   haut à gauche (ordinateur). Sur téléphone, chaque bandeau prend sa hauteur à
   la scène. D'où la RÈGLE DE PRIORITÉ :
     1. « DÉMONSTRATION, aucun lot n'est remis » : toujours, et toujours en
        premier. Personne ne doit croire à un lot (SPECS 13 bis), et rien ne
        saute quand un autre bandeau arrive dessous.
     2. la connexion (« Signal perdu… », « Serveur injoignable… », « Connexion
        rétablie. ») ;
     3. « Nouvelle version du jeu ». Sur téléphone elle ATTEND tant que le
        bandeau de la connexion est affiché (sans connexion, recharger ne mène
        nulle part) : deux bandeaux au plus, la question et ses quatre réponses
        gardent leur place. Sur ordinateur, où les bandeaux ne prennent rien à
        la scène, les trois se lisent.
   L'ordre s'écrit par « order », négatif : « Quitter le tutoriel », rangé dans
   le même emplacement (tutoriel.css), reste le dernier.
   ========================================================================== */
.bandeaux { gap: calc(4 * var(--u)); }
#bandeau-demo { order: -3; }
#bandeau-reseau { order: -2; }
#bandeau-version { order: -1; }
#bandeau-reseau:not([hidden]) ~ #bandeau-version { display: none; }

/* Hors du jeu, le bandeau de démonstration n'a pas lieu d'être : il dirait
   « rien n'est enregistré » au-dessus d'un profil qu'on enregistre, ou pendant
   le tutoriel de quelqu'un qui n'est pas dans la démonstration. Il accompagne
   l'accueil, le salon et tous les écrans de la partie (comme dans le jeu). */
body[data-ecran="auth"] #bandeau-demo,
body[data-ecran="profil"] #bandeau-demo,
body[data-ecran="stats"] #bandeau-demo,
body[data-ecran="tuto"] #bandeau-demo,
body.en-tutoriel #bandeau-demo { display: none; }

/* ---------- téléphone : des plaques basses, sur une ligne ---------- */
.bandeaux .bandeau { padding: calc(2 * var(--u)) calc(10 * var(--u)); gap: 0 calc(8 * var(--u)); border-radius: calc(13 * var(--u)); }
#bandeau-demo .demo-titre { letter-spacing: 0.12em; }
#bandeau-demo .demo-detail { color: var(--texte); }
/* « DÉMONSTRATION » et sa phrase sur la même ligne d'écriture : centrés chacun de
   son côté (le socle), les capitales du mot se lisaient deux à trois pixels plus
   haut que la phrase (relecture finale, 2026-10-08). L'interligne du mot est
   serré pour que le bandeau garde sa hauteur au pixel près : il la prend à la scène. */
#bandeau-demo { align-items: baseline; }
#bandeau-demo .demo-titre { line-height: 1; }
/* « Nouvelle version » : la phrase à gauche, sur deux lignes, « Recharger » à
   droite (dessous, il coûtait une rangée de plus à la scène). Le bouton occupe
   toute la hauteur du bandeau, qui n'est pas plus haut que lui : 44 px. */
#bandeau-version {
  flex-wrap: nowrap; justify-content: space-between; align-items: stretch; text-align: left;
  gap: calc(8 * var(--u)); padding: 0 0 0 calc(12 * var(--u));
}
#bandeau-version > span { flex: 1 1 auto; min-width: 0; align-self: center; line-height: 1.2; text-wrap: balance; }
#btn-recharger { padding: 0 calc(11 * var(--u)); letter-spacing: 0.03em; border-radius: calc(13 * var(--u)); }

/* ---------- téléphone couché : les bandeaux côte à côte, sur une rangée ---------- */
@media (orientation: landscape) and (max-height: 560px) {
  .bandeaux { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; gap: calc(4 * var(--u)) calc(8 * var(--u)); }
  #bandeau-version > span { flex: 0 1 auto; }
}
/* ---------- ordinateur : dans le coin, comme une mention de chaîne ---------- */
@media (min-width: 900px) and (min-aspect-ratio: 21/20) and (min-height: 561px) {
  .bandeaux { gap: calc(8 * var(--u)); }
  #bandeau-reseau:not([hidden]) ~ #bandeau-version { display: flex; }
  .bandeaux .bandeau { padding: calc(8 * var(--u)) calc(11 * var(--u)) calc(9 * var(--u)); gap: calc(3 * var(--u)); border-radius: calc(12 * var(--u)); }
  #bandeau-demo { align-items: center; }
  #bandeau-demo .demo-titre { letter-spacing: 0.08em; line-height: inherit; }
  #bandeau-version { flex-direction: column; flex-wrap: nowrap; align-items: flex-start; gap: calc(3 * var(--u)); padding: calc(8 * var(--u)) calc(11 * var(--u)) calc(9 * var(--u)); }
  #bandeau-version > span { flex: none; align-self: auto; }
  #btn-recharger { padding: 0 calc(14 * var(--u)); letter-spacing: 0.08em; border-radius: 999px; }
}


/* ============================================================================
   3. LE MESSAGE BREF (#toast)
   ----------------------------------------------------------------------------
   Il s'affichait au bas de l'écran : sur la bulle du professeur, et, selon
   l'écran, sur la dernière réponse ou sur la case des 18 ans. Il s'affiche EN
   HAUT, sur la barre du titre, comme une notification : rien de ce qui se joue
   n'est dessous. Il laisse passer les clics (les boutons du haut restent à
   portée), et réserve la marge de sécurité des téléphones à encoche.
   app.js pose lui-même son fond (var(--erreur) ou var(--ok)) ; le reflet est
   dessiné entre ce fond et le texte (z-index: -1 : le message bref, en
   position fixe, est son propre plan). Posé sur le texte, il délavait la
   première ligne du message.
   ========================================================================== */
#toast {
  /* téléphone debout : une barre de la largeur du pupitre, posée sur toute la barre du haut */
  top: calc(4 * var(--u) + var(--sur-haut)); bottom: auto;
  display: flex; align-items: center; justify-content: center;
  width: min(calc(100vw - 16px - var(--sur-gauche) - var(--sur-droite)), calc(414 * var(--u))); max-width: none;
  min-height: calc(54 * var(--u));
  padding: calc(6 * var(--u)) calc(16 * var(--u)); border-radius: calc(16 * var(--u));
  line-height: 1.25; text-wrap: balance; overflow-wrap: anywhere;
  pointer-events: none;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.85), 0 calc(6 * var(--u)) calc(22 * var(--u)) rgba(0, 0, 0, 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.4);
  animation: par-dessus-bref 0.22s ease-out;
}
#toast::before {
  content: ''; position: absolute; z-index: -1; top: 0; right: 0; bottom: 0; left: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0) 70%);
}
@keyframes par-dessus-bref { from { opacity: 0; transform: translate(-50%, calc(-10 * var(--u))); } to { opacity: 1; transform: translate(-50%, 0); } }
@media (orientation: landscape) and (max-height: 560px) {
  /* téléphone couché : la barre du haut n'occupe que la moitié gauche (les cadrans sont à droite) */
  #toast {
    top: calc(3 * var(--u) + var(--sur-haut)); left: calc(8px + var(--sur-gauche));
    width: calc(50vw - 16px - var(--sur-gauche)); min-height: calc(44 * var(--u));
    transform: none; animation: none;
  }
}
@media (min-width: 900px) and (min-aspect-ratio: 21/20) and (min-height: 561px) {
  /* ordinateur : sur la plaque du titre, qu'il couvre en entier (pseudo de 20 caractères
     compris) ; une ou deux lignes s'arrêtent au-dessus des cadrans */
  #toast {
    top: calc(9 * var(--u) + var(--sur-haut));
    width: max-content; min-width: min(calc(540 * var(--u)), calc(100vw - 24px)); max-width: min(calc(100vw - 24px), calc(880 * var(--u)));
    min-height: calc(52 * var(--u));
    padding: calc(5 * var(--u)) calc(24 * var(--u));
  }
}


/* ============================================================================
   4. LES FENÊTRES (<dialog>)
   ----------------------------------------------------------------------------
   Menu, confirmation, notifications, « Nos règles ont évolué », documents
   légaux. Une carte de verre cerclée de métal, comme celle d'un voile : le
   cerclage et les quatre rivets sont des fonds de la fenêtre elle-même (ils
   ne défilent pas avec son contenu, au contraire d'un pseudo-élément).
   Sur téléphone, les boutons d'une fenêtre prennent toute sa largeur, l'un
   sous l'autre ; « Fermer » est en verre (le laiton est pour le geste attendu).
   ========================================================================== */
dialog {
  --rivet: radial-gradient(circle at 38% 34%, var(--metal-vif) 0 16%, var(--metal-clair) 32%, var(--metal-creux) 60%, rgba(0, 0, 0, 0.85) 70%, transparent 74%);
  border: max(1.5px, calc(2 * var(--u))) solid transparent;
  background-image:
    var(--rivet), var(--rivet), var(--rivet), var(--rivet),
    linear-gradient(118deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0) 24%),
    linear-gradient(180deg, rgb(var(--verre-haut)), rgb(var(--verre-bas))),
    var(--cerclage-metal);
  background-position:
    left calc(7 * var(--u)) top calc(7 * var(--u)), right calc(7 * var(--u)) top calc(7 * var(--u)),
    left calc(7 * var(--u)) bottom calc(7 * var(--u)), right calc(7 * var(--u)) bottom calc(7 * var(--u)),
    0 0, 0 0, 0 0;
  background-size:
    calc(8 * var(--u)) calc(8 * var(--u)), calc(8 * var(--u)) calc(8 * var(--u)),
    calc(8 * var(--u)) calc(8 * var(--u)), calc(8 * var(--u)) calc(8 * var(--u)),
    auto, auto, auto;
  background-repeat: no-repeat;
  background-origin: padding-box, padding-box, padding-box, padding-box, padding-box, padding-box, border-box;
  background-clip: padding-box, padding-box, padding-box, padding-box, padding-box, padding-box, border-box;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75), 0 calc(18 * var(--u)) calc(50 * var(--u)) rgba(0, 0, 0, 0.7), inset 0 0 calc(30 * var(--u)) rgba(0, 0, 0, 0.42);
  padding: calc(24 * var(--u)) calc(20 * var(--u)) calc(20 * var(--u));
  scrollbar-width: thin; scrollbar-color: var(--metal-sombre) transparent;
}
dialog[open] { animation: par-dessus-fenetre 0.18s ease-out; }
@keyframes par-dessus-fenetre { from { opacity: 0; transform: translateY(calc(8 * var(--u))); } to { opacity: 1; transform: none; } }

/* le titre : celui d'une carte de voile */
dialog h3 { font-size: calc(var(--taille-titre) * 0.74); letter-spacing: 0.12em; text-shadow: 0 0 calc(18 * var(--u)) rgba(var(--accent-rvb), 0.55); }
dialog > p { font-size: var(--taille-texte); line-height: 1.42; text-wrap: pretty; }
dialog > p.note { font-size: var(--taille-note); line-height: 1.4; }

/* « Fermer » : un bouton de verre, toute la largeur sur téléphone */
dialog .dialogue-fermer {
  align-self: stretch; margin-top: calc(2 * var(--u));
  font-weight: 700; color: var(--metal-vif); text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  background:
    linear-gradient(118deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0) 24%),
    linear-gradient(180deg, rgba(var(--verre-haut), 0.86), rgba(var(--verre-bas), 0.92));
  box-shadow:
    inset 0 0 0 max(1.2px, calc(1.5 * var(--u))) var(--metal-clair),
    0 0 0 1px rgba(0, 0, 0, 0.8),
    var(--socle-verre),
    inset 0 calc(2 * var(--u)) 0 rgba(255, 255, 255, 0.05);
}
/* une rangée de boutons, dans une fenêtre : en colonne sur téléphone */
dialog .dialogue-actions, dialog .barre-outils { flex-direction: column; flex-wrap: nowrap; align-items: stretch; align-self: stretch; margin-top: calc(4 * var(--u)); }

/* ---------- Le menu du joueur : des touches de verre à médaillon ---------- */
#dialogue-menu { gap: calc(10 * var(--u)); }
/* « Menu de <pseudo> » : un pseudo de 20 caractères tient sur sa ligne */
#menu-titre { font-size: max(16px, calc(var(--taille-titre) * 0.56)); letter-spacing: 0.05em; }
#dialogue-menu .menu-liste { gap: calc(7 * var(--u)); --medaillon: calc(29 * var(--u)); }
#dialogue-menu .menu-liste button {
  position: relative; justify-content: flex-start; text-align: left; text-transform: none;
  min-height: max(44px, calc(46 * var(--u)));
  padding: calc(5 * var(--u)) calc(12 * var(--u)) calc(5 * var(--u)) calc(var(--medaillon) + 24 * var(--u));
  border-radius: calc(13 * var(--u));
  font-size: max(16px, calc(16 * var(--u))); letter-spacing: 0.02em; color: var(--texte);
  --pied: calc(3 * var(--u)); --course: calc(2 * var(--u));
  box-shadow:
    inset 0 0 0 max(1.2px, calc(1.5 * var(--u))) var(--metal-clair),
    0 0 0 1px rgba(0, 0, 0, 0.8),
    var(--socle-verre),
    inset 0 1px 0 rgba(255, 255, 255, 0.07);
}
/* le médaillon de laiton… */
#dialogue-menu .menu-liste button::before {
  content: ''; position: absolute; left: calc(12 * var(--u)); top: 50%;
  width: var(--medaillon); height: var(--medaillon); margin-top: calc(var(--medaillon) / -2); border-radius: 50%;
  background: linear-gradient(160deg, var(--metal-vif), var(--metal-clair) 38%, var(--metal-sombre) 78%, var(--metal-creux));
  box-shadow: inset 0 -2px 3px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(14, 8, 2, 0.8);
}
/* … et son pictogramme, découpé dans la couleur du texte posé sur le métal */
#dialogue-menu .menu-liste button::after {
  content: ''; position: absolute; left: calc(12 * var(--u)); top: 50%;
  width: var(--medaillon); height: var(--medaillon); margin-top: calc(var(--medaillon) / -2);
  background: var(--sur-metal);
  -webkit-mask: var(--picto) center / 58% 58% no-repeat;
  mask: var(--picto) center / 58% 58% no-repeat;
}
#dialogue-menu .menu-liste button.menu-danger { color: var(--alerte); }
/* les huit pictogrammes (dessins de la maquette, écrits dans la feuille : aucune image à charger) */
#dialogue-menu [data-menu="stats"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 19.5v-7M12 19.5v-15M18.5 19.5v-10'/%3E%3C/svg%3E"); }
#dialogue-menu [data-menu="profil"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8.05' r='4.1'/%3E%3Cpath d='M4.8 20.05c1.7-3.9 4.8-5.3 7.2-5.3s5.5 1.4 7.2 5.3'/%3E%3C/svg%3E"); }
#dialogue-menu [data-menu="tutoriel"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 6.8c-2.2-1.5-5-1.8-8-1v12.4c3-.8 5.8-.5 8 1 2.2-1.5 5-1.8 8-1V5.8c-3-.8-5.8-.5-8 1zM12 6.8v12.4'/%3E%3C/svg%3E"); }
#dialogue-menu [data-menu="regles"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 3.8h6.8l3.7 3.7v12.7H7zM13.5 3.8v4h4M9.8 12.5h5M9.8 16h5'/%3E%3C/svg%3E"); }
#dialogue-menu [data-menu="son"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.8 9.4h3.6l5.1-4v13.2l-5.1-4H3.8z'/%3E%3Cpath d='M16 9.6a3.6 3.6 0 0 1 0 4.8M18.7 7a7.2 7.2 0 0 1 0 10'/%3E%3C/svg%3E"); }
#dialogue-menu [data-menu="notifications"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.3 16.8v-5.3a5.7 5.7 0 0 1 11.4 0v5.3l1.6 2.2H4.7zM10 20.2a2 2 0 0 0 4 0'/%3E%3C/svg%3E"); }
#dialogue-menu [data-menu="admin"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.6l6.8 2.7v5.2c0 4.4-2.8 7.5-6.8 9-4-1.5-6.8-4.6-6.8-9V6.3z'/%3E%3Cpath d='M9.2 12.2l2 2 3.7-4'/%3E%3C/svg%3E"); }
#dialogue-menu [data-menu="deconnexion"] { --picto: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4.4v7'/%3E%3Cpath d='M7.75 7.26a6.9 6.9 0 1 0 8.5 0'/%3E%3C/svg%3E"); }

/* ---------- La boîte de confirmation ---------- */
/* le geste qui ne se défait pas, en pleine partie : en verre cerclé de rouge (app.js lui donne .bouton-danger) */
#confirmer-ok.bouton-danger {
  font-weight: 700; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  background:
    linear-gradient(118deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0) 24%),
    linear-gradient(180deg, rgba(var(--verre-haut), 0.86), rgba(var(--verre-bas), 0.92));
}

/* ---------- La fenêtre des notifications ---------- */
/* ses boutons rejoignent la colonne de la fenêtre : quand aucun n'est montré, leur rangée ne laisse aucun vide */
#dialogue-notifications .menu-liste { display: contents; }
#dialogue-notifications .menu-liste button { align-self: stretch; width: auto; }
/* le geste attendu, en laiton */
#notifications-activer {
  font-weight: 900; color: var(--sur-metal); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.35);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  background: var(--laiton-touche);
  box-shadow: var(--ombre-laiton);
}
/* la réponse à un geste (notifications.js lui donne .succes ou .erreur) */
#notifications-retour { padding: calc(8 * var(--u)) calc(12 * var(--u)); border-radius: calc(10 * var(--u)); text-align: left; }
#notifications-retour.succes { color: var(--ok-vif); background: rgba(var(--ok-rvb), 0.14); box-shadow: inset 0 0 0 max(1px, calc(1.3 * var(--u))) rgba(var(--ok-rvb), 0.75); }
#notifications-retour.erreur { color: var(--texte); background: rgba(var(--alerte-rvb), 0.16); box-shadow: inset 0 0 0 max(1px, calc(1.3 * var(--u))) rgba(var(--alerte-rvb), 0.8); }

/* ---------- « Nos règles ont évolué » ---------- */
/* chaque document à relire : une ligne, séparée de la suivante par un filet */
#consentement-liste { list-style: none; padding: 0; gap: 0; align-self: stretch; text-align: left; }
#consentement-liste li {
  padding: calc(11 * var(--u)) calc(4 * var(--u));
  font-size: var(--taille-texte); line-height: 1.35; color: var(--texte-doux);
}
#consentement-liste li + li { border-top: 1px solid rgba(var(--metal-clair-rvb), 0.18); }
/* le nom du document se touche : sa zone déborde de sa ligne, sans la grandir */
#consentement-liste a { padding: calc(11 * var(--u)) 0; font-weight: 600; }
#dialogue-consentement .case { align-self: stretch; }
/* le message affiché au moment où la fenêtre s'est ouverte (app.js pose son fond, celui du message bref) */
#consentement-contexte { align-self: stretch; color: #170b07; font-size: var(--taille-texte); }

/* ---------- Le lecteur des documents légaux ---------- */
/* très longs, ils défilent dans leur cadre ; les onglets en tête et « Fermer »
   au pied ne bougent pas, même sur le plus petit téléphone */
#dialogue-legal { gap: calc(9 * var(--u)); padding: calc(20 * var(--u)) calc(14 * var(--u)) calc(16 * var(--u)); }
/* quatre onglets, deux par rangée sur téléphone : en police courante, « Confidentialité » y tient à 16 px */
#dialogue-legal .legal-onglets { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
#dialogue-legal .legal-onglets button {
  white-space: normal; line-height: 1.1; padding: 0 calc(4 * var(--u));
  font-family: var(--police-texte); font-weight: 600; font-size: var(--taille-texte); text-transform: none; letter-spacing: 0;
}
#dialogue-legal .legal-onglets button.actif { font-weight: 700; }
#legal-titre { font-size: max(16px, calc(var(--taille-titre) * 0.56)); letter-spacing: 0.06em; }
#legal-contenu { scrollbar-width: thin; scrollbar-color: var(--metal-sombre) transparent; overscroll-behavior: contain; }
/* au clavier, le texte reçoit le focus pour défiler aux flèches : le même anneau que les boutons */
#legal-contenu:focus-visible { outline: var(--anneau-clavier); outline-offset: 2px; }

@media (orientation: landscape) and (max-height: 560px) {
  /* téléphone couché : la hauteur manque, les fenêtres s'élargissent et leurs boutons se rangent côte à côte */
  dialog { width: min(calc(100vw - 24px), calc(680 * var(--u))); padding: calc(14 * var(--u)) calc(20 * var(--u)) calc(12 * var(--u)); }
  #dialogue-notifications { width: min(calc(100vw - 24px), calc(780 * var(--u))); }
  #dialogue-notifications .menu-liste { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; gap: calc(8 * var(--u)); align-self: stretch; }
  #dialogue-notifications .menu-liste button { flex: 1 1 calc(240 * var(--u)); }
  dialog[open] { gap: calc(8 * var(--u)); }
  dialog .dialogue-actions, dialog .barre-outils { flex-direction: row; flex-wrap: wrap; align-items: center; align-self: center; }
  dialog .dialogue-fermer { align-self: center; }
  #dialogue-menu { width: min(calc(100vw - 24px), calc(720 * var(--u))); }
  #dialogue-menu .menu-liste { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(6 * var(--u)) calc(10 * var(--u)); }
  #dialogue-legal { padding: calc(10 * var(--u)) calc(14 * var(--u)); gap: calc(6 * var(--u)); }
  #dialogue-legal .legal-onglets { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* « Nos règles ont évolué » dans son état le plus chargé (trois documents, et le
     message redit en tête) : resserrée, pour que « Plus tard » reste entier à 812 x 375.
     Sur un écran plus bas encore, la fenêtre défile à l'intérieur (le socle). */
  #dialogue-consentement { padding-top: calc(10 * var(--u)); padding-bottom: calc(9 * var(--u)); }
  #dialogue-consentement[open] { gap: calc(5 * var(--u)); }
  #dialogue-consentement .barre-outils { margin-top: 0; }
  #consentement-contexte { padding: calc(4 * var(--u)) calc(12 * var(--u)); }
}
@media (min-width: 900px) and (min-aspect-ratio: 21/20) and (min-height: 561px) {
  dialog { width: min(calc(100vw - 24px), calc(600 * var(--u))); padding: calc(32 * var(--u)) calc(44 * var(--u)) calc(30 * var(--u)); }
  dialog[open] { gap: calc(14 * var(--u)); }
  dialog .dialogue-actions, dialog .barre-outils { flex-direction: row; flex-wrap: wrap; align-items: center; align-self: center; gap: calc(14 * var(--u)); }
  dialog .dialogue-fermer { align-self: center; }
  /* le menu : deux colonnes de touches */
  #dialogue-menu { width: min(calc(100vw - 24px), calc(720 * var(--u))); gap: calc(14 * var(--u)); }
  #menu-titre { font-size: calc(var(--taille-titre) * 0.6); letter-spacing: 0.06em; }
  #dialogue-menu .menu-liste { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(12 * var(--u)); --medaillon: calc(36 * var(--u)); }
  #dialogue-menu .menu-liste button { min-height: calc(62 * var(--u)); padding-left: calc(var(--medaillon) + 34 * var(--u)); font-size: calc(18 * var(--u)); border-radius: calc(15 * var(--u)); }
  #dialogue-menu .menu-liste button::before, #dialogue-menu .menu-liste button::after { left: calc(18 * var(--u)); }
  #dialogue-notifications .menu-liste button { align-self: center; }
  #dialogue-consentement { width: min(calc(100vw - 24px), calc(680 * var(--u))); }
  #consentement-liste li { padding: calc(10 * var(--u)) calc(10 * var(--u)); }
  #consentement-liste a { padding: calc(10 * var(--u)) 0; }
  #dialogue-legal { width: min(calc(100vw - 24px), calc(820 * var(--u))); padding: calc(26 * var(--u)) calc(32 * var(--u)) calc(24 * var(--u)); gap: calc(12 * var(--u)); }
  #dialogue-legal .legal-onglets { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  #dialogue-legal .legal-onglets button {
    font-family: var(--police-plateau); font-weight: 700; font-size: max(12px, calc(15 * var(--u))); text-transform: uppercase; letter-spacing: 0.05em;
  }
  #dialogue-legal .legal-onglets button.actif { font-weight: 900; }
  #legal-titre { font-size: calc(var(--taille-titre) * 0.62); letter-spacing: 0.1em; }
}


/* ============================================================================
   5. LES LIENS LÉGAUX DU PIED (#liens-legaux)
   ----------------------------------------------------------------------------
   Hors partie seulement (le socle les retire pendant la partie et sur l'écran
   de fin) : une ligne au-dessus du professeur sur téléphone, une petite
   colonne dans le coin en bas à droite sur ordinateur. Les mêmes documents se
   lisent à tout moment par le menu (« Règlement et documents »).
   ========================================================================== */
.pied a:focus-visible { outline: var(--anneau-clavier); outline-offset: 1px; border-radius: 3px; }
