/* =========================================================
   STUDIO CLAP — feuille de style commune
   Style "autocollant" : contours épais, ombres pleines,
   gros boutons, couleurs franches. Pensé pour des CM1.
   ========================================================= */

@import url('polices.css');
@import url('tokens.css'); /* palette, rôles, échelles et calques nommés (--z-…) : les anciens noms (--ink, --world…) y sont des alias */

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-body);
  font-size: 20px;
  line-height: 1.45;
  color: var(--ink);
  background-color: var(--paper);
  background-image: radial-gradient(circle at 1px 1px, rgba(29,27,47,.09) 1.5px, transparent 0);
  background-size: 26px 26px;
  overflow-x: hidden;
}
h1, h2, h3, .title { font-family: var(--font-title); line-height: 1.1; margin: 0 0 .4em; letter-spacing: .2px; }
h1 { font-size: clamp(32px, 5vw, 52px); }
h2 { font-size: clamp(26px, 3.6vw, 38px); }
h3 { font-size: 26px; }
p { margin: 0 0 .6em; }
img, svg { max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; }
.hidden, [hidden] { display: none !important; }
.center { text-align: center; }
.muted { color: var(--muted); }
.big-emoji { font-size: 72px; line-height: 1; display: inline-block; }
.wrap { width: min(1180px, 100% - 32px); margin: 0 auto; }

/* ---------- Focus (souris, clavier, manette) ---------- */
:focus { outline: none; }
:focus-visible, .pad-focus {
  outline: 6px solid var(--focus) !important;
  outline-offset: 4px;
  z-index: var(--z-page);
}

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45em;
  min-height: 60px; padding: 10px 24px;
  font-family: var(--font-title); font-weight: 600; font-size: 24px;
  color: var(--ink); background: var(--card);
  border: var(--border); border-radius: 999px;
  box-shadow: var(--shadow-sm);
  cursor: pointer; user-select: none; text-decoration: none;
  transition: transform .08s ease, box-shadow .08s ease, background .15s;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 6px 0 var(--line); }
.btn:active, .btn.is-pressed { transform: translateY(4px); box-shadow: 0 0 0 var(--line); }
.btn[disabled] { opacity: .45; pointer-events: none; }
/* boutons pleins : texte blanc sur une couleur assombrie, toujours lisible (au moins 4,5:1 sur toutes les couleurs de monde) */
.btn-primary, .btn-world, .btn-ok { background: var(--accent-plein); color: var(--sur-accent); }
.btn-primary { --accent-plein: var(--brand-plein); }
.btn-ok { --accent-plein: var(--ok-plein); }
.btn-yellow { background: var(--star); }
.btn-big { min-height: 84px; font-size: 32px; padding: 14px 40px; }
.btn-small { min-height: 46px; font-size: 19px; padding: 6px 16px; }
.btn-icon { width: 60px; min-width: 60px; padding: 0; font-size: 28px; }
.btn-icon.btn-small { width: 46px; min-width: 46px; font-size: 22px; }

/* 🔊 : une cible de 60 px, comme tous les boutons (règle maison) */
.say-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 60px; height: 60px; flex: 0 0 60px; padding: 0;
  font-size: 28px; border: var(--border); border-radius: 50%;
  background: var(--star); box-shadow: var(--shadow-sm); cursor: pointer;
}
.say-btn:active { transform: translateY(3px); box-shadow: none; }
.say-btn.speaking { animation: pulse 1s infinite; }

/* ---------- Barre du haut ---------- */
.topbar {
  position: sticky; top: 0; z-index: var(--z-barre);
  display: flex; align-items: center; gap: 14px;
  padding: 10px 16px;
  background: var(--card); border-bottom: var(--border);
}
.topbar .tb-title { font-family: var(--font-title); font-weight: 700; font-size: 26px; flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }
.topbar .tb-title span.t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .world-dot { width: 44px; height: 44px; border-radius: 12px; border: var(--border); background: var(--world); display: grid; place-items: center; font-size: 24px; flex: 0 0 auto; }
.player-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 14px 4px 4px; border: var(--border); border-radius: 999px;
  background: var(--paper-2); font-weight: 700; text-decoration: none; cursor: pointer;
}
.player-chip .av { width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; font-size: 30px; background: #fff; border: var(--border); }
.player-chip .lv { font-size: 15px; color: var(--muted); font-weight: 500; line-height: 1.1; }
/* La pastille est un bouton qui ouvre le menu « Moi » (coeur#23) */
button.player-chip { font: inherit; color: inherit; text-align: left; }
.player-chip .moi-fleche { font-size: 18px; margin-left: -2px; }
.moi-menu { position: fixed; z-index: var(--z-menu); min-width: 250px; max-width: calc(100vw - 16px); display: flex; flex-direction: column; gap: 4px; padding: 8px;
  background: var(--card); border: var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow); }
.moi-entree { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 6px 12px; border: 3px solid transparent; border-radius: 12px;
  background: none; color: var(--ink); font: inherit; font-weight: 700; font-size: 19px; text-align: left; text-decoration: none; cursor: pointer; }
.moi-entree .e { font-size: 26px; width: 32px; text-align: center; flex: 0 0 auto; }
.moi-entree:hover, .moi-entree:focus-visible { background: var(--paper-2); border-color: var(--line); }
.moi-adultes { align-self: flex-end; margin-top: 2px; padding: 6px 10px; border-radius: 10px; color: var(--muted); font-size: 15px; font-weight: 600; text-decoration: none; min-height: 32px; display: inline-flex; align-items: center; gap: .3em; } /* (gap : inline-flex avale l'espace après l'émoji « 🔐 Adultes ») */
.moi-adultes:hover, .moi-adultes:focus-visible { background: var(--paper-2); color: var(--ink); text-decoration: underline; }
/* PAS DISPONIBLE POUR LE MOMENT (01/11/2026) : une entrée VISIBLE mais GRISÉE, ni lien ni clic. Aujourd'hui « 🤖 Mon assistant » quand
   A.ASSISTANT_EN_PAUSE (js/atelier.js) : menu « Moi », tuile de l'accueil (index.html), menu des adultes (js/adultes/coquille.js).
   L'élément n'a pas de href et porte aria-disabled="true" ; le pointeur passe au travers (ni survol, ni clic, curseur normal).
   « Bientôt » (.indispo-mot ; .en-test sur la tuile de l'accueil) dit pourquoi. (!important : .tile, .moi-entree et le menu des adultes
   posent cursor: pointer, avec un poids égal ou plus fort.) */
.indispo { pointer-events: none !important; cursor: default !important; filter: grayscale(1); opacity: .6; }
.indispo-mot { display: inline-block; margin-left: auto; padding: 1px 10px; border: 2px solid currentColor; border-radius: 999px;
  font-family: var(--font-title); font-size: 15px; font-weight: 700; line-height: 1.3; white-space: nowrap; }
.stars-count { font-family: var(--font-title); font-weight: 700; font-size: 24px; white-space: nowrap; }
/* BARRE v2 (étape 5, 30/10) : ⬅ · logo (la vague) · fil d'Ariane · ⭐ · 🙋 · ⚙️ · pastille « Moi » (A.barre, js/atelier.js).
   ⬅ est caché (attribut hidden) quand il mènerait au même endroit que le logo. */
