/* ==========================================================================
   Sessions live.

   Deux publics, deux contraintes opposées :

   — Le formateur projette sur un vidéoprojecteur, souvent en 1280×720, dans
     une salle éclairée. Le code doit se lire du dernier rang : on le pose en
     très grand, en chiffres tabulaires, sur de l'encre. Les tailles sont en
     `vmin` pour que le plein écran et la fenêtre donnent le même résultat.
   — Le participant est sur un téléphone, debout. Une action par écran, des
     cibles de 52 px, rien à faire défiler avant d'avoir agi.
   ========================================================================== */

/* --- Écran projetable ----------------------------------------------------- */
.live-projection-wrap{display:grid;gap:12px}

.live-projection{
  display:grid;gap:clamp(12px,2vmin,28px);justify-items:center;
  padding:clamp(20px,3.5vmin,48px);
  border-radius:var(--radius-panel);
  background:var(--color-text);color:var(--color-on-dark);
  text-align:center;
}
/* Cet écran-ci n'est JAMAIS mis en plein écran : il est recréé toutes les trois
   secondes par l'interrogation de la salle, et le navigateur sort du plein
   écran dès que l'élément concerné quitte le document. Le plein écran a son
   propre conteneur, stable, en bas de ce fichier (`.live-scene`). */

.live-projection-step{
  font-family:var(--font-mono);font-size:clamp(.75rem,1.6vmin,1.1rem);
  font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--color-accent-light);
}
.live-projection-grid{
  display:grid;gap:clamp(20px,4vmin,56px);align-items:center;justify-items:center;
  grid-template-columns:1fr;
}
@media(min-width:720px){.live-projection-grid{grid-template-columns:auto auto}}

.live-projection-label{
  font-family:var(--font-mono);font-size:clamp(.7rem,1.4vmin,1rem);
  letter-spacing:.1em;text-transform:uppercase;opacity:.75;
}
/* Le code. `ch` plutôt que `rem` : six chiffres tabulaires occupent toujours
   la même largeur, donc la ligne ne saute pas d'un tirage à l'autre. */
.live-code{
  font-variant-numeric:tabular-nums;font-weight:700;
  font-size:clamp(3.5rem,15vmin,11rem);line-height:1;letter-spacing:.04em;
  margin:clamp(4px,1vmin,14px) 0;
}
.live-projection-url{
  font-family:var(--font-mono);font-size:clamp(.8rem,1.8vmin,1.35rem);
  word-break:break-all;opacity:.85;
}
.live-projection-qr{display:grid;gap:10px;justify-items:center}
/* Le QR est dessiné en noir sur blanc : sur fond d'encre il lui faut sa
   propre réserve claire, sinon les lecteurs peinent.

   La taille est calée sur ce qu'un vidéoprojecteur rend vraiment. Mesuré en
   1280×720, la définition courante d'un projecteur de salle : 26vmin donnaient
   187 px, soit un carré de huit centimètres sur un écran de deux mètres —
   inscannable depuis le fond. Le plancher passe à 220 px et la part de l'écran
   à 34vmin, ce qui donne 245 px en 720p et 367 px en 1080p. */
.live-projection-qr svg{
  background:#FFFFFF;padding:clamp(8px,1.4vmin,16px);border-radius:12px;
  width:clamp(220px,34vmin,420px);height:auto;
}
.live-qr-fallback{max-width:28ch;font-size:.95rem;opacity:.85}
.live-projection-foot{
  font-family:var(--font-mono);font-size:clamp(.75rem,1.6vmin,1.15rem);
  letter-spacing:.06em;opacity:.8;
}
.live-projection-actions{display:flex;flex-wrap:wrap;gap:10px}
.live-fullscreen{min-height:48px}

/* --- Panneaux du formateur ------------------------------------------------ */
.live-panel{min-width:0}
.live-actions{display:flex;flex-wrap:wrap;gap:10px}
.live-actions .button{min-height:48px}
.live-go{flex:1 1 220px}
.live-empty{font-size:.95rem;padding:14px;border-radius:var(--radius-card);background:var(--color-surface-high)}
.live-error{
  margin:0;padding:12px 14px;border-radius:var(--radius-card);
  background:var(--color-error-soft);color:var(--color-error-strong);font-size:.95rem;
}
.live-success{
  margin:0;padding:12px 14px;border-radius:var(--radius-card);
  background:var(--color-success-soft);color:var(--color-success);font-size:.95rem;
}

