/* =========================================================================
   FRACTILO — feuille de style unique de l'application enfant.

   Système graphique centralisé, dérivé du logo (public/logofractilo.PNG) :
     marine 39 % · turquoise 20 % · corail 15 % · violet 13 % · jaune 12 %

   Deux familles de jetons, à ne pas confondre :
   · « teintes de marque » (--marine, --turquoise, --corail, --jaune,
     --violet) : aplats décoratifs et remplissages de figures, toujours
     cernés par un trait marine — jamais de texte fin posé dessus ;
   · « rôles » (--ink, --acc, --ok, --err…) : versions assombries, seules
     autorisées derrière du texte. Contrastes vérifiés au niveau AA
     (4,5:1 pour le texte, 3:1 pour les bordures, focus et graphiques).
   ========================================================================= */
:root{
  /* --- teintes de marque, relevées sur le logo ------------------------- */
  --marine:#18315B; --turquoise:#3CC3CB; --corail:#F0624F;
  --jaune:#FDB220;  --violet:#8A70C7;

  /* --- fonds et surfaces ---------------------------------------------- */
  --bg:#F3F6FA;              /* fond général, marine très dilué           */
  --bg-2:#E9EEF7;            /* fond creux : pistes de jauge, cases vides */
  --card:#FFFFFF;            /* surface des cartes                        */
  --card-sel:#E4F4F6;        /* carte sélectionnée (turquoise très clair) */
  --card-ok:#E7F3ED;         /* carte correcte                            */
  --card-ko:#FBEDEB;         /* carte incorrecte                          */
  --voile:#F3F6FAEE;         /* voile des récompenses                     */

  /* --- textes ---------------------------------------------------------- */
  --ink:#17305C;             /* texte principal — marine                  */
  --soft:#59667C;            /* texte secondaire                          */
  --ink-inv:#FFFFFF;         /* texte sur aplat marine                    */

  /* --- rôles sémantiques (versions texte, assombries) ------------------ */
  --acc:#3CC3CB;             /* accent pédagogique : REMPLISSAGES         */
  --acc-txt:#0E6E78;         /* le même accent, version texte et bordure  */
  --acc2:#0B5A62;            /* accent appuyé (légendes sur fond clair)   */
  --ok:#1E7A5B;              /* réussite                                  */
  --err:#C33A2B;             /* erreur douce                              */
  --gold:#8A5A08;            /* récompense, version texte                 */
  --gold-vif:#FDB220;        /* étoiles et médailles, version aplat       */
  --violet-txt:#6B4FB0;      /* catégories, niveaux                       */

  /* --- surlignage pédagogique (numérateur / dénominateur) -------------- */
  --hlA:#FDB220;             /* numérateur : aplat                        */
  --hlA-txt:#8A5A08;         /* numérateur : texte                        */
  --hlB:#3CC3CB;             /* dénominateur : aplat                      */
  --hlB-txt:#0E6E78;         /* dénominateur : texte                      */

  /* --- traits et bordures ---------------------------------------------- */
  --line:#17305C;            /* contour des figures                       */
  --border:#C9D5E6;          /* filet décoratif                           */
  --border-fort:#7C8AA3;     /* bordure porteuse de sens (3,49:1)         */
  --part:#E3EAF5;            /* part non coloriée                         */

  /* --- ombres ----------------------------------------------------------- */
  --sh-1:0 1px 2px #17305C14;
  --sh-2:0 3px 10px #17305C1F;
  --sh-3:0 10px 28px #17305C26;

  /* --- rayons ----------------------------------------------------------- */
  --r-xs:8px; --r-sm:12px; --r:20px; --r-lg:24px; --r-pill:999px;

  /* --- espacements ------------------------------------------------------ */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:18px; --sp-5:26px; --sp-6:38px;

  /* --- durées et courbes ------------------------------------------------ */
  --t-fast:.12s; --t:.22s; --t-slow:.45s;
  --ease:cubic-bezier(.3,.8,.3,1);
  --ease-out:cubic-bezier(.2,.7,.3,1);

  /* --- zone tactile minimale (enfants, tablettes) ---------------------- */
  --touch:56px;
}

/* =========================================================================
   NUNITO — la police de Fractilo, hébergée ici et nulle part ailleurs.

   Pourquoi des fichiers chez nous plutôt qu'un lien vers Google Fonts :
   la politique de sécurité est `default-src 'self'`, aucun domaine tiers
   n'est autorisé — et c'est très bien ainsi. Aucune requête ne part vers
   un serveur tiers pendant qu'un enfant joue ; la promesse « sans revente
   de données » commence par là.

   `latin-ext` n'est PAS optionnel : il porte le œ de « cœur », « sœur » et
   « œil », qui apparaissent dans les énoncés. Sans lui, ces mots seraient
   rendus dans une autre police au milieu de la phrase. Le navigateur ne
   télécharge que les sous-ensembles dont la page a besoin.

   `font-display:swap` : le texte s'affiche immédiatement dans la police de
   repli, puis bascule. Un enfant n'attend jamais devant un écran vide.

   Licence SIL Open Font (OFL-1.1) — le texte est dans
   public/polices/LICENCE-Nunito.txt et doit rester avec les fichiers.

   CE BLOC EST VOLONTAIREMENT RECOPIÉ dans public/parent.css : les deux
   feuilles sont indépendantes par construction, et un @import coûterait un
   aller-retour de plus avant le premier affichage. Si tu touches à l'un,
   touche à l'autre.
   ========================================================================= */