.topbar [hidden] { display: none !important; }
.topbar .tb-retour, .topbar .tb-logo, .topbar .btn-main-barre { flex: 0 0 auto; }
.topbar .tb-logo { background: #fff; } /* la vague sur une pastille blanche, comme sur l'accueil */
.topbar .tb-logo svg { display: block; width: 40px; height: 40px; pointer-events: none; }
/* Bilan, commande « Formaliser » (body.b-commande, js/bilan.js) : aucune sortie par la barre. css/bilan.css cache ⬅ ; le logo, venu
   avec la barre v2, est caché ici (sans lui, l'élève pouvait quitter le bilan imposé vers l'accueil). */
body.b-commande .topbar .tb-logo { display: none; }
/* Le fil d'Ariane remplace le titre : les étages du haut sont des liens soulignés (cible de 44 px), le dernier est le titre de la page.
   Les étages du milieu cèdent leur place d'abord (« … ») ; sous 700 px, seul le dernier étage reste (⬅ et le logo suffisent). */
.tb-ariane { flex: 1; min-width: 0; }
.tb-ariane ol { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: 2px; min-width: 0; }
.tb-ariane li { display: flex; align-items: center; min-width: 0; }
.tb-ariane .ta-etage { flex: 0 6 auto; gap: 2px; } /* (ils rétrécissent 6 fois plus vite que le dernier) */
.tb-ariane .ta-ici { flex: 0 1 auto; gap: 10px; min-width: 3em; }
.tb-ariane .ta-lien { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; min-width: 2.4em; max-width: 13em; padding: 0 6px; border-radius: 12px; color: inherit; font-size: 19px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }
.tb-ariane .ta-mot { overflow: hidden; text-overflow: ellipsis; }
.tb-ariane .ta-lien:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
.tb-ariane .ta-sep { font-size: 24px; line-height: 1; padding: 0 2px; opacity: .85; }
/* Peu de place pour le fil (bouton « Lever la main » écrit, prénom long) : les étages du haut ne gardent que leur émoji (leur nom reste dans
   aria-label et title), le titre de la page garde la place. */
.topbar:not(.menu-haut) .tb-title { container-type: inline-size; } /* (pas l'accueil : son logo .mh-logo porte aussi .tb-title) */
@container (max-width: 620px) {
  .tb-ariane .ta-mot { display: none; }
  .tb-ariane .ta-lien { justify-content: center; min-width: 44px; padding: 0 4px; font-size: 22px; }
  .tb-ariane .ta-etage { flex-shrink: 0; } /* (un étage réduit à son émoji ne rétrécit plus : avant, il tombait à 0 px et son lien passait sous la pastille) */
}
/* Encore moins de place (environ 1000 à 1150 px de large avec « Lever la main » écrit et un prénom) : seul le dernier étage reste, comme
   sous 700 px. Ses liens ne sont plus ni invisibles ni touchables par erreur ; ⬅ et le logo mènent toujours aux étages du haut. */
@container (max-width: 360px) { .tb-ariane .ta-etage { display: none; } }
@media (max-width: 700px) { .tb-ariane .ta-etage { display: none; } }
/* « 🙋 Lever la main » dans la barre : l'émoji seul (rond de 60 px), avec son nom écrit au-dessus de 1000 px */
.btn-main-barre { gap: 8px; }
.btn-main-barre .bm-e { font-size: 30px; line-height: 1; }
.btn-main-barre .bm-t { display: none; white-space: nowrap; }
@media (min-width: 1001px) {
  .topbar .btn-main-barre { width: auto; padding: 0 18px 0 12px; font-size: 19px; }
  .topbar .btn-main-barre .bm-t { display: inline; }
}
.topbar .btn.btn-main-barre.levee { animation: none; }
.topbar .btn.btn-main-barre.levee .bm-e { display: inline-block; animation: mainLevee 1s ease-in-out infinite alternate; }
.topbar .btn.btn-main-barre.vue { --bg: var(--ok-bg, #d8f5e3); background: var(--ok-bg, #d8f5e3); }
.topbar .btn.btn-main-barre.vue .bm-e { animation: none; }
/* « 🕘 Mon historique » (31/10, A.historique) : le bouton « 🕘 12 ⭐ » de la barre (même hauteur que ⚙️, juste après « ⭐ total ») et sa fenêtre.
   Caché sous 480 px (comme « ⭐ total » : l'entrée du menu « Moi » reste), au tableau, pendant une activité obligatoire (le badge
   « 🔒 À finir » prend la place des étoiles), pendant le bilan imposé par le professeur, et quand la barre n'a plus la place (histo-sans-place,
   posée par js/atelier.js : jamais de défilement de côté). */
.topbar .btn-histo { flex: 0 0 auto; height: 60px; min-height: 60px; padding: 0 12px; gap: .3em; font-size: 21px; line-height: 1; white-space: nowrap; }
.topbar.ob-lie .btn-histo, body.b-commande .topbar .btn-histo, .topbar .btn-histo.histo-sans-place { display: none; } /* (bilan imposé « Formaliser » : rien d’autre à ouvrir) */
.modal.histo-modal { width: min(760px, 100%); text-align: left; }
.histo-modal .histo-titre { margin-bottom: 14px; }
.histo-qui { margin: 0 0 12px; }
.histo-qui-t { display: flex; align-items: center; gap: 12px; margin: 0 0 8px; font-weight: 700; }
.histo-qui-l, .histo-periodes { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.histo-periodes { margin: 0 0 14px; }
.histo-membre .avt, .histo-membre .av-simple { flex: 0 0 auto; }
/* bouton choisi : plein (couleur du monde assombrie, ≥ 4,5:1), et une coche (pas seulement la couleur) */
.histo-modal .btn[aria-pressed="true"] { --bg: var(--accent-plein); --fg: var(--sur-accent); background: var(--accent-plein); color: var(--sur-accent); }
.histo-modal .btn[aria-pressed="true"]::before { content: "✓" / ""; font-weight: 900; }
.histo-bulle { margin: 0 0 12px; }
.histo-encours { display: flex; align-items: center; gap: 12px; margin: 0 0 12px; padding: 6px 6px 6px 14px; border: 3px dashed var(--line); border-radius: 16px; font-weight: 700; }
.histo-encours > span { flex: 1; min-width: 0; overflow-wrap: break-word; }
.histo-resume-bloc { display: flex; align-items: center; gap: 12px; margin: 0 0 4px; }
.histo-resume { flex: 1; min-width: 0; margin: 0; font-family: var(--font-title); font-size: 26px; font-weight: 700; line-height: 1.2; overflow-wrap: break-word; }
.histo-petit { margin: 0 0 12px; font-size: 18px; }
.histo[aria-busy="true"] .histo-zone, .histo[aria-busy="true"] .histo-resume-bloc { opacity: .55; }
.histo-zone { margin-top: 10px; }
.histo-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.histo-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; padding: 8px 8px 8px 14px; border: 2px solid var(--line); border-radius: 16px; background: var(--paper-2); }
.histo-h { flex: 0 0 auto; min-width: 4.2em; font-family: var(--font-title); font-weight: 700; font-variant-numeric: tabular-nums; }
.histo-quoi { flex: 1 1 14em; min-width: 0; display: flex; flex-direction: column; gap: 2px; overflow-wrap: anywhere; }
.histo-nom { font-weight: 700; }
.histo-ou { color: var(--muted); font-size: 17px; }
.histo-detail { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 14px; font-size: 18px; }
.histo-ligne > .say-btn { margin-left: auto; }
.histo-liste .t-stars { font-size: 24px; letter-spacing: 2px; line-height: 1; }
.histo-liste .t-stars span { color: #fff; -webkit-text-stroke: 1.6px #6f6b85; paint-order: stroke fill; }
.histo-liste .t-stars span.on { color: #f5a623; -webkit-text-stroke: 1.6px #8a6100; }
.histo-fin { padding: 4px 14px; }
.histo-vide { display: flex; align-items: center; gap: 12px; margin: 0; }
.histo-vide > span { flex: 1; min-width: 0; }
.histo-plus { margin-top: 12px; }
.histo-adultes { margin: 14px 0 0; font-size: 16px; }
.histo-modal .btn { max-width: 100%; }
/* sur un téléphone : la bulle, les 🔊 (48 px, comme dans « Mon espace ») et les marges rétrécissent, le texte garde sa largeur */
@media (max-width: 480px) {
  .modal.histo-modal { padding: 20px 12px; }
  .histo-modal .bubble { gap: 8px; padding: 10px 12px; font-size: 20px; }
  .histo-modal .say-btn { width: 48px; height: 48px; flex-basis: 48px; font-size: 22px; }
  .histo-resume { font-size: 22px; }
  .histo-modal .btn-small { padding: 6px 12px; }
  .histo-ligne { gap: 4px 10px; padding: 8px 8px 8px 10px; }
}

/* ---------- Cartes et tuiles ---------- */
.card {
  background: var(--card); border: var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 22px;
}
.grid { display: grid; gap: 22px; }
.grid-tiles { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.tile {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; min-height: 210px; padding: 20px 14px 18px;
  text-align: center; text-decoration: none; color: var(--ink);
  background: var(--card); border: var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); cursor: pointer;
  transition: transform .1s ease, box-shadow .1s ease;
}
.tile:hover { transform: translateY(-4px) rotate(-.5deg); box-shadow: 0 10px 0 var(--line); }
.tile:active { transform: translateY(4px); box-shadow: 0 2px 0 var(--line); }
.tile .t-emoji { font-size: 76px; line-height: 1; filter: drop-shadow(0 4px 0 rgba(0,0,0,.12)); }
.tile .t-name { font-family: var(--font-title); font-weight: 700; font-size: 27px; line-height: 1.1; }
.tile .t-sub { font-size: 16px; color: var(--muted); }
.tile .t-band { position: absolute; inset: 0 0 auto 0; height: 16px; border-radius: 19px 19px 0 0; background: var(--c, var(--world)); border-bottom: var(--border); }
.tile .t-stars { font-size: 20px; letter-spacing: 2px; }
.tile .t-tags { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px; border: 2px solid var(--line); border-radius: 999px; font-size: 14px; font-weight: 700; background: var(--paper-2); }
/* Activité terminée : bien visible (cadre vert, tampon « ✔ Fait », étoiles dorées) ; 3 étoiles = tampon doré « Parfait » */
.tile.done { background: linear-gradient(180deg, #f2fff6 55%, #c9f2d8); border-color: var(--ok); box-shadow: 0 6px 0 var(--ok); }
.tile.done:hover { box-shadow: 0 10px 0 var(--ok); }
.tile.done::after {
  content: '✔ Fait'; position: absolute; top: 24px; left: -6px; z-index: var(--z-page);
  padding: 3px 12px 3px 10px; border: 3px solid var(--line); border-radius: 12px;
  background: var(--ok-plein); color: #fff; font-family: var(--font-title); font-weight: 700; font-size: 17px;
  transform: rotate(-8deg); box-shadow: 0 3px 0 var(--line);
}
.tile.done.e3 { background: linear-gradient(180deg, #fffbea 55%, #ffe7a3); border-color: #e0a100; box-shadow: 0 6px 0 #e0a100; }
.tile.done.e3::after { content: '🏆 Parfait'; background: var(--star); color: var(--ink); }
/* étoile pas encore gagnée : blanche avec un contour foncé (5:1), on la voit sur toutes les tuiles ;
   étoile gagnée : pleine, dorée, avec un contour brun. La différence se voit sans la couleur (vide / pleine). */
.tile .t-stars span { color: #fff; -webkit-text-stroke: 1.6px #6f6b85; paint-order: stroke fill; }
.tile .t-stars span.on { color: #f5a623; -webkit-text-stroke: 1.6px #8a6100; text-shadow: 0 2px 0 rgba(0, 0, 0, .18); }
.tile.done .t-stars { font-size: 28px; }
.tile.done .t-emoji { filter: drop-shadow(0 4px 0 rgba(0,0,0,.12)) saturate(1.15); }
/* Compteur « ✅ 4 / 7 faites » d'un monde ou d'une rubrique */
.compte-faites { display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px; border: var(--border); border-radius: 999px; background: #fff;
  font-family: var(--font-title); font-weight: 700; font-size: 18px; white-space: nowrap; }
.compte-faites .barre { width: 90px; height: 12px; border: 2px solid var(--line); border-radius: 8px; overflow: hidden; background: #eee; }
.compte-faites .barre i { display: block; height: 100%; background: var(--ok); }
.compte-faites.tout { background: var(--ok-bg); border-color: var(--ok); }
.tile .ribbon { position: absolute; top: 22px; right: -8px; background: var(--star); border: var(--border); border-radius: 10px; padding: 2px 10px; font-size: 15px; font-weight: 700; transform: rotate(6deg); }

/* ---------- Bulle / consigne ---------- */
.bubble {
  position: relative; display: flex; align-items: center; gap: 14px;
  background: #fff; border: var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: 14px 18px; font-size: 24px; font-weight: 500;
}
/* (coeur#50, 30/10) À toutes les largeurs : un mot plus long que la bulle (« cyberharcèlement » dans la colonne du coach du tableau, 1024 × 768)
   passe à la ligne au lieu d'être coupé à droite. overflow-wrap: break-word ne change pas la largeur des bulles : seul un mot qui ne tient pas se coupe. */
.bubble .b-text { flex: 1; min-width: 0; overflow-wrap: break-word; }

/* ---------- Écran d'intro d'activité ---------- */
.intro {
  max-width: 760px; margin: 40px auto; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
}
.intro .i-emoji { font-size: 120px; line-height: 1; animation: bob 2.4s ease-in-out infinite; }
.intro .i-metier { font-size: 18px; color: var(--muted); }
.intro .bubble { text-align: left; max-width: 100%; } /* (coeur#46 : zoomée par « Aa », la bulle restait plus large que la page à 375 px) */
.intro .i-gear { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }

.stage { width: min(1180px, 100% - 32px); margin: 24px auto 60px; }
.stage-head { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; flex-wrap: wrap; }
.stage-head .bubble { flex: 1; min-width: min(260px, 100%); } /* (coeur#46 : 260 px zoomés par « Aa » faisaient 364 px dans une page de 343 px) */

/* ---------- Progression ---------- */
.dots { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.dots i { width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--line); background: #fff; display: block; }
.dots i.ok { background: var(--ok); }
.dots i.ko { background: var(--star); }
.dots i.cur { background: var(--world); transform: scale(1.25); }

.xpbar { position: relative; height: 22px; border: var(--border); border-radius: 999px; background: #fff; overflow: hidden; min-width: 140px; }
.xpbar > b { position: absolute; inset: 0 auto 0 0; background: linear-gradient(90deg, var(--star), #ff9f1c); border-right: 3px solid var(--line); transition: width .8s cubic-bezier(.2,.9,.3,1.2); }

/* ---------- Moteur QUIZ ---------- */
.q-visual {
  display: grid; place-items: center; min-height: 220px; margin: 0 auto 20px;
  background: #fff; border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow-sm);
  padding: 16px; font-size: 120px; line-height: 1; max-width: 760px;
}
.q-visual svg { width: 100%; height: auto; max-height: 340px; display: block; }
.q-visual > .vis { display: block; width: 100%; text-align: center; }
.hs-wrap > .vis { display: block; width: 100%; }
.hs-wrap > .vis > svg { display: block; width: 100%; height: auto; }
.choices { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.choice {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  min-height: 120px; padding: 16px; text-align: center;
  font-family: var(--font-title); font-weight: 600; font-size: 25px;
  background: #fff; border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
  cursor: pointer; transition: transform .08s, box-shadow .08s, background .2s;
}
.choice:hover { transform: translateY(-3px); box-shadow: 0 9px 0 var(--line); }
.choice:active { transform: translateY(4px); box-shadow: 0 2px 0 var(--line); }
.choice .c-visual { font-size: 64px; line-height: 1; }
.choice .c-visual svg { width: 150px; height: auto; }
.choice.is-ok { background: var(--ok-bg); border-color: var(--ok); animation: pop .4s; }
.choice.is-ko { background: var(--ko-bg); animation: shake .45s; }
.choice.is-dim { opacity: .45; }
.explain { margin-top: 18px; }
.explain .bubble { background: var(--ok-bg); }

/* ---------- Moteur TRI (sort) ---------- */
.sort-item {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  max-width: 560px; margin: 0 auto 26px; padding: 22px;
  background: #fff; border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
  text-align: center; font-family: var(--font-title); font-size: 30px; font-weight: 600;
  animation: dropIn .45s cubic-bezier(.2,.9,.3,1.3);
}
.sort-item .s-visual { font-size: 96px; line-height: 1; }
.sort-item .s-visual svg { width: 260px; height: auto; }
.bins { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.bin {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  min-height: 150px; padding: 16px;
  border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
  background: var(--c, #fff); color: var(--ink); cursor: pointer;
  font-family: var(--font-title); font-weight: 700; font-size: 27px;
}
.bin .b-emoji { font-size: 58px; line-height: 1; }
.bin:active { transform: translateY(4px); box-shadow: 0 2px 0 var(--line); }
.bin.is-ok { animation: pop .4s; outline: 6px solid var(--ok); }
.bin.is-ko { animation: shake .45s; }

/* ---------- Moteur ORDRE ---------- */
.slots { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin-bottom: 26px; }
.slot {
  position: relative; min-height: 150px; border: 3px dashed var(--line); border-radius: var(--radius);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: rgba(255,255,255,.6); padding: 10px; text-align: center; font-weight: 600;
}
.slot .n { position: absolute; top: -16px; left: -12px; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; background: var(--accent-plein); color: var(--sur-accent); border: var(--border); font-family: var(--font-title); font-weight: 700; }
.slot.filled { border-style: solid; background: #fff; box-shadow: var(--shadow-sm); animation: pop .35s; }
.slot.next { border-color: var(--world); background: var(--world-soft); }
.pool { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.card-pick {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  min-height: 140px; padding: 12px; text-align: center; font-weight: 600; font-size: 19px;
  background: #fff; border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow);
  cursor: pointer;
}
.card-pick .p-visual, .slot .p-visual { font-size: 52px; line-height: 1; }
.card-pick .p-visual svg, .slot .p-visual svg { width: 120px; height: auto; }
.card-pick.is-ko { animation: shake .45s; background: var(--ko-bg); }
.card-pick.used { visibility: hidden; }

/* ---------- Moteur RELIER (match) ---------- */
/* (coeur#52, 30/10, repris du bloc « Le jeu Relier » de css/projets-cles.css) Deux colonnes égales qui peuvent rétrécir : « 1fr » ne descendait
   pas sous le mot le plus long, et un mot long (« porte-cles.hex ») ou un dessin poussait l'autre colonne hors de l'écran. La coche ✅ d'une paire
   trouvée est posée dans le coin de la carte (jeuRelier : .m-coche) : elle ne prend plus la place du texte. */
.match { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px 60px; }
.match .col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.m-item {
  position: relative; display: flex; align-items: center; gap: 12px; min-height: 84px; padding: 10px 16px;
  background: #fff; border: var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-sm);
  cursor: pointer; font-weight: 600; font-size: 21px; text-align: left;
}
.m-item > span { min-width: 0; overflow-wrap: break-word; }
/* (coeur#82) la coche sur le COIN de la carte à toutes les largeurs (dans le coin intérieur, avec « Aa », elle cachait la dernière lettre de la 1re ligne) */
.m-item > .m-coche { position: absolute; top: -11px; right: -7px; font-size: 20px; line-height: 1; pointer-events: none; }
.m-item .m-visual { font-size: 42px; line-height: 1; flex: 0 0 auto; }
/* grand texte « Aa » (cartes agrandies) : le dessin passe au-dessus du mot (sinon « Émetteur » était coupé en deux à 768 et 1024 px) */
html.aff-t1 .match .m-item:has(> .m-visual), html.aff-t2 .match .m-item:has(> .m-visual) { flex-direction: column; justify-content: center; gap: 4px; text-align: center; }
@media (max-width: 700px) { .match { gap: 14px 18px; } } /* (était dans « Petits écrans », plus bas : il aurait remplacé l'écart du téléphone) */
/* téléphone : cartes plus compactes, le dessin au-dessus du mot, la coche sur le coin de la carte (dans le coin intérieur, elle cachait la fin de la 1re ligne) */
@media (max-width: 640px) {
  .match { gap: 10px; }
  .match .col { gap: 10px; }
  .m-item { min-height: 72px; padding: 8px; gap: 4px; font-size: 17px; line-height: 1.2; }
  .m-item:has(> .m-visual) { flex-direction: column; justify-content: center; text-align: center; }
  .m-item .m-visual { font-size: 32px; }
  .m-item .m-visual svg { max-width: 56px; max-height: 45px; }
  .m-item > .m-coche { top: -11px; right: -7px; }
}
@media (max-width: 400px) { .match { gap: 8px; } .m-item { padding: 6px 5px; font-size: 15px; } } /* (320 à 400 px : un mot ne se coupe jamais) */
/* grand texte « Aa » sur un téléphone : deux colonnes couperaient les mots ; les mots, puis (sous un trait) les phrases */
@media (max-width: 640px) {
  html.aff-t2 .match { grid-template-columns: minmax(0, 1fr); }
  html.aff-t2 .match .col + .col { padding-top: 10px; border-top: 3px dashed var(--line); }
  html.aff-t2 .match .m-item:has(> .m-visual) { flex-direction: row; justify-content: flex-start; gap: 10px; text-align: left; }
}
@media (max-width: 400px) {
  html.aff-t1 .match { grid-template-columns: minmax(0, 1fr); }
  html.aff-t1 .match .col + .col { padding-top: 10px; border-top: 3px dashed var(--line); }
  html.aff-t1 .match .m-item:has(> .m-visual) { flex-direction: row; justify-content: flex-start; gap: 10px; text-align: left; }
}
.m-item.sel { background: var(--world-soft); outline: 5px solid var(--world); }
.m-item.done { background: var(--ok-bg); border-color: var(--ok); pointer-events: none; }
.m-item.is-ko { animation: shake .45s; background: var(--ko-bg); }
.memory { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.mem-card { aspect-ratio: 3/4; perspective: 800px; cursor: pointer; background: none; border: 0; padding: 0; }
.mem-card .inner { position: relative; width: 100%; height: 100%; transition: transform .45s; transform-style: preserve-3d; }
.mem-card.open .inner, .mem-card.found .inner { transform: rotateY(180deg); }
.mem-card .face { position: absolute; inset: 0; backface-visibility: hidden; border: var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 8px; text-align: center; font-weight: 600; font-size: 17px; }
.mem-card .back { background: var(--world); color: var(--sur-accent); font-size: 54px; }
.mem-card .front { background: #fff; transform: rotateY(180deg); }
.mem-card .front .m-visual { font-size: 48px; line-height: 1; }
.mem-card.found .front { background: var(--ok-bg); }

/* ---------- Moteur ZONES (hotspot) ---------- */
.hs-wrap { position: relative; max-width: 900px; margin: 0 auto; border: var(--border); border-radius: var(--radius); box-shadow: var(--shadow); background: #fff; overflow: hidden; touch-action: none; }
.hs-wrap > svg, .hs-wrap > img { display: block; width: 100%; height: auto; }
.hs-wrap:focus-visible { outline: 5px solid var(--world, #3a7bd5); outline-offset: 3px; }
.hs-zone { position: absolute; transform: translate(-50%, -50%); border-radius: 50%; cursor: pointer; }
.hs-zone.found { border: 5px solid var(--ok); background: rgba(31,157,85,.18); animation: pop .4s; }
.hs-zone.found::after { content: attr(data-label); position: absolute; left: 50%; top: 100%; transform: translate(-50%, 6px); white-space: nowrap; background: var(--ok-plein); color: #fff; font-weight: 700; font-size: 17px; padding: 2px 10px; border-radius: 999px; border: 2px solid var(--line); }
.hs-miss { position: absolute; width: 50px; height: 50px; margin: -25px 0 0 -25px; border-radius: 50%; border: 4px solid var(--ko); animation: missFade .7s forwards; pointer-events: none; }
.pad-cursor { position: absolute; width: 46px; height: 46px; margin: -23px 0 0 -23px; pointer-events: none; z-index: var(--z-curseur); border: 4px solid var(--focus); border-radius: 50%; box-shadow: 0 0 0 3px #fff; }
.pad-cursor::before, .pad-cursor::after { content: ''; position: absolute; background: var(--focus); }
.pad-cursor::before { left: 50%; top: -12px; bottom: -12px; width: 4px; margin-left: -2px; }
.pad-cursor::after { top: 50%; left: -12px; right: -12px; height: 4px; margin-top: -2px; }

/* ---------- Toast & feedback ---------- */
/* (--st-h : la hauteur du sous-titre affiché, posée par le cœur : les messages montent au-dessus de lui) */
/* (coeur#39, 30/10 : width/max-width) sans largeur, un élément « fixed » posé à left: 50% ne dépasse pas la moitié de l'écran : un mot par ligne sur un téléphone */
.toast-zone { position: fixed; left: 50%; bottom: calc(28px + var(--st-h, 0px)); transform: translateX(-50%); width: max-content; max-width: calc(100vw - 32px); z-index: var(--z-toast); display: flex; flex-direction: column; gap: 10px; align-items: center; pointer-events: none; transition: bottom .2s; }
.toast {
  display: flex; align-items: center; gap: 12px; padding: 12px 24px;
  font-family: var(--font-title); font-weight: 700; font-size: 28px;
  background: #fff; border: var(--border); border-radius: 999px; box-shadow: var(--shadow);
  animation: toastIn .35s cubic-bezier(.2,.9,.3,1.4);
}
.toast.ok { background: var(--ok-bg); }
.toast.ko { background: #fff3c4; }
.toast .e { font-size: 38px; }
.toast.out { animation: toastOut .3s forwards; }

/* ---------- Overlay / modales ---------- */
.overlay { position: fixed; inset: 0; z-index: var(--z-fenetre); background: rgba(29,27,47,.55); display: grid; place-items: center; padding: 16px; animation: fadeIn .2s; }
.modal { width: min(640px, 100%); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow: auto; background: #fff; border: var(--border); border-radius: 28px; box-shadow: 0 10px 0 var(--line); padding: 28px; text-align: center; animation: dropIn .4s cubic-bezier(.2,.9,.3,1.3); }
.modal:focus, .modal:focus-visible { outline: none !important; } /* (la fenêtre prend le focus quand elle n'a aucun bouton : pas de cadre) */
.modal .actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-top: 18px; }
.celebrate .stars-big { display: flex; justify-content: center; gap: 10px; margin: 10px 0 14px; }
.celebrate .stars-big span { font-size: 84px; line-height: 1; filter: grayscale(1) opacity(.25); transform: scale(.4); transition: all .45s cubic-bezier(.2,.9,.3,1.6); }
.celebrate .stars-big span.on { filter: none; transform: scale(1) rotate(-6deg); }
.celebrate .xp-line { font-family: var(--font-title); font-weight: 700; font-size: 30px; }
.celebrate .unlock { margin-top: 14px; padding: 12px; border: 3px dashed var(--line); border-radius: 16px; background: var(--paper-2); font-weight: 700; animation: pop .5s .9s both; }
.confetti { position: fixed; top: -20px; width: 12px; height: 18px; z-index: var(--z-confettis); pointer-events: none; border-radius: 3px; animation: confettiFall linear forwards; }

/* ---------- Équipe (plusieurs élèves sur un poste) ---------- */
.tour-annonce { text-align: center; }
.tour-annonce .tour-avatar { font-size: 120px; line-height: 1; animation: jump .7s ease 2; }
.tour-annonce h2 { font-size: 40px; margin-top: 8px; }
.eq-liste { display: flex; flex-direction: column; gap: 10px; margin: 14px 0; text-align: left; }
.eq-ligne { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border: 3px solid var(--line); border-radius: 16px; background: var(--paper-2); }
.eq-av { font-size: 44px; line-height: 1; }
.eq-txt { flex: 1; font-size: 22px; }
.eq-nouveau { font-size: 15px; color: var(--muted); }
.eq-etoiles span { font-size: 28px; filter: grayscale(1) opacity(.25); }
.eq-etoiles span.on { filter: none; }
.eq-xp { font-family: var(--font-title); font-weight: 700; font-size: 20px; white-space: nowrap; }
.player-chip.equipe .av-pile { display: flex; }
.player-chip.equipe .av-pile .av { width: 40px; height: 40px; font-size: 24px; margin-right: -10px; }
.player-chip.equipe .av-pile .av:last-child { margin-right: 4px; }

/* ---------- Classement anonyme ---------- */
.classement .cl-tete { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.classement h3 { margin: 0; }
.cl-ligne { display: flex; align-items: center; gap: 14px; padding: 10px 0; border-top: 2px dashed #ddd; }
.cl-med { font-size: 44px; line-height: 1; }
.cl-txt { flex: 1; font-size: 19px; }
.cl-txt b { font-family: var(--font-title); font-size: 21px; }
.cl-podium { display: flex; gap: 6px; align-items: flex-end; }
.cl-p { display: flex; flex-direction: column; align-items: center; font-size: 28px; line-height: 1; padding: 4px 6px; border: 2px solid var(--line); border-radius: 10px; background: #fff; }
.cl-p small { font-size: 11px; font-weight: 700; margin-top: 2px; }
.cl-p.p1 { background: #ffe9a8; } .cl-p.p2 { background: #eceff3; } .cl-p.p3 { background: #f6d9c4; }
.cl-astuce { margin: 10px 0 0; font-weight: 600; }

/* ---------- Mode démonstration : curseur fantôme ---------- */
.ghost-cursor { position: fixed; left: 0; top: 0; z-index: var(--z-fantome); pointer-events: none; width: 54px; height: 54px; transform: translate(-200px, -200px); will-change: transform; transition: opacity .25s; }
.ghost-cursor svg { width: 54px; height: 54px; overflow: visible; filter: drop-shadow(0 4px 0 rgba(29,27,47,.35)); }
/* (coeur#53, 30/10) l'étiquette part du côté où il y a de la place (classe g-gauche posée par placer, js/atelier.js : à gauche du curseur dans la
   moitié droite de l'écran) et passe à la ligne plutôt que de sortir de l'écran (max-width posé par placer : la place jusqu'au bord, moins 16 px). */
.ghost-cursor .g-label { position: absolute; left: 44px; top: 40px; width: max-content; white-space: normal; background: var(--hint); border: 3px solid var(--line); border-radius: 20px; padding: 2px 12px; font-family: var(--font-title); font-weight: 700; font-size: 18px; line-height: 1.25; }
.ghost-cursor.g-gauche .g-label { left: auto; right: 46px; text-align: right; }
/* (coeur#76) près du bas de l'écran (classe g-haut posée par placer) : l'étiquette passe au-dessus du curseur */
.ghost-cursor.g-haut .g-label { top: auto; bottom: calc(100% - 8px); }
@media (max-width: 640px) { .ghost-cursor .g-label { font-size: 16px; padding: 2px 10px; } }
.ghost-cursor.pressing svg { transform: scale(.85); transform-origin: 8px 6px; }
.ghost-ripple { position: fixed; z-index: var(--z-fantome-onde); pointer-events: none; width: 20px; height: 20px; margin: -10px 0 0 -10px; border-radius: 50%; border: 5px solid var(--hint); animation: ripple .6s ease-out forwards; }
.ghost-ripple.right { border-color: #ff6fb5; }
.ghost-drag { position: fixed; z-index: var(--z-fantome-traine); pointer-events: none; opacity: .85; transform-origin: 0 0; box-shadow: 0 14px 30px rgba(0,0,0,.25) !important; }
.ghost-key { position: fixed; z-index: var(--z-fantome-touche); pointer-events: none; display: flex; gap: 8px; align-items: center; font-family: var(--font-title); font-weight: 700; font-size: 26px; animation: pop .3s; }
.keycap { display: inline-grid; place-items: center; min-width: 58px; height: 58px; padding: 0 14px; background: #fff; border: 3px solid var(--line); border-bottom-width: 8px; border-radius: 12px; font-family: var(--font-title); font-weight: 700; font-size: 24px; }
.keycap.down { border-bottom-width: 3px; transform: translateY(5px); background: var(--hint); }
.watch-shield { position: fixed; inset: 0; z-index: var(--z-fantome-bouclier); cursor: not-allowed; }
/* VISITE GUIDÉE de l'élève (A.visite, étape 5) : une bulle près de l'élément montré (la phrase, 🔊, « ⏭ Passer ») et un anneau jaune autour.
   Rien n'est bloqué : pas de bouclier. */
.visite-bulle { position: fixed; left: 50%; top: 30%; z-index: var(--z-fantome-bandeau); display: flex; flex-direction: column; gap: 10px;
  width: min(400px, calc(100vw - 16px)); margin: 0; padding: 14px 16px; box-shadow: var(--shadow); }
.visite-bulle .visite-ligne { display: flex; align-items: center; gap: 12px; }
.visite-bulle .visite-ligne .b-text { flex: 1; min-width: 0; font-size: 21px; font-weight: 700; }
.visite-bulle .visite-bas { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.visite-bulle .visite-compte { font-family: var(--font-title); font-weight: 700; color: var(--muted); }
.visite-bulle .visite-passer { min-height: 52px; }
.visite-anneau { position: fixed; z-index: var(--z-indice-anneau); pointer-events: none; border: 5px solid var(--hint); border-radius: 18px; box-shadow: 0 0 0 4px rgba(29, 27, 47, .55); }
/* (coeur#58, 30/10) « 👀 Je te montre ! » est posé DANS la barre du haut (son titre sert moins pendant une démonstration) : à 86 px, juste sous la
   barre, il cachait le haut de la zone de travail (titre d'un éditeur, pastilles des phases). Plus petit sur un téléphone. */
.watch-banner { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: var(--z-fantome-bandeau); width: max-content; max-width: calc(100vw - 32px); background: var(--hint); border: var(--border); border-radius: 999px; box-shadow: var(--shadow-sm); padding: 8px 22px; font-family: var(--font-title); font-weight: 700; font-size: 26px; line-height: 1.3; text-align: center; animation: dropIn .4s; pointer-events: none; }
@media (max-width: 640px) { .watch-banner { top: 16px; padding: 6px 14px; font-size: 18px; line-height: 1.2; } } /* (coeur#77 : 18 px sur téléphone, moins haut) */

/* Indices visuels */
.hint-glow { animation: hintGlow 1.1s ease-in-out infinite !important; }
.hint-arrow { position: fixed; z-index: var(--z-indice); pointer-events: none; font-size: 64px; line-height: 1; filter: drop-shadow(0 4px 0 rgba(0,0,0,.25)); animation: arrowBounce .8s ease-in-out infinite; }
.hint-ring { position: fixed; z-index: var(--z-indice-anneau); pointer-events: none; border: 5px dashed var(--hint); border-radius: 20px; animation: ringPulse 1.2s ease-in-out infinite; }

/* ---------- Coach (mascotte) ---------- */
.coach { display: flex; align-items: flex-end; gap: 12px; }
.coach .c-face { font-size: 76px; line-height: 1; animation: bob 2.6s ease-in-out infinite; flex: 0 0 auto; }
.coach.happy .c-face { animation: jump .6s ease 2; }
.coach.think .c-face { animation: tilt 1.2s ease-in-out infinite; }
.coach .bubble { flex: 1; }
.coach .bubble::before { content: ''; position: absolute; left: -16px; bottom: 22px; border: 12px solid transparent; border-right-color: var(--line); }
/* Téléphone (coeur#36, 12/10) : la bulle ne peut pas rétrécir sous son mot le plus long + le bouton 🔊 (agrandis par « Aa » texte grand) ; à côté du visage
   elle sortait de la page, qui défilait de côté (lecture, PIX, Techno… à 320-375 px). Maintenant la bulle passe SOUS le visage, seulement quand elle ne
   tient plus à côté (flex-wrap : sinon rien ne change). La pointe de la bulle n'a plus de visage à montrer : elle est cachée. En dernier recours
   seulement (320 px, texte très grand, mot très long : « ingénieure »), le mot se coupe plutôt que de sortir de l'écran. */
@media (max-width: 520px) {
  .coach { flex-wrap: wrap; }
  /* (coeur#38, 30/10) une base de 240 px : avec « flex: 1 » (base 0), la bulle tenait toujours à côté du visage, large de 190 px (« Salut Test !
     Je suis Bip… » en 10 lignes de 2 mots dans le guide d'un portail à 375 px). Elle passe maintenant SOUS le visage quand 240 px ne tiennent pas à côté. */
  .coach .bubble { flex: 1 1 240px; max-width: 100%; }
  /* (.bubble .b-text : min-width 0 et coupure des mots trop longs à toutes les largeurs depuis coeur#50, plus haut) */
  .coach .bubble::before { display: none; }
  /* (30/10, avec coeur#46) « Aa » (texte grand ou très grand) : quand 6 em de texte ne tiennent plus à côté du 🔊 (bulle zoomée de 375 px), le bouton 🔊
     passe SOUS le texte, à droite, au lieu de couper un mot en deux (« premie-r ») ; sans « Aa », rien ne change */
  html.aff-t1 .bubble, html.aff-t2 .bubble { flex-wrap: wrap; }
  html.aff-t1 .bubble .b-text, html.aff-t2 .bubble .b-text { flex: 1 1 6em; }
  html.aff-t1 .bubble > .say-btn, html.aff-t2 .bubble > .say-btn { margin-left: auto; }
}

/* ---------- Animations ---------- */
@keyframes pop { 0% { transform: scale(.8); } 60% { transform: scale(1.08); } 100% { transform: scale(1); } }
@keyframes shake { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-10px); } 40% { transform: translateX(10px); } 60% { transform: translateX(-7px); } 80% { transform: translateX(7px); } }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@keyframes jump { 0%,100% { transform: translateY(0) scale(1); } 40% { transform: translateY(-26px) scale(1.1); } }
@keyframes tilt { 0%,100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }
@keyframes pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes dropIn { from { opacity: 0; transform: translateY(-30px) scale(.95); } to { opacity: 1; transform: none; } }
@keyframes toastIn { from { opacity: 0; transform: translateY(30px) scale(.8); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateY(20px) scale(.9); } }
@keyframes confettiFall { to { transform: translate3d(var(--dx, 0), 110vh, 0) rotate(var(--rot, 720deg)); } }
@keyframes ripple { from { transform: scale(1); opacity: 1; } to { transform: scale(4.5); opacity: 0; } }
@keyframes missFade { from { transform: scale(.6); opacity: 1; } to { transform: scale(1.4); opacity: 0; } }
@keyframes hintGlow { 0%,100% { box-shadow: 0 0 0 0 rgba(255,212,0,.0), var(--shadow-sm); } 50% { box-shadow: 0 0 0 12px rgba(255,212,0,.85), var(--shadow-sm); } }
@keyframes arrowBounce { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-16px); } }
@keyframes ringPulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .5; transform: scale(1.04); } }
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* ---------- Petits écrans ---------- */
@media (max-width: 700px) {
  body { font-size: 18px; }
  .topbar .tb-title { font-size: 21px; }
  .player-chip .lv { display: none; }
  .btn-big { font-size: 26px; min-height: 70px; padding: 10px 26px; }
}
/* Barre d'une page d'élève entre 701 et 900 px (étape 5, défaut vu au contrôle final, 30/10) : avec un élève, le rang sous le prénom élargissait
   la pastille « Moi » et la pastille de l'activité passait sur le nombre d'étoiles (à 701 px). Le rang est caché jusqu'à 900 px, comme sous 700 px
   (il reste dans « Mon espace »). */
@media (max-width: 900px) { .topbar:not(.menu-haut) .player-chip .lv { display: none; } }
/* Barre du haut sur un téléphone (coeur#31, 11/10) : sous 480 px, retour (60) + étoiles + « Aa » (60) + pastille de l'élève ne tenaient plus ;
   le titre tombait à 0 px, sa pastille de portail passait sous le nombre d'étoiles et la page défilait de côté. Maintenant : retour, étoiles,
   « Aa » et la pastille de l'élève gardent leur place (la pastille ne montre que l'avatar ; le prénom reste lu par les lecteurs d'écran et dans
   l'infobulle), le titre cède d'abord son texte (sous 440 px ; le texte reste lu), puis la pastille du portail (quand elle n'a plus de place).
   La barre a alors la hauteur qu'elle a sur grand écran (83 px au lieu de 89). Au-dessus de 480 px, seuls les prénoms très longs sont coupés
   par « … ». Pas l'accueil : sa barre (.menu-haut, avec son logo) a ses propres règles dans index.html. */
.player-chip .pc-nom > div { max-width: 15em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player-chip .pc-nom > .lv { max-width: 22em; } /* (le plus long rang, « Star de l'atelier », tient en entier) */
@media (max-width: 480px) {
  .topbar:not(.menu-haut) { gap: 8px; padding-left: 10px; padding-right: 10px; }
  .topbar:not(.menu-haut) .stars-count { font-size: 20px; }
  .topbar:not(.menu-haut) .player-chip { gap: 4px; padding-right: 8px; }
  .topbar:not(.menu-haut) .player-chip .pc-nom { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .topbar:not(.menu-haut) .player-chip.equipe .av-pile .av { margin-right: -24px; }
  .topbar:not(.menu-haut) .player-chip.equipe .av-pile .av:last-child { margin-right: 0; }
}
/* Barre v2 sur un téléphone (étape 5) : sous 480 px, ⬅, le logo, 🙋 et ⚙️ font 48 px (44 px sous 360 px), les étoiles se cachent (elles sont
   dans « Mon espace ») : toujours une ligne, sans défilement de côté, même avec 🙋 et une équipe de 4. */
@media (max-width: 480px) {
  .topbar:not(.menu-haut) { gap: 6px; }
  .topbar:not(.menu-haut) .stars-count { display: none; }
  .topbar:not(.menu-haut) .btn-histo { display: none; } /* (« 🕘 Mon historique » reste dans le menu « Moi ») */
  .topbar:not(.menu-haut) > .btn-icon { width: 48px; min-width: 48px; height: 48px; min-height: 48px; padding: 0; font-size: 24px; }
  .topbar:not(.menu-haut) .tb-logo svg { width: 32px; height: 32px; }
  .topbar:not(.menu-haut) .btn-aff .aff-roue { font-size: 26px; }
  .topbar:not(.menu-haut) .btn-main-barre .bm-e { font-size: 26px; }
}
@media (max-width: 360px) {
  .topbar:not(.menu-haut) { gap: 4px; padding-left: 8px; padding-right: 8px; }
  .topbar:not(.menu-haut) > .btn-icon { width: 44px; min-width: 44px; height: 44px; min-height: 44px; }
}
@media (max-width: 440px) {
  .topbar:not(.menu-haut) .tb-title { position: relative; gap: 0; container-type: inline-size; }
  .topbar:not(.menu-haut) .tb-title span.t { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  /* la pastille du portail (44 px) s'efface quand la place du titre est plus petite qu'elle (équipe de 4, étoiles à quatre chiffres) */
  @container (max-width: 43.9px) { .topbar:not(.menu-haut) .world-dot { display: none; } }
}
@media (max-width: 360px) { .topbar:not(.menu-haut) .world-dot { display: none; } } /* (secours : navigateur sans @container) */

/* ---------- Impression ---------- */
@media print {
  body { background: #fff; }
  .topbar, .no-print, .toast-zone { display: none !important; }
}

/* =========================================================
   MON AFFICHAGE (réglages de lecture de chaque élève, classes sur <html>)
   ========================================================= */
/* Taille du texte : on agrandit ce qui se lit (consignes, réponses, cartes) */
html.aff-t1 .bubble, html.aff-t1 .choice, html.aff-t1 .sort-item, html.aff-t1 .m-item, html.aff-t1 .card-pick,
html.aff-t1 .explain, html.aff-t1 .toast, html.aff-t1 .mot-carte, html.aff-t1 .c-notions, html.aff-t1 .sous-titre { zoom: 1.18; }
html.aff-t2 .bubble, html.aff-t2 .choice, html.aff-t2 .sort-item, html.aff-t2 .m-item, html.aff-t2 .card-pick,
html.aff-t2 .explain, html.aff-t2 .toast, html.aff-t2 .mot-carte, html.aff-t2 .c-notions, html.aff-t2 .sous-titre { zoom: 1.4; }
html.aff-t1 body { font-size: 23px; }
html.aff-t2 body { font-size: 26px; }
/* Lettres et mots espacés */
html.aff-espaces .b-text, html.aff-espaces .choice, html.aff-espaces .sort-item, html.aff-espaces .m-item, html.aff-espaces p, html.aff-espaces li {
  letter-spacing: .06em; word-spacing: .22em; line-height: 1.75;
}
/* Écriture facile à lire */
html.aff-andika { --font-body: 'Andika', 'Lexend', 'Segoe UI', Verdana, sans-serif; }
html.aff-andika .bubble, html.aff-andika .choice, html.aff-andika .sort-item, html.aff-andika .m-item { font-family: var(--font-body); }
/* Contraste fort */
/* Contraste fort : les variables (couleurs, contour) sont dans css/tokens.css */
html.aff-contraste body { background-image: none; }
html.aff-contraste .bubble, html.aff-contraste .choice { background: #fff; }
/* Un mot sur deux en couleur, pictogrammes au-dessus des mots */
.aw { display: inline; }
html.aff-couleurs .aw.m1 { color: #1a3fb5; }
html.aff-couleurs .aw.m2 { color: #b3261e; }
html.aff-contraste.aff-couleurs .aw.m1 { color: #0026a8; }
.aw.a-pic { display: inline-flex; flex-direction: column; align-items: center; vertical-align: bottom; line-height: 1.15; margin: 0 .04em; }
.aw.a-pic .pic { font-size: .85em; line-height: 1.1; padding: 0 .1em; border-radius: 8px; background: rgba(255, 197, 49, .25); }
html.aff-pictos .bubble { line-height: 1.5; }
/* Je n'entends pas bien : sous-titres et sons visibles */
.sous-titre { position: fixed; left: 50%; bottom: 18px; transform: translate(-50%, 20px); z-index: var(--z-soustitre); max-width: min(960px, calc(100% - 32px));
  padding: 10px 20px; border-radius: 14px; background: rgba(15, 14, 30, .92); color: #fff; font-family: var(--font-body); font-size: 24px; line-height: 1.35;
  text-align: center; opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; }
.sous-titre.on { opacity: 1; transform: translate(-50%, 0); }
.sous-titre::before { content: '💬 '; }
/* une fenêtre est ouverte : le sous-titre passe EN HAUT de l'écran (il ne cache plus les boutons du bas de la fenêtre),
   et les messages reprennent leur place en bas */
body:has(.overlay, .perso-voile) .sous-titre { top: 14px; bottom: auto; } /* (lot A : aussi la fenêtre du personnage, « J'ai compris ») */
body:has(.overlay, .perso-voile) .toast-zone { bottom: 28px; }
.flash-son { position: fixed; inset: 0; z-index: var(--z-flash); pointer-events: none; box-shadow: inset 0 0 0 14px var(--flash); animation: flashSon .7s ease-out forwards; }
@keyframes flashSon { from { opacity: 1; } to { opacity: 0; } }
/* animations réduites (réglage du système) : l'éclair du « son visible » reste AFFICHÉ, sans fondu (le cœur le retire après 0,7 s).
   Sans cette règle il allait tout de suite à son état final, invisible. */
@media (prefers-reduced-motion: reduce) { .flash-son { animation: none !important; opacity: 1; } }
.lien-lsf { text-decoration: none; }
/* Boutons de la barre du haut : « ⚙️ Mes réglages » et « 🙋 J'ai besoin d'aide » */
.topbar .btn-aff, .topbar .btn-aide { flex: 0 0 auto; }
.btn-aide.levee { background: var(--hint); animation: mainLevee 1s ease-in-out infinite alternate; }
@keyframes mainLevee { from { transform: rotate(-8deg); } to { transform: rotate(8deg) translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .btn-aide.levee { animation: none; } }
/* « 🙋 Lever la main » : bouton fixe en bas à gauche, toujours là pendant les activités.
   PLACE RÉSERVÉE (lot 1b, en attendant la barre unique du lot D) : au repos c'est un rond de 60 px rangé dans la marge
   gauche de la page ; il ne se pose plus sur les cartes ni sur les réponses (pages de 1212 px de large ou plus : il
   reste dans la marge et le contour des cartes). Son nom apparaît au survol, au focus (clavier, manette), et tout le
   temps sur un très grand écran, où la marge est assez large. La fin de la page garde aussi sa place (padding-bottom). */
.btn-main-flottante { position: fixed; left: 4px; bottom: 12px; z-index: var(--z-flottant); /* sous les fenêtres (.overlay : 300) */ display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-width: 60px; min-height: 60px; padding: 0; border: var(--border); border-radius: 999px; background: #fff; color: var(--ink); box-shadow: var(--shadow-sm); font-family: var(--font-title); font-weight: 700; font-size: 21px; cursor: pointer; }
.btn-main-flottante .bm-e { font-size: 34px; line-height: 1; }
.btn-main-flottante .bm-t { display: none; white-space: nowrap; }
.btn-main-flottante:hover, .btn-main-flottante:focus-visible, .btn-main-flottante.pad-focus { background: var(--hint); padding: 0 18px 0 8px; }
.btn-main-flottante:hover .bm-t, .btn-main-flottante:focus-visible .bm-t, .btn-main-flottante.pad-focus .bm-t { display: inline; }
/* (au clavier ou à la manette : le bouton s'écarte du bord, son cadre de focus n'est plus coupé par l'écran) */
.btn-main-flottante:not(.dans-colonne):focus-visible, .btn-main-flottante:not(.dans-colonne).pad-focus { left: 12px; bottom: 16px; }
.btn-main-flottante.levee { background: var(--hint); animation: none; box-shadow: 0 0 0 6px rgba(255, 196, 0, .45), var(--shadow-sm); }
.btn-main-flottante.levee .bm-e { display: inline-block; animation: mainLevee 1s ease-in-out infinite alternate; }
.btn-main-flottante.vue { background: var(--ok-bg, #d8f5e3); box-shadow: 0 0 0 6px rgba(31, 157, 85, .35), var(--shadow-sm); }
.btn-main-flottante.vue .bm-e { animation: none; }
body.avec-main { padding-bottom: 84px; }
@media (min-width: 1700px) {
  .btn-main-flottante { left: 16px; bottom: 16px; padding: 6px 22px 6px 14px; box-shadow: var(--shadow); }
  .btn-main-flottante .bm-t { display: inline; }
}
/* dans la colonne du coach (PIX, Techno, Lecture) : tout en bas, sur toute la largeur, avec son nom */
.btn-main-flottante.dans-colonne { position: static; align-self: stretch; justify-content: center; margin-top: 4px; min-height: 64px; padding: 6px 22px 6px 14px; box-shadow: var(--shadow); }
.btn-main-flottante.dans-colonne .bm-t { display: inline; }
@media (prefers-reduced-motion: reduce) { .btn-main-flottante.levee .bm-e { animation: none; } }
@media print { .btn-main-flottante { display: none; } }
/* Écran verrouillé par l'animateur : « Regardez au tableau » (par-dessus tout, rien n'est cliquable) */
.voile-tableau { position: fixed; inset: 0; z-index: var(--z-voile); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; padding: 24px; background: #000; color: #fff; text-align: center; cursor: default; outline: none; }
.voile-tableau .vt-emoji { font-size: clamp(70px, 14vw, 140px); line-height: 1; animation: vt-respire 2.4s ease-in-out infinite; }
.voile-tableau .vt-titre { font-family: var(--font-title); font-weight: 700; font-size: clamp(34px, 6vw, 72px); line-height: 1.1; }
.voile-tableau .vt-texte { font-size: clamp(24px, 3.6vw, 42px); color: #ffe27a; }
@keyframes vt-respire { 50% { transform: scale(1.08); } }
@media (prefers-reduced-motion: reduce) { .voile-tableau .vt-emoji { animation: none; } }
/* « L'enseignant arrive. » (coeur#12, PR.arrivee) : l'adulte a touché « J'arrive ». TOUT l'écran du poste est noir,
   au-dessus de tout (même de l'écran verrouillé) : le dessin d'un enseignant et le message en très grand, dans un cadre
   jaune qui respire doucement (immobile avec « animations réduites ») : l'adulte repère le poste de loin.
   « Suivant » apparaît après 5 s dans une place déjà réservée (rien ne bouge). Les sous-titres restent par-dessus. */
.overlay.arrivee { z-index: var(--z-arrivee); display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 28px; background: #000; color: #fff; text-align: center; cursor: default; outline: none; animation: none; overflow: hidden; }
.overlay.arrivee::before { content: ''; position: absolute; inset: 0; pointer-events: none; box-shadow: inset 0 0 0 16px #ffd400; animation: arriveeCadre 2.4s ease-in-out infinite alternate; }
@keyframes arriveeCadre { from { opacity: 1; } to { opacity: .45; } }
.arrivee-corps { position: relative; display: flex; align-items: center; justify-content: center; gap: clamp(16px, 4vw, 64px); flex-wrap: wrap; max-width: 1240px; }
.arrivee-dessin { flex: 0 0 auto; display: flex; }
.arrivee-dessin svg { height: min(64vh, 470px); width: auto; display: block; }
.arrivee-texte { display: flex; flex-direction: column; align-items: center; gap: 30px; max-width: min(640px, 92vw); }
.arrivee-titre { margin: 0; font-family: var(--font-title); font-weight: 700; font-size: clamp(46px, 7.6vw, 108px); line-height: 1.05; color: #fff; }
.arrivee-place { min-height: 84px; display: flex; align-items: center; justify-content: center; }
.arrivee-suivant { min-width: 280px; animation: pop .45s; }
.arrivee-suivant:focus-visible, .arrivee-suivant.pad-focus { outline: 6px solid #fff; outline-offset: 5px; }
@media (max-aspect-ratio: 1/1) { .arrivee-dessin svg { height: min(42vh, 380px); } .arrivee-texte { gap: 18px; } }
@media (prefers-reduced-motion: reduce) { .overlay.arrivee::before, .arrivee-suivant { animation: none; } }
html.arrivee-active .sous-titre { z-index: var(--z-arrivee-soustitre); }
@media print { .overlay.arrivee { display: none; } }
/* « 🔒 Activité obligatoire » (31/10, js/atelier.js : obAfficher, obMontrer, obRetour). Badge « 🔒 À finir » dans la barre (le toucher rouvre la
   fenêtre), bandeau d'attente (2e ligne de la barre, ou sous la barre de l'accueil), fenêtre douce (.modal.ob-fenetre, le dessin de
   « J'arrive ») et voile du retour forcé. Encre sur jaune pâle, blanc sur bleu nuit : plus de 7:1, aussi en « Couleurs très contrastées ».
   Rien ne bouge (aucune animation propre ; « Écran calme » coupe aussi celles de la fenêtre). */
.ob-badge { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: .3em; min-height: 48px; padding: 4px 16px; border: var(--border); border-radius: 999px;
  background: #ffe27a; color: #1d1b2f; box-shadow: var(--shadow-sm); font-family: var(--font-title); font-weight: 700; font-size: 20px; line-height: 1; white-space: nowrap; cursor: pointer; }
.ob-badge:hover { background: #ffd43b; }
.ob-badge .ob-badge-e { font-size: 22px; }
html.aff-contraste .ob-badge { color: #000; border-color: #000; }
/* pendant l'obligation, le badge prend la place des ⭐ (ils reviennent dès la fin) : le fil d'Ariane garde ses étages à 1280 px */
.topbar.ob-lie .stars-count { display: none; }
.ob-bandeau { display: flex; align-items: center; gap: 12px; margin: 10px 16px 0; padding: 6px 8px 6px 16px; border: 3px solid var(--line); border-radius: 16px;
  background: #fff4c2; color: var(--ink); font-size: 20px; font-weight: 700; line-height: 1.3; }
.topbar.ob-avec-bandeau { flex-wrap: wrap; row-gap: 8px; }
.topbar > .ob-bandeau { flex: 0 0 100%; order: 10; margin: 0; min-width: 0; }
.ob-bandeau .ob-bandeau-t { flex: 1; min-width: 0; overflow-wrap: break-word; }
.ob-bandeau .say-btn { width: 48px; height: 48px; flex: 0 0 48px; font-size: 22px; }
html.aff-contraste .ob-bandeau { background: #fff; color: #000; border-color: #000; }
.modal.ob-fenetre { width: min(700px, 100%); }
.ob-corps { display: flex; align-items: center; gap: 22px; text-align: left; }
.ob-dessin { flex: 0 0 auto; width: 128px; padding: 10px 8px 0; border: var(--border); border-radius: 22px; background: #1d1b2f; }
.ob-dessin svg { display: block; width: 100%; height: auto; }
.ob-texte { flex: 1; min-width: 0; }
.ob-fenetre .ob-titre { font-size: clamp(26px, 3.4vw, 34px); margin: 0 0 14px; }
.ob-fenetre .actions { justify-content: flex-start; }
@media (max-width: 560px) {
  .modal.ob-fenetre { padding: 18px 14px; }
  .ob-corps { flex-direction: column; gap: 10px; text-align: center; }
  .ob-dessin { width: 76px; padding: 6px 6px 0; border-radius: 16px; }
  .ob-fenetre .ob-titre { font-size: 24px; margin-bottom: 10px; }
  .ob-fenetre .bubble { text-align: left; gap: 10px; padding: 10px 12px; font-size: 20px; }
  .ob-fenetre .bubble .say-btn { width: 48px; height: 48px; flex-basis: 48px; font-size: 22px; }
  .ob-fenetre .actions { justify-content: center; margin-top: 12px; }
}
.ob-voile { position: fixed; inset: 0; z-index: calc(var(--z-voile) - 2); display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4vw; padding: 24px;
  background: #1d1b2f; color: #fff; text-align: center; }
.ob-voile-dessin svg { display: block; height: min(52vh, 380px); width: auto; }
.ob-voile-titre { margin: 0; max-width: 14em; color: #fff; font-size: clamp(32px, 5.6vw, 68px); line-height: 1.1; }
@media (max-aspect-ratio: 1/1) { .ob-voile-dessin svg { height: min(34vh, 300px); } }
/* « 📌 Pousser une activité » (01/11, js/atelier.js : obPartir, obVoilePousse). La ligne de l'activité poussée (emoji + titre) : dans la fenêtre
   de départ (.modal.ob-fenetre.ob-depart : les règles de la fenêtre douce, compacte sous 560 px) et sur le voile (.ob-voile-act, blanc sur bleu
   nuit). Le titre passe à la ligne (320 px). Encre sur jaune pâle, comme le bandeau ; noir sur blanc en « Couleurs très contrastées ». */
.ob-activite { display: flex; align-items: center; gap: .45em; margin: 0 0 14px; padding: 8px 16px; border: 3px solid var(--line); border-radius: 16px;
  background: #fff4c2; color: var(--ink); font-family: var(--font-title); font-weight: 700; font-size: clamp(22px, 2.6vw, 28px); line-height: 1.2; text-align: left; }
.ob-act-e { flex: 0 0 auto; font-size: 1.6em; line-height: 1; }
.ob-act-t { min-width: 0; overflow-wrap: anywhere; }
html.aff-contraste .ob-activite { background: #fff; color: #000; border-color: #000; }
.ob-voile-texte { display: flex; flex-direction: column; align-items: center; gap: clamp(14px, 3vh, 28px); min-width: 0; max-width: 100%; }
.ob-voile-act { display: flex; align-items: center; justify-content: center; gap: .4em; margin: 0; max-width: 16em; color: #fff;
  font-family: var(--font-title); font-weight: 700; font-size: clamp(26px, 4.2vw, 50px); line-height: 1.15; }
@media (max-width: 560px) { .ob-depart .ob-activite { justify-content: center; margin-bottom: 10px; padding: 6px 12px; font-size: 22px; } }
/* « 📌 Pousser plusieurs activités » (02/11, js/atelier.js : obAnnoncer, obRemplirListe, PR.obligeCelebrer). La fenêtre d'annonce
   (.modal.ob-fenetre.ob-annonce : les règles de la fenêtre douce, compacte sous 560 px) et sa liste numérotée (.ob-liste : 5 lignes tiennent à
   320 px, les titres passent à la ligne ; la courante encadrée, encre sur jaune pâle ; ▶ et ✅ se lisent sans la couleur) ; sous les étoiles de la
   célébration : « Il te reste 2 activités. » (.ob-reste) ou « ✅ Tu as fait toutes les activités. » (.ob-tout-fait). Noir sur blanc en « Couleurs
   très contrastées ». Rien ne bouge. */
.ob-liste { list-style: none; counter-reset: ob-l; display: flex; flex-direction: column; gap: 6px; margin: 0 0 14px; padding: 0; text-align: left; }
.ob-liste li { counter-increment: ob-l; display: flex; align-items: center; gap: .4em; min-height: 44px; padding: 4px 12px; border: 3px solid transparent; border-radius: 14px;
  color: var(--ink); font-family: var(--font-title); font-weight: 700; font-size: clamp(20px, 2.3vw, 24px); line-height: 1.2; }
.ob-liste li::before { content: counter(ob-l) "."; flex: 0 0 1.4em; }
.ob-liste .ob-l-m { flex: 0 0 1.3em; text-align: center; }
.ob-liste .ob-l-e { flex: 0 0 auto; font-size: 1.3em; line-height: 1; }
.ob-liste .ob-l-t { min-width: 0; overflow-wrap: anywhere; }
.ob-liste .ob-l-courante { border-color: var(--line); background: #fff4c2; }
.ob-liste .ob-l-faite { font-weight: 400; }
.ob-cache { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.celebrate .ob-reste, .celebrate .ob-tout-fait { margin: 4px auto 12px; max-width: 26em; padding: 8px 16px; border: 3px solid var(--line); border-radius: 16px; background: #fff4c2;
  color: var(--ink); font-family: var(--font-title); font-weight: 700; font-size: clamp(20px, 2.4vw, 26px); line-height: 1.25; }
html.aff-contraste .ob-liste li { color: #000; }
html.aff-contraste .ob-liste .ob-l-courante, html.aff-contraste .celebrate .ob-reste, html.aff-contraste .celebrate .ob-tout-fait { background: #fff; color: #000; border-color: #000; }
@media (max-width: 560px) {
  .ob-annonce .ob-titre { margin-bottom: 8px; }
  .ob-liste { gap: 4px; margin-bottom: 10px; }
  .ob-liste li { min-height: 40px; padding: 3px 8px; font-size: 19px; }
}
/* petits écrans : le badge garde 🔒 (son nom reste dans aria-label et title) ; à 400 px et moins, il prend la place du logo (qui, pendant
   l'obligation, ouvrirait la même fenêtre que ⬅ ; ⬅ reste, pour le doigt et pour le B de la manette) */
@media (max-width: 480px) {
  .ob-badge { min-height: 44px; min-width: 44px; padding: 0 10px; }
  .ob-badge .ob-badge-t { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .ob-bandeau { margin: 8px 10px 0; padding: 4px 6px 4px 12px; gap: 8px; font-size: 17px; }
  .topbar > .ob-bandeau { margin: 0; }
  .ob-bandeau .say-btn { width: 44px; height: 44px; flex-basis: 44px; font-size: 20px; }
}
@media (max-width: 400px) { .topbar.ob-lie > .tb-logo { display: none !important; } }
html.aff-calme .ob-badge, html.aff-calme .ob-bandeau, html.aff-calme .ob-bandeau *, html.aff-calme .ob-fenetre, html.aff-calme .ob-fenetre *,
html.aff-calme .overlay:has(> .ob-fenetre), html.aff-calme .ob-voile, html.aff-calme .ob-voile * { animation: none !important; }
@media print { .ob-badge, .ob-bandeau, .ob-voile, .overlay:has(> .ob-depart), .overlay:has(> .ob-annonce), .ob-reste, .ob-tout-fait { display: none !important; } }
/* Essai administrateur (coeur#13) : rappel discret et fixe, en bas à gauche ; il ne gêne aucun geste (pointer-events). */
.essai-admin { position: fixed; left: 12px; bottom: 12px; z-index: var(--z-rappel); display: inline-flex; align-items: center; gap: 4px; padding: 5px 14px; border: 2px solid var(--line); border-radius: 999px; background: #fff7d6; color: var(--ink); font-size: 16px; font-weight: 700; box-shadow: var(--shadow-sm); opacity: .94; pointer-events: none; }
html.mode-tableau .essai-admin { display: none; }
@media print { .essai-admin { display: none; } }
/* « ⏭ Passer » du coach (coeur#54) : essai administrateur seulement (le bouton n'est dans la page que dans ce cas) ; même fond que le
   rappel ci-dessus, bord en tirets : un outil de l'adulte, pas une réponse de l'élève. (0,3,0) : passe devant le .btn du thème « Quiz »
   (0,2,1), qui colore par --bg ; grisé, c'est le .btn[disabled] du thème (0,3,1) qui garde la main. */
.coach-actions .btn.coach-passer { --bg: #fff7d6; background: var(--bg); border-style: dashed; border-color: var(--line, #1d1b2f); }
html.mode-tableau .coach-passer { display: none; }
@media print { .coach-passer { display: none; } }
/* « 🎙️ L'animateur te parle » : bandeau en haut au centre pendant et après le message vocal */
.vocal-panneau { position: fixed; top: 96px; left: 50%; transform: translateX(-50%); z-index: var(--z-message); display: flex; align-items: center; gap: 12px; padding: 10px 14px 10px 18px; border: var(--border); border-radius: 999px; background: #e9f4ff; box-shadow: var(--shadow); font-size: 21px; animation: dropIn .35s; max-width: calc(100vw - 32px); }
.vocal-panneau .vocal-e { font-size: 34px; line-height: 1; animation: mainLevee .8s ease-in-out infinite alternate; }
/* le message ÉCRIT de l'adulte (seul, ou avec sa voix) : il se lit dans le bandeau */
.vocal-panneau .vocal-corps { display: flex; flex-direction: column; min-width: 0; text-align: left; }
.vocal-panneau .btn { flex: 0 0 auto; white-space: nowrap; }
.vocal-panneau.avec-texte { align-items: flex-start; border-radius: 24px; width: max-content; max-width: min(820px, calc(100vw - 32px)); }
.vocal-panneau .vocal-texte { font-size: 24px; font-weight: 500; line-height: 1.35; overflow-wrap: anywhere; }
html.aff-t1 .vocal-panneau .vocal-texte { font-size: 28px; }
html.aff-t2 .vocal-panneau .vocal-texte { font-size: 33px; }
@media (prefers-reduced-motion: reduce) { .vocal-panneau .vocal-e { animation: none; } }
.player-chip .av.av-habille { background: none; border: 0; box-shadow: none; width: auto; height: auto; }
.av-simple { font-size: 1em; }
/* Fenêtre « ⚙️ Mes réglages » (lot E ; ex « Aa Mes aides ») : le haut (titre, aperçu) et le bas (« C'est bon ») restent toujours visibles, le milieu défile */
.modal.aff-modal { display: flex; flex-direction: column; padding: 0; overflow: hidden; width: min(760px, 100%); }
.aff-panneau { text-align: left; display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; max-height: inherit; }
.aff-tete { padding: 10px 24px 8px; border-bottom: 3px solid var(--paper-2); flex: 0 0 auto; }
.aff-panneau h2 { text-align: center; margin: 0 0 6px; }
.aff-membres { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin: 4px 0 8px; }
.aff-poste { margin: 0 0 6px; font-size: 16px; text-align: center; }
.aff-apercu { display: flex; align-items: center; gap: 10px; margin: 4px 0 0; }
.aff-apercu-t { font-size: 15px; flex: 0 0 auto; }
.aff-apercu .b-text { flex: 1; }
.aff-intro { display: flex; align-items: center; gap: 10px; margin: 0 0 4px; font-weight: 600; }
.aff-intro .say-btn { width: 44px; height: 44px; flex: 0 0 44px; font-size: 20px; }
.aff-apercu { padding: 6px 12px; font-size: 18px; }
.aff-apercu .say-btn { width: 44px; height: 44px; flex: 0 0 44px; font-size: 20px; }
.aff-defile { overflow: auto; padding: 12px 24px; flex: 1 1 auto; min-height: 0; }
.aff-raccourcis { margin: 8px 0; }
.aff-raccourcis > b { display: block; margin-bottom: 6px; }
.aff-ligne { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 10px 0; }
.aff-tailles { display: flex; gap: 8px; flex-wrap: wrap; }
.aff-familles { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.aff-fam { border: var(--border); border-radius: 16px; background: #fff; }
.aff-fam-tete { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px; padding: 8px 16px; background: none; border: 0; border-radius: 13px; font: inherit; font-family: var(--font-title); font-weight: 700; font-size: 21px; color: var(--ink); text-align: left; cursor: pointer; }
.aff-fam-tete .e { font-size: 28px; }
.aff-fam-tete .t { flex: 1; text-transform: uppercase; letter-spacing: .03em; }
.aff-fam-tete .fl { transition: transform .15s; }
.aff-fam-tete[aria-expanded="true"] .fl { transform: rotate(180deg); }
.aff-fam-corps { padding: 2px 16px 12px; }
.aff-fam-corps[hidden] { display: none; }
.aff-options { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); margin: 8px 0 0; }
/* Un interrupteur qui dit OUI ou NON : le mot et la place du rond le disent, pas seulement la couleur */
.aff-inter { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 8px 14px; text-align: left; font: inherit; font-weight: 700; font-size: 19px;
  background: #fff; border: var(--border); border-radius: 16px; box-shadow: var(--shadow-sm); cursor: pointer; color: var(--ink); }
.aff-inter .e { font-size: 30px; }
.aff-inter .t { flex: 1; display: flex; flex-direction: column; }
.aff-inter .t small { font-weight: 500; font-size: 14px; color: var(--muted); }
.aff-inter .ai-pilule { display: inline-flex; align-items: center; gap: 6px; flex-direction: row-reverse; justify-content: flex-end; min-width: 92px; padding: 3px 5px 3px 12px; border: var(--border); border-radius: 999px; background: #fff; color: var(--ink); }
.aff-inter .ai-etat { font-family: var(--font-title); font-size: 19px; width: 2.4em; text-align: center; }
.aff-inter .ai-rond { width: 26px; height: 26px; border-radius: 50%; background: var(--line); flex: 0 0 auto; }
.aff-inter.on { background: var(--ok-bg); }
.aff-inter.on .ai-pilule { background: var(--ok-plein); color: #fff; flex-direction: row; padding: 3px 12px 3px 5px; }
.aff-inter.on .ai-rond { background: #fff; }
.aff-inter:active { transform: translateY(2px); box-shadow: none; }
.aff-pied { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: flex-end; padding: 10px 24px 14px; border-top: 3px solid var(--paper-2); background: #fff; flex: 0 0 auto; }
@media (max-width: 480px) { .aff-tete, .aff-defile, .aff-pied { padding-left: 14px; padding-right: 14px; } .aff-fam-tete { font-size: 19px; } }
.aff-nb { margin-right: auto; font-family: var(--font-title); font-weight: 700; font-size: 20px; }
html.aff-contraste .aff-inter.on .ai-pilule { background: var(--ok-plein); }
/* (12/10) Le bouton de la barre du haut montre SEULEMENT l'engrenage ⚙️ (plus de « Aa ») : un rond de 60 px comme les autres, l'émoji au centre.
   Le nom du bouton est dans son aria-label et son title (A.boutonAffichage) ; le panneau a le lien « ⚙️ Réglages du poste ». */
.btn-aff { position: relative; }
.btn-aff .aff-roue { display: block; font-size: 32px; line-height: 1; pointer-events: none; }
/* L'accueil (index.html) réduit les boutons ronds de sa barre .menu-haut (52 px, 46 px sur téléphone) : le bouton ⚙️ garde sa cible de 60 px
   et déborde de 4 px par une marge négative. La barre garde sa hauteur sur ordinateur (64 px : l'accueil tient dans 1280 × 720) ; sur téléphone
   elle gagne 6 px, et les deux lignes du menu ne se touchent pas. */
.menu-haut .mh-liens .btn-icon.btn-aff { width: 60px; min-width: 60px; height: 60px; min-height: 60px; margin-block: -4px; font-size: 28px; }
/* Son anneau de focus (6 px, décalé de 4 px) sortirait par le haut de l'écran : le bouton est à 2 px du bord (4 px sur téléphone), l'anneau serait tout entier au-dessus
   de la page, invisible. Décalé de -2 px (collé au bouton), il garde 4 px visibles en haut sur ordinateur et 6 px sur téléphone (avant : 0). */
.menu-haut .mh-liens .btn-icon.btn-aff:focus-visible, .menu-haut .mh-liens .btn-icon.btn-aff.pad-focus { outline-offset: -2px; }
.aff-reglages { display: flex; width: 100%; margin: 14px 0 4px; justify-content: flex-start; font-size: 20px; min-height: 60px; }
.aff-panneau h2 .aff-pastille { display: inline-grid; place-items: center; width: 52px; height: 52px; border: var(--border); border-radius: 14px; background: var(--star); font-size: 28px; line-height: 1; }

/* Test du son (début de séance) */
.test-son { text-align: center; max-width: 560px; }
.test-son .actions { justify-content: center; }

/* « C'est bien toi ? » (session encore ouverte dans un nouvel onglet) */
.qui-es-tu { text-align: center; max-width: 620px; }
.qui-es-tu h2 { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 0 0 12px; }
.qui-avatars { display: flex; flex-wrap: wrap; justify-content: center; gap: 18px; margin: 8px 0 18px; }
.qui-eleve { display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 1.3rem; }
.qui-es-tu .actions { justify-content: center; flex-wrap: wrap; }

/* =========================================================
   MODE TABLEAU (vidéoprojecteur) : classe html.mode-tableau, préfixe .mt-
   (à ne pas confondre avec .voile-tableau = l'écran noir « Regardez au tableau »)
   Cibles : 1280×720 et 1024×768 sans défilement pour un quiz à 4 choix.
   ========================================================= */
/* PLACE RÉSERVÉE sous la barre du tableau : --mt-h = la hauteur réelle de la barre (posée par le cœur, T.monterBarre).
   La page garde cette place en bas : « J'ai compris » et les réponses ne restent jamais cachés sous la barre. */
html.mode-tableau { scroll-padding: 90px 0 calc(var(--mt-h, 88px) + 22px); } /* un bouton montré par le pilote n'est jamais caché sous les barres */
html.mode-tableau body { font-size: 24px; padding-bottom: calc(var(--mt-h, 88px) + 8px); }
html.mode-tableau .bubble { font-size: 30px; }
html.mode-tableau .choice { min-height: 110px; font-size: var(--mt-choix, 28px); } /* (réponses très longues : 25 puis 22 px si l'écran déborde) */
html.mode-tableau .sort-item { font-size: 32px; margin-bottom: 18px; }
html.mode-tableau .bin { min-height: 130px; font-size: 28px; }
html.mode-tableau .m-item { font-size: 24px; }
html.mode-tableau .card-pick { font-size: 22px; }
/* Le repère d'un INVITÉ (deux petites images, les mêmes que sur l'écran de l'adulte) */
.poste-repere { position: fixed; right: 8px; bottom: 8px; z-index: var(--z-repere); display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px 2px 12px; background: var(--card);
  border: 3px solid var(--line); border-radius: 999px; pointer-events: none; font-weight: 700; font-size: 15px; color: var(--muted); }
.poste-repere .rp-img { display: inline-flex; width: 32px; height: 32px; align-items: center; justify-content: center; }
.poste-repere .rp-img svg { width: 32px; height: 32px; }
html.mode-tableau .poste-repere { display: none; }
html.mode-tableau .stars-count, html.mode-tableau .btn-histo, html.mode-tableau .btn-aff, html.mode-tableau .player-chip, html.mode-tableau .moi-menu, html.mode-tableau .btn-main-flottante,
html.mode-tableau .btn-aide, html.mode-tableau a[href*="#/cahier"], html.mode-tableau .mt-sans-cahier { display: none !important; }
html.mode-tableau .stage { margin: 14px auto 20px; }
html.mode-tableau .stage-head { margin-bottom: 12px; }
html.mode-tableau .q-visual { min-height: 0; padding: 10px; margin-bottom: 14px; font-size: 96px; }
html.mode-tableau .q-visual svg { max-height: max(150px, calc(100vh - 500px)); }
html.mode-tableau .choices { gap: 14px; }
html.mode-tableau .choice { gap: 4px; padding: 10px 12px; }
html.mode-tableau .choice .c-visual svg { width: 120px; }
html.mode-tableau .intro { margin: 16px auto; gap: 14px; }
html.mode-tableau .intro .i-emoji { font-size: 96px; }
html.mode-tableau .toast-zone { z-index: var(--z-tableau-toast); bottom: calc(var(--mt-h, 88px) + 16px + var(--st-h, 0px)); } /* au-dessus du sous-titre */
html.mode-tableau .sous-titre { z-index: var(--z-tableau-soustitre); bottom: calc(var(--mt-h, 88px) + 14px); }
/* une fenêtre est ouverte (roue, « Qui est là ? », célébration…) : le sous-titre en haut, pas sur ses boutons */
html.mode-tableau body:has(.overlay) .sous-titre { top: 14px; bottom: auto; }
html.mode-tableau body:has(.overlay) .toast-zone { bottom: calc(var(--mt-h, 88px) + 16px); }
html.mode-tableau .tile.mt-off { opacity: .55; filter: grayscale(.85); cursor: not-allowed; box-shadow: var(--shadow-sm); }
html.mode-tableau .tile.mt-off:hover, html.mode-tableau .tile.mt-off:active { transform: none; box-shadow: var(--shadow-sm); }
.tag.mt-tag { background: #dcefff; }
.mt-incompatible h1 { font-size: clamp(30px, 4vw, 44px); }

/* Barre du mode tableau : en bas, sous les fenêtres (.overlay : 300) */
.mt-barre { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-flottant); display: flex; align-items: center; gap: 10px; min-height: 84px; padding: 6px 12px;
  background: #1d1b2f; color: #fff; border-top: 4px solid var(--star); }
.mt-barre .btn { min-height: 60px; padding: 6px 14px; gap: 6px; font-size: 19px; white-space: nowrap; border-color: #000; box-shadow: 0 3px 0 #000; }
.mt-barre .btn[disabled] { opacity: .35; }
.mt-barre .btn[hidden] { display: none; } /* séance libre SANS prénom (ni liste, ni roue) et portail « En classe » (Formaliser) : boutons sans objet (coeur#49) */
.mt-barre .mt-e { font-size: 24px; line-height: 1; }
.mt-play { flex: 0 0 auto; min-height: 72px !important; min-width: 150px; font-size: 27px !important; background: var(--star); color: var(--ink); }
.mt-play.en-play { background: #fff; }
.mt-info { flex: 0 1 auto; display: flex; flex-direction: column; min-width: 0; max-width: 190px; line-height: 1.15; }
.mt-classe { font-family: var(--font-title); font-size: 21px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mt-etat { font-size: 16px; font-weight: 700; color: #ffd28a; white-space: nowrap; }
.mt-etat.on { color: #8ff0b0; }
.mt-puce { flex: 0 1 auto; display: inline-flex; align-items: center; gap: 8px; min-width: 0; padding: 3px 14px 3px 6px; border: 3px solid var(--star); border-radius: 999px;
  background: #fff; color: var(--ink); font-family: var(--font-title); font-weight: 700; font-size: 26px; }
.mt-puce .mt-micro { font-size: 28px; }
.mt-puce .mt-p-av { display: inline-flex; }
.mt-puce .mt-p-nom { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.mt-puce .mt-chrono { font-family: var(--font-body); font-size: 14px; font-weight: 600; color: var(--muted); white-space: nowrap; }
/* ▶ Play bloqué : le pilote ne sait pas continuer seul (message doux pour l'adulte, sur 2 lignes au plus) */
.mt-bloque { flex: 1 1 260px; min-width: 0; max-width: 460px; padding: 4px 14px; border: 3px solid var(--star); border-radius: 14px; background: #fff7d6; color: var(--ink);
  font-family: var(--font-title); font-weight: 700; font-size: 17px; line-height: 1.2; animation: pop .35s; }
.mt-bloque > span { display: block; }
.mt-bloque[hidden] { display: none; }
.mt-outils { flex: 0 0 auto; margin-left: auto; display: flex; align-items: center; gap: 8px; }
/* Chaque bouton garde son NOM visible (avant : des icônes seules sous 1360 px). Écrans de 1360 px ou moins : le nom passe
   sous l'icône, en petit ; sous 1120 px, seulement son premier mot (.mt-l2 = la suite) ; le prénom de l'élève passe en premier. */
@media (max-width: 1360px) {
  .mt-outils .mt-b { flex-direction: column; gap: 2px; min-width: 62px; padding: 4px 9px; }
  .mt-outils .mt-b .mt-l { font-size: 14px; line-height: 1.1; }
  .mt-info { max-width: 165px; }
}
@media (max-width: 1120px) { .mt-outils .mt-b .mt-l2, .mt-puce .mt-micro, .mt-puce .mt-chrono { display: none; } .mt-outils { gap: 6px; } .mt-info { max-width: 140px; } .mt-play { min-width: 130px; } }
.mt-menu { position: fixed; bottom: calc(var(--mt-h, 88px) + 4px); z-index: var(--z-rappel); display: flex; flex-direction: column; gap: 6px; min-width: 330px; padding: 8px;
  background: #fff; color: var(--ink); border: var(--border); border-radius: 18px; box-shadow: var(--shadow); }
.mt-menu-b { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 6px 14px; border: 3px solid transparent; border-radius: 14px;
  background: #fff; color: var(--ink); font: inherit; font-size: 20px; text-align: left; cursor: pointer; }
.mt-menu-b .e { font-size: 30px; }
.mt-menu-b .t { display: flex; flex-direction: column; line-height: 1.2; }
.mt-menu-b small { font-size: 15px; color: var(--muted); }
.mt-menu-b:hover, .mt-menu-b:focus-visible { background: var(--paper-2); }
.mt-menu-b.on { background: var(--ok-bg); border-color: var(--ok); }
.mt-banniere { position: fixed; left: 50%; top: 84px; transform: translateX(-50%); z-index: var(--z-tableau-banniere); display: flex; align-items: center; gap: 14px; max-width: calc(100vw - 32px);
  padding: 10px 14px 10px 20px; border: var(--border); border-radius: 18px; background: var(--ko); color: #fff; box-shadow: var(--shadow);
  font-family: var(--font-title); font-weight: 700; font-size: 22px; }
.mt-banniere .btn { color: var(--ink); }

/* La roue (au-dessus des fenêtres, sous le voile « Regardez au tableau ») */
.overlay.mt-roue-ov { z-index: var(--z-tableau); background: rgba(15, 14, 30, .82); }
.modal.mt-roue { position: relative; width: min(1040px, 100%); padding: 14px 24px 18px; }
.mt-r-pause { position: absolute; top: 12px; right: 14px; min-height: 60px; font-size: 20px; }
.mt-r-pause[hidden] { display: none; }
.mt-r-info { margin: 0 0 6px; padding: 6px 16px; border: 3px solid var(--star); border-radius: 999px; background: #fff7d6; font-family: var(--font-title); font-weight: 700; font-size: 24px; text-align: center; }
.mt-r-titre { margin: 0; font-size: 40px; }
.mt-r-q { max-width: 860px; margin: 2px auto 4px; font-size: 22px; color: var(--muted); }
.mt-r-zone { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; min-height: min(46vh, 380px); }
.mt-r-disque { flex: 0 0 auto; }
.mt-r-disque svg { display: block; width: min(44vh, 360px); height: auto; }
.mt-r-cote { min-width: 0; max-width: 100%; text-align: center; }
/* sous la roue : le prénom qui passe sous le repère */
.mt-r-nom { min-height: 1.1em; font-family: var(--font-title); font-weight: 700; font-size: 76px; line-height: 1.05; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mt-r-gagnant { display: flex; flex-direction: column; align-items: center; gap: 8px; animation: pop .45s; }
.mt-r-av { font-size: 130px; line-height: 1; }
.mt-r-gnom { font-family: var(--font-title); font-weight: 700; font-size: clamp(96px, 11vw, 116px); line-height: 1; }
.mt-r-actions { align-items: center; margin-top: 10px !important; }

/* « 👥 Qui est là ? » */
.overlay.mt-qui-ov { z-index: var(--z-tableau-fete); }
.modal.mt-qui { width: min(1180px, 100%); padding: 16px 22px 18px; text-align: left; }
.mt-qui-boite h2 { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; margin: 0 0 2px; }
.mt-q-classe { padding: 2px 14px; border: var(--border); border-radius: 999px; background: var(--paper-2); font-size: 24px; }
.mt-q-aide { margin: 0; font-size: 20px; }
.mt-q-compte { margin: 4px 0 6px; font-size: 19px; font-weight: 700; }
.mt-q-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 8px; max-height: 32vh; overflow: auto; padding: 4px; }
.mt-q-eleve { display: flex; align-items: center; gap: 8px; min-height: 62px; padding: 4px 10px 4px 6px; border: 3px solid var(--line); border-radius: 14px;
  background: #fff; color: var(--ink); font: inherit; font-size: 18px; font-weight: 700; text-align: left; cursor: pointer; }
.mt-q-eleve .mt-q-nom { min-width: 0; line-height: 1.15; overflow-wrap: anywhere; } /* jamais coupé : « Noé M. (1) » ≠ « Noé M. (2) » */
.mt-q-eleve.absent { background: #e6e4ec; color: #5f5c74; text-decoration: line-through; }
.mt-q-eleve.absent .mt-q-av { filter: grayscale(1); opacity: .6; }
.mt-q-options { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.mt-q-ligne { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.mt-q-ligne .mt-q-sep { flex: 1; }
.mt-q-choix { min-height: 56px; padding: 6px 18px; border: 3px solid var(--line); border-radius: 999px; background: #fff; color: var(--ink); font: inherit; font-size: 19px; font-weight: 700; cursor: pointer; }
.mt-q-modes { display: grid; grid-template-columns: repeat(3, 1fr); }
.mt-q-mode { display: grid; grid-template-columns: auto 1fr; align-items: center; column-gap: 10px; min-height: 64px; padding: 6px 12px; border: 3px solid var(--line); border-radius: 14px;
  background: #fff; color: var(--ink); font: inherit; font-size: 20px; text-align: left; cursor: pointer; }
.mt-q-mode .e { grid-row: span 2; font-size: 28px; }
.mt-q-mode small { font-size: 15px; color: var(--muted); line-height: 1.2; }
.mt-q-choix.on, .mt-q-mode.on { background: var(--ok-bg); border-color: var(--ok); box-shadow: 0 0 0 3px rgba(31, 157, 85, .35); }
.mt-q-auto { margin: 10px 0 0; font-size: 17px; color: var(--muted); }
.mt-qui .actions { justify-content: center; margin-top: 10px; }
@media (max-width: 760px) { .mt-q-modes { grid-template-columns: 1fr; } }

/* Célébration de la classe */
.modal.mt-fete-modal { width: min(980px, 100%); }
.mt-fete-liste { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; max-height: 38vh; overflow: auto; margin: 10px 0; }
.mt-fete-el { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 140px; padding: 6px; border: 3px solid var(--line); border-radius: 16px; background: var(--paper-2); }
.mt-fete-el b { max-width: 100%; overflow-wrap: anywhere; text-align: center; line-height: 1.15; font-size: 19px; }
.mt-fete-et { font-size: 14px; font-weight: 700; }
.mt-fete-ligne { font-size: 24px; font-weight: 700; }

/* Pilote automatique : l'anneau sur le bouton qui va être pressé tout seul */
.mt-anneau { position: fixed; z-index: var(--z-tableau-anneau); width: 44px; height: 44px; pointer-events: none; }
.mt-anneau svg { display: block; width: 44px; height: 44px; transform: rotate(-90deg); filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .35)); }
.mt-anneau .f { fill: #fff; stroke: #1d1b2f; stroke-width: 5; }
.mt-anneau .p { fill: none; stroke: #ffb400; stroke-width: 8; stroke-dasharray: 100; stroke-dashoffset: 100; animation: mtAnneau 1.5s linear forwards; }
@keyframes mtAnneau { to { stroke-dashoffset: 0; } }
.mt-va-avancer { box-shadow: 0 0 0 6px rgba(255, 180, 0, .8), var(--shadow-sm) !important; }
.mt-a-vous { animation: hintGlow 1.1s ease-in-out infinite !important; } /* le pilote attend le professeur sur ce bouton */

/* « 📒 C'est l'heure du bilan ! » (Formaliser, côté élève) : sous le voile « Regardez au tableau » */
.fz-voile { position: fixed; inset: 0; z-index: var(--z-fete); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  padding: 24px; background: rgba(255, 247, 232, .97); color: var(--ink); text-align: center; animation: fadeIn .25s; }
.fz-voile .fz-e { font-size: clamp(80px, 14vw, 150px); line-height: 1; animation: bob 1.4s ease-in-out infinite; }
.fz-voile .fz-t { font-family: var(--font-title); font-weight: 700; font-size: clamp(36px, 6vw, 72px); }
@media print { .mt-barre, .mt-anneau, .mt-banniere { display: none !important; } }

/* « 📒 Mon bilan » de l'élève (menu des portails, § 4.15) : jamais au tableau */
.bilan-bouton { display: inline-flex; align-items: center; gap: 10px; }
.btn-bilan { gap: 14px; padding: 10px 30px 10px 22px; background: #e3edff; color: var(--ink); text-align: left; }
.btn-bilan .bb-e { font-size: 44px; line-height: 1; }
.btn-bilan .bb-t { display: flex; flex-direction: column; line-height: 1.1; }
.btn-bilan .bb-t b { font-size: 30px; }
.btn-bilan .bb-t small { font-family: var(--font-body); font-size: 18px; font-weight: 600; color: var(--ink-soft, var(--muted)); }
.btn-bilan:hover, .btn-bilan:focus-visible { background: #cfe0ff; }
.btn-bilan.petit { gap: 10px; padding: 6px 22px 6px 16px; }
.btn-bilan.petit .bb-e { font-size: 32px; }
.btn-bilan.petit .bb-t b { font-size: 22px; }
.btn-bilan.petit .bb-t small { font-size: 15px; }
html.mode-tableau .bilan-bouton { display: none !important; }
@media print { .bilan-bouton { display: none !important; } }

/* Texte qui change : la bulle s'allume (le coach, la consigne d'un jeu) */
html.pas-de-son .bubble.nouveau, html.aff-sourd .bubble.nouveau { animation: bulleNouveau 1.4s ease-out; }
@keyframes bulleNouveau { 0% { box-shadow: 0 0 0 0 var(--hint); background: #fff7c2; } 60% { box-shadow: 0 0 0 10px rgba(255, 212, 0, .35); } 100% { box-shadow: var(--shadow); background: #fff; } }
/* Sans son, les sous-titres et les bulles restent bien lisibles */
html.pas-de-son .sous-titre, html.aff-sourd .sous-titre { font-size: 26px; }
@media (prefers-reduced-motion: reduce) { html.pas-de-son .bubble.nouveau, html.aff-sourd .bubble.nouveau { animation: none; outline: 4px solid var(--hint); } }

/* « Écran calme » (Aa, lot E) : rien ne bouge. Les animations et les transitions s'arrêtent tout de suite (elles finissent dans
   leur état final) ; le flash qui remplace un son (sous-titres) reste visible, sans mouvement. */
html.aff-calme *, html.aff-calme *::before, html.aff-calme *::after {
  animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
  transition-duration: .01ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
html.aff-calme .flash-son { animation: none !important; opacity: 1; }
html.aff-calme .btn-main-flottante.levee .bm-e, html.aff-calme .btn-aide.levee, html.aff-calme .btn-main-barre.levee .bm-e { animation: none !important; }
html.aff-calme .overlay.arrivee::before { animation: none !important; opacity: 1; }

/* =====================================================================
   LA FENÊTRE DU PERSONNAGE (« le personnage en grand », lot A, 02/11/2026 ; js/atelier.js, « LA FENÊTRE DU PERSONNAGE »)
   Une consigne : le personnage en grand au milieu, sa phrase, 🔊 et « ✅ J'ai compris ». Voile très sombre (88 %) sous la barre du site.
   Légère (.legere : étape, phrase longue sans son, tableau, essai administrateur) : voile clair, les clics passent, elle se range seule.
   Calque : --z-perso (270 : entre le rappel 260 et les menus 280) ; au-dessus : menus de la barre du site, A.modal, messages, curseur fantôme,
   « Regardez au tableau », « J'arrive ». Ce n'est pas une .overlay : A.SEL_FENETRES dit « une fenêtre est ouverte ».
   ===================================================================== */
.perso-voile {
  position: fixed; left: 0; right: 0; bottom: 0; top: 0; z-index: var(--z-perso, 270);
  display: flex; align-items: center; justify-content: center; padding: 18px 20px; overflow: auto;
  background: rgba(24, 5, 66, .88);
}
.perso-voile.entre { animation: fadeIn .2s; }
.perso-voile.legere { background: rgba(24, 5, 66, .5); pointer-events: none; }
/* (coeur#96, coeur#97, 03/11) : dans la fenêtre LÉGÈRE, seuls ses boutons (🔊) prennent le geste ; un toucher sur la carte (bulle, dessin,
   place vide autour) passe à la page dessous : il range la fenêtre (écoute « premier geste ») ET touche ce qui est dessous, en un seul geste */
.perso-voile.legere .perso-fenetre { pointer-events: none; }
.perso-voile.legere .perso-fenetre button { pointer-events: auto; }
.perso-fenetre {
  display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "pourquoi pourquoi" "visage bulle" "bas bas";
  align-items: center; gap: 22px 30px; width: min(980px, 100%); margin: auto; outline: none;
}
.perso-visage { grid-area: visage; position: relative; font-size: 168px; line-height: 1; text-align: center; filter: drop-shadow(0 8px 0 rgba(12, 2, 40, .5)); }
.perso-visage .c-face { display: inline-block; font-size: inherit; line-height: 1; animation: bob 2.6s ease-in-out infinite; }
.perso-visage .v-coach-boulon { width: 1.05em; height: 1.15em; }
.perso-fenetre .perso-bulle { grid-area: bulle; position: relative; font-size: 34px; line-height: 1.3; padding: 24px 22px 24px 28px; border-radius: 28px; gap: 18px; zoom: 1; }
.perso-fenetre .perso-bulle::before {
  content: ''; position: absolute; display: block; left: -24px; right: auto; top: 50%; bottom: auto; margin: -16px 0 0 0;
  border: 16px solid transparent; border-left-width: 0; border-right: 24px solid #fff;
}
.perso-fenetre .perso-bulle > .say-btn { width: 74px; height: 74px; flex: 0 0 74px; font-size: 36px; }
.perso-fenetre .perso-bulle.change { animation: pop .35s; }
.perso-bas { grid-area: bas; display: flex; justify-content: center; align-items: center; gap: 16px; flex-wrap: wrap; }
.perso-ok { min-width: min(400px, 100%); }
.perso-ok.perso-appel { animation: pulse .6s 2; }
/* Projets : « 🤔 Pourquoi ? » de la tâche (t.pourquoi), au-dessus de la phrase */
.perso-pourquoi { grid-area: pourquoi; justify-self: center; max-width: 100%; padding: 8px 18px; border-radius: 16px; background: #f3e8ff; color: #4c1d95; font-size: 24px; font-weight: 600; line-height: 1.3; }
/* « Aa » : la taille vient de font-size (le zoom de .bubble faisait déborder la bulle) */
html.aff-t1 .perso-fenetre .perso-bulle { font-size: 40px; }
html.aff-t2 .perso-fenetre .perso-bulle { font-size: 46px; }
html.aff-contraste .perso-voile { background: rgba(0, 0, 0, .9); }
html.aff-contraste .perso-voile.legere { background: rgba(0, 0, 0, .6); }
html.aff-contraste .perso-fenetre .perso-bulle { border: 3px solid #000; }
/* téléphone, tablette en hauteur : le personnage au-dessus de sa bulle */
@media (max-width: 760px) {
  .perso-voile { padding: 12px; align-items: flex-start; }
  .perso-fenetre { grid-template-columns: minmax(0, 1fr); grid-template-areas: "pourquoi" "visage" "bulle" "bas"; gap: 16px; justify-items: stretch; }
  .perso-visage { font-size: 104px; }
  .perso-fenetre .perso-bulle { font-size: 27px; padding: 16px 14px 16px 18px; gap: 12px; }
  .perso-fenetre .perso-bulle::before { left: 50%; top: -22px; margin: 0 0 0 -16px; border: 16px solid transparent; border-top-width: 0; border-right-color: transparent; border-bottom: 22px solid #fff; }
  .perso-fenetre .perso-bulle > .say-btn { width: 60px; height: 60px; flex: 0 0 60px; font-size: 28px; }
  .perso-ok { width: 100%; min-width: 0; font-size: 28px; padding: 12px 16px; }
  html.aff-t1 .perso-fenetre .perso-bulle { font-size: 31px; }
  html.aff-t2 .perso-fenetre .perso-bulle { font-size: 35px; }
  /* (coeur#46, coeur#83) le 🔊 passe sous le texte quand 6 em ne tiennent plus à côté */
  html.aff-t1 .perso-fenetre .perso-bulle, html.aff-t2 .perso-fenetre .perso-bulle { flex-wrap: wrap; }
  html.aff-t1 .perso-fenetre .perso-bulle .b-text, html.aff-t2 .perso-fenetre .perso-bulle .b-text { flex: 1 1 6em; }
  html.aff-t1 .perso-fenetre .perso-bulle > .say-btn, html.aff-t2 .perso-fenetre .perso-bulle > .say-btn { margin-left: auto; }
}
/* tableau : la barre du tableau reste visible sous la fenêtre (légère) */
html.mode-tableau .perso-voile { bottom: var(--mt-h, 88px); }
/* animations réduites, « écran calme » : rien ne bouge */
@media (prefers-reduced-motion: reduce) {
  .perso-visage .c-face, .perso-voile.entre, .perso-fenetre .perso-bulle.change, .perso-ok.perso-appel { animation: none; }
}
@media print { .perso-voile { display: none; } }
/* lecteur d'écran : la zone « aria-live » des messages, étapes et indices (la bulle de la barre ne l'est pas) */
.perso-annonce { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* LE PERSONNAGE DANS LA CARTE (A.carteParle : accueil « ▶ C'est parti ! », leçon) : son visage, sa phrase et 🔊 */
.perso-carte { display: flex; align-items: center; gap: 18px; width: min(900px, 100%); text-align: left; }
.perso-carte .perso-visage { font-size: 92px; filter: none; flex: 0 0 auto; }
.perso-carte .perso-visage .c-face { animation: none; }
.perso-carte .bubble { flex: 1 1 auto; min-width: 0; zoom: 1; font-size: 27px; line-height: 1.3; }
.perso-carte .bubble::before { content: ''; position: absolute; display: block; left: -18px; top: 50%; bottom: auto; margin-top: -12px; border: 12px solid transparent; border-left-width: 0; border-right: 18px solid #fff; }
html.aff-t1 .perso-carte .bubble { font-size: 31px; }
html.aff-t2 .perso-carte .bubble { font-size: 36px; }
.pix-intro .perso-carte { width: min(820px, 100%); }
.pix-intro .perso-carte .perso-visage { font-size: 72px; }
.pix-intro .perso-carte .bubble { font-size: 25px; padding: 10px 14px 10px 18px; }
html.aff-t1 .pix-intro .perso-carte .bubble { font-size: 29px; }
html.aff-t2 .pix-intro .perso-carte .bubble { font-size: 34px; }
@media (max-width: 760px) {
  .perso-carte { flex-direction: column; gap: 10px; }
  .perso-carte .perso-visage, .pix-intro .perso-carte .perso-visage { font-size: 64px; }
  .perso-carte .bubble { font-size: 23px; width: 100%; }
  html.aff-t1 .perso-carte .bubble { font-size: 27px; }
  html.aff-t2 .perso-carte .bubble { font-size: 31px; }
  .perso-carte .bubble::before { left: 50%; top: -18px; margin: 0 0 0 -12px; border: 12px solid transparent; border-top-width: 0; border-right-color: transparent; border-bottom: 18px solid #fff; }
  html.aff-t1 .perso-carte .bubble, html.aff-t2 .perso-carte .bubble { flex-wrap: wrap; }
  html.aff-t1 .perso-carte .bubble .b-text, html.aff-t2 .perso-carte .bubble .b-text { flex: 1 1 6em; }
  html.aff-t1 .perso-carte .bubble > .say-btn, html.aff-t2 .perso-carte .bubble > .say-btn { margin-left: auto; }
}
/* (« Aa » zoome les .bubble : la fenêtre et la carte règlent leur taille par font-size, plus haut) */
html .perso-fenetre .perso-bulle, html .perso-carte .bubble { zoom: 1; }