.live-roster,.live-progress-list,.live-misconceptions,.live-answer-list,.live-recent-list{
  list-style:none;margin:0;padding:0;display:grid;gap:8px;
}
.live-roster-row{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:10px 14px;border:1px solid var(--color-border);
  border-radius:var(--radius-card);background:var(--color-surface);
}
.live-roster-name{font-weight:600;min-width:0;overflow-wrap:anywhere}
.live-remove{min-height:44px;padding-inline:14px;flex:none}

/* --- Suivi pendant le test ------------------------------------------------ */
.live-progress-row{
  display:grid;gap:6px 12px;grid-template-columns:1fr auto;align-items:center;
  padding:10px 14px;border:1px solid var(--color-border);
  border-radius:var(--radius-card);background:var(--color-surface);
}
.live-progress-row.is-done{border-color:var(--color-success);background:var(--color-success-soft)}
.live-progress-name{font-weight:600;min-width:0;overflow-wrap:anywhere}
.live-progress-count{font-family:var(--font-mono);font-size:.82rem;font-variant-numeric:tabular-nums}
.live-progress-track,.live-block-track{
  grid-column:1 / -1;height:6px;border-radius:999px;background:var(--color-track);overflow:hidden;
}
.live-progress-track i,.live-block-track i{display:block;height:100%;background:var(--color-accent);border-radius:999px}
/* La barre avance par pas de trois secondes : une transition la rend lisible
   au lieu de la faire sauter. */
@media(prefers-reduced-motion:no-preference){
  .live-progress-track i{transition:width .6s ease}
}

/* --- Rapport de classe ---------------------------------------------------- */
.live-blocks,.live-learner-blocks{
  display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(min(100%,230px),1fr));
}
.live-block{
  display:grid;gap:6px;padding:14px;border:1px solid var(--color-border);
  border-radius:var(--radius-card);background:var(--color-surface);min-width:0;
}
.live-block-title{font-weight:600;font-size:.95rem;overflow-wrap:anywhere}
.live-block-estimate{font-size:1.9rem;font-weight:600;line-height:1;font-variant-numeric:tabular-nums}
.live-block-level{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.05em;text-transform:uppercase}

.live-misconceptions li{
  display:grid;gap:4px 12px;grid-template-columns:auto 1fr;align-items:baseline;
  padding:12px 14px;border:1px solid var(--color-border);
  border-radius:var(--radius-card);background:var(--color-surface);
}
.live-misconception-share{
  font-size:1.3rem;font-weight:700;font-variant-numeric:tabular-nums;color:var(--color-error-strong);
}
.live-misconception-skill{font-weight:600;overflow-wrap:anywhere}
.live-misconceptions .teacher-kpi-detail{grid-column:2}

/* Un tableau ne se redimensionne pas : il défile dans sa propre boîte, sinon
   c'est la page entière qui part en largeur sur un téléphone. */
.live-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.live-table{width:100%;border-collapse:collapse;font-size:.92rem;min-width:520px}
.live-table th,.live-table td{padding:10px 12px;text-align:left;border-bottom:1px solid var(--color-border)}
.live-table th{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.05em;text-transform:uppercase}
.live-table-row{cursor:pointer}
.live-table-row:hover,.live-table-row:focus-visible{background:var(--color-accent-soft)}
.live-table-row:focus-visible{outline:2px solid var(--color-accent-strong);outline-offset:-2px}

.live-answer-list{grid-template-columns:repeat(auto-fill,minmax(min(100%,200px),1fr))}
.live-answer-list li{
  display:flex;justify-content:space-between;gap:10px;padding:8px 12px;
  border-radius:var(--radius-xs);background:var(--color-surface-high);font-size:.85rem;
}
.live-answer-list li.is-wrong{background:var(--color-error-soft);color:var(--color-error-strong)}
.live-answer-skill{min-width:0;overflow-wrap:anywhere}
.live-answer-mark{font-family:var(--font-mono);font-size:.7rem;text-transform:uppercase;flex:none}

.live-recent{display:grid;gap:8px}
.live-recent-list li{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;
  padding:10px 14px;border:1px solid var(--color-border);
  border-radius:var(--radius-card);background:var(--color-surface);
}
.live-recent-code{font-family:var(--font-mono);font-weight:600;font-variant-numeric:tabular-nums}
.live-recent-meta{font-size:.85rem;flex:1 1 140px}
.live-recent-open{min-height:44px}

/* --- Écrans du participant ------------------------------------------------ */
/* Pas de navigation, pas d'en-tête d'application : un invité n'a nulle part
   d'autre où aller, et chaque élément en plus est une occasion de se tromper. */
