/* Défi calcul (lot 1a, 03/10/2026 ; glisse-nombres et tableau à flèches au lot 1b).
   Première partie : ce qui vient de Défi tables, copié puis adapté (la
   page, le bandeau de suivi, le cadre et son échelle, l'accueil, le pavé,
   la série, le verdict, le rekenrek). Deuxième partie : ce que Défi tables
   n'a pas (le parcours par palier, les niveaux, les aides, la phrase-bilan),
   repris des maquettes de l'étape 2. Défi tables n'est pas touché : rien
   n'est partagé entre les deux applis. */
:root {
  --ink: #143451;
  --muted: #506b7d;
  --line: #d4e3ed;
  --blue: #0755b8;
  --teal: #087a71;
  --green: #147447;
  --green-soft: #e5f7eb;
  --red: #a93030;
  --red-soft: #ffebeb;
  color-scheme: light;
  font-family: Inter, ui-rounded, "Arial Rounded MT Bold", "Segoe UI", sans-serif;
}

@media (min-width: 1024px) {
  :root { font-family: Inter, ui-rounded, Nunito, "Arial Rounded MT Bold", "Segoe UI", sans-serif; }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}
html { min-height: 100%; background: #edf5fb; -webkit-text-size-adjust: 100%; }
body {
  /* Relecture 1 (05/11/2026) : sur iPhone, Safari prend pour 100vh la
     hauteur de l'écran barres cachées, plus grande que ce qu'on voit ; la
     page « débordait » toujours et « À retenir » rapetissait jusqu'au
     minimum. 100svh : la hauteur visible avec les barres (100vh reste pour
     les navigateurs qui ne connaissent pas svh). */
  min-height: 100vh;
  min-height: 100svh;
  margin: 0;
  color: var(--ink);
  background:
    radial-gradient(circle at 8% 5%, rgba(8, 168, 159, .14), transparent 26rem),
    radial-gradient(circle at 92% 7%, rgba(250, 204, 21, .18), transparent 24rem),
    linear-gradient(#fbfdff, #edf5fb);
}

button,
a,
input { font: inherit; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

/* Lot R3 (A19) : le contour du clavier était à 1,6:1 sur blanc — il
   fallait 3:1 pour un repère non textuel, et au vidéoprojecteur il ne se
   voyait pas. Le même bleu, plein : 4,6:1. */
button:focus-visible,
a:focus-visible {
  outline: 3px solid #0f6cf9;
  outline-offset: 3px;
}

h1[tabindex="-1"]:focus { outline: none; }

.shell { width: min(850px, calc(100% - 28px)); margin: auto; padding-bottom: 30px; }
/* Audit 3 (01/10/2026) : sur ordinateur, le cadre blanc tient toujours
   entier dans l'écran. ajusterEchelle() mesure la place et pose
   l'échelle : jamais plus grand que nature dans une fenêtre, un peu plus
   petit quand ça ne rentre pas ; en plein écran, agrandi jusqu'à remplir
   la hauteur. 1 sur un téléphone ou une tablette. Jamais à l'impression :
   la fiche a sa propre mise à l'échelle. */
@media screen {
  .shell { zoom: var(--echelle, 1); }
}
/* Le temps d'une mesure : sans le pied de page ni la hauteur minimale du
   corps, la hauteur de la page est celle du cadre. */
body.mesure-cadre { min-height: 0 !important; }
.topbar {
  min-height: 70px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
/* Suivi de classe : un repère discret, mais toujours visible, sur tous les
   écrans — l'élève doit savoir en permanence que son travail part chez son
   professeur. Il occupe une ligne entière sous le logo et les boutons. */
.suivi-repere { flex: 1 0 100%; display: flex; align-items: center; justify-content: center; gap: 8px;
                flex-wrap: wrap; min-height: 44px; margin: -4px 0 8px; padding: 0 12px; border-radius: 12px;
                background: #eef6f6; color: #0b5f5c; font-weight: 800; font-size: .9rem; }
.suivi-repere .puce { width: 9px; height: 9px; border-radius: 50%; background: #08aaa5; flex: 0 0 auto; }
.suivi-repere.hors-ligne { background: #fdf0e3; color: #8a4c0a; }
.suivi-repere.hors-ligne .puce { background: #d9822b; }
.suivi-repere.detache { background: #eceff3; color: #3d4a5a; }
.suivi-repere.detache .puce { display: none; }
/* La sortie vit sur le repère lui-même : ce qui dit « tu es Léa » doit
   permettre de dire « ce n'est pas moi ». Un menu que personne n'ouvre ne
   remplace pas une porte. */
/* Lot R3 (A11) : sur tablette, cette sortie est la SEULE (la pilule de
   l'en-tête n'existe qu'au téléphone) et elle ne faisait que 28 px de
   haut. Elle passe à 44 px, et c'est elle qui donne sa hauteur au
   bandeau — qui n'a donc plus besoin de ses 6 px de marge intérieure. */
.suivi-repere .sortie { border: 0; background: none; padding: 0 2px; margin: 0;
                        font: inherit; color: inherit; text-decoration: underline;
                        cursor: pointer; opacity: .85; min-height: 44px; }
.suivi-repere .sortie:hover, .suivi-repere .sortie:focus-visible { opacity: 1; }
/* R4 bis (13/09/2026) : le lien du site « ← Calcul mental » ne s'affiche
   que sur l'accueil de l'appli. Sur Mes calculs, Mon parcours, une série
   ou un résultat, la seule flèche à l'écran est celle de l'appli — Gwenaël
   touchait celle du haut et sortait de l'appli au lieu de revenir au menu. */
body.ecran-interne #lien-retour { display: none; }
.suivi-garde { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(20, 52, 81, .55); }
.suivi-garde[hidden] { display: none; }
.suivi-garde-carte { background: #fff; color: var(--ink); border-radius: 16px; padding: 22px 20px; max-width: 420px; width: 100%;
  box-shadow: 0 18px 40px rgba(20, 52, 81, .3); text-align: center; }
.suivi-garde-titre { margin: 0 0 8px; font-size: 1.35rem; font-weight: 700; }
.suivi-garde-note { margin: 0 0 16px; color: var(--muted); font-size: .95rem; line-height: 1.4; }
.suivi-garde-boutons { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.suivi-garde-form { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.suivi-garde-label { font-size: .9rem; font-weight: 700; color: var(--muted); }
.suivi-garde-code { font-family: inherit; font-size: 1.5rem; font-weight: 700; line-height: 1.2; letter-spacing: .18em; text-align: center; text-transform: uppercase;
  width: 9em; max-width: 100%; min-height: 48px; padding: 6px 8px; border: 2px solid #c9d8e6; border-radius: 12px; color: var(--ink); background: #f7fbff; }
.suivi-garde-code:focus { outline: 3px solid #7fb3e0; outline-offset: 1px; }
.suivi-garde-erreur { margin: 0; color: #b3261e; font-size: .9rem; font-weight: 700; }
.suivi-garde-erreur[hidden] { display: none; }

.brand img { display: block; width: 105px; height: auto; }
.back-icon { display: grid; place-items: center; flex: 0 0 auto; }
.back-icon svg { display: block; width: 20px; height: 20px; }
.catalogue-link {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 0 13px;
  border: 1px solid #d5e1ec;
  border-radius: 999px;
  color: #24415f;
  background: #fff;
  font-size: .8rem;
  font-weight: 900;
  text-decoration: none;
}

.topbar-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 7px;
}

.fullscreen-toggle {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 11px;
  border: 1px solid #b9d0df;
  border-radius: 999px;
  color: #17405e;
  background: rgba(255, 255, 255, .96);
  font-size: .78rem;
  font-weight: 950;
  white-space: nowrap;
  cursor: pointer;
}

.fullscreen-toggle-icon { display: grid; place-items: center; }
.fullscreen-toggle-icon svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fullscreen-collapse { display: none; }
body.fullscreen-active .fullscreen-expand { display: none; }
body.fullscreen-active .fullscreen-collapse { display: block; }

.panel {
  min-height: 650px;
  padding: clamp(20px, 5vw, 42px);
  overflow-anchor: none;
  border: 1px solid var(--line);
  border-radius: 28px;
  background: rgba(255, 255, 255, .97);
  box-shadow: 0 18px 55px rgba(26, 66, 100, .12);
}

.intro,
.result { max-width: 650px; margin: 40px auto; text-align: center; }
.intro { max-width: 720px; margin: 14px auto 24px; }
.hero-icon { display: block; font-size: 4.2rem; }
.eyebrow {
  margin: 8px 0;
  color: var(--teal);
  font-size: .8rem;
  font-weight: 950;
  letter-spacing: .1em;
  text-transform: uppercase;
}

h1 { margin: 0; font-size: clamp(2rem, 6vw, 3.35rem); line-height: 1.03; }
p { line-height: 1.5; }
.intro > p:not(.eyebrow),
.result > p:not(.eyebrow) { color: var(--muted); }

/* ---- L'accueil : Mon module, la séance, le parcours ---- */
.acc { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; max-width: 560px; margin: 0 auto; text-align: left; }
.matable { padding: 14px 14px 12px; border: 2px solid #cfe2ed; border-radius: 22px; background: #fff; }
.matable-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.matable-droite { display: grid; justify-items: end; gap: 0; padding-top: 4px; text-align: right; }
.matable-droite small { color: #5b7286; font-weight: 800; font-size: .8rem; line-height: 1.2; }
.matable-head .eyebrow { margin: 0; font-size: .74rem; letter-spacing: .06em; }
.matable-head h1 { display: block; margin: 0; font-size: 1.55rem; font-weight: 900; color: var(--ink); line-height: 1.1; }
.matable-head h1:focus { outline: none; }
.matable-changer { min-height: 44px; padding: 0 6px; border: 0; background: none; color: var(--blue); font-size: .84rem; font-weight: 850; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; cursor: pointer; }
.etapes { display: grid; gap: 8px; }
.etape { width: 100%; min-height: 58px; display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid #c9dbe6; border-radius: 15px; background: #f8fcff; box-shadow: 0 2px 0 #c3d8e5; color: var(--ink); text-align: left; font: inherit; cursor: pointer; }
.etape .num { width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; background: #e3ecf2; color: #2c4a63; font-weight: 950; }
.etape strong { display: block; font-size: 1.05rem; line-height: 1.15; }
.etape small { display: block; color: #5b7286; font-size: .78rem; font-weight: 800; line-height: 1.25; margin-top: 2px; }
.acc-bas { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 18px; margin-top: 2px; }
.acc-bas button { min-height: 44px; padding: 0 4px; border: 0; background: none; color: #5b7286; font: inherit; font-size: .82rem; font-weight: 800; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
/* « Effacer mon historique » (06/11/2026) : le visiteur SANS code seulement,
   discret, sous Mon parcours (au téléphone : tout en bas), sur la ligne de
   « Comment ça marche ? » ; la question se pose à sa place (« Effacer » en
   rouge, « Garder » à côté). */
.acc-effacer-zone { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.lien-effacer { min-height: 44px; margin-top: 2px; padding: 0 6px; border: 0; background: none; color: #5b7286; font: inherit; font-size: .82rem; font-weight: 800; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.acc-confirm { width: 100%; max-width: 440px; margin: 14px 0 0; padding: 14px; border: 2px solid #cfe2ed; border-radius: 16px; background: #f8fcff; text-align: center; }
.acc-confirm p { margin: 0 0 10px; color: var(--ink); font-weight: 900; }
.acc-confirm-boutons { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.acc-confirm-boutons button { min-height: 44px; padding: 0 22px; border-radius: 13px; font: inherit; font-weight: 950; cursor: pointer; }
.acc-confirm-boutons .danger { color: #fff; border: 0; background: var(--red); box-shadow: 0 4px 0 #7a1f1f; }
.acc-confirm-boutons .garder { color: var(--blue); border: 2px solid #c5d9e6; background: #fff; box-shadow: 0 4px 0 #c5d9e6; }

/* ---- Le verdict d'une série ---- */
.result-verdict {
  max-width: 520px;
  margin: 0 auto 14px;
  padding: 16px 14px 15px;
  border: 2px solid #9fd3cb;
  border-radius: 18px;
  background: linear-gradient(135deg, #e9f8f5, #eef6ff);
}
.result-verdict .hero-icon { margin: 0; color: var(--teal); font-size: 2.9rem; line-height: 1; }
.result-verdict h1 { margin: 8px 0 0; color: var(--teal); font-size: clamp(1.55rem, 5.6vw, 2.1rem); line-height: 1.15; letter-spacing: -.01em; }
.result-score { margin: 8px 0 0; color: var(--ink) !important; font-size: 1rem; font-weight: 850; line-height: 1.35; }
.result.is-fete .result-verdict { animation: fete-pop .5s ease-out; }
.result.is-fete .hero-icon { font-size: 3.4rem; }
.result.is-rate .result-verdict { border-color: #f1c2c2; background: linear-gradient(135deg, #fff1f1, #fff8f0); }
.result.is-rate .result-verdict h1,
.result.is-rate .hero-icon { color: var(--red); }
.result.is-neutre .result-verdict { border-color: var(--line); background: #f6f9fb; }
.result.is-neutre .result-verdict h1,
.result.is-neutre .hero-icon { color: var(--ink); }
.result.is-neutre .hero-icon { display: none; }
@keyframes fete-pop { 0% { transform: scale(.85); opacity: 0; } 60% { transform: scale(1.04); } 100% { transform: scale(1); opacity: 1; } }

/* ---- La carte de la séance, ses liens, « Cette semaine », le fil ---- */
.carte-seance { display: block; width: 100%; padding: 16px; border: 2px solid var(--blue); border-radius: 18px; background: #fff; box-shadow: 0 0 0 3px rgba(7, 85, 184, .16), 0 3px 0 #b7cfe8; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.carte-seance .tete { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.carte-seance .tete strong { display: block; color: var(--blue); font-size: 1.3rem; font-weight: 950; line-height: 1.15; }
.carte-seance .duree { display: block; margin-top: 1px; color: var(--muted); font-size: .82rem; font-weight: 800; }
.carte-seance .go { padding: 11px 18px 9px; border-radius: 999px; background: var(--blue); color: #fff; font-size: 1.02rem; font-weight: 950; white-space: nowrap; }
.carte-seance .programme { display: grid; gap: 6px; margin-top: 10px; }
.carte-seance .programme > span { display: grid; grid-template-columns: 24px minmax(0, 1fr); align-items: center; gap: 9px; font-size: .95rem; font-weight: 850; line-height: 1.25; }
.carte-seance .programme i { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: #e4edf5; color: var(--ink); font-size: .8rem; font-style: normal; font-weight: 950; line-height: 1; }
.carte-seance .programme small { color: var(--muted); font-size: .84rem; font-weight: 750; }
.seance-liens { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 18px; margin: 8px 0 -6px; }
.seance-liens button { min-height: 44px; padding: 0 2px; border: 0; background: none; color: var(--blue); font: inherit; font-size: .9rem; font-weight: 850; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.semaine { display: flex; align-items: center; justify-content: center; gap: 8px; margin: -2px 0; color: var(--muted); font-size: .86rem; font-weight: 800; }
.seance-fil { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; color: var(--muted); font-size: .9rem; font-weight: 850; }
.seance-fil ol { display: flex; align-items: center; gap: 0; margin: 0; padding: 0; list-style: none; }
.seance-fil li { display: inline-grid; place-items: center; width: 24px; height: 24px; border: 2px solid #b9cbd8; border-radius: 50%; background: #fff; color: #6b8192; font-size: .78rem; font-weight: 950; line-height: 1; box-sizing: border-box; }
/* Relecture 1 (05/11/2026) : le chiffre était 1,5 à 2,5 px trop haut dans
   son rond (la boîte d'une ligne de texte garde la place des lettres qui
   descendent). « text-box » rogne la boîte à la hauteur du chiffre : il se
   centre pour de bon, quelle que soit la police (navigateurs qui le
   connaissent ; les autres gardent le centrage d'avant). */
@supports (text-box: trim-both cap alphabetic) {
  .seance-fil li { display: inline-block; align-content: center; text-align: center; text-box: trim-both cap alphabetic; }
}
.seance-fil li + li { position: relative; margin-left: 18px; }
.seance-fil li + li::before { content: ""; position: absolute; top: 50%; right: 100%; width: 18px; height: 2px; margin-right: 2px; background: #b9cbd8; }
.seance-fil li.ok { border-color: var(--teal); background: var(--teal); color: #fff; }
.seance-fil li.ok + li::before { background: var(--teal); }
.seance-fil li.ici { border-color: var(--blue); background: var(--blue); color: #fff; box-shadow: 0 0 0 3px rgba(7, 85, 184, .18); }
.seance-fil b { color: var(--ink); font-weight: 900; }
.seance-fil.centre { justify-content: center; margin: 0 0 12px; }
.seance-suite { display: grid; justify-items: center; gap: 10px; margin: 14px 0 0; }
.seance-suite .primary { min-height: 48px; padding: 12px 18px 8px; }
.seance-suite .arreter { min-height: 44px; margin-top: -8px; padding: 0 4px; border: 0; background: none; color: var(--blue); font: inherit; font-size: .88rem; font-weight: 850; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.seance-suite .cadre { width: 100%; padding: 11px 13px; border: 1px solid #cfe0f2; border-radius: 13px; background: #eef6ff; color: var(--ink); font-weight: 800; box-sizing: border-box; }
.seance-suite .cadre p { margin: 0; line-height: 1.4; }
.seance-suite .cadre p b { color: var(--blue); }
.seance-suite .boutons { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; width: 100%; }
.seance-suite .boutons .secondary { min-height: 48px; padding: 10px 18px; }

/* ---- La barre d'un écran intérieur (« Comment ça marche ? ») ---- */
.settings-toolbar { position: relative; display: grid; place-items: center; min-height: 44px; padding: 0 86px; }
.settings-back {
  position: absolute;
  left: 0;
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 7px 12px;
  border: 1px solid #bfd3df;
  border-radius: 999px;
  color: #31566c;
  background: #fff;
  font-size: .8rem;
  font-weight: 900;
  cursor: pointer;
}
.settings-heading { margin: 0; color: var(--ink); font-size: clamp(1.55rem, 5vw, 2.15rem); text-align: center; }

.primary,
.secondary {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 17px;
  border-radius: 13px;
  font-weight: 950;
  text-decoration: none;
  cursor: pointer;
}

/* R4 bis : le relief de 5 px sous le bouton fait paraître le texte 2 px
   trop haut (Gwenaël, sur « Réviser mes 36 calculs du jour ») — le texte
   était centré au pixel dans la boîte, pas dans la forme visible. Deux
   pixels de marge passent du bas vers le haut, la hauteur ne change pas. */
.primary { color: #fff; border: 0; background: var(--blue); box-shadow: 0 5px 0 #043f8c; padding-top: 12px; padding-bottom: 8px; }
.primary:disabled { color: #718493; background: #dbe5eb; box-shadow: 0 3px 0 #bdcbd4; cursor: not-allowed; }
.secondary { color: var(--blue); border: 1px solid #c5d9e6; background: #fff; }
#play,
body.challenge-playing,
body.challenge-playing .question { touch-action: manipulation; }
.status { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-weight: 950; }
.status-left { display: flex; align-items: center; gap: 10px; }
.game-menu {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 11px;
  border: 1px solid #b9d0df;
  border-radius: 999px;
  color: #17405e;
  background: #f4f9fc;
  font-size: .82rem;
  font-weight: 950;
  cursor: pointer;
}
.status strong {
  min-width: 92px;
  padding: 7px 13px;
  border-radius: 999px;
  color: var(--green);
  background: var(--green-soft);
  font-size: 1.25rem;
  text-align: center;
}

.status strong.no-timer { color: var(--teal); background: #e7f8f5; font-size: .92rem; }
.progress-track { height: 10px; margin: 12px 0 18px; overflow: hidden; border-radius: 99px; background: #dfebf3; }
.progress-track b { display: block; width: 0; height: 100%; background: linear-gradient(90deg, var(--teal), var(--blue)); transition: width .2s; }
.question {
  min-height: 480px;
  padding: clamp(19px, 5vw, 34px);
  overflow-anchor: none;
  border: 2px solid var(--line);
  border-radius: 23px;
  background: #fff;
  text-align: center;
}

.expression {
  min-height: 155px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  margin: 10px 0 16px;
  padding: 15px;
  border-radius: 18px;
  background: #f3f8fb;
  font-size: clamp(2.2rem, 9vw, 4.2rem);
  font-weight: 950;
}

.inline-answer {
  min-width: 1.45em;
  min-height: 1.18em;
  display: inline-grid;
  place-items: center;
  margin: 0 .1em;
  padding: 0 .12em;
  border: .08em solid #8fb5cb;
  border-radius: .18em;
  color: var(--ink);
  background: #fff;
  line-height: 1;
  vertical-align: -.08em;
}
.inline-answer.is-invalid { border-color: var(--red); background: var(--red-soft); }
.inline-answer.is-correct { border-color: var(--green); color: var(--green); background: var(--green-soft); }
.inline-answer.is-corrected { border-color: var(--green); color: var(--green); background: #fff7dc; }
.inline-answer.is-wrong { border-color: var(--red); color: var(--red); background: var(--red-soft); }
.answer-feedback {
  min-height: 42px;
  display: grid;
  place-items: center;
  margin: 6px auto 0;
  padding: 7px 12px;
  border-radius: 12px;
  font-weight: 900;
}
.answer-feedback.is-correct { color: var(--green); background: var(--green-soft); }
.answer-feedback.is-wrong { color: var(--red); background: var(--red-soft); }

/* Le pavé numérique (lot 1 « clavier », 07/09/2026) : les mêmes touches
   partout, mais à la taille de l'écran. Les mesures vivent sur #play pour
   que la rangée Valider suive le pavé : même largeur, même espacement.
   Téléphone : touches de 50 px (44 sur les écrans courts, comme avant) ;
   tablette : 56 px ; ordinateur (≥ 1040 px) : 64 px. La hauteur suit celle
   de la fenêtre (dvh) pour que le défi tienne toujours sans défiler : un
   portable 1366 × 768 n'a que 625 px de haut sous la barre de Chrome. */
#play {
  --pave-largeur: 360px;
  --touche-h: clamp(44px, 7.5dvh, 50px);
  --touche-ecart: clamp(2px, .45dvh, 3px);
  --touche-gap: 6px;
  --touche-police: 1.5rem;
  --valider-gap: 14px;
  --valider-police: 1.15rem;
}
/* Comme le clavier numérique d'un téléphone : un fond teinté, des touches
   blanches, et pas de zone morte — chaque bouton occupe toute sa case de
   la grille, seule sa face visible (::before) est en retrait de
   --touche-ecart. Un doigt qui tombe entre deux touches touche quand même
   la plus proche au lieu de ne rien faire. */
.keypad { width: min(100%, var(--pave-largeur)); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; margin: 8px auto 0; padding: 2px 4px; border-radius: 18px; background: #e3ecf2; }
.keypad button {
  position: relative;
  isolation: isolate;
  min-height: 44px;
  height: calc(var(--touche-h) + 2 * var(--touche-ecart));
  padding: 0 4px;
  border: 0;
  color: var(--ink);
  background: none;
  font-size: var(--touche-police);
  font-weight: 950;
  line-height: 1;
  cursor: pointer;
}
.keypad button::before {
  content: "";
  position: absolute;
  inset: var(--touche-ecart);
  z-index: -1;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 1px 0 #b3c6d3;
}
.keypad button[data-key="clear"],
.keypad button[data-key="backspace"] { color: #2c4a63; }
.keypad button[data-key="clear"]::before,
.keypad button[data-key="backspace"]::before { background: #cbdae5; }
.keypad button[data-key="clear"] { font-size: calc(var(--touche-police) * .68); }
.keypad button:active::before { background: #d6e3ec; box-shadow: none; }
.keypad button:disabled { opacity: .45; cursor: default; }
.keypad button:focus-visible { outline: none; }
.keypad button:focus-visible::before { outline: 3px solid #0f6cf9; outline-offset: 1px; }

/* Valider a sa propre rangée, séparée des chiffres par un vrai espace et
   large comme deux touches (sous 1-2, 4-5, 7-8, Effacer-0) ; Passer prend
   la troisième colonne. Sans Passer (J'apprends), Valider fait toute la
   largeur du pavé. */
.actions { width: min(100%, var(--pave-largeur)); display: grid; grid-template-columns: 2fr 1fr; gap: var(--touche-gap); margin: var(--valider-gap) auto 0; }
.actions button { min-width: 0; min-height: 44px; height: var(--touche-h); padding: 0 10px; font-size: var(--valider-police); }
.question.no-skip .actions { grid-template-columns: 1fr; }

/* Les corrections viennent APRÈS les boutons : les erreurs seules, en
   lignes courtes (le calcul avec sa bonne réponse, la réponse donnée barrée
   à droite) ; les réponses justes sont repliées derrière un titre
   dépliable — ouvertes d'office sur ordinateur, où la place ne manque pas. */
.corrections { margin: 18px 0 0; padding: 0; text-align: left; }
.corrections:empty { display: none; }
.corrections h2 { margin: 0 0 8px; color: var(--red); font-size: .98rem; }
.corrections > p { margin: 6px 0 0; color: var(--muted); }
.correction-list { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.correction-list li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; padding: 9px 11px; border: 1px solid #f1c2c2; border-radius: 12px; background: #fff6f6; }
.correction-question { display: flex; align-items: center; gap: 8px; }
.correction-expression { color: var(--ink); font-size: 1.05rem; font-weight: 900; }
.correction-expression .expected-answer { color: var(--green); font-weight: 950; }
.given-answer { color: var(--red); font-size: .95rem; font-weight: 800; text-decoration: line-through; }
/* Un calcul passé n'a pas de réponse à barrer (relecture du lot R2). */
.given-answer.is-passe { text-decoration: none; }

html.fullscreen-fallback { width: 100%; height: 100%; overflow: hidden; }
html.fullscreen-fallback body {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  min-height: 100dvh;
  overflow: auto;
  overscroll-behavior: none;
}


body.fullscreen-active .fullscreen-toggle { border-color: #7899ae; background: #fff; }
body.fullscreen-active .shell { min-height: calc((100dvh - var(--bas-cadre, 0px)) / var(--echelle, 1)); padding-bottom: 0; }

/* ---- Le rekenrek de 100 perles (copié de « Je pousse les perles ») ----
   UNE règle de géométrie à tous les écrans : l'intérieur du cadre fait
   exactement 20 perles de large, donc les 10 perles d'une rangée en
   occupent la moitié et la coupure entre les perles poussées et celles au
   repos tombe toujours au MILIEU. Les tailles sont calculées en JS
   (defi_calcul_aides.js), pas zoomées. */
.perles-consigne.est-refus { color: var(--red); animation: perles-refus .28s ease-out; }
@keyframes perles-refus { 0%, 100% { transform: translateX(0); } 30% { transform: translateX(-5px); } 70% { transform: translateX(5px); } }
.perles-cadre {
  position: relative;
  border-radius: 10px;
  background: #f3e3c9;
  box-shadow: 0 3px 10px rgba(43, 67, 84, .16);
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.perles-montant { position: absolute; top: 0; bottom: 0; z-index: 3; background: #b08d57; }
.perles-montant.gauche { left: 0; border-radius: 10px 0 0 10px; }
.perles-montant.droite { right: 0; border-radius: 0 10px 10px 0; }
.perles-interieur { position: relative; overflow: hidden; touch-action: none; cursor: grab; }
.perles-rangee { position: relative; width: 100%; }
.perles-tige { position: absolute; top: 50%; right: 0; left: 0; height: 2px; transform: translateY(-50%); background: #a98352; }
.perle {
  position: absolute;
  top: 50%;
  z-index: 2;
  border-radius: 50%;
  transform: translateY(-50%);
  box-shadow: inset -3px -3px 7px rgba(0, 0, 0, .34), 0 1px 3px rgba(0, 0, 0, .35);
  pointer-events: none;
}
.perle.rouge { background: radial-gradient(circle at 30% 30%, #ff5f5f, #a00); }
.perle.blanche { background: radial-gradient(circle at 30% 30%, #fff, #bbb); }

@media (max-width: 620px) {
  .shell { width: 100%; }
  .topbar { min-height: 58px; padding: 5px 10px; gap: 6px 12px; }
  .brand img { width: 82px; }
  .topbar-actions { gap: 4px; }
  .catalogue-link { padding: 0 10px; font-size: .73rem; }
  .fullscreen-toggle { display: none; }
  /* Le bloc de suivi (comme dans Défi tables) :
     trois lignes centrées — « Suivi par ton professeur », le prénom, la
     classe — et « Se déconnecter » à droite, DANS le bloc (plus de pilule
     dans l'en-tête). Centré en hauteur : le texte était collé en haut d'un
     bandeau de 44 px. Les états longs (code refusé, hors ligne) passent à
     la ligne : rien n'y est coupé. */
  .suivi-repere { display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; min-height: 44px; margin: -2px 0 0; padding: 5px 6px 5px 10px;
                  font-size: .78rem; line-height: 1.22; border-radius: 10px; text-align: center; }
  .suivi-repere .puce { margin: 0; }
  .repere-texte { flex: 1 1 auto; min-width: 0; }
  .repere-texte > span { display: block; }
  .repere-prenom { font-weight: 900; color: var(--ink); }
  .repere-sep { display: none; }
  .suivi-repere .sortie-bloc { flex: 0 0 auto; font-size: 0; }
  .suivi-repere .repere-lien { flex: 0 0 auto; white-space: nowrap; }
  .suivi-repere .sortie { min-height: 36px; padding: 0 11px; border: 1px solid #b7d9d6; border-radius: 999px; background: #fff;
                          font-size: .74rem; font-weight: 900; text-decoration: none; opacity: 1; }
  .panel { min-height: calc(100vh - 96px); min-height: calc(100svh - 96px); padding: 18px 12px 27px; border-right: 0; border-left: 0; border-radius: 20px; }
  .intro,
  .result { margin: 20px auto; }
  .intro { margin: 6px auto 14px; }
  .settings-toolbar { padding: 0 70px; }
  .settings-back { padding: 6px 10px; font-size: .74rem; }
  .question { min-height: 560px; padding: 19px 10px; }
  .expression { min-height: 135px; }

  .challenge-playing { height: 100dvh; overflow: hidden; }
  .challenge-playing .shell { height: calc(100dvh / var(--echelle, 1)); display: grid; grid-template-rows: auto minmax(0, 1fr); padding: 0; }
  .challenge-playing .topbar { min-height: 48px; padding: max(3px, env(safe-area-inset-top)) 10px 3px; }
  .challenge-playing .suivi-repere { margin: 0 0 2px; padding: 2px 8px; font-size: .74rem; border-radius: 8px; }
  .challenge-playing .brand img { width: 74px; }
  .challenge-playing .panel { min-height: 0; height: auto; padding: 6px 10px max(7px, env(safe-area-inset-bottom)); overflow: hidden; border-radius: 16px 16px 0 0; }
  .challenge-playing #play { height: 100%; display: flex; flex-direction: column; }
  .challenge-playing .status { min-height: 34px; gap: 8px; }
  .challenge-playing .status-left { min-width: 0; gap: 8px; }
  .challenge-playing .game-menu { padding: 4px 9px; white-space: nowrap; }
  .challenge-playing #question-count { font-size: .92rem; line-height: 1.15; }
  .challenge-playing .status strong { min-width: 78px; padding: 4px 10px; font-size: 1.05rem; flex-shrink: 0; white-space: nowrap; }
  .challenge-playing .status strong.no-timer { padding: 4px 9px; font-size: .84rem; }
  .challenge-playing .progress-track { height: 6px; margin: 4px 0 4px; }
  .challenge-playing .question { flex: 1; min-height: 0; justify-content: flex-start; padding: 6px 10px 6px; overflow-y: auto; overscroll-behavior: contain; }
  /* Le calcul s'écrit aussi gros que la largeur le permet ; il se pose
     juste au-dessus du pavé, la place libre passe en haut. */
  .challenge-playing .expression { min-height: clamp(68px, 12dvh, 92px); margin: auto 0 6px; padding: 7px; font-size: clamp(2rem, min(12.4vw, 8dvh), 3.4rem); }
  .challenge-playing .answer-feedback { min-height: 56px; margin-top: 2px; padding: 5px 10px; font-size: .95rem; }
  .challenge-playing .keypad { margin: 6px auto 0; }
  .challenge-playing .actions { margin-bottom: 0; }
  .challenge-playing footer { display: none; }
}

@media (min-width: 621px) and (max-height: 900px) {
  .challenge-playing { height: 100dvh; overflow: hidden; }
  /* La colonne est agrandie ou réduite par --echelle ; sa hauteur est donc
     celle de la fenêtre divisée par l'échelle, moins le liseré qui laisse
     voir le bas du cadre blanc sur ordinateur. */
  .challenge-playing .shell { height: calc((100dvh - var(--bas-cadre, 0px)) / var(--echelle, 1)); display: grid; grid-template-rows: auto minmax(0, 1fr); padding: 0; }
  .challenge-playing .topbar { min-height: 50px; }
  .challenge-playing .panel { min-height: 0; height: auto; padding: 12px 36px; overflow: hidden; }
  .challenge-playing #play { height: 100%; display: flex; flex-direction: column; }
  .challenge-playing .status { min-height: 38px; }
  .challenge-playing .progress-track { height: 7px; margin: 5px 0 7px; }
  .challenge-playing .question { flex: 1; min-height: 0; justify-content: flex-start; padding: 10px 28px 12px; overflow-y: auto; overscroll-behavior: contain; }
  .challenge-playing .expression { min-height: 84px; margin: 4px 0 8px; padding: 10px; font-size: clamp(2.2rem, min(7vw, 8.5dvh), 4rem); }
  .challenge-playing .answer-feedback { min-height: 38px; margin-top: 4px; }
  .challenge-playing .keypad { margin: 6px auto 0; }
  .challenge-playing .actions { margin-bottom: auto; }
}

/* Tablette et ordinateur : le pavé grandit avec l'écran. La hauteur des
   touches suit aussi la hauteur de la fenêtre (dvh) pour que la série tienne
   sans défiler. */
@media (min-width: 621px) {
  #play {
    --touche-h: clamp(46px, calc(12.6dvh - 41px), 56px);
    --touche-ecart: 3px;
    --touche-gap: clamp(6px, 1.2dvh, 8px);
    --touche-police: 1.5rem;
    --valider-gap: 16px;
    --valider-police: 1.25rem;
  }
}
@media (min-width: 1040px) {
  #play {
    --pave-largeur: 390px;
    --touche-h: clamp(46px, calc(12.6dvh - 33px), 64px);
    --touche-gap: clamp(6px, 1.2dvh, 10px);
    --touche-police: 1.7rem;
    --valider-gap: 18px;
    --valider-police: 1.35rem;
  }
}
@media (max-width: 400px) {
  .catalogue-link-label { display: none; }
}
.question.no-skip #skip { display: none; }

/* ============================================================
   Ce que Défi tables n'a pas (maquettes de l'étape 2)
   ============================================================ */

/* ---- la ligne des niveaux, sous le nom du module ---- */
.dc-niv { display: flex; align-items: center; gap: 8px; margin: 2px 0 12px; }
.dc-niv .cases { display: flex; gap: 5px; }
.dc-niv .cases b { display: inline-grid; place-items: center; width: 34px; height: 34px; border: 2px solid #9fb6c6; border-radius: 9px; background: #fff; color: #4d6578; font-size: 15px; font-weight: 900; line-height: 1; box-sizing: border-box; }
/* Une case par compétence, de la couleur de sa boîte : vert su, bleu en
   route, rouge à revoir ; le niveau en cours est cerclé. */
.dc-niv .cases b.v { border-color: var(--teal); background: var(--teal); color: #fff; }
.dc-niv .cases b.b { border-color: var(--blue); background: var(--blue); color: #fff; }
.dc-niv .cases b.r { border-color: #c62828; background: #c62828; color: #fff; }
.dc-niv .cases b.ici { border: 3px solid var(--blue); background: #fff; color: var(--blue); }
.dc-niv span.txt { color: var(--ink); font-size: .92rem; font-weight: 850; line-height: 1.2; }
.dc-niv span.txt small { display: block; color: var(--muted); font-size: .8rem; font-weight: 800; }

/* ---- l'écran du module : les cases de niveau, les trois étapes ---- */
.dc-module { max-width: 620px; margin: 0 auto; text-align: left; }
.dc-lab { margin: 4px 0 6px; color: #5b7286; font-size: .74rem; font-weight: 900; letter-spacing: .06em; text-transform: uppercase; }
.dc-niveaux { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin: 0 0 12px; }
.dc-niveaux button { display: grid; gap: 3px; justify-items: center; align-content: center; min-height: 62px; padding: 6px 4px; border: 2px solid #b9cbd8; border-radius: 13px; background: #fff; color: var(--ink); font: inherit; text-align: center; cursor: pointer; }
.dc-niveaux button small { display: flex; align-items: center; gap: 4px; color: #5b7286; font-size: .74rem; font-weight: 900; }
.dc-niveaux button strong { font-size: .95rem; font-weight: 900; line-height: 1.15; }
.dc-niveaux button em { color: #5b7286; font-size: .7rem; font-style: normal; font-weight: 800; line-height: 1.1; }
.dc-niveaux button.ok { border-color: var(--teal); background: #eaf7f4; }
.dc-niveaux button.ok small { color: var(--teal); }
/* Relecture 1 (05/11/2026) : le bouton choisi garde un bord de 2 px, comme
   les autres (avec 3 px, son texte perdait 2 px de large et se recoupait
   autrement) ; la sélection se marque par une ombre. */
.dc-niveaux button.ici { border-color: var(--blue); box-shadow: 0 0 0 1px var(--blue), 0 0 0 4px rgba(7, 85, 184, .16); }
.dc-niveaux button.ici small { color: var(--blue); }
.dc-niveaux.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.dc-niveaux.n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.dc-niveaux.n5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 620px) {
  .dc-niveaux, .dc-niveaux.n3, .dc-niveaux.n5 { grid-template-columns: 1fr 1fr; }
  .dc-niveaux button { min-height: 54px; }
}
.dc-etapes { display: grid; gap: 7px; }
.dc-etapes .etape .fl { color: var(--blue); font-weight: 950; font-size: 1.1rem; }

/* ---- le parcours : les paliers et les modules ---- */
.dc-parcours { padding: 12px 12px 10px; border: 2px solid #cfe2ed; border-radius: 22px; background: #fff; }
.dc-ptete { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 2px 8px; }
.dc-ptete .eyebrow { margin: 0; font-size: .74rem; letter-spacing: .06em; }
.dc-ptete small { color: #5b7286; font-size: .8rem; font-weight: 800; }
.dc-paliers { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; margin-bottom: 8px; }
.dc-paliers button { display: grid; justify-items: center; gap: 1px; min-height: 46px; padding: 4px 0 3px; border: 2px solid #c5d9e6; border-radius: 12px; background: #fff; color: var(--ink); font: inherit; cursor: pointer; }
.dc-paliers button b { font-size: 1.05rem; font-weight: 950; line-height: 1; }
.dc-paliers button small { color: #5b7286; font-size: .68rem; font-weight: 850; line-height: 1; }
.dc-paliers button.fini { border-color: var(--teal); background: var(--teal); color: #fff; }
.dc-paliers button.fini small { color: #fff; }
.dc-paliers button.ici { border-color: var(--blue); background: #eef6ff; color: var(--ink); box-shadow: 0 0 0 1px var(--blue); }
.dc-paliers button.ici b { color: var(--blue); }
.dc-paliers button.ici small { color: #5b7286; }
.dc-ptitre { margin: 0 2px 6px; color: var(--ink); font-size: 1.02rem; font-weight: 900; }
.dc-mods { display: grid; gap: 3px; }
.dc-mod { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; align-items: center; gap: 8px; width: 100%; min-height: 34px; padding: 3px 9px 3px 7px; border: 1px solid #c9dbe6; border-radius: 10px; background: #fff; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.dc-mod:disabled { cursor: default; opacity: 1; }
.dc-mod .st { display: inline-grid; place-items: center; width: 20px; height: 20px; border: 2px solid #8fa6b7; border-radius: 50%; box-sizing: border-box; font-style: normal; font-size: 12px; font-weight: 950; line-height: 1; color: #fff; }
.dc-mod .nom { font-size: .9rem; font-weight: 850; line-height: 1.15; }
.dc-mod .nom small { display: block; color: #5b7286; font-size: .72rem; font-weight: 800; }
.dc-mod.su .st { border-color: var(--teal); background: var(--teal); }
.dc-mod.encours { border: 2px solid var(--blue); background: #f3f8ff; }
.dc-mod.encours .st { border-color: var(--blue); background: linear-gradient(90deg, var(--blue) 50%, #fff 50%); }
.dc-mod.rouge { border: 2px solid #c62828; background: #fff5f5; }
.dc-mod.rouge .st { border-color: #c62828; background: #fff; color: #c62828; font-size: 13px; }
.dc-mod.bientot { border-style: dashed; background: #f4f7f9; color: #6b8192; }
/* « bientôt » sur la ligne du nom : avec la légende, le palier de 14 modules
   doit encore tenir dans le cadre. */
.dc-mod.bientot .nom small { display: inline; margin-left: 6px; }
/* Un petit carré par compétence du palier, à droite de la ligne ; le niveau
   en cours est cerclé de bleu. */
.dc-comp { display: inline-flex; gap: 4px; align-items: center; }
.dc-comp i { width: 14px; height: 14px; border: 2px solid #9fb6c6; border-radius: 4px; background: #fff; box-sizing: border-box; }
.dc-comp i.ici { border-color: var(--blue); box-shadow: 0 0 0 2px rgba(7, 85, 184, .25); }
.dc-comp i.r { border-color: #c62828; background: #c62828; }
.dc-comp i.b { border-color: var(--blue); background: var(--blue); }
.dc-comp i.v { border-color: var(--teal); background: var(--teal); }
.dc-mod .dc-comp { justify-self: end; }
div.dc-mod { cursor: default; }
.dc-legende { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 8px 2px 0; color: #5b7286; font-size: .74rem; font-weight: 800; }
.dc-legende > span { display: inline-flex; align-items: center; gap: 5px; }
.dc-mod.bientot .st { border-style: dashed; border-color: #a9bbc8; }

@media (min-width: 1040px) {
  .intro.dc-large { max-width: none; }
  .acc.dc-a { max-width: none; grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr); align-items: start; gap: 14px; }
  .acc.dc-a .carte-seance { display: flex; flex-direction: column; }
  .acc.dc-a .carte-seance .tete { display: contents; }
  .acc.dc-a .carte-seance .tete > span:first-child { order: 1; }
  .acc.dc-a .carte-seance .programme { order: 2; }
  .acc.dc-a .carte-seance .go { order: 3; margin-top: 12px; text-align: center; }
  /* Modules lot 2 (31/10/2026) : le palier 1 a 11 modules construits (16
     au lot 3) ; la carte « Mon parcours » prend la hauteur de la colonne de
     gauche, et sa liste défile dedans, le module en cours toujours montré.
     Le cadre tient ainsi dans l'écran, quel que soit le nombre de modules. */
  .acc.dc-a .dc-parcours { contain: size; align-self: stretch; display: flex; flex-direction: column; min-height: 0; }
  .acc.dc-a .dc-parcours .dc-mods { flex: 1 1 auto; min-height: 0; overflow-y: auto; grid-auto-rows: max-content; align-content: start; padding: 0 2px 6px 0; scrollbar-gutter: stable; }
}
.acc.dc-a .gauche { display: grid; gap: 12px; min-width: 0; }
/* Lot « Effacer l'historique » (06/11/2026) : sur l'ordinateur, deux
   rangées — Mon module | Mon parcours, puis « Comment ça marche ? » |
   « Effacer mon historique » sur la même ligne, chacun sous sa carte. */
@media (min-width: 1040px) {
  .acc.dc-a { grid-template-areas: "gauche parcours" "bas effacer"; }
  .acc.dc-a > .gauche { grid-area: gauche; }
  .acc.dc-a > .dc-parcours { grid-area: parcours; }
  .acc.dc-a > .acc-bas { grid-area: bas; }
  .acc.dc-a > .acc-effacer-zone { grid-area: effacer; }
  /* Rien à effacer (élève à code, mode professeur, appareil vide) :
     « Comment ça marche ? » centré sous les deux cartes. */
  .acc.dc-a:not(.avec-effacer) { grid-template-areas: "gauche parcours" "bas bas"; }
}
.acc.dc-a:not(.avec-effacer) > .acc-effacer-zone { display: none; }
/* Tant que le serveur n'a pas dit qui est l'élève, l'accueil attend. */
.acc.en-attente > * { visibility: hidden; }
@media (min-width: 621px) { .acc { max-width: 620px; } .etape { min-height: 60px; } .etape strong { font-size: 1.12rem; } }
@media (max-width: 620px) { .matable-head h1 { font-size: 1.32rem; } }
@media (max-width: 520px) {
  .carte-seance { padding: 13px; }
  .carte-seance .tete strong { font-size: 1.12rem; }
  .carte-seance .go { padding: 9px 12px 7px; font-size: .92rem; }
  .seance-fil { gap: 8px; font-size: .84rem; }
  .seance-suite .boutons > button,
  .seance-suite > .primary { width: 100%; }
}

/* ---- la série : le calcul, l'aide, le pavé ----
   Ordinateur : l'aide entre le calcul et le pavé. Téléphone : l'aide
   au-dessus du calcul, le pavé ne bouge pas. Le rekenrek, lui, reste sous
   le calcul partout : c'est lui qu'on touche. */
.question { display: flex; flex-direction: column; }
.question > * { flex: 0 0 auto; }
.dc-aide { width: min(100%, 560px); margin: 4px auto 2px; }
.dc-aide[hidden] { display: none; }
.dc-aide .consigne { margin: 0 0 2px; color: var(--teal); font-size: 1.02rem; font-weight: 900; line-height: 1.25; text-align: center; }
.dc-aide .consigne.est-refus { color: var(--red); animation: perles-refus .28s ease-out; }
.dc-aide svg { display: block; width: 100%; height: auto; }
/* M4 (modules lot 3) : le rectangle de points est étroit ; il ne grandit
   pas au-delà de la taille des autres dessins quand la place s'ouvre. */
svg.dc-points { max-width: 210px; margin-left: auto; margin-right: auto; }
.dc-aide text { font-family: inherit; font-weight: 900; }
@media (max-width: 620px) {
  .challenge-playing .question.aide-image .dc-aide { order: -1; margin-top: auto; }
  .challenge-playing .question.aide-image .expression { margin-top: 6px; }
}
/* « J'écris » (lot « relier ») : le dessin AU-DESSUS des étapes, partout
   (sur ordinateur aussi) : chaque égalité juste le remplit, l'œil monte de
   l'égalité à son morceau. */
.question.ecrit.aide-image .dc-aide { order: -1; }
/* Sur un écran bas d'ordinateur, le dessin cède un peu de hauteur aux
   trois lignes d'étapes (le schéma en barres de M1 est haut). */
@media (min-width: 621px) {
  .challenge-playing .question.ecrit.aide-image .dc-aide svg { max-height: 21dvh; }
  .challenge-playing .question.ecrit.aide-image .dc-aide svg.dc-tableau { max-height: 18dvh; }
}
/* Téléphone : les étapes s'écrivent un peu plus serré pour laisser la
   place au dessin ; une fois J'écris fini (juste, ou la réponse donnée),
   le pavé grisé ne sert plus : il s'efface et le dessin rempli prend sa
   place. */
@media (max-width: 620px) {
  .challenge-playing .question.ecrit.aide-image .expression.dc-lignes { font-size: 1.32rem; padding-top: 4px; padding-bottom: 4px; }
  .challenge-playing .question.ecrit.aide-image .expression.dc-lignes .lg { row-gap: 3px; }
  .challenge-playing .question.ecrit.aide-image > .actions { margin-top: 6px; }
  .challenge-playing .question.ecrit-fini > .keypad { display: none; }
  /* La touche « , » (D2) est à part du pavé : elle s'efface avec lui
     (vu par Code sur la PR #1083). */
  .challenge-playing .question.ecrit-fini > .dc-touches { display: none; }
  /* Relecture 1 (05/11/2026) : J'écris fini reste à l'écran, avec
     « Suivant ». Le travail se colle en haut (plus de grand vide au-dessus
     du dessin) ; « Suivant » reste en bas, à la place de « Valider ». */
  .challenge-playing .question.ecrit-fini.aide-image > .dc-aide { margin-top: 0; }
  .challenge-playing .question.ecrit-fini.aide-image > .actions { margin-top: auto; }
}
/* Avec une image, le pavé redescend un peu pour que tout tienne sans
   défiler (la même mesure que « J'apprends » de Défi tables). */
.question.aide-image, .question.ecrit { --touche-h: clamp(44px, 6.9dvh, 46px); }
@media (min-width: 621px) {
  .question.aide-image, .question.ecrit { --touche-h: clamp(46px, calc(10.5dvh - 30px), 56px); }
  /* Le fil de « J'apprends » se pose sur la ligne du bouton de retour. */
  #play .status { position: relative; }
  #play .status .seance-fil { position: absolute; top: 0; left: 150px; min-height: 44px; margin: 0; }
}
@media (min-width: 1040px) {
  .question.aide-image, .question.ecrit { --touche-h: clamp(46px, calc(10.5dvh - 30px), 64px); }
}
@media (min-width: 621px) and (max-height: 900px) {
  .challenge-playing .question.aide-image .dc-aide { width: min(100%, 470px); margin: 2px auto 0; }
  .challenge-playing .question.aide-image .answer-feedback { min-height: 34px; margin-top: 2px; padding: 5px 12px; }
  .challenge-playing .question.aide-image .expression { min-height: 64px; margin: 2px 0 4px; padding: 6px 10px; }
}
/* « Je représente » : pas de ligne de retour — la case passe au vert ou au
   rouge, la consigne tremble. La place va à l'image. */
.question.sans-retour .answer-feedback { display: none; }
/* Le rekenrek : ni pavé ni retour écrit ; « Suivant » garde sa place, et
   n'apparaît qu'une fois le geste fait (le boulier ne change pas de taille). */
.question.aide-perles .keypad,
.question.aide-perles .answer-feedback,
.question.aide-glisse .keypad,
.question.aide-glisse .answer-feedback,
.question.aide-perles .dc-touches,
.question.aide-glisse .dc-touches { display: none; }
.question.aide-perles .actions,
.question.aide-glisse .actions { visibility: hidden; }
.question.aide-perles.est-finie .actions,
.question.aide-glisse.est-finie .actions { visibility: visible; }
.question.aide-perles .dc-aide { flex: 1 1 auto; min-height: 0; width: 100%; display: flex; flex-direction: column; align-items: center; margin: 0; }
.perles-zone { flex: 1 1 auto; min-height: 0; width: 100%; display: flex; flex-direction: column; align-items: center; }
.perles-scene { flex: 1 1 auto; min-height: 132px; width: 100%; display: grid; place-items: center; }
/* La droite du boulier (« Je manipule », lot « relier ») : un saut par
   geste. Elle garde sa hauteur ; c'est le boulier qui prend le reste. */
.perles-droite { flex: 0 0 auto; width: min(100%, 520px); margin: 2px auto 0; }
.perles-droite svg { display: block; width: 100%; height: auto; max-height: 20dvh; }
.perles-droite text { font-family: inherit; font-weight: 900; }
.challenge-playing .question.aide-perles .expression,
.expression.dc-petit { min-height: 0; margin: 0 0 4px; padding: 6px 12px; font-size: 1.9rem; }
/* Au clavier (seulement) : la rangée et la perle choisies. */
.perles-interieur:focus { outline: none; }
.perles-interieur:focus-visible .perles-rangee.curseur { border-radius: 8px; box-shadow: inset 0 0 0 3px rgba(15, 108, 249, .55); }
.perles-interieur:focus-visible .perle.curseur { outline: 3px solid #0f6cf9; outline-offset: 2px; z-index: 2; }
/* align-items: center — sinon la pastille s'étire à 42 px et son texte
   reste en haut (lot 1b, vu par Gwenaël sur « 27 × 100 = … »). */
/* C1 (modules lot 4) : les jetons du calcul, à toucher ; la parenthèse
   touchée se referme sur son nombre, en vert. */
.dc-toucher { width: 100%; }
.dc-toucher-calcul { display: flex; flex-wrap: nowrap; justify-content: center; align-items: center; gap: 0 2px; margin: 14px auto 4px; color: var(--ink); font-size: clamp(1.55rem, 7.2vw, 2.6rem); font-weight: 950; line-height: 1.2; }
.dc-jeton { display: inline-flex; align-items: center; justify-content: center; min-width: .9em; min-height: 1.6em; padding: 0 .08em; border-radius: 10px; cursor: pointer; touch-action: manipulation; }
.dc-jeton.est-signe { font-weight: 700; }
.dc-jeton.est-parenthese { min-width: .5em; font-weight: 500; }
.dc-jeton:hover, .dc-jeton:focus-visible { background: var(--blue-soft, #eaf2ff); outline: none; }
.dc-jeton.est-trouve, .dc-jeton.est-venu { margin: 0 .1em; padding: 0 .25em; border: 3px solid var(--green); background: var(--green-soft); color: var(--green); animation: dc-referme .3s ease-out; }
.dc-jeton.est-venu { animation: none; }
.dc-toucher.est-finie .dc-jeton { cursor: default; }
/* L'entraînement (relecture 1) : le calcul à faire d'abord, entouré, sans
   son nombre. */
.dc-jetons-choisis { display: inline-flex; align-items: center; margin: 0 .1em; padding: 0 .12em; border: 3px solid var(--green); border-radius: 10px; background: var(--green-soft); color: var(--green); }
.dc-jetons-choisis .dc-jeton { cursor: default; }
@keyframes dc-referme { from { transform: scale(.6); opacity: .3; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .dc-jeton.est-trouve { animation: none; } }
/* L'escalier de C1 et les facteurs de M10 : étroits, à leur taille. */
.dc-aide svg.dc-escalier { width: auto; max-width: 100%; height: auto; margin: 0 auto; }
/* Sur un écran bas d'ordinateur, l'escalier (et les facteurs de M10) cèdent
   un peu de hauteur au pavé et à « Valider ». */
@media (min-width: 621px) and (max-height: 900px) {
  .challenge-playing .question.aide-image:not(.ecrit) .dc-aide svg.dc-escalier { max-height: 27dvh; }
}
/* « À retenir » : l'escalier rapetisse avec la phrase (--retenir-z). */
.dc-retenir .dc-aide svg.dc-escalier { max-height: calc(26dvh * var(--retenir-z, 1)); }
.dc-trace { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px 10px; min-height: 42px; margin: 8px 0 0; }
.dc-trace b { padding: 6px 14px; border-radius: 12px; font-size: 1.15rem; font-weight: 950; line-height: 1.2; }
.dc-trace b.ok { background: var(--green-soft); color: var(--green); }
.dc-trace b.ici { border: 3px solid var(--blue); padding: 3px 11px; color: var(--blue); background: #fff; }
@media (max-width: 620px) {
  .dc-trace b { font-size: 1rem; }
  .challenge-playing .question.aide-perles { padding-right: 3px; padding-left: 3px; }
}
@media (min-width: 621px) and (min-height: 901px) {
  .challenge-playing .question.aide-perles { height: min(76dvh, 860px); }
}
@media (max-width: 620px) {
  .challenge-playing .expression.dc-long { flex-wrap: nowrap; font-size: clamp(1.9rem, min(9.6vw, 8dvh), 2.35rem); }
  .challenge-playing .expression.dc-tres-long { flex-wrap: nowrap; font-size: clamp(1.6rem, min(7.9vw, 8dvh), 1.95rem); }
}
/* Un calcul tient sur une ligne : trop long, il s'écrit plus petit
   (ajusterCalcul). */
.challenge-playing .expression { flex-wrap: nowrap; white-space: nowrap; }
/* La case ne rétrécit jamais sous sa réponse (sa largeur minimale est
   fixée, elle se serait laissé écraser). */
.challenge-playing .expression .inline-answer { flex-shrink: 0; }
/* « J'écris » (lot 3) : une étape par ligne, les morceaux en colonnes — la
   case est sous la case, le « + » sous le « + ». L'étape faite garde sa
   réponse en vert, celle qui se joue a la case, les suivantes sont grisées ;
   au 2e essai faux, tout se révèle. */
.expression.dc-lignes,
.challenge-playing .expression.dc-lignes { height: auto; font-size: clamp(1.5rem, 5vw, 2.1rem); }
.expression.dc-lignes .lg { display: grid; grid-template-columns: repeat(var(--colonnes, 5), auto); justify-content: center; align-items: center; column-gap: .28em; row-gap: 6px; text-align: center; }
.expression.dc-lignes .lg > span { display: contents; }
.expression.dc-lignes .lg .cel { min-width: 0; text-align: center; }
.expression.dc-lignes .lg .cel .inline-answer { display: inline-grid; }
.expression.dc-lignes .lg > span.apres .cel { color: #9fb6c6; }
.expression.dc-lignes .lg > span.apres .inline-answer.est-vide { border-color: #d5e0e8; background: #f6f9fb; color: transparent; }
.expression.dc-lignes .lg > span.faite .cel { color: #4d6578; }
/* La ligne de touches en plus, au-dessus du pavé (virgule, fraction) : le
   pavé lui-même ne change jamais. La virgule : D2 et tout le palier 3. */
.dc-touches { width: min(100%, var(--pave-largeur)); display: grid; gap: 6px; margin: 6px auto 0; }
.dc-touches:empty { display: none; }
.dc-touches button { min-height: calc(var(--touche-h, 56px) * .82); border: 0; border-radius: 13px; color: var(--ink); background: #cfdbe5; font-size: 1.9rem; font-weight: 950; line-height: 1; cursor: pointer; }
.dc-touches button:disabled { opacity: .45; cursor: default; }

/* ---- modules lot 5 (04/11/2026) : les décimaux ----
   Les fractions s'écrivent comme sur le cahier : le numérateur, la barre,
   le dénominateur (« 3 + 2/10 », « 0,3 = □/10 » : la case au numérateur). */
.dc-frac { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; vertical-align: middle; margin: 0 .1em; font-size: .62em; line-height: 1.04; white-space: nowrap; }
.dc-frac > .dc-frac-num { min-width: 1.2em; padding: 0 .14em .07em; border-bottom: .1em solid currentColor; text-align: center; }
.dc-frac > .dc-frac-den { padding: .07em .14em 0; text-align: center; }
.dc-frac .inline-answer { margin: 0 0 .08em; font-size: 1.2em; }
.correction-expression .dc-frac, .answer-feedback .dc-frac, .consigne .dc-frac, .dc-trace .dc-frac,
.dc-retenir .phrase .dc-frac, .annonce .dc-frac { font-size: .8em; }
.expression.dc-lignes .lg .cel .dc-frac .inline-answer { display: inline-grid; }
/* Dans les étapes de J'écris, une fraction ne fait pas grandir la ligne.
   Modules lot 6b (05/11/2026, choix de Gwenaël, planche avant/après) :
   0,78 de la taille du texte au lieu de 0,52 — à 0,52, « 1/2 = 50/100 »
   faisait 11 pixels au téléphone. */
.expression.dc-lignes .lg .cel .dc-frac { font-size: .78em; line-height: 1; }
/* Sur ordinateur, le texte des étapes est plus grand (2,1rem) : 0,6 suffit
   (et le dessin de J'écris en fractions rapetisse un peu, plus bas), pour
   que la carte tienne sans défiler à 1366 × 768 (F5-1 : trois étapes). Le
   carré de 100 de Je représente aussi (F1 : « 1/100 = □ » est haut). */
@media (min-width: 621px) {
  .expression.dc-lignes .lg .cel .dc-frac { font-size: .6em; }
  .challenge-playing .question.aide-image .dc-aide svg.dc-carre { max-height: 28dvh; }
}
/* Le tableau de numération et le carré de 100 dessinés : à leur taille. */
.dc-aide svg.dc-numeration, .dc-aide svg.dc-carre { width: auto; max-width: 100%; height: auto; margin: 0 auto; }
.dc-aide svg.dc-carre { max-height: 34dvh; }
@media (max-width: 620px) {
  .challenge-playing .question.aide-image .dc-aide svg.dc-numeration { max-height: 30dvh; }
  .challenge-playing .question.ecrit.aide-image .dc-aide svg.dc-numeration { max-height: 27dvh; }
  .challenge-playing .question.aide-image .dc-aide svg.dc-carre { max-height: 28dvh; }
}
@media (min-width: 621px) {
  .challenge-playing .question.ecrit.aide-image .dc-aide svg.dc-numeration { max-height: 18dvh; }
  /* Sur ordinateur, le carré de 100 se dessine plus grand que sa taille
     naturelle : les bandes se comptent. */
  .dc-aide svg.dc-carre { width: min(100%, 320px); }
}
.dc-retenir .dc-aide svg.dc-numeration { max-height: calc(28dvh * var(--retenir-z, 1)); }
/* D1 : le carré de 100 à colorier. Les unités, en petit, à gauche ; le
   grand carré, qu'on touche, à droite. */
.dc-carre-manip { width: 100%; }
.dc-carre-scene { --n: 1; display: flex; align-items: center; justify-content: center; gap: 10px; margin: 10px auto 0; }
/* Tous les carrés ont la même taille : l'unité est le grand carré. */
.dc-carre-scene > .dc-carre-unite, .dc-carre-scene > .dc-carre-grand { flex: 0 0 auto; width: min(230px, 33dvh, calc((100% - (var(--n) - 1) * 10px) / var(--n))); }
/* Téléphone, trois carrés ou plus : deux rangées de deux, des carrés deux
   fois plus grands (les bandes se comptent mieux). */
@media (max-width: 620px) {
  .dc-carre-scene.deux-rangees { flex-wrap: wrap; width: min(100%, 330px); }
  .dc-carre-scene.deux-rangees > .dc-carre-unite, .dc-carre-scene.deux-rangees > .dc-carre-grand { width: min(150px, 22dvh, calc((100% - 10px) / 2)); }
}
.dc-carre-grand { border-radius: 4px; cursor: pointer; touch-action: manipulation; }
.dc-carre-grand:focus-visible { outline: 3px solid #0f6cf9; outline-offset: 3px; }
.dc-carre-manip.est-finie .dc-carre-grand { cursor: default; }
/* D4 : le tableau à jetons et sa réserve. Les jetons en carré de 3 × 3 ;
   la virgule, un trait rouge entre les unités et les dixièmes ; le paquet
   de 10 à échanger, entouré de bleu. Noir et blanc : les jetons sont
   blancs à bord noir, ceux qui arrivent à bord épais, ceux qui s'en vont
   en pointillés. */
.dc-jetons { width: 100%; --pion: 30px; }
.dc-jetons.colonnes-4 { --pion: 26px; }
.dc-jetons-tableau { display: grid; grid-template-columns: repeat(var(--colonnes, 3), minmax(0, 1fr)); gap: 8px; width: min(100%, 430px); margin: 8px auto 0; }
.dc-jetons-col { position: relative; display: flex; flex-direction: column; min-height: calc(var(--pion) * 3 + 50px); border: 2px solid #143451; border-radius: 12px; background: #fff; }
.dc-jetons-col.apres-virgule::before { content: ""; position: absolute; top: 4px; bottom: 4px; left: -7px; width: 3.5px; border-radius: 2px; background: #c62828; }
.dc-jetons-col .tete { padding: 5px 2px 4px; border-radius: 10px 10px 0 0; background: #e3ecf2; color: #2c4a63; font-size: .74rem; font-weight: 850; line-height: 1.1; text-align: center; }
.dc-jetons-col .pile { display: grid; grid-template-columns: repeat(3, var(--pion)); gap: 3px; justify-content: center; align-content: start; padding: 6px 2px; }
.dc-jetons-col.a-echanger { border-color: var(--blue); box-shadow: 0 0 0 2px var(--blue); cursor: pointer; }
.dc-jetons-col.a-echanger:focus-visible { outline: 3px solid #0f6cf9; outline-offset: 3px; }
.dc-paquet { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, var(--pion)); gap: 3px; justify-content: center; padding: 3px; border: 3px dashed var(--blue); border-radius: 12px; }
.dc-pion { box-sizing: border-box; display: grid; place-items: center; width: var(--pion); height: var(--pion); border: 2px solid #143451; border-radius: 50%; background: #fff; color: #143451; font-size: calc(var(--pion) * .36); font-weight: 900; line-height: 1; letter-spacing: -.04em; }
.dc-pion.l1 { font-size: calc(var(--pion) * .5); }
.dc-pion.l4 { font-size: calc(var(--pion) * .3); }
.dc-pion.l5 { font-size: calc(var(--pion) * .26); }
/* Chaque jeton porte sa valeur, dans sa colonne nommée (décision du 04/11,
   les disques de Singapour). Celui qui arrive : vert, écrit en vert. */
.dc-pion.est-venu { border: 3px solid var(--green); background: #fff; color: var(--green); animation: dc-referme .3s ease-out; }
.dc-pion.est-parti { border: 2px dashed #8a9caa; background: repeating-linear-gradient(45deg, #fff 0 3px, #e6ecf1 3px 6px); color: #8a9caa; }
.dc-reserve { display: flex; align-items: center; justify-content: center; gap: 10px; width: fit-content; margin: 10px auto 0; padding: 6px 12px; border: 2px dashed #9fb6c6; border-radius: 14px; }
.dc-reserve-titre { color: #5b7286; font-size: .82rem; font-weight: 850; }
.dc-reserve .dc-pion { --pion: 46px; cursor: pointer; font-family: inherit; touch-action: manipulation; }
.dc-reserve .dc-pion:hover, .dc-reserve .dc-pion:focus-visible { background: var(--blue-soft, #eaf2ff); outline: none; box-shadow: 0 0 0 3px rgba(15, 108, 249, .45); }
.dc-reserve .dc-pion:disabled { opacity: .45; cursor: default; box-shadow: none; }
@media (prefers-reduced-motion: reduce) { .dc-pion.est-venu { animation: none; } }
@media (max-width: 620px) {
  .dc-jetons { --pion: 27px; }
  .dc-jetons-tableau { gap: 7px; margin-top: 6px; }
  .dc-jetons-col { min-height: calc(var(--pion) * 3 + 40px); }
  .dc-jetons-col .tete { padding: 3px 1px; font-size: .66rem; }
  .dc-jetons-col .pile { gap: 2px; padding: 4px 1px; grid-template-columns: repeat(3, var(--pion)); }
  .dc-paquet { gap: 2px; padding: 2px; }
  .dc-reserve { margin-top: 8px; padding: 4px 10px; }
  .dc-reserve .dc-pion { --pion: 42px; }
  /* Quatre colonnes (millièmes) : des ronds plus petits. */
  .dc-jetons.colonnes-4 { --pion: 24px; }
  .dc-jetons.colonnes-4 .dc-jetons-col .dc-pion { border-width: 1.5px; letter-spacing: -.06em; }
  .dc-jetons.colonnes-4 .dc-jetons-col .dc-pion.l4 { font-size: calc(var(--pion) * .31); }
  .dc-jetons.colonnes-4 .dc-jetons-col .dc-pion.l5 { font-size: calc(var(--pion) * .28); }
}

/* ---- le glisse-nombres (copié d'Automatismes, place-value-table.js et
   03-slideshow.js) : la bande grise et ses chiffres glissent au-dessus du
   nombre de départ, la virgule reste fixe. Les colonnes viennent de
   --colonnes (6 pour M2, 7 pour D2). ---- */
/* Le glisse-nombres prend la place du pavé : il se pose au milieu, et
   « Suivant » reste en bas, comme pour le rekenrek. Il ne rétrécit
   jamais sous sa taille (« 1 0 auto ») : s'il manque de place, c'est le
   cadre qui déborde, la mesure le voit et réduit l'échelle — rien ne passe
   sous « Suivant » ni par-dessus le calcul. */
.question.aide-glisse .dc-aide { flex: 1 0 auto; width: min(100%, 560px); display: flex; flex-direction: column; justify-content: safe center; margin: 0 auto; }
.glisse-zone { width: 100%; }
.place-value-tool { width: 100%; margin: 4px auto 0; user-select: none; -webkit-user-select: none; touch-action: none; }
.place-value-grid { position: relative; overflow: hidden; border: 3px solid #17384d; border-radius: 14px; background: #fff; }
.place-value-head-row, .place-value-window-row, .place-value-fixed-row { display: grid; grid-template-columns: repeat(var(--colonnes, 7), minmax(0, 1fr)); }
.place-value-head { display: flex; min-width: 0; align-items: center; justify-content: center; height: 34px; padding: 0 2px; overflow: hidden; border-right: 1.5px solid #9fb3c8; border-bottom: 1.5px solid #9fb3c8; background: #eef6ff; color: #35526e; font-size: .7rem; font-weight: 800; line-height: 1.05; letter-spacing: -.02em; text-align: center; }
.place-value-head:last-child { border-right: 0; }
.place-value-preview-row, .place-value-fixed-row { position: relative; height: 58px; }
.place-value-preview-row { background: #f7f8fa; }
.place-value-fixed-row { border-top: 1.5px solid #9fb3c8; background: #fff; }
.place-value-window-row { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.place-value-window { border-right: 1.5px solid #9fb3c8; }
.place-value-window:last-child { border-right: 0; }
.place-value-strip-viewport { position: absolute; inset: 0; z-index: 3; overflow: hidden; pointer-events: none; }
/* Sa largeur et ses colonnes (celles du tableau + 3 de chaque côté) sont
   posées par le script. */
.place-value-strip { position: absolute; inset: 0 auto 0 0; display: grid; align-items: center; justify-items: center; will-change: transform; }
.place-value-strip-digit, .place-value-fixed-digit { display: grid; place-items: center; color: #0b2147; font-family: "Cambria Math", "Times New Roman", serif; font-size: 2.35rem; font-weight: 850; line-height: 1; }
.place-value-fixed-digit.is-units-digit, .place-value-strip-digit.is-units-digit { color: #0879d0; }
/* Lot 3 : les zéros de position, écrits en gris une fois la bande lâchée. */
.place-value-strip-digit.is-zero-position { color: #8fa3b3; }
.place-value-drag-bar { position: absolute; z-index: 2; left: -24px; right: -24px; top: 7px; height: 44px; cursor: grab; touch-action: none; outline: none; will-change: transform; }
.place-value-drag-bar span { display: block; width: 100%; height: 100%; border: 1px solid rgba(107, 114, 128, .3); background: rgba(209, 213, 219, .62); box-shadow: inset 0 2px 3px rgba(0, 0, 0, .12), inset 0 -2px 3px rgba(255, 255, 255, .55); }
.place-value-drag-bar:focus-visible span { box-shadow: inset 0 0 0 3px #f07818; }
.place-value-fixed-digit { border-right: 1.5px solid #9fb3c8; }
.place-value-fixed-digit:last-child { border-right: 0; }
.place-value-fixed-digit[data-place-value-source] { position: relative; z-index: 8; cursor: pointer; touch-action: manipulation; outline: none; }
.place-value-fixed-digit[data-place-value-source]:focus-visible,
.place-value-tool.tap-selecting .place-value-fixed-digit[data-place-value-source] { background: #fff1df; box-shadow: inset 0 0 0 3px #f07818; }
.place-value-tool.tap-selecting .place-value-head { cursor: pointer; box-shadow: inset 0 0 0 2px #f07818; }
.place-value-tool.tap-selecting .place-value-head:hover,
.place-value-tool.tap-selecting .place-value-head:focus-visible { background: #fff1df; color: #7a3500; outline: none; }
.place-value-comma { position: absolute; z-index: 7; bottom: 2px; color: #c62828; font-family: "Cambria Math", serif; font-size: 2.2rem; font-weight: 900; line-height: 1; pointer-events: none; }
.glisse-zone.est-finie .place-value-drag-bar { cursor: default; }
@media (max-width: 620px) {
  .place-value-grid { border-width: 2px; border-radius: 10px; }
  .place-value-head { height: 36px; padding: 0 1px; font-size: .56rem; letter-spacing: -.04em; }
  .place-value-preview-row, .place-value-fixed-row { height: 52px; }
  .place-value-drag-bar { left: -13px; right: -13px; top: 6px; height: 40px; }
  .place-value-strip-digit, .place-value-fixed-digit { font-size: 2.05rem; }
  .place-value-comma { font-size: 2rem; }
}

/* ---- le tableau à flèches (« je représente » de M2 et D2) : à sa taille
   naturelle, jamais plus large que la place. ---- */
.dc-aide svg.dc-tableau { width: auto; max-width: 100%; height: auto; margin: 0 auto; }
/* Sur un écran bas, le tableau d'une correction se fait plus petit : la
   phrase, l'image, le pavé et « Suivant » tiennent ensemble. */
@media (min-width: 621px) and (max-height: 900px) {
  .challenge-playing .question.aide-image .dc-aide svg.dc-tableau { max-height: 25dvh; }
}

/* ---- la phrase-bilan, à la fin de « J'apprends » ---- */
.dc-retenir { max-width: 560px; margin: 0 auto 14px; padding: 18px 18px 14px; border: 2px solid #9fd3cb; border-radius: 20px; background: linear-gradient(135deg, #eaf7f4, #f2f8ff); text-align: center; }
.dc-retenir .eyebrow { margin: 0 0 6px; }
.dc-retenir .phrase { margin: 0 0 4px; color: var(--ink); font-size: calc(var(--retenir-z, 1) * clamp(1.5rem, 5.4vw, 2.1rem)); font-weight: 950; line-height: 1.2; }
.dc-retenir .phrase:focus { outline: none; }
/* Relecture 1 (05/11/2026) : le calcul du bilan, seul sur sa ligne, d'un
   seul tenant. */
.dc-retenir .dc-retenir-calcul { display: block; margin-top: .3em; white-space: nowrap; }
.dc-retenir .dc-aide { max-width: 440px; }
/* Téléphone : --retenir-z (posé par la page) rapetisse la phrase et le
   dessin ensemble quand le cadre dépasserait l'écran. */
@media (max-width: 620px) {
  .dc-retenir .dc-aide { width: calc(min(100%, 440px) * var(--retenir-z, 1)); }
}
.dc-retenir .cahier { margin: 8px 0 0; color: #5b7286; font-size: .9rem; font-weight: 800; }

/* ---- le bilan : « Juste, mais trop long » ---- */
.result .seance-suite .cadre { max-width: 520px; text-align: center; }
/* M4 (modules lot 3) : le bouton qui ouvre Défi tables, sous la phrase. */
.seance-suite .cadre .renvoi-tables { justify-content: center; margin-top: 8px; }
.seance-suite .cadre .renvoi-tables a { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 16px; border-radius: 14px; text-decoration: none; font-weight: 900; }

/* ---- « Comment ça marche ? » ---- */
.notice-screen { max-width: 620px; margin: 0 auto; }
.notice { margin: 12px 0 0; padding: 12px 14px; border: 1px solid #c9dbe6; border-radius: 15px; background: #f8fcff; color: var(--ink); font-size: .95rem; text-align: left; }
.notice p { margin: 0; line-height: 1.45; }
.notice p + p { margin-top: 8px; }
.notice b { color: var(--teal); }

@media (max-width: 480px) {
  .settings-toolbar { padding: 0 50px; }
  .settings-back { width: 44px; padding: 0; }
  .settings-back-label { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after { transition: none !important; animation: none !important; }
}

/* ------------------------------------------------- la séance guidée (lot 2a) */
.carte-seance .programme small { display: block; }
/* Le bouton de la carte : sous le programme, sur toute la largeur, son texte
   au milieu — au téléphone comme sur ordinateur. */
.carte-seance { display: flex; flex-direction: column; }
.carte-seance .tete { display: contents; }
.carte-seance .tete > span:first-child { order: 1; }
.carte-seance .programme { order: 2; }
.carte-seance .go { order: 3; margin-top: 12px; padding: 10px 18px; line-height: 1.2; text-align: center; }
/* Deux boutons côte à côte ont la même hauteur (l'ombre du bouton bleu comprise). */
.seance-suite .boutons { align-items: flex-start; }
.seance-suite .boutons .secondary { min-height: 48px; padding: 12px 18px 8px; box-shadow: 0 5px 0 #d3e1ea; }
.carte-seance.est-faite { border-color: #9fd3cb; box-shadow: none; text-align: left; }
.carte-seance.est-faite .tete strong { color: var(--teal); }
/* Le fil de la séance : sur sa ligne, centré, au-dessus de la barre. */
#play .seance-fil.seance { justify-content: center; margin: 0 0 6px; }
@media (max-width: 620px) {
  /* Téléphone : le fil des trois temps a sa ligne, au-dessus du bouton de
     retour ; dans une séance (le fil de la séance est déjà au-dessus), il
     partage la ligne du bouton. */
  #play .status { flex-wrap: wrap; }
  #play .status .seance-fil { order: -1; flex: 0 0 100%; margin: 0; }
  #play.en-seance .status .seance-fil { order: 0; flex: 0 1 auto; margin-left: auto; }
  #play .seance-fil.seance { justify-content: flex-start; flex-wrap: wrap; gap: 2px 8px; }
  /* Le nom de la compétence est sur la carte et dans les bilans : ici, le
     fil tient sur une ligne. */
  #play .seance-fil.seance .quoi { display: none; }
  /* Lot 3b : les séances ont plus d'étapes (les « encore », puis la
     nouveauté) ; pendant le jeu, les points se resserrent et « Ma séance »
     s'efface pour que le fil tienne sur une ligne. */
  #play .seance-fil.seance > span:first-child { display: none; }
  #play .seance-fil.seance li + li { margin-left: 10px; }
  #play .seance-fil.seance li + li::before { width: 10px; }
}
/* Le mode professeur. */
.prof-pilule { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px 8px; max-width: 560px; margin: 0 auto 10px; padding: 7px 14px; border-radius: 999px; background: #3b1f6b; color: #fff; font-size: .86rem; font-weight: 850; line-height: 1.25; }
.prof-pilule b { font-weight: 950; }
.prof-pilule button { padding: 0; border: 0; background: none; color: #fff; font: inherit; font-weight: 900; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.prof-pilule.est-refus { background: #5b7286; }
/* Le bilan du test : une ligne par niveau. */
.bilan-niveaux { display: grid; gap: 6px; width: 100%; margin: 0; }
.bilan-niveaux > span { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 7px 10px; border: 1px solid #cfe0f2; border-radius: 10px; background: #fff; font-size: .95rem; font-weight: 850; text-align: left; }
.bilan-niveaux i { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; color: #fff; font-style: normal; font-size: 13px; font-weight: 950; line-height: 1; }
.bilan-niveaux .oui i { background: var(--teal); }
.bilan-niveaux .non i { background: #c62828; }
.bilan-niveaux small { color: #5b7286; font-size: .78rem; font-weight: 800; text-align: right; }
.bilan-niveaux .oui small { color: var(--teal); }
/* Téléphone : le détail passe sous le nom du niveau. */
@media (max-width: 620px) {
  .bilan-niveaux > span { grid-template-columns: 22px minmax(0, 1fr); gap: 0 8px; }
  .bilan-niveaux small { grid-column: 2; text-align: left; }
}
/* Ce qui monte et ce qui redescend, et les étapes d'une séance faite. */
.mouv { display: grid; gap: 4px; width: 100%; margin: 0; font-size: .92rem; font-weight: 850; text-align: left; }
.mouv > span { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
.mouv > span > span:last-child { text-align: right; }
.mouv .monte { color: var(--teal); }
.mouv .descend { color: #c62828; }

/* Comme dans Défi tables : l'élève à code
   (body.mode-eleve) n'a plus qu'UNE barre fine en haut — « ← Mon
   espace » (la flèche seule au téléphone), le bloc de suivi avec
   « Se déconnecter » dedans, et « Plein écran » sur ordinateur. Le logo
   passe, en petit, dans le pied de page. Le visiteur sans code garde
   l'en-tête du site : le logo est son chemin vers le site. */
body.mode-eleve .topbar { flex-wrap: nowrap; min-height: 0; padding-top: 8px; padding-bottom: 8px; gap: 8px; }
body.mode-eleve .topbar > .brand { display: none; }
body.mode-eleve .topbar-actions { display: contents; }
body.mode-eleve #lien-retour { order: 1; flex: 0 0 auto; }
body.mode-eleve .suivi-repere { order: 2; flex: 1 1 auto; min-width: 0; margin: 0; }
body.mode-eleve .fullscreen-toggle { order: 3; flex: 0 0 auto; }
@media (max-width: 620px) {
  body.mode-eleve .topbar { padding: 6px 10px; gap: 6px; }
  body.mode-eleve #lien-retour { width: 40px; min-width: 40px; min-height: 40px; padding: 0; }
  body.mode-eleve #lien-retour .catalogue-link-label { display: none; }
}

/* ------------------------------------------------- le scénario d'un module (lot 3) */
/* Le test d'entrée en escalier : une marche par niveau, de plus en plus
   haute ; montée en vert, celle qui se joue encadrée de bleu, ratée en
   rouge ; sous chaque marche, un point par calcul (vert juste, rouge faux). */
.dc-escalier { margin: 0 auto 6px; text-align: center; }
.dc-escalier[hidden] { display: none; }
.dc-escalier .marches { display: flex; align-items: flex-end; justify-content: center; gap: 6px; }
.dc-escalier .marche { display: grid; justify-items: center; gap: 4px; width: 58px; }
.dc-escalier .marche b { display: grid; place-items: center; width: 100%; height: calc(26px + var(--h, 1) * 10px); border: 2px solid #c5d9e6; border-radius: 9px; background: #f1f6fa; color: #8fa6b7; font-size: 1rem; font-weight: 950; box-sizing: border-box; }
.dc-escalier .marche.ok b { border-color: var(--teal); background: var(--teal); color: #fff; }
.dc-escalier .marche.ici b { border: 3px solid var(--blue); background: #fff; color: var(--blue); }
.dc-escalier .marche.ratee b { border-color: #c62828; border-style: dashed; background: #fff; color: #c62828; }
.dc-escalier .points { display: flex; gap: 4px; min-height: 10px; }
.dc-escalier .points i { width: 10px; height: 10px; border: 2px solid #c5d9e6; border-radius: 50%; background: #fff; box-sizing: border-box; }
.dc-escalier .points i.juste { border-color: var(--teal); background: var(--teal); }
.dc-escalier .points i.faux { border-color: #c62828; background: #c62828; }
.dc-escalier p { margin: 4px 0 0; color: #5b7286; font-size: .82rem; font-weight: 850; }
/* « Nouveau : la case est devant » : une écriture nouvelle à l'entraînement. */
.dc-annonce-forme { width: fit-content; margin: 0 auto 6px; padding: 4px 12px; border: 2px solid #e2a200; border-radius: 999px; background: #fff7dc; color: #7a4f00; font-size: .9rem; font-weight: 900; }
.dc-annonce-forme[hidden] { display: none; }
/* L'outil à manipuler à l'entraînement (après deux erreurs de suite) : on
   manipule d'abord, le pavé et la touche « , » arrivent quand le geste est
   fait, et on tape la réponse. */
.question.manip-entraine.est-finie .keypad { display: grid; }
.question.manip-entraine.est-finie .dc-touches:not([hidden]) { display: grid; }
.question.manip-entraine.est-finie .answer-feedback { display: block; }
.question.manip-entraine .dc-aide { flex: 0 1 auto; }
.question.manip-entraine .perles-scene { min-height: 110px; max-height: 36dvh; }
/* Les modules qui viennent, dans un palier : une liste compacte. */
.dc-bientot { margin: 4px 2px 0; padding: 6px 9px; border: 1px dashed #c5d9e6; border-radius: 10px; background: #f6f9fb; color: #6b8192; font-size: .78rem; font-weight: 700; line-height: 1.35; text-align: left; }
.dc-bientot b { color: #5b7286; font-weight: 900; }
/* Le bilan du test : une marche qu'on n'a pas jouée. */
.bilan-niveaux .pas i { background: #c5d9e6; color: #fff; }
.bilan-niveaux .pas { color: #6b8192; }

/* ---- En-tête commun des applis suivies (variante A, planches du
   31/10/2026, AGENTS.md) — l'élève à code (même dessin que Défi tables) ----
   Plus de barre au-dessus du cadre : la barre du haut (la même, avec ses
   boutons, son bloc de suivi et sa garde) passe DANS le cadre blanc, en
   premier (placerEnTete, body.en-tete-cadre). Sur l'accueil de l'appli :
   la flèche ronde à gauche (vers Mon espace), le titre au centre
   (« Calcul mental » puis « Défi calcul »), le plein écran rond à droite,
   et sous le titre la ligne « ● Suivi · Rania · 405 · Se déconnecter ».
   Sur les autres écrans (Mon parcours, une série, un résultat…), où
   l'écran a déjà sa flèche et son titre : la ligne seule, centrée, avec
   le plein écran à droite sur ordinateur — ce que portait la barre
   d'avant, sans la barre. */
.ec-titre { display: none; }
body.en-tete-cadre .topbar { display: grid; grid-template-columns: minmax(44px, 1fr) auto minmax(44px, 1fr);
  grid-template-areas: "g t d" "l l l"; align-items: center; gap: 0 12px; min-height: 0; margin: 0 0 8px; padding: 0; }
body.en-tete-cadre .shell { padding-top: 10px; }
/* Le haut du cadre BLANC, comme le reste (31/10/2026, soir, planche 16 :
   « tout blanc » remplace le bleu très pâle de la planche 5), avec le
   trait fin gris sous la ligne de suivi (le même que sous le bandeau
   d'Anzan). Deux ombres intérieures : elles suivent l'arrondi du
   cadre et passent sous son contenu. Leur hauteur, --haut-teinte, est
   posée par teinterHaut() : le bas de la barre, plus 6 px. */
body.en-tete-cadre .shell > .panel.haut-teinte { box-shadow: inset 0 var(--haut-teinte) 0 0 #fff,
  inset 0 calc(var(--haut-teinte) + 1px) 0 0 #e3ebf0, 0 18px 55px rgba(26, 66, 100, .12); }
body.en-tete-cadre.ecran-interne .topbar { grid-template-areas: "g l d"; margin-bottom: 10px; }
body.en-tete-cadre #lien-retour { grid-area: g; justify-self: start; width: 44px; min-width: 44px; min-height: 44px; padding: 0; border-radius: 50%; border-color: #d4e3ed; }
body.en-tete-cadre #lien-retour .catalogue-link-label { display: none; }
body.en-tete-cadre .fullscreen-toggle { grid-area: d; justify-self: end; width: 44px; min-width: 44px; padding: 0; border-radius: 50%; border-color: #d4e3ed; }
body.en-tete-cadre .fullscreen-toggle [data-fullscreen-label] { display: none; }
body.en-tete-cadre .fullscreen-toggle-icon svg { width: 20px; height: 20px; }
body.en-tete-cadre:not(.ecran-interne) .ec-titre { display: block; grid-area: t; min-width: 0; text-align: center; }
.ec-titre .eyebrow { margin: 0 0 2px; font-size: .72rem; letter-spacing: .12em; }
.ec-titre .ec-nom { margin: 0; color: var(--ink); font-size: 2rem; line-height: 1.1; font-weight: 900; }
/* La ligne de suivi : les mêmes règles, les mêmes valeurs que dans les
   cinq applis suivies (tests/en-tete-commun.test.mjs). Elle remplace
   ici le bandeau pâle d'avant. */
body.en-tete-cadre .suivi-repere { grid-area: l; display: block; flex: none; order: 0; box-sizing: border-box; min-width: 0; min-height: 0;
  margin: 4px 0 0; padding: 0; border-radius: 0; background: none; color: #506b7d; font-weight: 500; font-size: .86rem; line-height: 1.35; text-align: center; }
body.en-tete-cadre .suivi-repere[hidden] { display: none; }
body.en-tete-cadre.ecran-interne .suivi-repere { margin: 0; }
body.en-tete-cadre .suivi-repere .puce { display: inline-block; width: 8px; height: 8px; margin: 0 6px 0 0; border-radius: 50%; background: #147447; vertical-align: 1px; }
body.en-tete-cadre .suivi-repere .repere-texte { display: inline; }
body.en-tete-cadre .suivi-repere .morceau, body.en-tete-cadre .suivi-repere .sortie-bloc,
body.en-tete-cadre .suivi-repere .repere-lien { display: inline; white-space: nowrap; font-size: inherit; }
body.en-tete-cadre .suivi-repere .repere-prenom { font-weight: 700; color: #143451; }
body.en-tete-cadre .suivi-repere .sortie { position: relative; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; background: none;
  font: inherit; color: inherit; text-decoration: underline; text-underline-offset: 2px; opacity: 1; cursor: pointer; }
body.en-tete-cadre .suivi-repere .sortie::after { content: ""; position: absolute; left: -8px; right: -8px; top: -22px; height: 44px; }
body.en-tete-cadre .suivi-repere .sortie:hover, body.en-tete-cadre .suivi-repere .sortie:focus-visible { color: #143451; }
body.en-tete-cadre .suivi-repere .repere-lien a { color: inherit; text-underline-offset: 2px; }
body.en-tete-cadre .suivi-repere.hors-ligne { background: none; color: #8a4c0a; }
body.en-tete-cadre .suivi-repere.hors-ligne .puce { background: #d9822b; }
body.en-tete-cadre .suivi-repere.detache { background: none; color: #3d4a5a; }
body.en-tete-cadre .suivi-repere.detache .puce { display: none; }
/* Pendant une série, la ligne reste en haut du cadre, sans rien changer
   à la mise en page du jeu : la colonne n'a plus qu'une rangée. */
body.en-tete-cadre.challenge-playing .shell { grid-template-rows: minmax(0, 1fr); }
body.en-tete-cadre.challenge-playing .topbar { min-height: 0; padding: 0; margin-bottom: 4px; }
/* La barre et le jeu s'empilent dans le cadre : le jeu prend la place qui
   reste. Sans cela, le cadre débordait de la hauteur de la barre et le
   navigateur le faisait défiler en donnant le focus à la case réponse :
   la ligne de suivi était rognée en haut. */
body.en-tete-cadre.challenge-playing .panel { display: flex; flex-direction: column; }
body.en-tete-cadre.challenge-playing .panel > .topbar { flex: 0 0 auto; }
body.en-tete-cadre.challenge-playing #play { flex: 1 1 auto; min-height: 0; height: auto; }
/* Le titre de l'écran d'abord, la ligne dessous (31/10/2026) : la barre
   est rangée juste sous le titre de l'écran ou sous le fil de la séance
   (placerEnTete, body.ligne-sous-titre) ; le fil, centré, devient le titre
   de l'écran de jeu. */
body.en-tete-cadre header.topbar { flex: 0 0 auto; }
body.en-tete-cadre.ligne-sous-titre .topbar,
body.en-tete-cadre.ligne-sous-titre.challenge-playing .topbar { margin: 2px 0 12px; }
body.en-tete-cadre.ligne-sous-titre #play .seance-fil.seance { justify-content: center; margin-bottom: 4px; }
body.en-tete-cadre.ligne-sous-titre #result-fil { margin-bottom: 4px; }
body.en-tete-cadre.ligne-sous-titre #result { margin-top: 8px; }
/* La flèche toujours en haut à gauche (31/10/2026, soir) : pendant la
   séance, « ← Accueil » monte sur la ligne du fil ; la ligne de suivi vient
   dessous, puis le compteur. */
body.en-tete-cadre.ligne-sous-titre.challenge-playing #play { position: relative; }
body.en-tete-cadre.ligne-sous-titre.challenge-playing #fil-seance { min-height: 44px; padding: 0 112px; box-sizing: border-box;
  flex-wrap: wrap; justify-content: center; row-gap: 2px; text-align: center; }
/* « Ma séance » : les ronds numérotés le disent déjà, la place va au nom. */
body.en-tete-cadre.ligne-sous-titre.challenge-playing #fil-seance > span:first-child { display: none; }
body.en-tete-cadre.ligne-sous-titre.challenge-playing #game-menu { position: absolute; top: 0; left: 0; }
/* Sur ordinateur, la barre du jeu n'est plus le repère de la flèche (elle
   monte) : le fil de « J'apprends » reprend sa place dans la barre, entre le
   compteur et « À ton rythme ». */
@media (min-width: 621px) {
  body.en-tete-cadre.ligne-sous-titre.challenge-playing #play .status { position: static; }
  body.en-tete-cadre.ligne-sous-titre.challenge-playing #play .status .seance-fil { position: static; min-height: 0; }
}
@media (max-width: 620px) {
  /* Au téléphone, les ronds à côté de la flèche, le nom de l'activité sur
     toute la largeur juste dessous (il garde sa ligne entière). */
  body.en-tete-cadre.ligne-sous-titre.challenge-playing #fil-seance { padding: 0 4px; flex-wrap: wrap; justify-content: center; row-gap: 2px; text-align: center; }
  body.en-tete-cadre.ligne-sous-titre.challenge-playing #fil-seance > b { flex-basis: 100%; }
  body.en-tete-cadre.ligne-sous-titre.challenge-playing #game-menu { width: 44px; min-width: 44px; padding: 0; border-radius: 50%; }
  body.en-tete-cadre.ligne-sous-titre.challenge-playing #game-menu .game-menu-label { display: none; }
}
@media (max-width: 620px) {
  body.en-tete-cadre.ligne-sous-titre #play .seance-fil.seance { justify-content: center; }
}
@media (max-width: 620px) {
  body.en-tete-cadre .topbar { gap: 0 8px; padding: 0; }
  body.en-tete-cadre:not(.ecran-interne) .topbar { margin-top: 2px; }
  body.en-tete-cadre .ec-titre .ec-nom { font-size: 1.5rem; }
  body.en-tete-cadre .suivi-repere { font-size: .8rem; }
  body.en-tete-cadre.challenge-playing .topbar { padding: 0; margin-bottom: 2px; }
  body.en-tete-cadre.challenge-playing .suivi-repere { margin: 0; padding: 0; font-size: .74rem; border-radius: 0; }
}

/* ------------------------------------------------- téléphone : tout tient (audit du 31/10)
   Sur iPhone, la hauteur VISIBLE est celle de l'écran moins la barre
   d'adresse de Safari (en bas) et le bandeau de suivi : 560 à 750 px.
   Rien ne cédait de place (« .question > * » ne rétrécit pas) : le cadre du
   jeu défilait en dedans et « Valider » passait sous l'écran. Ce qui cède,
   quand la place manque, dans l'ordre : la ligne de retour tant qu'elle est
   vide, les touches du pavé (jusqu'à 44 px de haut, la taille d'un doigt),
   l'image et le rekenrek (dessinés plus petit, jamais déformés), la case du
   calcul jusqu'à la taille de ses chiffres. Quand la place ne manque pas
   (390 × 844), rien ne change. */
@media (max-width: 620px) {
  .challenge-playing .question > .answer-feedback { flex: 0 8 56px; min-height: auto; }
  .challenge-playing .question:not(.aide-perles) > .expression { flex: 0 1 clamp(68px, 12dvh, 92px); min-height: auto; }
  .challenge-playing .question > .keypad { flex: 0 2 calc(4 * (var(--touche-h) + 2 * var(--touche-ecart)) + 4px); min-height: 180px; grid-template-rows: repeat(4, minmax(0, 1fr)); }
  .challenge-playing .question > .keypad button { height: auto; }
  .challenge-playing .question.aide-image > .dc-aide { flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .challenge-playing .question.aide-image > .dc-aide > svg { flex: 0 1 auto; min-height: 0; max-width: 100%; }
  .challenge-playing .question.aide-image > .dc-aide > .consigne { flex: 0 0 auto; }
  /* « Calcul 6 · 1 juste de suite » passe sur deux lignes à côté du bouton
     plutôt que de pousser « À ton rythme » sur une ligne à lui. */
  .challenge-playing #play .status-left { flex: 1 1 0; }
  /* Le rekenrek de l'entraînement prend la place qui reste (et non sa
     propre taille) : avant le geste, tout l'espace ; après, ce que le pavé
     laisse. La consigne du geste (rekenrek, glisse-nombres) s'efface une
     fois le geste fait. */
  .challenge-playing .question.aide-perles.manip-entraine > .dc-aide { flex: 1 1 36dvh; min-height: 0; }
  .challenge-playing .question.manip-entraine .perles-scene { min-height: 0; }
  .challenge-playing .question.manip-entraine.est-finie .dc-aide .consigne { display: none; }
  /* Le glisse-nombres garde sa taille : c'est ajusterGlisseTelephone() qui
     le dessine plus petit, le geste fait, quand la place manque. */
  .challenge-playing .question.aide-glisse.manip-entraine > .dc-aide { flex: 0 0 auto; }
  .challenge-playing .question.aide-glisse.manip-entraine.est-finie > .dc-aide.sans-tableau .place-value-tool { display: none; }
}

/* Modules lot 6 (04/11/2026) : les fractions. Le schéma en barres sur la
   droite graduée (Je représente, l'aide, J'écris, « À retenir ») : des
   parts à compter, comme le tableau de numération. */
.dc-aide svg.dc-fractions { width: auto; max-width: 100%; height: auto; margin: 0 auto; }
@media (max-width: 620px) {
  .challenge-playing .question.aide-image .dc-aide svg.dc-fractions { max-height: 30dvh; }
  .challenge-playing .question.ecrit.aide-image .dc-aide svg.dc-fractions { max-height: 27dvh; }
}
@media (min-width: 621px) {
  .dc-aide svg.dc-fractions { width: min(100%, 480px); }
  /* (Lot 6b : 20dvh au lieu de 28 — les fractions des étapes ont grandi.) */
  .challenge-playing .question.ecrit.aide-image .dc-aide svg.dc-fractions { max-height: 20dvh; }
}
.dc-retenir .dc-aide svg.dc-fractions { max-height: calc(28dvh * var(--retenir-z, 1)); }
/* Les bandes du site, posées sur la droite (Je manipule). Ce qu'on touche
   est entouré de bleu ; le contour bat doucement tant que l'élève n'a pas
   fait son premier geste. */
.dc-bandes { width: 100%; }
.dc-bandes-scene { width: min(100%, 520px); margin: 8px auto 0; border-radius: 8px; cursor: pointer; touch-action: manipulation; }
.dc-bandes-scene svg { display: block; width: 100%; height: auto; }
.dc-bandes-scene:focus-visible { outline: 3px solid #0f6cf9; outline-offset: 3px; }
.dc-bandes.est-finie .dc-bandes-scene { cursor: default; }
.dc-bandes-scene [data-piece], .dc-bandes-scene [data-reserve] { cursor: pointer; }
.dc-bandes-scene.dc-attente .dc-cible { animation: dc-battement 1.2s ease-in-out infinite; }
@keyframes dc-battement { 0%, 100% { stroke-opacity: 1; } 50% { stroke-opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .dc-bandes-scene.dc-attente .dc-cible { animation: none; } }