@font-face{font-family:'Nunito';font-style:normal;font-weight:400;font-display:swap;
  src:url('/polices/nunito-latin-400-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Nunito';font-style:normal;font-weight:700;font-display:swap;
  src:url('/polices/nunito-latin-700-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Nunito';font-style:normal;font-weight:800;font-display:swap;
  src:url('/polices/nunito-latin-800-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Nunito';font-style:normal;font-weight:400;font-display:swap;
  src:url('/polices/nunito-latin-ext-400-normal.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,
    U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,
    U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Nunito';font-style:normal;font-weight:700;font-display:swap;
  src:url('/polices/nunito-latin-ext-700-normal.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,
    U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,
    U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Nunito';font-style:normal;font-weight:800;font-display:swap;
  src:url('/polices/nunito-latin-ext-800-normal.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,
    U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,
    U+2C60-2C7F,U+A720-A7FF}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;height:100%}
body{
  background:var(--bg); color:var(--ink);
  /* Nunito d'abord ; la pile de repli reste celle d'avant, mot pour mot, pour
     que le fichier hors-ligne (dist/atelier-fractions.html), qui n'a pas les
     .woff2 à côté de lui, reste exactement tel qu'il était. */
  font-family:'Nunito',"Trebuchet MS","Verdana",system-ui,-apple-system,"Segoe UI",sans-serif;
  overflow:hidden; user-select:none;
}

/* focus clavier visible et homogène sur toute l'application */
:focus-visible{outline:3px solid var(--acc-txt);outline-offset:3px;border-radius:var(--r-xs)}

#app{height:100dvh;display:flex;flex-direction:column}

/* ---------- en-tête ---------- */
#top{
  flex:0 0 auto;display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-2) var(--sp-4);font-size:14px;color:var(--soft);
  background:var(--card);border-bottom:1px solid var(--border);box-shadow:var(--sh-1);
  position:relative;z-index:5;
}
#top .marque{width:30px;height:30px;display:block;flex:none}
#top .title{font-weight:800;letter-spacing:.01em;color:var(--ink);font-size:16px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#top .spacer{flex:1}
#top button{
  background:none;border:2px solid transparent;color:var(--soft);font-size:19px;cursor:pointer;
  min-width:40px;height:40px;padding:0 var(--sp-2);border-radius:var(--r-sm);
  transition:background var(--t),color var(--t),border-color var(--t);
}
#top button:hover{color:var(--ink);background:var(--bg-2)}

/* ---------- LE TABLEAU DE NUMÉRATION À QUATRE CLASSES ---------------------
   Douze colonnes de chiffres plus quatre en-têtes : sur un téléphone de
   360 px, c'est le premier candidat au débordement. On ne rétrécit pas les
   chiffres au point de les rendre illisibles — on laisse la table défiler
   DANS SA PROPRE boîte, et la page ne bouge pas.
   Le trait épais marque la séparation des classes : c'est lui qui enseigne
   la convention des paquets de trois. */
/* UNE COULEUR PAR CLASSE — signalé le 31 août 2026 : « n'hésite pas à
   utiliser des couleurs dans les nombres, sinon c'est inbuvable ».
   Douze chiffres marine d'affilée ne se lisent pas. La couleur ne décore
   pas : elle PORTE la classe, et c'est la même dans le nombre, dans le
   tableau et dans les mots. Les quatre teintes sortent de la charte, en
   version texte assombrie, et tiennent 4,5:1 sur --bg, --card et --bg-2
   (mesuré, et rejoué par test/n5-entiers.test.js).
   Aucune n'est le rouge des erreurs ni le vert des réussites : dans cette
   application, une couleur ne dit jamais deux choses à la fois. */
/* « sept-cent-sept-milliards-vingt-mille-quatorze » ne tient pas sur la
   largeur d'un téléphone, et un mot de quarante-cinq lettres ne se coupe
   pas tout seul : il sortait de l'écran. On l'autorise à passer à la ligne
   au trait d'union — c'est là qu'un lecteur le coupe aussi. */
.motslongs{
  display:inline-block;max-width:100%;
  overflow-wrap:anywhere;word-break:break-word;
  line-height:1.3;font-size:.82em;
}

/* LE REPÈRE DE CLASSE SUR UNE CARTE DE NIVEAU — voir app/niveaux.js.
   Écrit petit, en gris, sous le titre : c'est une note pour l'adulte qui
   regarde par-dessus l'épaule, pas le nom de la carte. Un enfant lit
   d'abord « Niveau 3 ». Si un jour ce texte grossit ou prend une couleur,
   il devient une étiquette scolaire — et ce n'est plus la même chose. */
.mcard .repere{
  margin:2px 0 6px;font-size:13px;font-weight:700;color:var(--soft);
  letter-spacing:.02em;
}

.cl-g{color:var(--violet-txt)}   /* milliards */
.cl-m{color:var(--gold)}         /* millions  */
.cl-k{color:var(--acc-txt)}      /* mille     */
.cl-u{color:var(--ink)}          /* unités    */

.tnum.classes5{border-collapse:collapse;margin:0 auto}
.tnum.classes5 th{
  font-size:12px;font-weight:800;letter-spacing:.01em;color:var(--soft);
  padding:2px 4px;white-space:nowrap;
}
.tnum.classes5 td{padding:0;min-width:26px}
.tnum.classes5 th,.tnum.classes5 td{border:1px solid var(--border)}
.tnum.classes5 th.sep,.tnum.classes5 td.sep{border-left:3px solid var(--ink)}
.tnum.classes5 th:first-child,.tnum.classes5 td:first-child{border-left:1px solid var(--border)}
.tnum.classes5 .chiffre{font-size:20px;padding:3px 5px}
@media(max-width:560px){
  .tnum.classes5 th{font-size:10px;padding:2px}
  .tnum.classes5 td{min-width:20px}
  .tnum.classes5 .chiffre{font-size:16px;padding:2px 3px}
}

/* ---------- PROPORTIONNALITÉ : LE SCHÉMA FLÉCHÉ ET LE TABLEAU ------------
   Les couleurs ne sont PAS nouvelles : ce sont exactement les trois teintes
   déjà en service pour les classes de nombres ci-dessus. Turquoise pour la
   première grandeur, or pour la seconde, violet pour l'opérateur. Elles sont
   déjà mesurées à 4,5:1 et déjà connues de l'œil de l'enfant — on n'invente
   pas un quatrième système de couleurs pour un quatrième domaine.

   La couleur n'est jamais seule à porter l'information : les flèches de la
   première grandeur sont en TRAIT PLEIN, celles de la seconde en POINTILLÉ.
   Un enfant daltonien lit le schéma ; imprimé en noir et blanc, il tient.
   Les contrastes sont rejoués depuis ce fichier par
   test/n5-proportionnalite.test.js — changer une valeur ici fait tomber le
   test, c'est le but.                                                      */
.fig.prop,.fig.ech{max-height:none;max-width:min(94vw,680px)}
.fig.prop .pr-a{fill:var(--acc-txt)}
.fig.prop .pr-b{fill:var(--gold)}
.fig.prop .pr-op{fill:var(--violet-txt);font-size:19px;font-weight:800;font-family:inherit}
.fig.prop .pr-lab{fill:var(--soft);font-size:17px}
.fig.prop .pr-val{font-size:23px;font-weight:800;font-family:inherit}
.fig.prop .pr-box{fill:var(--card);stroke:var(--border);stroke-width:2}
.fig.prop .pr-box.pr-cible{stroke:var(--acc-txt);stroke-width:3.5;stroke-dasharray:7 5}
.fig.prop .pr-fl-a{stroke:var(--acc-txt);stroke-width:3}                    /* plein     */
.fig.prop .pr-fl-b{stroke:var(--gold);stroke-width:3;stroke-dasharray:6 5}  /* pointillé */
.fig.prop .pr-tete-a{fill:var(--acc-txt)}
.fig.prop .pr-tete-b{fill:var(--gold)}
.fig.prop .pr-fl-h{stroke:var(--soft);stroke-width:2}
.fig.prop .pr-tete-h{fill:var(--soft)}

/* le tableau de deux grandeurs — mêmes teintes, mêmes rôles */
.tprop{border-collapse:collapse;margin:0 auto;font-weight:800}
.tprop th,.tprop td{border:2px solid var(--border);padding:7px 13px;text-align:center;
  font-size:clamp(15px,2.5vw,20px);white-space:nowrap}
.tprop th{background:var(--bg-2);font-size:clamp(12px,2vw,15px);text-align:right}
.tprop .pr-a{color:var(--acc-txt)}
.tprop .pr-b{color:var(--gold)}
.tprop .pr-op{color:var(--violet-txt)}
.tprop tr.qline td,.tprop tr.qline th{border-top:3px solid var(--border-fort);background:var(--bg)}
.tprop tr.entete td{border:none;background:none;color:var(--soft);
  font-size:clamp(12px,2vw,15px);padding-bottom:2px}
.tprop td.vise{background:var(--card-sel);outline:3px solid var(--acc-txt);outline-offset:-3px}

/* l'échelle qu'on reporte : le segment plein est celui qu'on a déjà compté */
.fig.ech .ech-route{stroke:var(--border-fort);stroke-width:3}
.fig.ech .ech-seg{fill:var(--card);stroke:var(--border-fort);stroke-width:2}
.fig.ech .ech-seg.on{fill:var(--acc)}
.fig.ech .ech-num{font-size:15px;font-weight:800;fill:var(--ink);font-family:inherit}

/* ---------- PROBABILITÉS : L'ARBRE, LE SAC, L'ÉCHELLE DE 0 À 1 -----------
   Toujours les mêmes teintes, toujours les mêmes rôles. La branche qu'on
   vient d'ajouter est en violet — la couleur qui sert déjà à désigner
   l'opérateur dans le schéma fléché : dans les deux cas, c'est « ce qui
   vient de se passer ». Aucun vert de réussite, aucun rouge d'erreur : une
   couleur ne dit jamais deux choses à la fois dans cette application.     */
.fig.arbre,.fig.sac,.fig.ep{max-height:none;max-width:min(94vw,680px)}
.fig.arbre .ar-trait{stroke:var(--border-fort);stroke-width:2.5}
.fig.arbre .ar-trait.neuf{stroke:var(--violet-txt);stroke-width:4}
.fig.arbre .ar-noeud{fill:var(--border-fort)}
.fig.arbre .ar-noeud.neuf{fill:var(--violet-txt)}
.fig.arbre .ar-lbl{font-size:15px;font-weight:800;fill:var(--soft);font-family:inherit}
.fig.arbre .ar-lbl.neuf{fill:var(--violet-txt)}
.fig.arbre .ar-feuille{font-size:15px;font-weight:800;fill:var(--acc-txt);font-family:inherit}

/* LES COULEURS DES BILLES SONT DES ÉTIQUETTES, PAS DES JUGEMENTS. Elles ne
   valent que dans ce dessin, et chacune porte AUSSI sa lettre : un enfant
   daltonien lit le sac, et imprimé en noir et blanc il reste lisible. */
.fig.sac .bille{stroke:var(--line);stroke-width:2.5}
.fig.sac .bille.vise{stroke:var(--ink);stroke-width:5}
.fig.sac .bl-r{fill:#F0624F}
.fig.sac .bl-b{fill:#3CC3CB}
.fig.sac .bl-v{fill:#8A70C7}
.fig.sac .bl-j{fill:#FDB220}
.fig.sac .bille-l{font-size:17px;font-weight:800;fill:var(--ink);font-family:inherit;
  pointer-events:none}

/* l'échelle de 0 à 1 : le dessin qui porte tout l'atelier de synthèse */
.fig.ep .ep-axe{stroke:var(--line);stroke-width:5;stroke-linecap:round}
.fig.ep .ep-grad{stroke:var(--border-fort);stroke-width:3}
.fig.ep .ep-mot{font-size:13px;font-weight:700;fill:var(--soft);font-family:inherit}
.fig.ep .ep-borne{font-size:19px;font-weight:800;fill:var(--ink);font-family:inherit}
.fig.ep .ep-pt{fill:var(--acc);stroke:var(--card);stroke-width:3}
.fig.ep .ep-pt.vise{stroke:var(--acc-txt);stroke-width:4}
.fig.ep .ep-lbl{font-size:17px;font-weight:800;fill:var(--acc-txt);font-family:inherit}
.fig.ep .ep-lien{stroke:var(--border-fort);stroke-width:2;stroke-dasharray:4 4}
.fig.ep .ep-ecr{font-size:18px;font-weight:800;fill:var(--acc-txt);font-family:inherit}

/* les trois conditions d'une expérience aléatoire, cochées une par une */
.cond3{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px;
  text-align:left;max-width:520px}
.cond3 li{display:flex;gap:10px;align-items:flex-start;font-size:clamp(14px,2.3vw,16px);
  padding:8px 12px;border-radius:var(--r-xs);border:2px solid var(--border);
  background:var(--card);color:var(--soft)}
.cond3 li .marque{font-weight:800;min-width:18px;text-align:center}
.cond3 li.oui{border-color:var(--acc-txt);color:var(--ink)}
.cond3 li.oui .marque{color:var(--acc-txt)}
/* « non » n'est pas une faute : c'est une condition qui n'est pas remplie.
   D'où le violet des catégories, et surtout PAS le rouge des erreurs. */
.cond3 li.non{border-color:var(--violet-txt);color:var(--ink)}
.cond3 li.non .marque{color:var(--violet-txt)}
.cond3 li.attente{opacity:.62}

/* ---------- LE RETOUR ----------------------------------------------------
   Signalé le 31 août 2026 : « l'icône est trop discrète ». Mesuré : les
   quatre boutons de l'en-tête avaient exactement la même couleur
   rgb(89,102,124), aucun fond, aucune bordure — et ⌂, glyphe creux, était
   le plus pâle des quatre. Rien ne désignait la sortie.
   Celui-ci porte donc une vraie forme de bouton : un fond, une bordure, la
   couleur d'accent. Ce n'est plus un glyphe parmi des glyphes.            */
#top button.retour{
  color:var(--acc-txt);background:var(--bg-2);border-color:var(--border);
  font-size:23px;font-weight:800;line-height:1;
}
#top button.retour:hover{background:var(--card-sel);border-color:var(--acc-txt);color:var(--acc-txt)}
/* Dès qu'il y a la place, le mot accompagne la flèche : une flèche seule se
   confond avec le retour du navigateur, le mot dit qu'on reste dans le jeu. */
@media(min-width:640px){
  #top button.retour::after{
    content:' Retour';font-size:15px;font-weight:800;letter-spacing:.01em;
  }
  #top button.retour{padding:0 var(--sp-3)}
}
/* Sur un téléphone, cinq boutons et un titre ne tiennent pas côte à côte.
   C'est le titre qui cède — il répète ce que l'écran dit déjà juste
   en dessous — jamais les boutons.                                        */
@media(max-width:479px){
  #top .title{display:none}
  #top button{min-width:36px;padding:0 var(--sp-1)}
}
#top button:active{transform:scale(.94)}
#steps{display:flex;gap:calc(var(--sp-1) + 3px);align-items:center}
#steps i{width:9px;height:9px;border-radius:50%;background:var(--border);display:block;
  transition:background var(--t)}
#steps i.on{background:var(--acc-txt);transform:scale(1.25)}
#steps i.done{background:var(--ok)}

/* ---------- zone de contenu ----------
   Le défilement appartient à #screen. Les deux dégradés « local » restent
   collés au contenu, les deux ombres « scroll » n'apparaissent que s'il
   reste quelque chose à faire défiler : l'enfant voit qu'il y a une suite. */
#screen{
  flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;display:flex;
  overscroll-behavior:contain;scrollbar-gutter:stable;
  background:
    linear-gradient(var(--bg) 30%,#F3F6FA00) top/100% 26px local no-repeat,
    linear-gradient(#F3F6FA00,var(--bg) 70%) bottom/100% 26px local no-repeat,
    radial-gradient(farthest-side at 50% 0,#17305C1F,#17305C00) top/100% 12px scroll no-repeat,
    radial-gradient(farthest-side at 50% 100%,#17305C24,#17305C00) bottom/100% 14px scroll no-repeat,
    var(--bg);
}
.stage{
  flex:1;display:flex;flex-direction:column;align-items:center;
  justify-content:center;
  justify-content:safe center;   /* si ça déborde, on ne rogne pas le haut */
  gap:clamp(10px,2.2vh,26px);padding:var(--sp-3) var(--sp-4) var(--sp-6);
  text-align:center;width:100%;
}
.consigne{
  font-size:clamp(21px,3.6vw,32px);font-weight:800;margin:0;line-height:1.25;max-width:900px;
  color:var(--ink);
}
.sub{font-size:clamp(16px,2.4vw,22px);color:var(--soft);margin:0;font-weight:600}
.big-txt{font-size:clamp(24px,4vw,36px);font-weight:800;margin:0}

.figzone{display:flex;align-items:center;justify-content:center;
  gap:clamp(14px,4vw,48px);flex-wrap:wrap;width:100%}
/* Les SVG ont une taille intrinsèque (attributs width/height) : on les réduit
   proportionnellement, ils ne débordent pas de leur boîte. */
.fig{display:block;height:auto;max-width:100%;max-height:min(42vh,380px);overflow:visible}
.fig.sm{max-height:min(26vh,200px)}
.fig.xs{max-height:min(21vh,155px)}
.part{stroke:var(--line);stroke-width:5;stroke-linejoin:round;
  transition:fill var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease), opacity var(--t)}
.fig.sm .part,.fig.xs .part{stroke-width:6}
.outline{fill:none;stroke:var(--line);stroke-width:7;pointer-events:none;stroke-linejoin:round}
/* ---- les parts sur lesquelles l'enfant CLIQUE -----------------------------
   Signalé le 25 août 2026 : « il faut cliquer sur une partie de l'image pour
   que cela la sélectionne, c'est pas fluide et on a l'impression que cela ne
   fonctionne pas ».

   La cause n'était pas le clic — il fonctionnait — mais son écho : .part
   fait passer sa couleur en 0,45 s. Ce fondu lent est voulu quand la figure
   se colorie TOUTE SEULE pendant une démonstration ; appliqué à un clic, il
   fait croire qu'il ne s'est rien passé, et l'enfant reclique.

   On ne raccourcit donc que les parts cliquables, et on ajoute ce qui
   manquait : un survol qui dit « ceci se clique » avant même le clic.    */
.clickable .part{cursor:pointer;
  transition:fill var(--t-fast) var(--ease-out),stroke var(--t-fast),stroke-width var(--t-fast)}
@media (hover:hover) and (pointer:fine){
  .clickable .part:hover{stroke:var(--acc-txt);stroke-width:9}
}
/* le doigt ou la souris appuie : la part réagit tout de suite, sans pâlir —
   pâlir ressemblait à « désactivé », c'était le contraire du message.   */
.clickable .part:active{opacity:1;stroke:var(--acc-txt);stroke-width:11}
.plab{font-size:38px;font-weight:800;fill:var(--ink);font-family:inherit;pointer-events:none}
.fig.sm .plab,.fig.xs .plab{font-size:52px}

/* ---------- cartes de figures : une grille, jamais de superposition ------ */
.cards{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:clamp(12px,2.4vw,26px);
  justify-items:stretch;align-items:stretch;
  width:100%;max-width:880px;margin:0 auto;
}
.card{
  background:var(--card);border:4px solid var(--border);border-radius:var(--r);
  padding:var(--sp-2);cursor:pointer;position:relative;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  width:100%;min-width:0;min-height:150px;               /* zone de clic confortable */
  box-shadow:var(--sh-1);
  transition:border-color var(--t),transform var(--t-fast),box-shadow var(--t),background var(--t);
}
.card:hover{border-color:var(--border-fort);box-shadow:var(--sh-2)}
.card:active{transform:scale(.97)}
.card.sel{border-color:var(--acc-txt);background:var(--card-sel);box-shadow:0 0 0 4px #0E6E7833}
.card.good{border-color:var(--ok);background:var(--card-ok);box-shadow:0 0 0 4px #1E7A5B2E}
.card.bad{border-color:var(--err);background:var(--card-ko);box-shadow:0 0 0 4px #C33A2B2E}
.card.dim{opacity:.35}
/* pastille : l'état ne repose jamais sur la seule couleur */
.card.sel::after,.card.good::after,.card.bad::after{
  position:absolute;top:-11px;right:-11px;width:28px;height:28px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:16px;font-weight:800;color:#fff;box-shadow:var(--sh-1);
}
.card.sel::after{content:"✓";background:var(--acc-txt)}
.card.good::after{content:"✓";background:var(--ok)}
.card.bad::after{content:"✗";background:var(--err)}
.cards.n3{max-width:760px}
.cards.n4{max-width:820px}
.cards.n6{max-width:900px;grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}
.cards.n8{max-width:960px;grid-template-columns:repeat(auto-fit,minmax(132px,1fr))}
.cards .fig{max-height:min(22vh,170px)}
.cards.n6 .fig{max-height:min(19vh,140px)}
.cards.n8 .fig{max-height:min(17vh,124px)}
@media (max-width:520px){
  .cards{grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px}
  .card{min-height:130px;padding:7px;border-width:3px}
  .cards .fig{max-height:118px}
}

/* ---------- boutons ------------------------------------------------------
   États couverts : normal · survol · focus clavier · pressé · sélectionné ·
   correct · incorrect · désactivé · chargement.                            */
.choices{display:flex;flex-wrap:wrap;gap:clamp(10px,2.2vw,22px);justify-content:center;align-items:center}
.big{
  font-family:inherit;font-size:clamp(24px,4.2vw,34px);font-weight:800;color:var(--ink);
  background:var(--card);border:4px solid var(--ink);border-radius:var(--r-lg);
  padding:14px 32px;min-width:150px;min-height:var(--touch);cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:10px;position:relative;
  box-shadow:var(--sh-1);
  transition:transform var(--t-fast),background var(--t),border-color var(--t),
             box-shadow var(--t),color var(--t);
}
.big:hover:not([disabled]){background:var(--bg-2);box-shadow:var(--sh-2);transform:translateY(-1px)}
.big:active:not([disabled]){transform:scale(.96) translateY(0);box-shadow:var(--sh-1)}
.big.yes{border-color:var(--ok)}
.big.no{border-color:var(--err)}
.big.num{min-width:104px;padding:14px 10px;font-size:clamp(28px,5vw,40px)}
.big.word{font-size:clamp(20px,3.2vw,28px);min-width:190px;padding:16px 22px}
.big.ghost{border-color:var(--border-fort);color:var(--soft);
  font-size:clamp(18px,2.6vw,24px);padding:12px 26px;min-width:0;font-weight:700}
.big.ghost:hover:not([disabled]){color:var(--ink);border-color:var(--ink)}
.big.go{background:var(--ink);color:var(--ink-inv);border-color:var(--ink)}
.big.go:hover:not([disabled]){background:#0F2247;border-color:#0F2247;color:#fff}
.big[disabled]{opacity:.4;pointer-events:none;box-shadow:none}
.big.sel{background:var(--card-sel);border-color:var(--acc-txt);color:var(--acc-txt)}
.big.sel::after{content:"✓";font-size:.6em;margin-left:.2em}
/* réponse jugée : marque de forme en plus de la couleur */
.big.good{border-color:var(--ok);background:var(--card-ok);color:var(--ok)}
.big.good::after{content:"✓";font-size:.62em;margin-left:.25em}
.big.bad{border-color:var(--err);background:var(--card-ko);color:var(--err)}
.big.bad::after{content:"✗";font-size:.62em;margin-left:.25em}
.big.chargement{color:transparent;pointer-events:none}
.big.chargement::before{
  content:"";position:absolute;width:22px;height:22px;border-radius:50%;
  border:3px solid #17305C33;border-top-color:var(--acc-txt);animation:tourne .8s linear infinite;
}
@keyframes tourne{to{transform:rotate(360deg)}}

/* ---------- bouton « Continuer » (rythme des ateliers) ------------------- */
.suite{
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  width:100%;margin-top:var(--sp-2);min-height:74px;justify-content:center;
}
.suite .attente{
  width:min(230px,60vw);height:7px;border-radius:var(--r-pill);background:var(--bg-2);
  overflow:hidden;box-shadow:inset 0 0 0 1px #17305C14;
}
.suite .attente span{
  display:block;height:100%;width:100%;background:var(--acc);border-radius:var(--r-pill);
  transform-origin:left center;animation:lecture linear forwards;
}
@keyframes lecture{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.suite .btn-suivant{
  animation:apparait var(--t-slow) var(--ease-out) both;
  border-color:var(--acc-txt);background:var(--acc-txt);color:var(--ink-inv);
  font-size:clamp(20px,3vw,26px);padding:14px 34px;
}
.suite .btn-suivant:hover:not([disabled]){background:#0B5A62;border-color:#0B5A62;color:#fff}
.suite .indice-auto{font-size:14px;color:var(--soft);font-weight:700}
/* anneau de décompte quand le passage automatique est activé */
.suite .btn-suivant.auto::before{
  content:"";position:absolute;inset:-4px;border-radius:inherit;
  border:3px solid #0E6E7855;clip-path:inset(0 0 0 0);
  animation:decompte var(--decompte,6s) linear forwards;
}
@keyframes decompte{from{clip-path:inset(0 0 0 0)}to{clip-path:inset(0 100% 0 0)}}
@keyframes apparait{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}

/* ---------- fractions ---------- */
.note.frise{display:block;margin-top:10px;letter-spacing:1px}
.mixte{display:inline-flex;align-items:center;gap:.22em;font-weight:800;vertical-align:middle}
/* le + d'un nombre mixte : lisible, mais en retrait — il relie deux
   écritures, il ne demande pas d'effectuer une addition. */
.mixte-plus{font-style:normal;font-weight:700;opacity:.6;font-size:.8em;padding:0 .05em}
.frac{display:inline-flex;flex-direction:column;align-items:center;line-height:1;font-weight:800;vertical-align:middle}
.frac .num,.frac .den{padding:1px 6px}
.frac .bar{height:.11em;width:100%;min-width:1.1em;background:currentColor;border-radius:3px;margin:.07em 0}
.frac.f0{font-size:clamp(17px,2.5vw,23px)}
.frac.f1{font-size:clamp(26px,4vw,34px)}
.frac.f2{font-size:clamp(40px,8vw,72px)}
.frac.f3{font-size:clamp(56px,12vw,110px)}
.frac .hiA{color:var(--hlA-txt)}
.frac .hiB{color:var(--hlB-txt)}
.frac .slot{min-width:1.15em;border-radius:var(--r-xs);background:var(--bg-2);
  border:3px dashed var(--border-fort);color:var(--soft)}
.frac .slot.full{background:transparent;border-color:transparent;color:inherit}
.frac .slot.act{border-color:var(--acc-txt);background:var(--card-sel);color:var(--acc-txt)}

/* ---------- feedback ----------
   Jamais de couleur seule : un pictogramme précède le message.
   Le message est du texte courant, pas une rangée de boîtes : en flex, chaque
   fraction inline devenait un élément insécable et la phrase se coupait autour
   d'elle (« ✓ » seul sur sa ligne, virgule orpheline en début de ligne). En
   flux inline, la coupure retombe entre deux mots quelle que soit la longueur,
   et max-width aligne la longueur de ligne sur celle de .consigne. */
.fb{font-size:clamp(19px,3vw,27px);font-weight:800;min-height:1.4em;margin:0;
  line-height:1.35;max-width:900px;text-align:center;overflow-wrap:break-word}
.fb.ok{color:var(--ok)}
.fb.err{color:var(--err)}
.fb.ok::before,.fb.err::before{margin-right:.35em;vertical-align:middle}
.fb.ok::before{content:"✓";font-size:1.05em;line-height:1}
.fb.err::before{content:"↻";font-size:1.15em;line-height:1}
/* Une égalité se lit d'abord avec les yeux : les fractions debout sur la
   première ligne — inline-flex pour que le picto ✓ reste avec elles — et la
   lecture en mots juste en dessous, en plus petit. */
.eq-frac{display:inline-flex;align-items:center;justify-content:center;
  gap:.3em;flex-wrap:wrap;vertical-align:middle;max-width:100%}
.eq-frac b{font-size:clamp(20px,3vw,27px);color:var(--soft);font-weight:800}
.eq-mots{display:block;font-size:.72em;font-weight:700;opacity:.9;
  margin-top:1px;line-height:1.3}
.note .eq-frac .frac{font-size:clamp(19px,2.8vw,25px)}
.note .eq-frac b{font-size:clamp(16px,2.4vw,21px)}
.note{font-size:clamp(16px,2.3vw,21px);color:var(--soft);font-weight:600;margin:0}
/* le numéro de version, discret sur l'accueil, et l'écran « à propos » */
.lien-version{background:none;border:0;padding:2px 6px;font:inherit;color:var(--soft);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer;border-radius:var(--r-xs)}
.lien-version:hover{color:var(--acc-txt)}
.apropos-t{margin-bottom:0}
.notes-maj{width:min(94vw,620px);margin:var(--sp-4) auto;text-align:left}
.maj{background:var(--card);border:2px solid var(--border);border-radius:var(--r);
  padding:var(--sp-3) var(--sp-4);margin-bottom:var(--sp-3)}
.maj h3{margin:0 0 6px;font-size:clamp(16px,2.4vw,20px);color:var(--ink)}
.maj-d{font-weight:600;color:var(--soft);font-size:.82em}
.maj ul{margin:0;padding-left:1.15em}
.maj li{font-size:clamp(14px,2.2vw,17px);color:var(--soft);font-weight:600;margin:3px 0}

/* ---------- barres de comparaison ---------- */
.bars{display:flex;flex-direction:column;gap:10px;width:min(320px,70vw)}
.bar-row{height:26px;background:var(--bg-2);border-radius:var(--r-xs);overflow:hidden;
  border:2px solid var(--border)}
.bar-row span{display:block;height:100%;border-radius:6px;transition:width var(--t-slow) var(--ease-out)}

/* ---------- progression ----------
   Réussi = disque, raté = carré : la forme dit déjà l'essentiel. */
.dots{display:flex;gap:8px;justify-content:center}
.dots i{width:14px;height:14px;border-radius:50%;background:var(--border);display:block;
  transition:background var(--t),border-radius var(--t)}
.dots i.ok{background:var(--ok)}
.dots i.ko{background:var(--err);border-radius:4px}
.stars{display:flex;gap:10px;align-items:center;justify-content:center;font-size:30px;line-height:1}
.stars b{opacity:.22;filter:grayscale(1);transition:opacity var(--t),filter var(--t),transform var(--t)}
.stars b.on{opacity:1;filter:none}
.stars b.on::after{content:"";display:block;height:3px;margin-top:3px;border-radius:2px;
  background:var(--gold-vif)}
.pop{animation:pop .9s var(--ease-out)}
@keyframes pop{0%{transform:scale(.2) rotate(-25deg);opacity:0}45%{transform:scale(1.45) rotate(8deg);opacity:1}100%{transform:scale(1) rotate(0);opacity:1}}
.reward{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;
  background:var(--voile);z-index:40;font-size:96px;pointer-events:none;
  backdrop-filter:blur(1.5px)}

/* ---------- accueil ----------
   `safe center` : centré tant que ça tient, aligné en haut dès que ça
   déborde — jamais de titre coupé au-dessus de la zone visible. */
.home{
  display:flex;flex-direction:column;align-items:center;
  justify-content:center;justify-content:safe center;
  gap:var(--sp-4);flex:1;width:100%;
  padding:var(--sp-5) var(--sp-4) var(--sp-6);
}
.home h1{font-size:clamp(26px,5vw,40px);margin:0;color:var(--ink);letter-spacing:-.01em}
/* 🎮 Les défis — visiblement à part des ateliers : un trait au-dessus, un
   titre plus discret. On voit d'un coup d'œil que le parcours s'arrête là
   et que ce qui suit est un jeu.                                          */
.defis-titre{
  width:100%;max-width:1000px;margin:var(--sp-6) auto var(--sp-2);
  padding-top:var(--sp-5);border-top:2px dashed var(--border);
  font-size:clamp(18px,3vw,24px);color:var(--soft);letter-spacing:-.01em;
}
.menu{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(250px,100%),1fr));
  gap:var(--sp-4);justify-content:center;
  width:100%;max-width:1000px;margin:0 auto;
}
/* Les cartes portent une largeur en dur dans leur balise (width:290px,
   width:300px…) : c'est ce qui leur donne leur allure sur grand écran. Mais
   une largeur en dur ne sait pas rétrécir, et sur une tablette en portrait
   la troisième carte dépassait du bord — coupée, donc inatteignable.
   `max-width` prime toujours sur `width`, y compris écrite dans la balise :
   une seule règle ici suffit à toutes les cartes, de tous les menus.     */
.menu > .mcard{max-width:100%}
.mcard{
  background:var(--card);border:3px solid var(--border);border-left:9px solid var(--marine);
  border-radius:var(--r-lg);padding:var(--sp-4) var(--sp-5);
  width:auto;text-align:left;cursor:pointer;box-shadow:var(--sh-1);
  transition:transform var(--t-fast),box-shadow var(--t),border-color var(--t);
}
.mcard:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--border-fort)}
.mcard:active{transform:scale(.985)}
/* une couleur de marque par niveau : repère de catégorie, pas de décor */
.menu .mcard:nth-child(4n+1){border-left-color:var(--marine)}
.menu .mcard:nth-child(4n+2){border-left-color:var(--turquoise)}
.menu .mcard:nth-child(4n+3){border-left-color:var(--corail)}
.menu .mcard:nth-child(4n+4){border-left-color:var(--violet)}
.mcard h3{margin:0 0 6px;font-size:22px;color:var(--ink)}
.mcard p{margin:0;font-size:16.5px;color:var(--soft);font-weight:600;line-height:1.35}
.mcard .tag{display:inline-block;margin-top:12px;font-size:14px;font-weight:800;color:var(--ok);
  background:var(--card-ok);border-radius:var(--r-pill);padding:3px 12px}
.mcard.lock{border-color:var(--border);border-left-color:var(--border-fort);opacity:.7}
.mcard.lock .tag{color:var(--soft);background:var(--bg-2)}

/* ---------- machine / personnage ---------- */
.machine{
  background:var(--card);border:4px solid var(--ink);border-radius:var(--r);
  padding:14px 30px;font-size:clamp(22px,3.6vw,30px);font-weight:800;display:flex;
  align-items:center;gap:14px;min-height:76px;box-shadow:var(--sh-1)}
.perso{font-size:clamp(44px,9vw,76px);line-height:1}
.flyer{position:fixed;z-index:50;pointer-events:none;
  transition:transform .85s cubic-bezier(.4,.1,.3,1),opacity .85s}
.obj-label{font-size:26px;margin-bottom:2px}

/* ---------- panneau adulte ---------- */
.overlay{position:fixed;inset:0;background:#0B1A3799;z-index:60;display:flex;
  align-items:flex-start;justify-content:center;padding:var(--sp-4);overflow:auto}
.panel{background:var(--card);border-radius:var(--r);padding:var(--sp-5);max-width:960px;width:100%;
  font-size:15px;color:var(--ink);box-shadow:var(--sh-3)}
.panel h2{margin:0 0 6px;font-size:22px;color:var(--ink)}
/* la sortie du jeu : un panneau étroit, deux issues clairement séparées */
.panel.sortie{max-width:440px;text-align:center}
.panel.sortie .choices.col{flex-direction:column;align-items:stretch;gap:10px}
.panel.sortie .choices.col .big{width:100%}
.panel.sortie .mini-note{font-size:13px;color:var(--soft);font-weight:600;
  margin:var(--sp-3) 0 0;line-height:1.4}
/* le prénom, changer d'enfant, se déconnecter : une seule ligne lisible */
.ligne-profil{margin:0;display:flex;flex-wrap:wrap;justify-content:center;
  align-items:baseline;gap:6px}
.lien-profil{border:none;background:none;color:var(--acc-txt);font-family:inherit;
  font-weight:700;font-size:15px;cursor:pointer;text-decoration:underline;
  text-underline-offset:3px;padding:2px 4px;border-radius:var(--r-xs)}
.lien-profil:hover{background:var(--card-sel)}
.lien-profil.deco{color:var(--err)}
.champ-verrou{font-size:28px;width:130px;text-align:center;padding:8px;
  border-radius:var(--r-sm);border:3px solid var(--border-fort);font-weight:800;
  color:var(--ink);background:var(--card)}
.panel h3{margin:20px 0 6px;font-size:17px;color:var(--ink);
  border-top:1px solid var(--border);padding-top:14px}
.panel h3:first-of-type{border-top:none;padding-top:0}
.panel table{border-collapse:collapse;width:100%;font-size:13.5px;margin-top:6px}
.panel th,.panel td{border:1px solid var(--border);padding:5px 8px;text-align:left}
.panel th{background:var(--bg)}
.panel .mini{font-size:13px;color:var(--soft)}
.panel button{font-family:inherit;font-size:14px;font-weight:700;padding:10px 15px;
  border-radius:var(--r-sm);border:2px solid var(--ink);background:var(--card);color:var(--ink);
  cursor:pointer;margin:4px 6px 4px 0;transition:background var(--t),color var(--t)}
.panel button:hover:not([disabled]){background:var(--ink);color:var(--ink-inv)}
.panel button[disabled]{opacity:.45;cursor:default}
.panel button.actif{background:var(--acc-txt);border-color:var(--acc-txt);color:var(--ink-inv)}
.panel textarea{width:100%;height:90px;font-family:monospace;font-size:12px;
  border:1px solid var(--border-fort);border-radius:var(--r-xs);padding:8px}
.bar2{height:12px;background:var(--bg-2);border-radius:6px;overflow:hidden;min-width:90px}
.bar2 span{display:block;height:100%;background:var(--ok)}
table.bilan{border-collapse:collapse;width:100%;font-size:15px;background:var(--card);
  border-radius:var(--r-sm);overflow:hidden}
table.bilan th,table.bilan td{border:1px solid var(--border);padding:7px 10px;text-align:left}
table.bilan th{background:var(--bg);font-size:13px}
.hidden{display:none!important}
@media (max-width:640px){
  .big{padding:12px 22px;min-width:120px}
  .figzone{gap:14px}
}

/* ---------- saisie guidée d'une fraction (numérateur puis dénominateur) --- */
.saisie{display:flex;align-items:center;justify-content:center;gap:clamp(10px,2vw,20px);flex-wrap:wrap}
.sfrac{display:flex;flex-direction:column;align-items:center;line-height:1;font-weight:800;
  font-size:clamp(40px,8vw,66px)}
.sbar{height:.11em;width:100%;min-width:1.4em;background:currentColor;border-radius:3px;margin:.08em 0}
.sslot{min-width:1.5em;text-align:center;padding:2px 10px;border-radius:14px;border:4px dashed transparent;
  transition:background var(--t),border-color var(--t),color var(--t),opacity var(--t)}
.sslot.actif{border-color:var(--acc-txt);background:var(--card-sel);color:var(--acc-txt);
  animation:respire 1.8s ease-in-out infinite}
.sslot.inactif{border-color:var(--border);background:var(--bg-2);color:var(--soft);opacity:.55}
.sslot.rempli{border-color:transparent;background:transparent;color:var(--ink)}
.sfrac.fini .sslot.rempli{color:var(--ink)}
.sfrac .num.rempli{color:var(--hlA-txt)}
.sfrac .den.rempli{color:var(--hlB-txt)}
.sguide{display:flex;align-items:center;gap:8px;max-width:min(360px,52vw);text-align:left}
.sguide.haut{align-self:flex-start;margin-top:6px}
.sguide.bas{align-self:flex-end;margin-bottom:6px}
.sfleche{font-size:clamp(22px,3.4vw,30px);color:var(--acc-txt);animation:pointe 1.6s ease-in-out infinite}
.stxt{display:flex;flex-direction:column;gap:2px}
.sq{font-size:clamp(16px,2.5vw,21px);line-height:1.2}
.ss{font-size:clamp(13px,2vw,16px);color:var(--soft);font-weight:600}
@keyframes respire{0%,100%{box-shadow:0 0 0 0 #0E6E7833}50%{box-shadow:0 0 0 7px #0E6E7822}}
@keyframes pointe{0%,100%{transform:translateX(0)}50%{transform:translateX(-5px)}}
@media (max-width:560px){
  .saisie{flex-direction:column;gap:6px}
  .sguide.haut,.sguide.bas{align-self:center;margin:0;text-align:center;max-width:88vw}
  .sfleche{transform:rotate(90deg)}
  @keyframes pointe{0%,100%{transform:rotate(90deg) translateX(0)}50%{transform:rotate(90deg) translateX(-5px)}}
}

/* ---------- niveau 4 ---------- */
.bloc4{font-size:clamp(17px,2.6vw,21px);margin:18px 0 2px;color:var(--violet-txt);font-weight:800;
  display:flex;align-items:center;gap:var(--sp-2)}
.bloc4::before{content:"";width:10px;height:10px;border-radius:50%;background:var(--violet);flex:none}
.mcard.n4{width:auto}
.mcard.n4 h3{font-size:19px}
.lgd{font-size:20px;font-weight:800;fill:var(--ink);font-family:inherit}
.fig.ligne,.fig.bm,.fig.grp,.fig.g100{max-height:none}
.fig.ligne{max-width:min(94vw,680px)}
.fig.bm{max-width:min(94vw,660px)}
.saisie-nb{font-size:clamp(34px,6vw,52px);font-weight:800;margin:4px 0}
.saisie-nb .unite{font-size:.6em;color:var(--soft)}
.tnum .chiffre.boite{display:inline-block;min-width:1.3em;padding:2px 8px;border-radius:10px;
  background:var(--bg-2);border:3px dashed var(--border-fort);color:var(--soft);cursor:pointer}
.tnum .chiffre.boite.rempli{background:transparent;border-color:transparent;color:var(--ink)}
.tnum .chiffre.boite.act{border-color:var(--acc-txt);border-style:solid;background:var(--card-sel);color:var(--acc-txt)}
.saisiemixte{display:inline-flex;align-items:center;gap:.28em;font-weight:800;vertical-align:middle}
.saisiemixte .boite.ent{font-size:1.5em}
.saisiefrac .boite,.saisiepaire .boite{display:inline-block;min-width:1.15em;padding:0 .12em;
  border-radius:10px;background:var(--bg-2);border:3px dashed var(--border-fort);color:var(--soft)}
.saisiefrac .boite.act,.saisiepaire .boite.act{border-color:var(--acc-txt);background:var(--card-sel);color:var(--acc-txt)}
.saisiepaire{display:flex;align-items:center;justify-content:center;gap:.3em;flex-wrap:wrap}
.saisiepaire .rel{color:var(--soft);font-weight:800}
.cahier .consigne{font-size:clamp(20px,3vw,26px)}
.cahier-num{display:inline-block;min-width:1.9em;color:var(--soft);font-weight:800}
.choices.pave{max-width:420px}
.choices.pave .big.num{min-width:72px;min-height:52px;padding:10px 6px;font-size:clamp(24px,4.4vw,32px)}
.trou{display:inline-block;min-width:1.2em;border-bottom:5px solid var(--acc-txt);color:var(--acc-txt)}
/* Le tableau de numération se lisait petit : en-têtes à 14 px pour des mots
   longs (« centièmes », « millièmes »), sur un écran d'un mètre de large.
   Signalé le 25 août 2026 : « le schéma est étrange… sinon fais le plus
   gros ». On agrandit, et on donne à la colonne des unités le poids qu'elle
   doit avoir : c'est elle qui porte la virgule.                        */
table.tnum{border-collapse:collapse;margin:auto;font-size:20px}
table.tnum th{background:var(--bg);padding:9px 16px;border:2px solid var(--border);
  font-size:clamp(15px,1.6vw,18px);font-weight:800;color:var(--soft)}
table.tnum td{border:2px solid var(--border);padding:12px 20px;text-align:center}
table.tnum .sep{border-right:4px solid var(--ink)}
table.tnum .chiffre{font-size:clamp(34px,4.4vw,44px);font-weight:800}
/* La pose en colonnes du niveau 5 : deux nombres alignés sur la même
   colonne, et le signe de l'opération à droite. */
table.tnum.pose5 td{padding:8px 14px}
table.tnum .op5{border:none;font-size:26px;font-weight:800;color:var(--soft);padding-left:10px}
/* SUR PETIT ÉCRAN, le tableau débordait — mesuré à 386 px de large sur un
   écran de 360. La colonne perdue était la dernière : les millièmes, c'est-
   à-dire précisément celle dont parlait l'exercice. Rien ne le signalait,
   parce qu'un débordement ne lève aucune erreur. Vaut pour le niveau 4
   comme pour le niveau 5. */
@media(max-width:560px){
  table.tnum{font-size:16px}
  table.tnum th{padding:6px 5px;font-size:11.5px;line-height:1.15}
  table.tnum td{padding:8px 6px}
  table.tnum.pose5 td{padding:6px 5px}
  table.tnum .chiffre{font-size:clamp(24px,7.4vw,34px)}
  table.tnum .op5{font-size:20px;padding-left:4px}
}

/* ---------- explication en étapes (remédiation) ---------- */
.etapes{display:flex;flex-direction:column;align-items:center;gap:10px;margin:2px 0}
.etape{display:flex;align-items:center;gap:12px;font-size:clamp(18px,2.8vw,24px);font-weight:800;
  background:var(--card);border:2px solid var(--border);border-left:6px solid var(--turquoise);
  border-radius:var(--r-sm);padding:10px 16px;box-shadow:var(--sh-1);
  animation:apparait var(--t-slow) var(--ease-out) both}
.etape.somme{flex-wrap:wrap;justify-content:center;max-width:min(92vw,760px);gap:6px;
  border-left-color:var(--ok)}

/* ---------- missions ---------- */
.mission-hud{display:flex;align-items:center;justify-content:center;gap:12px;flex-wrap:wrap;
  font-size:15px;font-weight:800;color:var(--soft);margin-top:2px}
.mission-hud .mtitre{white-space:nowrap;color:var(--ink)}
.mdots{display:inline-flex;gap:6px;align-items:center}
.mdot{width:13px;height:13px;border-radius:50%;background:var(--border);display:block;
  transition:background var(--t)}
.mdot.on{background:var(--acc-txt)}
.mdot.pop-dot{animation:popdot .6s var(--ease-out)}
@keyframes popdot{0%{transform:scale(1)}40%{transform:scale(1.7)}100%{transform:scale(1)}}
.mserie{color:var(--gold)}
.mflash{background:#FBF0DE;color:var(--gold);border-radius:var(--r-pill);padding:2px 12px;
  font-weight:800;border:2px solid var(--jaune);animation:pop .5s var(--ease-out)}
.mfig{display:block}
.mfin{animation:pop .7s var(--ease-out)}

/* ---------- progression interne d'un atelier (niveau 4) ---------- */
.etapes4{display:flex;flex-direction:column;gap:8px;width:min(94vw,620px);margin:auto}
.etape4{display:flex;align-items:center;gap:14px;background:var(--card);border:3px solid var(--border);
  border-radius:var(--r);padding:12px 16px;cursor:pointer;min-height:var(--touch);
  box-shadow:var(--sh-1);transition:border-color var(--t),transform var(--t-fast),box-shadow var(--t)}
.etape4:active{transform:scale(.99)}
.etape4.lock{opacity:.5;cursor:default}
.etape4:not(.lock):hover{border-color:var(--acc-txt);box-shadow:var(--sh-2)}
.num4{width:36px;height:36px;border-radius:50%;background:var(--card-sel);color:var(--acc-txt);
  display:flex;align-items:center;justify-content:center;font-weight:800;flex:0 0 auto}
.lib4{flex:1;font-weight:800;font-size:17px;text-align:left}
.st4{font-size:14px;color:var(--soft);font-weight:700;white-space:nowrap}
@media(max-width:560px){.st4{display:none}}

.jauge{font-family:monospace;font-size:19px;letter-spacing:-1px;color:var(--acc-txt)}
.jaugeligne{margin:6px 0 0}
.pose{font-family:monospace;font-size:26px;font-weight:800;text-align:right;display:inline-block;
  border-radius:var(--r-sm);background:var(--card);padding:10px 18px;border:3px solid var(--border)}
.pose hr{border:none;border-top:3px solid var(--ink);margin:4px 0}

/* =========================================================================
   Mouvement réduit — on retire le décoratif, on garde les changements
   d'état indispensables et surtout le temps de lecture, qui n'est pas une
   animation mais une durée pédagogique.
   ========================================================================= */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important;
  }
  /* la jauge d'attente reste lisible : elle indique un temps, pas un décor */
  .suite .attente span{animation:none;transform:none;opacity:.5}
  .suite .btn-suivant.auto::before{animation:none;border-color:#0E6E7833}
  .card:hover,.mcard:hover,.big:hover:not([disabled]){transform:none}
  .reward{backdrop-filter:none}
}

/* =========================================================================
   ATELIER SIMPLIFIER — LE GÂTEAU

   Contrainte tenue par la géométrie, pas par le réglage : la barre est une
   boîte de largeur fixe ; la zone colorée est un enfant en POURCENTAGE de
   cette boîte ; les séparations sont des traits en position absolue, qui
   ne prennent aucune place. Conséquence : pour 6/10, la limite de la zone
   colorée est à 60 % de la barre AVANT comme APRÈS le regroupement, quels
   que soient le nombre de traits et leur épaisseur. Fusionner ne fait
   qu'effacer les traits intérieurs aux groupes — rien d'autre ne bouge.
   La règle globale prefers-reduced-motion (plus haut) rend la fusion
   instantanée sans la supprimer.
   ========================================================================= */
.gat{width:min(620px,92vw);margin:var(--sp-4) auto 0}
.gat-barre{position:relative;height:clamp(52px,8.6vw,72px);
  background:var(--part);border:3px solid var(--ink);border-radius:var(--r-sm);
  overflow:hidden;box-shadow:var(--sh-1,none)}
/* la quantité de gâteau : une seule boîte, en pourcentage. Elle ne dépend
   d'aucun trait, donc aucun trait ne peut la déplacer.                    */
.gat-part{position:absolute;top:0;bottom:0;left:0;background:var(--acc)}
/* les découpes : posées PAR-DESSUS, largeur nulle en flux */
.gat-trait{position:absolute;top:0;bottom:0;width:3px;margin-left:-1.5px;
  background:var(--ink);opacity:.5;
  transition:opacity 1.1s var(--ease),width .5s var(--ease)}
/* le bord d'une grosse part : franc, et il survit au regroupement */
.gat-trait.bord{opacity:1;width:5px;margin-left:-2.5px}
/* le trait intérieur à un groupe : c'est LUI, et lui seul, qui s'efface */
.gat-barre.fus .gat-trait.int{opacity:0}
/* le repère : il montre que la couleur s'arrête exactement au même endroit
   dans les deux barres. Discret, mais aligné au pixel près.              */
.gat-rep{position:absolute;top:0;bottom:0;width:0;margin-left:-1.5px;
  border-left:3px dashed var(--corail);pointer-events:none}
/* la zone qui ne tombe pas juste, quand on essaie une mauvaise taille */
.gat-pb{position:absolute;top:0;bottom:0;background:#C33A2B26;
  box-shadow:inset 0 0 0 3px var(--err)}
/* les parts numérotées : compter ne doit pas demander d'effort */
.gat-num{position:relative;height:20px;margin-top:3px}
.gat-num span{position:absolute;top:0;transform:translateX(-50%);
  font-weight:800;font-size:clamp(12px,2.2vw,15px);color:var(--soft)}
.gat-num span.on{color:var(--acc-txt)}
.gat-cap{max-width:min(620px,92vw);margin:var(--sp-2) auto 0;text-align:center;
  font-size:clamp(14px,2.4vw,17px);color:var(--soft);font-weight:600}
.gat-lab{display:flex;align-items:center;gap:clamp(8px,2vw,16px);flex-wrap:wrap;
  max-width:min(620px,92vw);margin:var(--sp-3) auto 3px;text-align:left;
  font-weight:800;color:var(--ink);font-size:clamp(14px,2.4vw,17px)}
/* la fraction collée à sa barre : assez grande pour être lue d'un coup,
   assez sobre pour ne pas voler la vedette au dessin.                   */
.gat-lab .gat-frac .frac{font-size:clamp(21px,3.1vw,28px);color:var(--acc2)}
.gat-duo .gat{margin-top:var(--sp-2)}
.gat-duo .gat-cap{margin-top:var(--sp-3)}

/* -------------------------------------------------------------------------
   LA LIGNE DES NOMBRES — la même invariance, dite autrement.
   Le point est posé en pourcentage de l'axe, exactement comme la zone
   colorée de la barre : il ne peut donc pas bouger quand on regroupe.
   C'est cette représentation qui empêche la fraction de rester une portion
   de gâteau et la fait devenir un NOMBRE.
   ------------------------------------------------------------------------- */
.drt{width:min(620px,92vw);margin:var(--sp-4) auto 0}
/* la marge latérale laisse dépasser l'étiquette aux extrémités sans jamais
   déformer l'axe : les deux lignes d'un AVANT/APRÈS restent superposables. */
.drt-zone{margin:0 26px}
/* l'axe réserve d'abord la place de l'étiquette : la fraction est écrite en
   vertical, elle occupe deux lignes, et elle ne doit jamais toucher le point. */
.drt-axe{position:relative;height:clamp(92px,13vw,116px)}
.drt-ligne{position:absolute;left:0;right:0;top:70%;height:4px;
  background:var(--border-fort);border-radius:2px}
.drt-plein{position:absolute;left:0;top:70%;height:4px;background:var(--acc-txt);
  border-radius:2px}
.drt-tick{position:absolute;top:calc(70% - 7px);height:18px;width:3px;margin-left:-1.5px;
  background:var(--border-fort);transition:opacity 1.1s var(--ease)}
.drt-tick.bord{background:var(--ink);height:26px;top:calc(70% - 11px);width:4px;margin-left:-2px}
.drt-axe.fus .drt-tick.int{opacity:0}
.drt-pt{position:absolute;top:calc(70% - 6px);width:16px;height:16px;margin-left:-8px;
  border-radius:50%;background:var(--corail);border:3px solid var(--ink);box-sizing:border-box}
.drt-etq{position:absolute;top:0;transform:translateX(-50%);color:var(--ink);
  padding-bottom:6px}
.drt-b0,.drt-b1{position:absolute;top:calc(70% + 12px);font-weight:800;
  font-size:clamp(13px,2.2vw,16px);color:var(--soft)}
.drt-b0{left:0;transform:translateX(-50%)}
.drt-b1{right:0;transform:translateX(50%)}

/* -------------------------------------------------------------------------
   LE SÉLECTEUR DE REPRÉSENTATION
   Discret : ce n'est pas une question posée à l'enfant, c'est une porte de
   sortie s'il ne comprend pas avec celle qui est à l'écran.
   ------------------------------------------------------------------------- */
.repr-choix{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-2);
  margin:var(--sp-3) auto 0;max-width:min(620px,92vw)}
.repr-b{background:var(--bg-2);border:2px solid var(--border);border-radius:var(--r-pill);
  padding:5px 14px;font:inherit;font-weight:800;font-size:clamp(12px,2.1vw,15px);
  color:var(--soft);cursor:pointer;min-height:34px}
.repr-b.act{background:var(--card-sel);border-color:var(--acc-txt);color:var(--acc-txt)}
.repr-b:focus-visible{outline:3px solid var(--acc-txt);outline-offset:2px}
/* un bouton de réponse porte parfois une phrase : elle passe à la ligne
   plutôt que de sortir de l'écran sur un téléphone.                      */
.red-serre .big.rep,.repr~.choices .big.rep,.gat-duo~.choices .big.rep{
  max-width:min(560px,92vw);white-space:normal;text-align:center;line-height:1.2}

/* une étape de calcul, révélée seule, jamais en bloc */
.red-etape{display:flex;justify-content:center;align-items:center;gap:10px;flex-wrap:wrap;
  font-size:clamp(20px,3.4vw,29px);font-weight:800;color:var(--ink);
  margin:var(--sp-3) 0;text-align:center}
.red-etape.pale{opacity:.35}
.red-chaine{display:flex;justify-content:center;align-items:center;flex-wrap:wrap;
  gap:clamp(6px,2vw,18px);margin:var(--sp-3) 0}
.red-chaine b{font-size:clamp(24px,4vw,36px);color:var(--soft)}
/* le pont entre le dessin et les nombres : un nombre, ce qu'il désigne */
.red-lien{display:flex;justify-content:center;align-items:center;gap:12px;
  max-width:min(620px,92vw);margin:var(--sp-2) auto;
  font-size:clamp(15px,2.5vw,19px);color:var(--soft);font-weight:600}
.red-lien span{display:inline-block;min-width:2.2em;padding:2px 10px;
  background:var(--card-sel);border:2px solid var(--acc-txt);border-radius:var(--r-pill);
  color:var(--acc-txt);font-weight:800;font-size:clamp(18px,3vw,24px);text-align:center}
/* les tables, montrées seulement quand l'enfant bloque */
.red-table{max-width:min(620px,92vw);margin:var(--sp-2) auto;text-align:center;
  font-size:clamp(15px,2.5vw,19px);color:var(--soft);font-weight:600;line-height:1.9}
.red-table span{padding:1px 6px;border-radius:var(--r-xs)}
.red-table span.vise{background:var(--hlA);color:var(--hlA-txt);font-weight:800}
.red-table b{color:var(--ink)}

/* écriture factorisée : le facteur du haut tombe exactement sous celui du
   bas, sinon « le même × 2 en haut ET en bas » ne se voit pas. D'où la
   grille à trois colonnes, identique en haut et en bas.                   */
.frac.fact .num,.frac.fact .den{display:grid;align-items:center;justify-items:center;
  grid-template-columns:1.05em .8em 1.05em;column-gap:.04em;padding:1px 4px;
  transition:grid-template-columns var(--t-slow) var(--ease)}
.frac.fact .fx-op,.frac.fact .fx-b{min-width:0;overflow:hidden;border-radius:var(--r-xs);
  transition:opacity var(--t-slow) var(--ease),background var(--t) var(--ease),
             color var(--t) var(--ease)}
.frac.fact .fx-op.vise,.frac.fact .fx-b.vise{background:var(--hlA);color:var(--hlA-txt)}
.frac.fact.efface .num,.frac.fact.efface .den{grid-template-columns:1.05em 0 0}
.frac.fact.efface .fx-op,.frac.fact.efface .fx-b{opacity:0}
/* la baguette : elle monte, elle descend, et elle tremble quand elle refuse */
.bag{display:inline-block;font-size:clamp(30px,5.4vw,46px);line-height:1;
  transition:transform var(--t-slow) var(--ease)}
.bag.haut{transform:translateY(-.55em) rotate(-18deg)}
.bag.bas{transform:translateY(.55em) rotate(-18deg)}
.bag.tremble{animation:bagTremble .45s linear 2}
@keyframes bagTremble{0%,100%{transform:rotate(-12deg)}25%{transform:rotate(8deg)}
  50%{transform:rotate(-20deg)}75%{transform:rotate(3deg)}}
/* la suite mentale, toujours la même, qui finit par se dire toute seule */
.red-rituel{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-2);
  max-width:min(760px,94vw);margin:var(--sp-2) auto;padding:0;list-style:none}
.red-rituel span{background:var(--bg-2);border:2px solid var(--border);border-radius:999px;
  padding:4px 13px;font-weight:800;font-size:clamp(12px,2.2vw,15px);color:var(--soft)}
.red-rituel span.act{background:var(--card-sel);border-color:var(--acc-txt);color:var(--acc-txt)}
.regle{background:var(--card-sel);border:2px solid var(--acc-txt);border-radius:var(--r);
  padding:var(--sp-4);max-width:520px;margin:var(--sp-4) auto;text-align:center;
  font-size:1.15rem;color:var(--ink)}
.regle b{color:var(--acc2)}
.regle.non{background:#FBE7E4;border-color:var(--err)}
.regle.non b{color:var(--err)}
/* la phrase-rituelle : elle doit se lire d'un coup d'œil, sans être lue */
.regle.grand{font-size:clamp(19px,3.4vw,28px);font-weight:800;line-height:1.45}

/* ÉCRAN RESSERRÉ — consigne + gâteau + opération + pavé + valider doivent
   tenir ensemble sur un écran d'ordinateur portable. Le gâteau n'est
   jamais celui qu'on sacrifie : c'est lui qui porte le sens.            */
.red-serre .consigne{font-size:clamp(17px,2.7vw,23px);margin:0 auto}
.red-serre .gat{margin:var(--sp-2) auto 0}
.red-serre .gat-barre{height:clamp(36px,5.4vw,52px)}
.red-serre .gat-num{height:16px;margin-top:2px}
.red-serre .gat-num span{font-size:clamp(11px,1.9vw,13px)}
.red-serre .red-etape{margin:var(--sp-2) 0;font-size:clamp(18px,3vw,26px)}
.red-serre .red-chaine{margin:var(--sp-2) 0}
.red-serre .frac.f2{font-size:clamp(30px,5.4vw,46px)}
.red-serre .big-txt{font-size:clamp(20px,3.2vw,28px)}
.red-serre .red-rituel{margin:2px auto;gap:6px}
.red-serre .red-rituel span{padding:2px 10px;font-size:clamp(11px,1.9vw,13px)}
.red-serre .fb{font-size:clamp(16px,2.4vw,21px);min-height:1.2em}
.red-serre .choices.pave{margin:var(--sp-2) auto;gap:6px}
.red-serre .choices.pave .big.num{min-width:60px;min-height:42px;padding:6px 4px;
  font-size:clamp(20px,3.4vw,26px)}
.red-serre .choices.pave .big.ghost{min-height:42px;padding:6px 14px}
.red-serre .saisie-nb{font-size:clamp(28px,5vw,42px);margin:0}
.red-serre .gat-cap,.red-serre .gat-lab{margin-top:3px;font-size:clamp(13px,2.1vw,15px)}
.red-serre .gat-lab .gat-frac .frac{font-size:clamp(17px,2.5vw,22px)}
.red-serre .drt{margin:var(--sp-2) auto 0}
.red-serre .drt-axe{height:clamp(78px,10vw,96px)}
.red-serre .repr-choix{margin-top:var(--sp-2);gap:6px}
.red-serre .repr-b{padding:3px 11px;font-size:clamp(11px,1.9vw,13px);min-height:28px}
.red-serre .sub{font-size:clamp(14px,2.1vw,18px)}

/* =========================================================================
   OBJECTIF EN ÉTOILES — remplace les cadenas
   Les couleurs viennent des jetons de marque : jaune du logo pour l'étoile
   gagnée, trait marine dilué pour celle qui reste à conquérir.
   ========================================================================= */
.etoiles-lot{font-size:clamp(17px,3vw,21px);letter-spacing:2px;line-height:1}
.et-vide{opacity:.28;filter:grayscale(1)}
.objectif{margin:2px 0 6px;font-size:clamp(15px,2.3vw,18px);font-weight:700;
          color:var(--ink);display:flex;align-items:center;gap:10px;
          justify-content:center;flex-wrap:wrap}
.et-jauge{display:inline-block;width:min(190px,42vw);height:10px;border-radius:999px;
          background:var(--bg-2);overflow:hidden;vertical-align:middle}
.et-jauge span{display:block;height:100%;border-radius:999px;
               background:linear-gradient(90deg,var(--jaune),var(--corail));
               transition:width .6s var(--ease-out,ease)}

/* Un choix irréversible ne se présente pas comme les autres : le bouton qui
   efface est écrit en rouge, et il n'est jamais celui qu'on touche par
   réflexe — le bouton qui protège reste en premier.                       */
.choices.col{flex-direction:column;align-items:stretch;gap:10px;
  max-width:460px;margin-left:auto;margin-right:auto}
.choices.col .big{width:100%}
.big.ghost.danger{color:var(--err);border-color:var(--err)}
.big.ghost.danger:hover:not([disabled]){background:#FBE7E4}
.big.danger-plein{background:var(--err);border-color:var(--err);color:#fff}
.big.danger-plein:hover:not([disabled]){background:#A82C1F;color:#fff}

/* =========================================================================
   🎯 TRIOFRAC (niveau 3) — trois représentations d'une même fraction
   Trois zones nommées, côte à côte. Les largeurs sont volontairement
   inégales : une droite graduée en douzièmes a besoin de place, une
   fraction écrite non. Sur écran étroit, les droites passent en pleine
   largeur plutôt que de devenir illisibles.
   ========================================================================= */
.trio-titre{margin:0}
/* l'écran doit tenir d'un seul tenant sur tablette : on resserre les espaces
   de cet atelier-là, sans toucher au rythme des autres écrans */
.stage.trio-stage{gap:clamp(6px,1.4vh,16px);padding-bottom:var(--sp-3)}
.trio-grille{
  display:grid;
  grid-template-columns:minmax(80px,.60fr) minmax(104px,.92fr) minmax(210px,2.30fr);
  gap:clamp(8px,1.6vw,18px);
  width:100%;max-width:1060px;margin:0 auto;
}
.trio-col{display:flex;flex-direction:column;gap:clamp(6px,1.2vh,14px);min-width:0}
.trio-cat{
  margin:0 0 2px;font-size:clamp(11px,1.8vw,15px);font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;color:var(--soft);
}
.trio-carte{
  font-family:inherit;color:var(--ink);background:var(--card);
  border:4px solid var(--border);border-radius:var(--r);
  padding:clamp(4px,1vw,10px);
  height:clamp(84px,18vh,158px);min-height:var(--touch);min-width:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  cursor:pointer;position:relative;box-shadow:var(--sh-1);
  transition:border-color var(--t),box-shadow var(--t),transform var(--t-fast),
             background var(--t),opacity var(--t);
}
.trio-carte:hover:not([disabled]){border-color:var(--border-fort);box-shadow:var(--sh-2)}
.trio-carte:active:not([disabled]){transform:scale(.97)}
.trio-in{display:flex;align-items:center;justify-content:center;
  width:100%;min-width:0;min-height:0;flex:1}
.trio-carte .fig{max-height:100%;max-width:100%}
.trio-carte .fig.ligne{width:100%;max-width:100%}
/* les traits de partage doivent rester nets une fois la figure réduite */
.trio-carte .fig .part{stroke-width:7}
.trio-carte .fig .outline{stroke-width:9}
.trio-carte .frac.f2{font-size:clamp(24px,4.4vw,42px)}

/* --- appartenance à une famille : un contour partagé, jamais une couleur seule
   pointillé = trio en cours de formation · plein = trio réuni               */
.trio-carte.sel{
  border-color:var(--fam,var(--acc-txt));background:var(--card-sel);
  outline:4px dashed var(--fam,var(--acc-txt));outline-offset:3px;
}
.trio-carte.reussi{
  border-color:var(--fam,var(--acc-txt));background:var(--card);cursor:default;opacity:1;
  outline:4px solid var(--fam,var(--acc-txt));outline-offset:3px;
}
.trio-carte.sel::after,.trio-carte.reussi::after{
  position:absolute;top:-11px;right:-11px;width:26px;height:26px;border-radius:50%;
  background:var(--fam,var(--acc-txt));border:3px solid var(--card);
  display:flex;align-items:center;justify-content:center;
  font-size:14px;font-weight:800;color:#fff;box-shadow:var(--sh-1);
}
.trio-carte.sel::after{content:"…"}
.trio-carte.reussi::after{content:"✓"}
/* mise en retrait pendant la démonstration guidée : une seule tâche à la fois */
.trio-carte.attente{opacity:.3;pointer-events:none;box-shadow:none}
.trio-carte[disabled]{pointer-events:none}

/* --- animations courtes : regroupement, refus doux, invitation ------------ */
.trio-carte.fusion{animation:trioFusion .62s var(--ease-out)}
@keyframes trioFusion{0%{transform:scale(1)}34%{transform:scale(1.07)}100%{transform:scale(1)}}
/* un refus ne se signale pas par une croix rouge : la carte hésite, puis revient */
.trio-carte.refus{animation:trioRefus .42s ease-in-out}
@keyframes trioRefus{0%,100%{transform:translateX(0)}
  22%{transform:translateX(-7px)}62%{transform:translateX(7px)}}
.trio-carte.pulse{animation:trioPulse 1.6s var(--ease) infinite}
@keyframes trioPulse{0%,100%{box-shadow:var(--sh-1)}50%{box-shadow:0 0 0 9px #3CC3CB40}}
.trio-grille.fini .trio-carte.reussi{animation:trioFusion .6s var(--ease-out)}

/* --- aide progressive : elle montre où regarder, elle ne donne pas la réponse */
.trio-leg{
  display:none;font-size:clamp(10px,1.7vw,13px);font-weight:800;line-height:1.6;
  color:var(--acc2);background:var(--card-sel);border-radius:var(--r-pill);padding:0 9px;
}
.trio-grille.aide1 .trio-leg{display:block}
.trio-grille.aide2 .trio-frac .frac .den{
  background:var(--card-sel);color:var(--acc-txt);border-radius:var(--r-xs);
}

/* --- barre discrète du bas : son, étape, sortie --------------------------- */
.trio-bas{display:flex;align-items:center;justify-content:center;
  gap:clamp(10px,2vw,20px);flex-wrap:wrap;width:100%;max-width:1060px;margin:0 auto}
.trio-etat{font-size:clamp(12px,1.9vw,15px);font-weight:800;color:var(--soft)}
/* le retour tient sur une ligne : il accompagne le geste, il ne le commente pas */
.fb.trio-fb{font-size:clamp(15px,2.4vw,22px);min-height:1.6em}
.trio-mini{
  font-family:inherit;font-size:21px;line-height:1;color:var(--ink);background:var(--card);
  border:3px solid var(--border);border-radius:var(--r-pill);
  width:52px;height:52px;min-width:52px;cursor:pointer;box-shadow:var(--sh-1);
  display:flex;align-items:center;justify-content:center;
}
.trio-mini:hover{border-color:var(--border-fort)}
.trio-mini:active{transform:scale(.95)}

/* --- écran étroit : les droites reprennent toute la largeur --------------- */
@media (max-width:760px){
  .trio-grille{grid-template-columns:1fr;gap:4px}
  .trio-col{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;align-items:stretch}
  .trio-cat{grid-column:1/-1;margin:12px 0 0}
  .trio-col.trio-lig{grid-template-columns:1fr}
  .trio-carte{height:clamp(66px,10vh,98px)}
  .trio-col.trio-lig .trio-carte{height:clamp(62px,9vh,86px)}
}

/* =========================================================================
   SIGNALER UN DÉFAUT — formulaire pensé pour le doigt autant que la souris

   Contraintes tenues ici : toute cible tactile fait au moins 44 px de haut
   (recommandation d'accessibilité, et taille réelle d'un doigt d'adulte) ;
   les champs font 16 px minimum, faute de quoi Safari sur iPad zoome tout
   seul à la saisie et l'écran part de travers ; rien ne dépend du survol.
   ========================================================================= */
/* Le formulaire est une SURCOUCHE posée sur le jeu, qui reste intact
   derrière : signaler ne doit plus coûter la séance en cours.
   Il n'emprunte volontairement pas la classe .panel — ses règles
   (.panel button, .panel textarea) écraseraient les boutons et le champ
   de saisie du formulaire, qui ont déjà leur propre habillage.        */
.sig-panneau{
  background:var(--card);border-radius:var(--r);box-shadow:var(--sh-3);
  padding:var(--sp-5) var(--sp-4);max-width:760px;width:100%;margin:auto;
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(8px,1.6vh,18px);text-align:center;
}
.sig-form{width:100%;max-width:680px;margin:0 auto;text-align:left}
.sig-bloc{border:none;margin:0 0 var(--sp-5);padding:0}
.sig-bloc legend{padding:0;margin-bottom:var(--sp-2);font-weight:800;color:var(--ink);font-size:16px}
.sig-objets{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(240px,100%),1fr));gap:var(--sp-3)}
.sig-objet{
  display:flex;flex-direction:column;gap:4px;text-align:left;min-height:64px;
  padding:var(--sp-3) var(--sp-4);cursor:pointer;font:inherit;
  background:var(--card);border:3px solid var(--border);border-radius:var(--r-sm);
  color:var(--ink);transition:border-color var(--t),background var(--t);
}
.sig-objet b{font-size:17px}
.sig-objet span{font-size:14px;color:var(--soft);font-weight:600}
.sig-objet.on{border-color:var(--acc-txt);background:var(--card-sel)}
.sig-objet:active{transform:scale(.99)}
.sig-form textarea,.sig-form input[type=email]{
  width:100%;box-sizing:border-box;font:inherit;font-size:16px;color:var(--ink);
  background:var(--card);border:3px solid var(--border);border-radius:var(--r-sm);
  padding:var(--sp-3);min-height:48px;resize:vertical;
}
.sig-form textarea:focus,.sig-form input[type=email]:focus{
  outline:none;border-color:var(--acc-txt);box-shadow:0 0 0 3px var(--card-sel)}
.sig-apercu{
  /* l'aperçu doit se voir sans repousser le bouton Envoyer hors de l'écran :
     on le borne en hauteur et on garde ses proportions */
  display:block;width:100%;height:auto;max-height:38vh;object-fit:contain;
  object-position:top;margin-top:var(--sp-3);
  border:2px solid var(--border);border-radius:var(--r-sm);background:var(--card);
}
.sig-joindre{display:flex;align-items:center;gap:var(--sp-2);min-height:44px;
  font-weight:700;color:var(--ink);cursor:pointer}
.sig-joindre input{width:22px;height:22px}
/* un <input type=file> ne se met pas en forme : on habille son <label> et
   on cache le champ, sans jamais le retirer du clavier ni des lecteurs */
.sig-cache{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.sig-fichier{
  display:inline-flex;align-items:center;justify-content:center;min-height:48px;
  padding:0 var(--sp-5);margin-top:var(--sp-2);cursor:pointer;font-weight:800;
  background:var(--card);border:3px solid var(--acc-txt);border-radius:var(--r-sm);color:var(--acc-txt);
}
.sig-cache:focus + .sig-fichier,.sig-fichier:active{box-shadow:0 0 0 3px var(--card-sel)}
.sig-avis{border-left:4px solid var(--border);padding-left:var(--sp-3);margin:var(--sp-5) 0}
.sig-detail{margin-top:var(--sp-5);font-size:14px;color:var(--soft)}
.sig-detail summary{cursor:pointer;min-height:44px;display:flex;align-items:center;font-weight:700}
.sig-ctx{margin:0;padding-left:var(--sp-5);line-height:1.7;word-break:break-word}
.sig-form .lien{background:none;border:none;color:var(--acc-txt);font:inherit;font-weight:700;
  text-decoration:underline;cursor:pointer;min-height:44px;padding:0}

/* L'annonce d'une nouveauté : un panneau, une flèche vers la barre du haut.
   La flèche est décorative (aria-hidden) : ce qui la remplace pour un
   lecteur d'écran, c'est le titre, qui dit déjà « en haut ».            */
.panel.annonce{margin-top:56px;text-align:center;position:relative}
.annonce-fleche{
  position:absolute;top:-30px;right:26px;margin:0;
  font-size:22px;color:var(--card);line-height:1;
  text-shadow:0 -2px 0 var(--border);
}
.panel.annonce h2{margin-bottom:12px}

/* Les écrans joints à un signalement : une bande horizontale qui défile
   plutôt qu'une pile verticale — sur un téléphone, trois images empilées
   repousseraient le bouton Envoyer à des kilomètres. */
.sig-bandeau{display:flex;gap:var(--sp-3);overflow-x:auto;padding:var(--sp-2) 0 var(--sp-3);
  -webkit-overflow-scrolling:touch;scroll-snap-type:x mandatory}
.sig-vignette{flex:0 0 auto;width:min(230px,64vw);margin:0;scroll-snap-align:start}
.sig-vignette img{display:block;width:100%;height:auto;max-height:30vh;object-fit:contain;
  object-position:top;background:var(--card);
  border:2px solid var(--border);border-radius:var(--r-sm)}
.sig-vignette figcaption{margin-top:6px;font-size:12.5px;font-weight:700;color:var(--soft);
  line-height:1.35}

/* =========================================================================
   L'ÎLE DU NIVEAU 3

   Le principe tient en une ligne : l'image garde ses proportions carrées,
   et les marqueurs sont posés en POURCENTAGE. Le Temple reste donc sur le
   Temple, que la carte fasse 320 px sur un téléphone ou 560 sur un écran.

   Les marqueurs ne sont pas des décorations : ce sont des boutons, avec
   une cible tactile d'au moins 44 px et un anneau de focus visible.
   ========================================================================= */
.ile-cadre{width:100%;display:flex;flex-direction:column;align-items:center;margin:var(--sp-3) 0}
.ile{
  position:relative;width:min(560px,92vw);aspect-ratio:1/1;
  border-radius:var(--r);overflow:hidden;
  box-shadow:var(--sh-2);background:var(--bg-2);
}
.ile-fond{display:block;width:100%;height:100%;object-fit:cover;user-select:none;-webkit-user-drag:none}

.lieu{
  position:absolute;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:3px;
  min-width:44px;min-height:44px;padding:0;margin:0;
  background:none;border:none;cursor:pointer;font:inherit;
  transition:transform var(--t);
}
.lieu:active{transform:translate(-50%,-50%) scale(.93)}
.lieu:focus-visible{outline:none}
.lieu:focus-visible .lieu-rond{box-shadow:0 0 0 4px var(--card),0 0 0 7px var(--acc-txt)}

/* le rond : assez grand pour un doigt, assez contrasté pour se détacher
   aussi bien de l'herbe claire que de la roche marine */
.lieu-rond{
  display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:50%;font-size:22px;line-height:1;
  background:var(--card);border:3px solid var(--border-fort);
  box-shadow:0 2px 6px rgba(11,26,55,.45);
}
.lieu-nom{
  display:flex;align-items:baseline;gap:5px;white-space:nowrap;
  padding:2px 7px;border-radius:var(--r-xs);
  font-size:12px;font-weight:800;letter-spacing:.01em;
  color:#fff;background:rgba(11,26,55,.82);
  text-shadow:0 1px 2px rgba(0,0,0,.4);
}
.lieu-pts{display:inline-flex;align-items:center;gap:3px}
.lieu-pts .pt{
  display:block;width:8px;height:8px;border-radius:50%;
  background:#fff;opacity:.32;                 /* notion pas encore maîtrisée */
  box-shadow:0 0 0 1px rgba(0,0,0,.25);
}
/* réussie seul : le passage s'ouvre le jour même */
.lieu-pts .pt.on{opacity:1;background:var(--jaune,#FDB220)}
/* consolidée un autre jour : c'est le 🟢 du moteur, il se voit aussi ici */
.lieu-pts .pt.on.sur{background:var(--ok,#0E9F6E);box-shadow:0 0 0 1px rgba(255,255,255,.55)}

/* rien n'est verrouillé : un lieu vierge est seulement en retrait */
.lieu.vierge .lieu-rond{opacity:.7;filter:saturate(.5)}
.lieu.vierge .lieu-nom{background:rgba(11,26,55,.62)}
.lieu.encours .lieu-rond{border-color:var(--acc-txt)}
/* passage ouvert : le lieu a livré son indice, il reste à consolider */
.lieu.fini .lieu-rond{border-color:var(--ok);background:var(--card-ok)}
.lieu.fini .lieu-nom{background:rgba(7,98,57,.88)}
/* tout est consolidé : l'anneau se ferme d'un second trait */
.lieu.fini.sur .lieu-rond{box-shadow:0 2px 6px rgba(11,26,55,.45),0 0 0 3px var(--ok)}

/* le lieu conseillé respire, pour qu'on sache où reprendre sans le lire */
.lieu.ici .lieu-rond{border-color:var(--acc-txt);animation:lieuPouls 2.2s ease-in-out infinite}
@keyframes lieuPouls{
  0%,100%{box-shadow:0 2px 6px rgba(11,26,55,.45),0 0 0 0 rgba(60,195,203,.55)}
  50%    {box-shadow:0 2px 6px rgba(11,26,55,.45),0 0 0 9px rgba(60,195,203,0)}
}
/* le mouvement est un confort, jamais une information */
@media (prefers-reduced-motion:reduce){
  .lieu.ici .lieu-rond{animation:none;box-shadow:0 2px 6px rgba(11,26,55,.45),0 0 0 4px var(--acc-txt)}
}
.ile-legende{margin:var(--sp-3) 0 0;font-size:14px;font-weight:700;color:var(--soft);text-align:center}

/* Téléphone : les sept étiquettes deviendraient illisibles et se
   chevaucheraient. On garde les ronds — qui restent des cibles de 44 px —
   et on ne nomme que le lieu conseillé. Le nom complet reste annoncé par
   aria-label, et s'affiche à l'écran d'entrée de l'atelier.              */
@media (max-width:520px){
  .lieu-nom{display:none}
  .lieu.ici .lieu-nom{display:flex}
  .lieu-rond{width:40px;height:40px;font-size:19px}
}

/* ---- La porte du château : le cadran des six indices --------------------
   Chaque indice est écrit dans la langue de son lieu — fraction, nombre
   mixte, addition. C'est volontaire : l'épreuve consiste précisément à
   voir que ces six écritures désignent des nombres.                     */
.cadran{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr));
  gap:var(--sp-3);width:100%;max-width:680px;margin:var(--sp-4) auto;
}
.cadran.serre{grid-template-columns:repeat(auto-fit,minmax(min(96px,100%),1fr))}
.ind{
  display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:var(--sp-3);min-height:92px;justify-content:center;
  background:var(--card);border:3px dashed var(--border);border-radius:var(--r-sm);
}
.ind.ok{border-style:solid;border-color:var(--ok);background:var(--card-ok)}
.ind-lieu{font-size:12px;font-weight:800;color:var(--soft);text-align:center;line-height:1.25}
.ind-val{font-size:20px;font-weight:800;color:var(--ink);display:flex;align-items:center;gap:4px}
.ind-q{font-size:26px;color:var(--soft);opacity:.55}
.ind-txt{font-size:15px;font-weight:800}
.ind-grand{font-size:26px}


/* ---------- 🪙 les pièces de trésor ---------------------------------------
   Le seul nombre que deux enfants comparent entre eux. Il se lit de loin,
   d'un bout à l'autre de la table — donc gros, doré, et jamais rouge :
   ce n'est pas une note, c'est une collection.                          */
.tag.pieces{background:var(--jaune,#FDB220);border-color:var(--jaune,#FDB220);
  color:#3A2A00;font-weight:800}
.prog-bandeau{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(8px,2vw,18px);margin:0}
.prog-qui{font-size:17px}
.prog-pieces{font-size:clamp(20px,3vw,26px);font-weight:800;color:#7A4706;
  background:var(--jaune,#FDB220);border-radius:999px;padding:4px 14px}
.prog-niv{display:inline-flex;flex-direction:column;align-items:flex-start;gap:3px;
  font-size:14px;font-weight:700;color:var(--soft)}
.prog-jauge{display:block;width:130px;height:9px;border-radius:999px;
  background:var(--bg-2);overflow:hidden}
.prog-jauge > i{display:block;height:100%;background:var(--ok);border-radius:999px;
  transition:width var(--t-slow) var(--ease-out)}
.prog-etoiles{font-size:16px;font-weight:700}
.prog-titre{color:var(--ink)}
.prog-gain{color:#7A4706}
.prog-niveau{font-weight:700}


/* ---------- 🔢 le glissement des chiffres (niveau 3) ----------------------
   La virgule est FIXE : elle vit entre les unités et les dixièmes, et c'est
   tout le propos du module. Le chiffre mobile est posé en absolu au-dessus
   des colonnes pour que l'œil puisse SUIVRE son déplacement — un saut qu'on
   ne voit pas ne s'explique pas.                                        */
.dec3{display:inline-block;margin:0 auto}
.dec3-scene{position:relative;display:inline-block}
.dec3-cols{display:flex;align-items:flex-end;gap:0}
.dec3-col{display:flex;flex-direction:column;align-items:center;
  min-width:clamp(78px,11vw,104px);border:2px solid var(--border);
  border-radius:var(--r-sm);margin:0 3px;background:var(--card);overflow:hidden}
.dec3-col.vise{border-color:var(--acc-txt);box-shadow:0 0 0 3px var(--card-sel)}
.dec3-th{display:block;width:100%;background:var(--bg);color:var(--soft);
  font-size:clamp(12px,1.4vw,15px);font-weight:800;padding:6px 4px;text-align:center}
.dec3-case{display:flex;align-items:center;justify-content:center;
  height:clamp(52px,7vh,68px);font-size:clamp(30px,4.4vw,42px);font-weight:800;color:var(--ink)}
.dec3-virgule{align-self:flex-end;font-size:clamp(34px,5vw,46px);font-weight:800;
  color:var(--coral,#F0624F);line-height:1;padding:0 2px 6px;transform:translateY(2px)}
.dec3-mobile{
  position:absolute;top:50%;transform:translate(-50%,-50%);
  pointer-events:none;
  font-size:clamp(30px,4.4vw,42px);font-weight:800;color:var(--acc-txt);
  background:var(--card-sel);border-radius:10px;padding:2px 12px;
  transition:left var(--t-slow) var(--ease),top var(--t-slow) var(--ease);
}
.dec3-lecture{margin:10px 0 0;font-size:clamp(17px,2.4vw,21px);font-weight:700;color:var(--soft)}
@media (prefers-reduced-motion:reduce){ .dec3-mobile{transition:none} }

/* =========================================================================
   LE TABLEAU DE DONNÉES — domaine 📊 du niveau 5 (n5/donnees.js)

   POURQUOI IL NE RESSEMBLE PAS À .tprop NI À .tnum

   La première version copiait leur style : quadrillage gris de 2 px, cases
   serrées, surlignage à peine teinté. Sur un tableur c'est très bien. Pour
   un enfant de 6e qui a du mal à suivre une ligne sur cinq colonnes, c'est
   un mur de traits où rien n'aide l'œil — et le surlignage, qui est
   justement le geste qu'on enseigne, ne se voyait pas.

   Quatre décisions, et chacune répond à une difficulté précise :

   1. PAS DE TRAITS VERTICAUX entre les cases. C'est le plus gros gain.
      Suivre une ligne sur toute sa largeur est le geste difficile ; un
      quadrillage complet le découpe en cases isolées et fait perdre la
      ligne. On garde des filets horizontaux fins, et la ligne redevient
      une ligne.

   2. DEUX TRAITS FRANCS, ET DEUX SEULEMENT : après la ligne d'en-tête et
      après la colonne d'en-tête. Ils ne décorent rien — ils DESSINENT les
      deux axes dont on parle à l'enfant. Le tableau dit lui-même « voici
      les lignes, voici les colonnes ».

   3. DES BANDES ALTERNÉES très pâles. Un œil qui décroche retombe sur sa
      bande plutôt que de recommencer à gauche.

   4. UN SURLIGNAGE QUI SE VOIT. C'est le cœur pédagogique du domaine : si
      l'aide est discrète, elle n'aide personne. La ligne et la colonne
      prennent un fond turquoise franc, et l'intersection est REMPLIE — le
      turquoise plein, celui que Fractilo réserve depuis toujours aux
      remplissages pédagogiques. Aucun vert de réussite, aucun rouge
      d'erreur dans ce jeu : ici une couleur ne dit jamais deux choses.

   Contrastes vérifiés : marine --ink sur le fond de surlignage et sur le
   turquoise plein, très au-dessus de 4,5:1 ; les filets d'axe et l'anneau
   de l'intersection au-dessus de 3:1.
   ========================================================================= */
.tdon-bloc{max-width:100%}
.tdon-cadre{max-width:100%;overflow-x:auto;margin:0 auto;
  padding:2px 2px 6px;                       /* l'ombre de la carte respire */
  -webkit-overflow-scrolling:touch}

/* le titre : un vrai titre, fixe au-dessus du tableau — il ne défile pas
   avec lui, voir la note dans tableauDonnees5. */
.tdon-titre{margin:0 0 10px;padding:0 4px;color:var(--ink);
  font-size:clamp(15px,2.1vw,18px);font-weight:800;text-align:center;
  line-height:1.3}

.tdon{border-collapse:separate;border-spacing:0;margin:0 auto;
  background:var(--card);border-radius:18px;overflow:hidden;
  box-shadow:0 0 0 2px var(--border),0 6px 20px rgba(24,49,91,.09)}

/* ---- les cases ------------------------------------------------------- */
.tdon th,.tdon td{padding:clamp(11px,1.8vw,16px) clamp(12px,2.2vw,22px);
  text-align:center;color:var(--ink);border:0;
  font-variant-numeric:tabular-nums;line-height:1.2}
.tdon td{font-size:clamp(19px,2.9vw,25px);font-weight:800;white-space:nowrap}

/* filets horizontaux fins entre les lignes de données — et rien de vertical */
.tdon tr+tr th,.tdon tr+tr td{border-top:1.5px solid var(--border)}

/* ---- les deux traits qui dessinent les axes --------------------------- */
.tdon tr:first-child th{border-bottom:3px solid var(--ink)}
.tdon th.rh,.tdon th.coin{border-right:3px solid var(--ink)}

/* ---- les en-têtes ---------------------------------------------------- */
.tdon th{background:var(--bg-2);font-weight:800;
  font-size:clamp(14px,2.1vw,18px)}
.tdon th.ch{letter-spacing:.01em}
.tdon th.rh{text-align:right;white-space:nowrap}
.tdon th.coin{background:var(--bg);color:var(--soft);
  font-size:clamp(12px,1.8vw,15px)}
.tdon .u{display:block;font-weight:700;color:var(--soft);
  font-size:.78em;margin-top:2px}

/* ---- les bandes alternées : on retombe sur sa ligne ------------------- */
.tdon tr:nth-child(odd) td{background:#F7FAFD}

/* ---- une case à trouver : une FENTE à remplir. Un « ? » posé au milieu
   d'une case vide se lit comme une valeur ; un cadre en pointillés se lit
   comme un trou, et c'est ce qu'on veut dire. */
.tdon td.cel.vide{color:var(--soft)}
.tdon td.cel.vide span{display:inline-block;min-width:2em;padding:2px 10px;
  border:2.5px dashed var(--acc-txt);border-radius:10px;
  color:var(--acc-txt);background:var(--card-sel)}

/* =========================================================================
   LE SURLIGNAGE — il APPARAÎT, il ne clignote pas.
   prefers-reduced-motion supprime le mouvement sans rien retirer de
   l'information : l'état final est exactement le même.
   ========================================================================= */
.tdon td,.tdon th{transition:background var(--t-slow) var(--ease),
  box-shadow var(--t-slow) var(--ease),color var(--t) var(--ease)}

/* LA SPÉCIFICITÉ SE COMPTE, ELLE NE SE DEVINE PAS. `.tdon td.lg` pèse
   (0,2,1) et la bande alternée `.tdon tr:nth-child(odd) td` pèse (0,2,2) :
   la bande gagnait, et une ligne sur deux ne s'éclairait tout simplement
   pas. Vu à l'écran, jamais à la lecture. On passe donc par la classe
   `.cel`, que porte toute case de données — (0,3,1), et l'aide repasse
   devant la décoration, ce qui est l'ordre normal des choses ici.
   La ligne et la colonne partagent le MÊME fond : ce ne sont pas deux
   informations, c'est un seul geste en deux temps. */
.tdon td.cel.lg,.tdon td.cel.cl{background:#C5EAEE}
.tdon th.lg,.tdon th.cl{background:#A9DFE5;color:var(--acc2)}

/* l'intersection, elle, change de nature — c'est elle, la réponse */
.tdon td.cel.ix{background:var(--acc);color:var(--ink);
  /* PAS de taille de police différente ici : la case grossirait, la
     colonne s'élargirait, et tout le tableau bougerait entre la question
     et la correction. Un tableau qui saute sous les yeux au moment où on
     découvre la réponse, c'est le pire instant pour le faire bouger. */
  box-shadow:inset 0 0 0 3px var(--acc2)}

/* une case mal choisie se signale, puis s'efface d'elle-même : la classe
   est retirée au bout de 800 ms (voir marquerFaux5), sinon un second clic
   au même endroit ne rejouerait rien. */
.tdon td.cel.faux{background:var(--card-ko);
  box-shadow:inset 0 0 0 3px var(--err);color:var(--err)}

/* ---- ce qui est cliquable a l'air cliquable -------------------------- */
.tdon td[data-c]{cursor:pointer}
@media (hover:hover){
  .tdon td[data-c]:hover{background:var(--card-sel);
    box-shadow:inset 0 0 0 3px var(--acc-txt)}
}
.tdon td[data-c]:active{transform:scale(.97)}

@media (prefers-reduced-motion:reduce){
  .tdon td,.tdon th{transition:none}
  .tdon td[data-c]:active{transform:none}
}
@media (max-width:560px){
  .tdon th,.tdon td{padding:9px 10px}
  /* sur téléphone, un nom d'arrêt a le droit de passer à la ligne : mieux
     vaut deux lignes lisibles qu'un tableau qu'il faut faire défiler. */
  .tdon th.rh{white-space:normal;max-width:10em}
}

/* =========================================================================
   GÉOMÉTRIE — LE PLAN, SES LIGNES, ET LES SALVES   (n5/geometrie.js)

   Tout le contenu du dessin est AUX BOUTS : une droite continue, un
   segment s'arrête aux deux, une demi-droite d'un seul côté. Le trait est
   donc volontairement épais et les extrémités très marquées — ce sont
   elles qu'il faut voir, pas la ligne.

   La cible (l'objet dont on parle) passe en turquoise appuyé, comme tous
   les remplissages pédagogiques de Fractilo. Aucun vert de réussite,
   aucun rouge d'erreur dans le dessin lui-même.
   ========================================================================= */
.fig.geo5{max-width:100%;height:auto;overflow:hidden}
.g5-l{stroke:var(--ink);fill:none}
.g5-l.cible{stroke:var(--acc-txt);stroke-width:7}
.g5-ext{fill:var(--ink);stroke:var(--card);stroke-width:2.5}
.g5-ext.cible{fill:var(--acc-txt)}
.g5-pt{fill:var(--soft)}
.g5-pt.cible{fill:var(--acc-txt)}
.g5-nom{font-size:21px;font-weight:800;fill:var(--ink)}
.g5-nom.cible{fill:var(--acc-txt)}
.g5-num-f{fill:var(--bg-2);stroke:var(--border);stroke-width:2}
.g5-num{font-size:17px;font-weight:800;fill:var(--soft)}
.g5-angle{fill:none;stroke:var(--acc-txt);stroke-width:3.5}
.g5-cod{font-size:20px;font-weight:800;fill:var(--acc-txt)}
/* LE CODAGE DU COURS : les petits traits en travers qui disent « ces deux
   longueurs sont égales ». Ils sont fins mais nets, et dans l'encre du
   dessin — ce n'est pas une aide de Fractilo, c'est une donnée de
   l'exercice, au même titre qu'un nombre écrit. */
/* l'anneau du point dont on PARLE — il désigne, il ne répond pas.
   Gris, jamais turquoise : le turquoise est réservé à la réponse. */
.g5-vise{fill:none;stroke:var(--soft);stroke-width:2.5;stroke-dasharray:4 4}
.g5-cod-t{stroke:var(--ink);stroke-width:3;stroke-linecap:round}
.g5-cod-t.cible{stroke:var(--acc-txt)}
/* une longueur écrite sous un segment */
.g5-mes{font-size:18px;font-weight:800;fill:var(--soft)}
.g5-mes.cible{fill:var(--acc-txt)}

/* ---- la notation, écrite comme au tableau ---------------------------- */
.g5-not{display:inline-block;font-weight:800;letter-spacing:.04em;
  font-size:1.12em;color:var(--ink);background:var(--bg-2);
  border-radius:9px;padding:1px 10px;white-space:nowrap}

/* =========================================================================
   LA SALVE — huit questions, une touche chacune

   Le compteur et la jauge disent où on en est : sans eux, une série de
   huit questions n'a pas de fin visible, et c'est décourageant bien avant
   la huitième.
   ========================================================================= */
.g5-compteur{display:flex;align-items:center;justify-content:center;gap:10px;
  font-weight:800;color:var(--soft)}
.g5-jauge{display:inline-block;width:clamp(90px,22vw,170px);height:8px;
  background:var(--bg-2);border-radius:99px;overflow:hidden}
.g5-jauge span{display:block;height:100%;background:var(--acc);
  border-radius:99px;transition:width var(--t) var(--ease)}

/* la réponse d'une salve se touche, elle ne se valide pas : les boutons
   sont donc larges et bien séparés — on vise vite. */
.g5-salve .big.rep{min-width:clamp(120px,30vw,210px)}
.g5-salve .big.rep.juste{background:var(--card-ok);border-color:var(--ok);
  color:var(--ok)}
.g5-salve .big.rep.rate{background:var(--card-ko);border-color:var(--err);
  color:var(--err)}

/* une vignette : un dessin minuscule qui sert de bouton */
.g5-salve .big.rep.g5-vignette{padding:6px 8px;min-width:0}
.g5-salve .big.rep.g5-vignette svg{display:block;width:clamp(150px,34vw,230px);height:auto}

@media (prefers-reduced-motion:reduce){ .g5-jauge span{transition:none} }

/* ---- les cartes d'idées-clés : des phrases, pas des nombres ----------
   La grille standard des cartes du niveau 4 en met quatre par ligne, ce
   qui convient à « 12 » et pas du tout à « qui part d'un point et ne
   s'arrête jamais ». Deux colonnes larges, texte aligné à gauche. */
.cards.g5-defs{display:grid;gap:12px;max-width:640px;margin:0 auto;
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.cards.g5-defs .card{display:flex;align-items:center;justify-content:flex-start;
  text-align:left;padding:14px 18px;min-height:0;
  font-size:clamp(15px,2.2vw,18px);font-weight:700;line-height:1.35}
@media (max-width:560px){ .cards.g5-defs{grid-template-columns:1fr} }