.live-guest{
  min-height:100svh;display:grid;align-items:start;justify-items:center;
  padding:clamp(20px,6vw,48px) clamp(16px,5vw,32px);
  padding-bottom:max(clamp(20px,6vw,48px),env(safe-area-inset-bottom));
  background:var(--color-bg);
}
.live-guest-card{
  width:min(100%,440px);display:grid;gap:18px;
  padding:clamp(22px,6vw,34px);
  border:1px solid var(--color-border);border-radius:var(--radius-panel);
  background:var(--color-surface);
}
.live-guest-brand{
  font-family:var(--font-mono);font-size:.7rem;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--color-accent-strong);
}
.live-guest-code{
  font-family:var(--font-mono);font-size:.8rem;letter-spacing:.08em;
  font-variant-numeric:tabular-nums;
}
.live-guest-title{font-size:clamp(1.5rem,6vw,2rem);line-height:1.1;letter-spacing:-.03em}
.live-guest-lead{font-size:1rem;line-height:1.55}
.live-guest-hint{font-size:.88rem;line-height:1.5}
.live-guest-form{display:grid;gap:10px}
.live-guest-label{font-weight:600;font-size:.9rem}
.live-guest-input,.live-code-input{
  width:100%;min-height:52px;padding:12px 14px;
  border:1px solid var(--color-border-strong);border-radius:var(--radius-button);
  background:var(--color-surface);color:var(--color-text);
  /* 16 px au minimum : en dessous, iOS zoome à la mise au point et la page
     part de travers. */
  font-size:1rem;font-family:inherit;
}
.live-guest-input:focus-visible,.live-code-input:focus-visible{
  outline:2px solid var(--color-accent-strong);outline-offset:1px;
}
.live-code-input{
  font-family:var(--font-mono);font-size:clamp(1.8rem,9vw,2.6rem);
  font-variant-numeric:tabular-nums;letter-spacing:.14em;text-align:center;
  min-height:72px;
}
.live-guest-submit{min-height:52px;justify-content:center}
.live-guest-submit[disabled]{opacity:.5;pointer-events:none}

/* Trois points qui respirent : la salle d'attente doit avoir l'air vivante,
   sinon on croit que c'est bloqué et on recharge. */
.live-waiting-mark{display:flex;gap:8px;justify-content:center;padding:6px 0}
.live-waiting-mark span{
  width:10px;height:10px;border-radius:50%;background:var(--color-accent);opacity:.3;
}
@media(prefers-reduced-motion:no-preference){
  .live-waiting-mark span{animation:livePulse 1.4s ease-in-out infinite}
  .live-waiting-mark span:nth-child(2){animation-delay:.2s}
  .live-waiting-mark span:nth-child(3){animation-delay:.4s}
}
@keyframes livePulse{0%,100%{opacity:.25;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}

/* --- Garder son résultat -------------------------------------------------- */
.live-keep{
  display:grid;gap:12px;margin-top:20px;padding:18px;
  border:1px solid var(--color-border);border-radius:var(--radius-card);
  background:var(--color-accent-soft);
}
.live-keep h2{font-size:1.1rem;letter-spacing:-.02em}
.live-keep p{font-size:.95rem;line-height:1.5}
.live-keep-form{display:grid;gap:10px}
.live-keep-form .button{min-height:48px}

/* --- La coquille, en session live ----------------------------------------
   Un participant invité n'a ni parcours ni profil : les onglets et l'en-tête
   pointeraient vers des écrans qui lui sont fermés. On les retire, et la page
   occupe toute la hauteur pour que le test soit la seule chose à l'écran.
   La classe tombe dès qu'un vrai compte prend la place — la conversion en fin
   de test, par exemple — et tout revient sans rien recharger.             */
.live-guest-view .bottom-nav,
.live-guest-view .shell-status,
.live-guest-view .app-header{display:none}
.live-guest-view .content-stage{padding:0}
.live-guest-view .page{max-width:none}
/* L'écran de saisie se centre ; celui du test garde sa mise en page, sinon
   une question longue serait coincée au milieu d'une boîte. */
.live-guest-view .page:has(.live-guest){padding:0}

/* ==========================================================================
   Grille de positionnement — écran de question.

   Un téléphone tenu debout, trente-deux fois de suite. Tout ce qui n'aide pas
   à répondre a été retiré : pas de score en cours, pas de minuterie, pas de
   couleur de correction. L'avancement par bloc dit où l'on en est, jamais
   comment on s'en sort.
   ========================================================================== */
.pos-page{display:grid;gap:14px}

.pos-progress{display:grid;gap:6px}
.pos-blocks{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(5,1fr);gap:6px;
}
.pos-block{display:grid;gap:3px;justify-items:center;font-size:.7rem}
.pos-block-id{
  font-family:var(--font-mono);font-weight:600;font-size:.72rem;
  color:var(--color-text);opacity:.5;
}
.pos-block.is-current .pos-block-id{opacity:1;color:var(--color-accent-strong)}
.pos-block.is-done .pos-block-id{opacity:.85}
.pos-block-rail{
  display:block;width:100%;height:4px;border-radius:999px;
  background:var(--color-track);overflow:hidden;
}
.pos-block-rail i{display:block;height:100%;background:var(--color-accent);border-radius:999px}
.pos-block.is-done .pos-block-rail i{background:var(--color-success)}
.pos-block-count{
  font-family:var(--font-mono);font-size:.62rem;font-variant-numeric:tabular-nums;opacity:.6;
}
.pos-block-title{font-size:.85rem;font-weight:600}
.pos-duree{font-size:.82rem;opacity:.8}

/* L'étape de certitude. Trois gestes, aucun présélectionné : « sûr » coché
   d'avance fausserait la moitié du rapport. */
.pos-certitude-step{
  display:grid;gap:10px;margin-top:16px;padding:16px;
  border:1px solid var(--color-accent);border-radius:var(--radius-card);
  background:var(--color-accent-soft);
}
.pos-certitude-question{font-weight:600;font-size:1.05rem}
.pos-certitude-choices{display:grid;gap:8px}
@media(min-width:420px){.pos-certitude-choices{grid-template-columns:repeat(3,1fr)}}
.pos-certitude{min-height:52px;justify-content:center}
.pos-certitude[disabled]{opacity:.5}
.pos-certitude-aide{font-size:.8rem;line-height:1.45;opacity:.85}
.pos-valider{min-height:52px;width:100%}
.pos-error{
  margin:0;padding:10px 12px;border-radius:var(--radius-card);
  background:var(--color-error-soft);color:var(--color-error-strong);font-size:.9rem;
}
.live-start-choix{display:grid;gap:8px}
.live-start-choix .button{min-height:52px;justify-content:center;text-align:center}

/* --- Rapport de classe : la répartition, et ce que révèle une erreur ----- */
.live-repartition{display:grid;gap:4px}
.live-repartition-rail{
  display:flex;height:8px;border-radius:999px;overflow:hidden;background:var(--color-track);
}
.live-repartition-rail i{display:block;height:100%}
.live-repartition-rail .is-maitrise{background:var(--color-success)}
.live-repartition-rail .is-en-cours{background:var(--color-accent)}
.live-repartition-rail .is-a-construire{background:var(--color-error)}
.live-repartition-legende{font-size:.72rem;line-height:1.4}

.live-misconception-reveals{
  grid-column:2;font-size:.88rem;line-height:1.5;margin:2px 0 0;
}
.live-misconception-choix{grid-column:2;font-size:.82rem;margin:0}
.live-misconception-choix.is-bonne{color:var(--color-success)}
.live-incomplet{
  display:inline-block;margin-left:6px;padding:1px 6px;border-radius:999px;
  background:var(--color-warning-soft);color:var(--color-warning);
  font-family:var(--font-mono);font-size:.62rem;text-transform:uppercase;letter-spacing:.04em;
}

/* Une alerte pendant le test : retiré de la salle, code expiré, envoi en
   attente. Elle se place au-dessus de la question, en haut de l'écran, parce
   qu'elle change ce que la personne devrait faire. */
.live-alerte{
  margin:0 0 12px;padding:12px 14px;
  border:1px solid var(--color-warning);border-radius:var(--radius-card);
  background:var(--color-warning-soft);color:var(--color-warning);
  font-size:.92rem;line-height:1.5;
}

/* Le rappel de la réponse choisie, pendant l'étape de certitude. Les options
   sont repliées : la question « vous étiez ? » doit être ce qu'on voit, pas
   ce qu'on trouve après avoir fait défiler trente-deux fois. */
.pos-rappel{
  display:grid;gap:3px;margin:0 0 12px;padding:12px 14px;
  border:1px solid var(--color-border);border-radius:var(--radius-card);
  background:var(--color-surface-high);font-size:.95rem;line-height:1.5;
}
.pos-rappel-etiquette{
  font-family:var(--font-mono);font-size:.66rem;letter-spacing:.06em;
  text-transform:uppercase;opacity:.7;
}

/* Une liste de participants ne doit jamais repousser les commandes hors de
   l'écran. Mesuré avec 55 personnes : la page faisait 5 070 px et le bouton
   « Lancer le test » se trouvait à 4 839 px. Elle défile donc chez elle. */
.live-liste-defilante{
  max-height:min(46vh,420px);overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  border:1px solid var(--color-border-faint);border-radius:var(--radius-card);
  padding:8px;
}
.live-progress-row{grid-template-columns:1fr auto auto}
.live-progress-row .live-remove{grid-column:3}

/* ==========================================================================
   L'écran projeté en plein écran — un conteneur qui ne bouge jamais.

   Il vit dans `<body>`, hors de `.content-stage`, parce que l'écran du
   formateur est remplacé en entier toutes les trois secondes et qu'un élément
   en plein écran retiré du document fait sortir le navigateur du plein écran.
   Voir `js/components/liveProjector.js`.

   Deux modes : le plein écran natif, et le repli pleine page quand le
   navigateur le refuse. Les deux donnent la même image ; seules les barres du
   navigateur restent dans le second.

   Rien ici ne grandit avec l'effectif : pas de liste de noms, donc aucune
   hauteur qui dépend du nombre de participants. À zéro, dix ou soixante, la
   mise en page est la même.
   ========================================================================== */
.live-scene{display:none}
.live-scene.is-ouvert{display:block}
.live-scene.is-repli{
  position:fixed;z-index:var(--z-modal);inset:0;
}
.live-scene,
.live-scene .live-scene-inner{background:var(--color-text);color:var(--color-on-dark)}

/* `100%` en plein écran natif, `100dvh` en repli : dans le premier cas
   l'élément EST la fenêtre, dans le second il faut lui dire sa hauteur. */
.live-scene-inner{
  box-sizing:border-box;height:100%;min-height:100%;
  display:grid;align-content:center;justify-items:center;
  gap:clamp(10px,1.8vmin,26px);
  padding:clamp(16px,3vmin,56px);
  text-align:center;
  /* Aucun débordement possible : si une définition très basse rendait le
     contenu plus grand que l'écran, il défile chez lui plutôt que de couper
     le bouton « Terminer la session ». */
  overflow:auto;
}
.live-scene.is-repli .live-scene-inner{height:100dvh;min-height:100dvh}

.live-scene-step{
  font-family:var(--font-mono);font-size:clamp(.75rem,1.6vmin,1.1rem);
  font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--color-accent-light);
}
.live-scene-grid{
  display:grid;gap:clamp(18px,3.4vmin,52px);align-items:center;justify-items:center;
  grid-template-columns:1fr;
}
@media(min-width:720px){.live-scene-grid{grid-template-columns:auto auto}}

.live-scene-label{
  font-family:var(--font-mono);font-size:clamp(.7rem,1.4vmin,1rem);
  letter-spacing:.1em;text-transform:uppercase;opacity:.75;
}
/* Le code, lu du dernier rang. Mesuré en 1280×720 : 14vmin donnent 100 px, et
   le plancher à 5.5rem tient les définitions plus basses. */
.live-scene-chiffres{
  font-variant-numeric:tabular-nums;font-weight:700;
  font-size:clamp(5.5rem,14vmin,11rem);line-height:1;letter-spacing:.04em;
  margin:clamp(4px,1vmin,14px) 0;
}
.live-scene-url{
  font-family:var(--font-mono);font-size:clamp(.8rem,1.8vmin,1.35rem);
  word-break:break-all;opacity:.85;
}
.live-scene-qr{display:grid;gap:8px;justify-items:center}
/* Même réserve claire et même plancher que l'écran de la page : 220 px au
   minimum, ce qui se scanne à trois mètres. */
.live-scene-qr svg{
  background:#FFFFFF;padding:clamp(8px,1.4vmin,16px);border-radius:12px;
  width:clamp(220px,30vmin,400px);height:auto;display:block;
}
.live-scene-compteur{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  font-size:clamp(1.1rem,3vmin,2.4rem);font-weight:600;letter-spacing:.04em;
}
.live-scene-detail{
  font-family:var(--font-mono);font-size:clamp(.75rem,1.5vmin,1.1rem);
  letter-spacing:.05em;opacity:.8;min-height:1.2em;
}
.live-scene-actions{display:flex;flex-wrap:wrap;gap:12px;justify-content:center}
.live-scene-actions .button{
  min-height:clamp(48px,6vmin,72px);
  font-size:clamp(1rem,1.9vmin,1.5rem);
  padding-inline:clamp(18px,3vmin,40px);
}
.live-scene-action[disabled]{opacity:.45;pointer-events:none}
/* Sortir doit rester lisible sans voler l'attention au code. */
.live-scene-quit{
  background:transparent;color:var(--color-on-dark);
  border:1px solid rgba(255,255,255,.45);
}
