/* La Cabane à Maths — feuille de style unique, sans dépendance. */

:root {
  /* ── La charte du site ──────────────────────────────────────────────────
     Relevée sur briace.org : l'orange du bandeau, l'or du logo, l'anthracite du
     mot BRIACÉ, et les deux couleurs des onglets latéraux — le bleu de « portes
     ouvertes », le turquoise de « boutique ». Aucune couleur n'est écrite en dur
     ailleurs dans cette feuille : ces huit valeurs, et leurs équivalents du mode
     sombre juste en dessous, sont les seules à changer.

     Une remarque sur les deux oranges. L'orange de la marque est éclatant, et
     c'est ce qui fait le site : filet de tête, onglet actif, jauges. Mais du
     blanc dessus ne tient que 3:1 — illisible sur un vidéoprojecteur de salle
     de classe. On écrit donc en anthracite sur l'orange vif, exactement comme le
     bandeau Parcoursup de briace.org, et on garde un orange brique, le même en
     plus sombre, partout où du blanc doit se poser : boutons, liens, focus. La
     couleur reste celle de l'établissement ; seule la valeur change avec l'usage.

     Tout ce qui porte du texte tient au moins 4,9:1. L'or et l'orange vif, qui
     ne peuvent pas y arriver, ne servent jamais de fond à du texte clair. */
  --briace-orange: #e8740c;
  --briace-brique: #a34d05;
  --briace-or: #f5b301;
  --briace-anthracite: #1d1d1b;
  --briace-bleu: #15617f;
  --briace-turquoise: #00705f;
  --briace-grenat: #b3261e;
  --briace-blanc: #fdfbf8;

  color-scheme: light dark;
  --fond: var(--briace-blanc);
  --fond-carte: #ffffff;
  --fond-doux: #f4efe7;
  --fond-zebre: #faf6f0;
  --texte: var(--briace-anthracite);
  --texte-doux: #5b5b58;
  --bordure: #e6dfd4;

  /* L'orange de la marque, et ce qui s'écrit dessus. */
  --marque: var(--briace-orange);
  --marque-fonce: #d16a0b;
  --sur-marque: var(--briace-anthracite);
  /* L'orange qui agit : boutons, liens, focus, état actif. */
  --accent: var(--briace-brique);
  --accent-doux: #fbeee1;
  --accent-fonce: #7d3a03;
  --sur-accent: #ffffff;
  /* Ce qui est acquis, ce qui a réussi. */
  --succes: var(--briace-turquoise);
  --succes-doux: #e2f2ef;
  --succes-fonce: #00483d;
  /* L'or du logo : décoratif, jamais sous du texte clair. */
  --or: #8a6400;
  --or-doux: #fdf3d9;
  --bleu: var(--briace-bleu);
  --bleu-clair: #e8f1f5;
  --rouge: var(--briace-grenat);
  --rouge-clair: #fbebea;

  --rayon: .7rem;
  --ombre: 0 1px 2px rgba(29, 29, 27, .05), 0 6px 16px rgba(29, 29, 27, .06);
  /* Le halo de focus : visible sur tous les fonds, y compris sur un aplat orange. */
  --halo: 0 0 0 3px rgba(163, 77, 5, .3);

  /* Les graphiques de la lecture rapide. Une seule teinte, l'orange, en trois
     pas du clair au foncé pour les tranches ordonnées ; deux couleurs d'état,
     à jour et en retard, distinctes pour un daltonien ; un neutre pour « pas
     commencé ». Vérifiées au validateur : contraste, séparation, une teinte. */
  --graphe-1: #f0a25e;
  --graphe-2: #e8740c;
  --graphe-3: #a34d05;
  --graphe-neutre: #c9c3b9;
  --graphe-a-jour: #12907a;
  --graphe-en-retard: #c47f00;
}

@media (prefers-color-scheme: dark) {
  :root {
    --briace-orange: #f28c33;
    --briace-brique: #eb9450;
    --briace-or: #f0c256;
    --briace-anthracite: #171614;
    --briace-bleu: #79b8d6;
    --briace-turquoise: #4fc9ac;
    --briace-grenat: #e8908a;
    --briace-blanc: #eeece8;

    --fond: var(--briace-anthracite);
    --fond-carte: #201f1c;
    --fond-doux: #292723;
    --fond-zebre: #232220;
    --texte: var(--briace-blanc);
    --texte-doux: #adaaa3;
    --bordure: #3b3833;

    --marque-fonce: #e07d22;
    --sur-marque: var(--briace-anthracite);
    --accent-doux: #33230f;
    --accent-fonce: #f6b47c;
    --sur-accent: var(--briace-anthracite);
    --succes-doux: #14302a;
    --graphe-neutre: #4a463f;
    --succes-fonce: #7fdcc1;
    --or: #f0c256;
    --or-doux: #2f2712;
    --bleu-clair: #17262e;
    --rouge-clair: #331d1c;

    --ombre: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 16px rgba(0, 0, 0, .3);
    --halo: 0 0 0 3px rgba(235, 148, 80, .32);
  }
}

/* ── OpenDyslexic, hébergée ici : rien ne part vers un serveur tiers ──────── */
@font-face { font-family: "OpenDyslexic"; src: url("/polices/OpenDyslexic-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "OpenDyslexic"; src: url("/polices/OpenDyslexic-Bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "OpenDyslexic"; src: url("/polices/OpenDyslexic-Italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "OpenDyslexic"; src: url("/polices/OpenDyslexic-Bold-Italic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }

/* ── Réglages d'affichage : des attributs sur <html>, choisis dans le profil ──
   Ils ne touchent qu'à la présentation — jamais au contenu ni à la correction. */
html[data-police="dyslexie"] body { font-family: "OpenDyslexic", ui-sans-serif, system-ui, sans-serif; }
html[data-police="dyslexie"] { font-size: 94%; }
html[data-police="lisible"] body { font-family: Verdana, "DejaVu Sans", Geneva, sans-serif; }
html[data-espacement="large"] body { letter-spacing: .05em; word-spacing: .14em; line-height: 1.85; }
html[data-espacement="large"] p, html[data-espacement="large"] li { margin-bottom: .6em; }
html[data-taille="grande"] { font-size: 118%; }

/* Daltonisme : le juste en bleu, le faux en vermillon (palette Okabe-Ito), et
   des bordures différentes pour que la forme dise ce que dit la couleur. */
html[data-couleurs="daltonien"] {
  --succes: #0072b2; --succes-doux: #e3eef8; --succes-fonce: #004b78;
  --rouge: #d55e00; --rouge-clair: #fdece0; --briace-grenat: #d55e00;
  --or: #6e5a00; --or-doux: #fbf3d6;
}
html[data-couleurs="daltonien"] .pastille.juste { border-width: 2px; border-style: solid; }
html[data-couleurs="daltonien"] .pastille.faux { border-width: 2px; border-style: dashed; }
html[data-couleurs="daltonien"] .message.succes { border-left-width: 6px; }
html[data-couleurs="daltonien"] .message.erreur { border-left-width: 6px; border-left-style: dashed; }

/* Contraste renforcé : du noir sur du blanc, des bordures nettes. */
html[data-couleurs="contraste"] {
  --fond: #ffffff; --fond-carte: #ffffff; --fond-doux: #f1f1f1; --fond-zebre: #f6f6f6;
  --texte: #000000; --texte-doux: #2b2b2b; --bordure: #6b6b6b;
  --accent: #7a3400; --accent-fonce: #4d2000; --succes-fonce: #003a31; --rouge: #8f1a12;
  --ombre: none;
}
html[data-couleurs="contraste"] a { text-decoration: underline; }

/* Fond atténué : un crème qui n'éblouit pas, des couleurs adoucies. */
html[data-couleurs="apaise"] {
  --fond: #f3ecdc; --fond-carte: #faf5ea; --fond-doux: #ece3d0; --fond-zebre: #f5efe2;
  --texte: #3a352e; --texte-doux: #6a635a; --bordure: #d9cfbc;
  --marque: #d98a3a; --accent: #9c5a1e; --accent-doux: #f1e3cf; --accent-fonce: #6e3d12;
  --succes: #3c8a7a; --succes-doux: #e2ede8; --succes-fonce: #2b5f54;
  --rouge: #b5544b; --rouge-clair: #f3e2de; --or: #8a6d1f; --or-doux: #f4ebd2;
}

@media (prefers-color-scheme: dark) {
  html[data-couleurs="daltonien"] {
    --succes: #56b4e9; --succes-doux: #142a3a; --succes-fonce: #9fd4f5;
    --rouge: #f0a06a; --rouge-clair: #3a2416; --briace-grenat: #f0a06a;
  }
  html[data-couleurs="contraste"] {
    --fond: #000000; --fond-carte: #0a0a0a; --fond-doux: #1a1a1a; --fond-zebre: #141414;
    --texte: #ffffff; --texte-doux: #e0e0e0; --bordure: #9a9a9a;
    --accent: #ffb070; --accent-fonce: #ffd0a8; --succes-fonce: #9fe8d2; --rouge: #ff9e96;
  }
  html[data-couleurs="apaise"] {
    --fond: #24211b; --fond-carte: #2c2822; --fond-doux: #35302a; --fond-zebre: #302b25;
    --texte: #e6dfd2; --texte-doux: #b3aa9a; --bordure: #4a443b;
  }
}

.groupe-reglage { border: 1px solid var(--bordure); border-radius: var(--rayon); padding: .8rem 1rem 1rem; margin: 0 0 1rem; }
.groupe-reglage legend { font-weight: 700; padding: 0 .4rem; }
.pied .version { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .8em; opacity: .75; }

* { box-sizing: border-box; }

/* L'attribut hidden doit primer sur les display des classes ci-dessous. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--fond);
  color: var(--texte);
  line-height: 1.6;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5rem; }
h1 { font-size: 1.55rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1.02rem; }
p { margin: 0 0 .8rem; }
a { color: var(--accent); }

.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.lien-evitement {
  position: absolute; left: -999px; background: var(--accent); color: var(--sur-accent);
  padding: .6rem 1rem; z-index: 10; border-radius: 0 0 var(--rayon) 0;
}
.lien-evitement:focus { left: 0; }

/* ── En-tête ─────────────────────────────────────────────────────────────── */

.entete {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: .7rem 1.2rem;
  background: var(--fond-carte);
  /* Un filet vert en haut de page : la couleur de l'établissement se voit dès
     l'ouverture, sans bandeau qui mange la hauteur d'un écran de téléphone. */
  border-top: 3px solid var(--marque);
  border-bottom: 1px solid var(--bordure);
  position: sticky; top: 0; z-index: 5;
}
.marque { display: flex; align-items: center; gap: .65rem; text-decoration: none; color: inherit; }
.marque-icone { width: 2.5rem; height: 2.5rem; flex: 0 0 auto; transition: transform .25s ease; }
.marque:hover .marque-icone { transform: translateY(-1px) rotate(-2deg); }
.marque-nom { display: block; font-weight: 700; font-size: 1.08rem; letter-spacing: .01em; line-height: 1.15; }
.marque small { display: block; color: var(--texte-doux); font-size: .76rem; letter-spacing: .04em; margin-top: .1rem; }
.bouton-menu {
  margin-left: auto; font-size: 1.3rem; background: none; border: 1px solid var(--bordure);
  border-radius: var(--rayon); padding: .2rem .55rem; color: inherit; cursor: pointer; display: none;
}
.navigation { display: flex; gap: .25rem; margin-left: auto; flex-wrap: wrap; align-items: center; }
.navigation a {
  padding: .42rem .7rem; border-radius: var(--rayon); text-decoration: none;
  color: var(--texte-doux); font-size: .93rem; font-weight: 500;
}
.navigation a:hover { background: var(--fond-doux); color: var(--texte); }
.navigation a.actif { background: var(--accent-doux); color: var(--accent-fonce); }
.navigation .separateur { width: 1px; height: 1.4rem; background: var(--bordure); margin: 0 .3rem; }
.navigation .choix-classe {
  /* Assez large pour lire « Maths — 1re Bac professionnel SAPAT » ; au-delà,
     le nom se coupe proprement, la liste déroulée le montre en entier. */
  width: auto; max-width: 15rem; flex: 0 1 auto; text-overflow: ellipsis;
  font: inherit; font-size: .9rem; font-weight: 500; color: var(--accent-fonce); background: var(--accent-doux);
  border: 1px solid var(--bordure); border-radius: var(--rayon); padding: .3rem .5rem; cursor: pointer;
}

@media (max-width: 860px) {
  .bouton-menu { display: block; }
  .navigation { display: none; width: 100%; flex-direction: column; align-items: stretch; }
  .navigation.ouverte { display: flex; }
  .navigation .separateur { display: none; }
}

/* ── Structure ───────────────────────────────────────────────────────────── */

.contenu { flex: 1; width: 100%; max-width: 62rem; margin: 0 auto; padding: 1.4rem 1.2rem 3rem; }
.contenu:focus { outline: none; }
.pied {
  border-top: 1px solid var(--bordure); padding: 1rem 1.2rem; color: var(--texte-doux);
  font-size: .84rem; text-align: center; background: var(--fond-carte);
}
.pied p { margin: 0; }

.carte {
  background: var(--fond-carte); border: 1px solid var(--bordure); border-radius: var(--rayon);
  padding: 1.1rem 1.2rem; margin-bottom: 1rem; box-shadow: var(--ombre);
}
.carte > h2:first-child, .carte > h3:first-child {
  margin-bottom: .7rem; padding-bottom: .5rem; border-bottom: 1px solid var(--bordure);
}
.grille { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
/* Trois nombres n'ont pas besoin de 15 rem chacun : sur un téléphone, ils
   tenaient sur trois écrans là où ils tiennent sur une ligne et demie. */
.grille.grille-chiffres { grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: .7rem; }
.entete-page { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.2rem; }
.entete-page p { color: var(--texte-doux); margin: 0; max-width: 44rem; }

/* ── Éléments ────────────────────────────────────────────────────────────── */

.bouton {
  display: inline-flex; align-items: center; gap: .4rem; justify-content: center;
  background: var(--accent); color: var(--sur-accent); border: 1px solid transparent;
  padding: .55rem 1rem; border-radius: var(--rayon); font-size: .95rem; font-weight: 600;
  cursor: pointer; text-decoration: none; font-family: inherit;
  /* 2,6 rem : la cible tactile reste confortable au doigt, sur un téléphone
     tenu d'une main au fond de la classe. */
  min-height: 2.6rem;
  transition: background-color .12s ease, border-color .12s ease, transform .06s ease;
}
.bouton:hover { background: var(--accent-fonce); color: var(--sur-accent); }
.bouton:active { transform: translateY(1px); }
.bouton:disabled { opacity: .55; cursor: not-allowed; transform: none; }
.bouton.secondaire { background: var(--fond-carte); color: var(--texte); border-color: var(--bordure); }
.bouton.secondaire:hover { background: var(--fond-doux); color: var(--texte); }
.bouton.discret { background: none; border: none; color: var(--accent); text-decoration: underline; padding: .3rem; }
.bouton.discret:hover { background: none; color: var(--accent-fonce); }
.barre-actions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; margin-top: 1rem; }

label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: .25rem; }
input, select, textarea {
  width: 100%; padding: .55rem .7rem; border: 1px solid var(--bordure); border-radius: var(--rayon);
  background: var(--fond); color: var(--texte); font-size: 1rem; font-family: inherit;
}
input[readonly] { background: var(--fond-doux); color: var(--texte-doux); cursor: default; }
input:focus, select:focus, textarea:focus, .bouton:focus-visible, .navigation a:focus-visible,
a:focus-visible, .choix:focus-within, summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; box-shadow: var(--halo);
}
.champ { margin-bottom: .9rem; }
.grille-formulaire { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0 1rem; }
.grille-formulaire .barre-actions { grid-column: 1 / -1; }
.champ .aide { color: var(--texte-doux); font-size: .82rem; font-weight: 400; margin-top: .2rem; display: block; }

.etiquette {
  display: inline-block; padding: .12rem .5rem; border-radius: 999px; font-size: .76rem;
  font-weight: 600; background: var(--fond-doux); color: var(--texte-doux);
}
.etiquette.acquis { background: var(--succes-doux); color: var(--succes-fonce); }
.etiquette.en-cours { background: var(--bleu-clair); color: var(--bleu); }
.etiquette.fragile { background: var(--rouge-clair); color: var(--rouge); }
.etiquette.non-travaille { background: var(--fond-doux); color: var(--texte-doux); }
/* « À toi » : la séance que l'élève a gagnée, ouverte avant le reste de la classe. */
.etiquette.a-toi { background: var(--accent); color: white; }
.etiquette.niveau { background: var(--or-doux); color: var(--or); }

/* ── La Cabane raconte ─────────────────────────────────────────────────────
   Une blague se raconte en deux temps : la question, un silence, la chute. Le
   bouton de la chute est le silence — et il doit donner envie d'être touché. */
.bouton-blague { font-size: 1.05rem; padding: .7rem 1.3rem; }
.bouton-blague span { font-size: 1.2rem; margin-right: .2rem; }

.scene-blague { border: 2px solid var(--or); background: var(--or-doux); }
.blague-question, .scene-blague .chute {
  display: flex; align-items: flex-start; gap: .9rem; margin: 0;
}
.blague-question p, .scene-blague .chute p { margin: 0; align-self: center; }
.blague-question p { font-size: 1.12rem; line-height: 1.5; }
.scene-blague .chute {
  margin-top: .9rem; padding-top: .9rem; border-top: 1px dashed var(--or);
}
.scene-blague .chute p { font-size: 1.22rem; font-weight: 600; color: var(--or); }
.bouton-chute { margin-top: .9rem; background: var(--or); color: #1d1d1b; }
.bouton-chute:hover { filter: brightness(1.06); }

.pouces { display: flex; gap: .6rem; margin-top: .2rem; }
.pouce {
  font-size: 1.5rem; line-height: 1; padding: .45rem .8rem; cursor: pointer;
  background: var(--fond-carte); border: 2px solid var(--bordure); border-radius: var(--rayon);
}
.pouce:hover:not([disabled]) { border-color: var(--accent); transform: translateY(-2px); }
.pouce.choisi { border-color: var(--accent); background: var(--accent-doux); }
.pouce[disabled] { cursor: default; opacity: .55; }
.pouce.choisi[disabled] { opacity: 1; }

.carnet-blagues { list-style: none; margin: .6rem 0 0; padding: 0; }
.carnet-blagues li { padding: .6rem 0; border-top: 1px solid var(--bordure); }
.carnet-blagues .question { margin: 0; }
.carnet-blagues .chute { margin: .15rem 0 .15rem; font-weight: 600; color: var(--or); }
.carnet-blagues .discret { margin: 0; }

/* Le répertoire, côté enseignant : la chute reste lisible sans être criarde. */
.repertoire-blagues { list-style: none; margin: .6rem 0 0; padding: 0; }
.repertoire-blagues li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem .8rem;
  padding: .55rem 0; border-top: 1px solid var(--bordure);
}
.repertoire-blagues li.retiree { opacity: .55; }
.repertoire-blagues .texte { flex: 1 1 18rem; min-width: 0; }
.repertoire-blagues .texte .chute { color: var(--or); font-weight: 600; }

/* À faire sur l'ordinateur : l'encadré qui précède la question dans les cours
   d'informatique. Il se distingue de l'énoncé — c'est une consigne d'action,
   pas une lecture — sans crier : un fond doux et un liseré à gauche. */
.pratique {
  margin: .8rem 0; padding: .7rem .9rem;
  background: var(--accent-doux); border-left: 4px solid var(--accent);
  border-radius: 0 var(--rayon) var(--rayon) 0;
}
.pratique-titre { margin: 0 0 .4rem; display: flex; align-items: center; gap: .45rem; }
.pratique-icone { font-size: 1.15rem; }
.pratique-etapes { margin: 0; padding-left: 1.3rem; }
.pratique-etapes li { margin: .25rem 0; }
.pratique-etapes code, .pratique code {
  background: var(--fond-carte); padding: .1rem .35rem; border-radius: .3rem;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: .92em;
}
.pratique .discret { margin: .45rem 0 0; }

/* La ligne qu'une notification vient de montrer : un liseré, le temps qu'on la
   voie. « Y aller » ouvrait l'onglet et laissait l'enseignant devant la liste
   des élèves, sans rien dire d'où était le problème. */
tr.vise > td { background: var(--or-doux) !important; }
tr.vise > td:first-child { box-shadow: inset 3px 0 0 var(--or); }

/* Le compte d'essai : un liseré et une mention sur toutes les pages. Tout lui
   est ouvert et rien de ce qu'il fait ne compte — on ne doit jamais le prendre
   pour le compte d'un élève. */
body.mode-essai { border-top: 4px solid var(--or); }
body.mode-essai .entete::after {
  content: 'Compte d’essai — tout est ouvert, rien n’est compté';
  display: block; width: 100%; order: 3;
  background: var(--or-doux); color: var(--or);
  font-size: .82rem; font-weight: 600; text-align: center;
  padding: .25rem .6rem; border-radius: 999px; margin-top: .3rem;
}

/* Les identifiants du compte d'essai : on les recopie dans un autre navigateur,
   ils doivent se lire sans effort. */
.identifiants-essai {
  background: var(--fond-doux); border-radius: var(--rayon); padding: .6rem .8rem; margin: .6rem 0;
}
.identifiants-essai p { margin: 0; }
.identifiants-essai strong { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }

/* L'objectif de la classe, replié : le chiffre se lit d'un coup d'œil, le
   calcul qui le justifie ne s'ouvre que si on le demande. */
.objectif-classe { margin: .6rem 0 1rem; padding: .6rem .8rem; background: var(--fond-doux); border-radius: var(--rayon); }
.objectif-classe > summary { cursor: pointer; padding: .2rem 0; }
.objectif-classe > summary:hover { text-decoration: underline; }
.objectif-chapitres { list-style: none; margin: .6rem 0 0; padding: 0; }
.objectif-chapitres li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .7rem;
  padding: .35rem 0; border-top: 1px solid var(--bordure);
}
.objectif-chapitres li > span:first-child { flex: 1 1 12rem; min-width: 0; }

/* L'objectif de points : la ligne qui dit si l'élève suit. Verte quand il est
   à jour, ambrée quand il lui manque des points — jamais rouge : un retard se
   rattrape, ce n'est pas une faute. */
.objectif-etat { margin: .4rem 0 0; padding: .5rem .7rem; border-radius: var(--rayon); font-size: .95rem; }
.objectif-etat.a-jour { background: var(--succes-doux); color: var(--succes-fonce); }
.objectif-etat.a-rattraper { background: var(--or-doux); color: var(--or); }

.jauge { height: .5rem; background: var(--fond-doux); border-radius: 999px; overflow: hidden; margin: .4rem 0; }
.jauge span { display: block; height: 100%; background: var(--marque); border-radius: 999px; }

.message { padding: .8rem 1rem; border-radius: var(--rayon); margin-bottom: 1rem; border: 1px solid; overflow-wrap: anywhere; }
.message.info { background: var(--bleu-clair); border-color: var(--bleu); }
.message.succes { background: var(--succes-doux); border-color: var(--succes); }
.message.erreur { background: var(--rouge-clair); border-color: var(--rouge); }
.message.attention { background: var(--or-doux); border-color: var(--or); }
.message p:last-child { margin-bottom: 0; }

/* Le repère fixé par l'enseignant, rappelé au-dessus de l'avancée des élèves. */
.bandeau-repere {
  padding: .7rem .9rem; margin-bottom: 1rem;
  border-left: 3px solid var(--bleu); background: var(--bleu-clair);
  border-radius: 0 var(--rayon) var(--rayon) 0;
}
.bandeau-repere p { margin: 0; }
.bandeau-repere p + p { margin-top: .3rem; }

table { width: 100%; border-collapse: collapse; font-size: .93rem; }
th, td { text-align: left; padding: .5rem .6rem; border-bottom: 1px solid var(--bordure); vertical-align: top; }
th {
  font-weight: 600; color: var(--texte-doux); font-size: .84rem; text-transform: uppercase;
  letter-spacing: .02em; background: var(--fond-carte);
}
/* Une classe fait vingt-cinq lignes : l'œil perd la ligne sans un fond alterné,
   et l'en-tête sans une colle en haut du cadre. */
/* Toutes les cellules sont opaques : une colonne figée doit cacher ce qui
   défile dessous, et une ligne transparente laisserait passer le texte. */
tbody > tr > td { background: var(--fond-carte); }
tbody tr:nth-child(even) > td { background: var(--fond-zebre); }
tbody tr:hover > td { background: var(--accent-doux); }
.tableau-defilant { overflow-x: auto; max-height: 78vh; overflow-y: auto; }
.tableau-defilant thead th { position: sticky; top: 0; z-index: 2; }

/* ── Les tableaux sur un écran étroit ────────────────────────────────────────
   Un tableau de classe comprimé dans 390 px empile les noms sur trois lignes et
   ne se lit plus. On lui rend donc sa largeur naturelle — il défile — et on fige
   sa première colonne : le nom de l'élève reste en vue pendant qu'on fait
   glisser le reste. C'est le geste attendu sur une tablette. */
@media (max-width: 46rem) {
  .tableau-defilant > table:not(.tableau-enonce) { min-width: max-content; }
  .tableau-defilant > table:not(.tableau-enonce) th:first-child,
  .tableau-defilant > table:not(.tableau-enonce) td:first-child {
    position: sticky; left: 0; z-index: 1;
    box-shadow: 1px 0 0 var(--bordure);
  }
  .tableau-defilant > table:not(.tableau-enonce) thead th:first-child { z-index: 3; }
}

.tableau-enonce { margin: .6rem 0; border: 1px solid var(--bordure); border-radius: var(--rayon); overflow: hidden; }
.tableau-enonce th, .tableau-enonce td { border-bottom: 1px solid var(--bordure); padding: .35rem .55rem; font-size: .9rem; text-transform: none; letter-spacing: 0; }
.tableau-enonce th { background: var(--fond-doux); color: var(--texte); }

.formule { font-size: 1.35rem; text-align: center; margin: .9rem 0; font-weight: 600; letter-spacing: .02em; }
.code {
  background: var(--fond-doux); padding: .8rem 1rem; border-radius: var(--rayon);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: .92rem;
  white-space: pre; overflow-x: auto; margin: .7rem 0; border: 1px solid var(--bordure);
}
/* Une fraction empilée : le numérateur au-dessus du dénominateur, comme au
   tableau. Le trait « / » reste dans le balisage pour les lecteurs sans style
   et pour le tuteur, mais ne s'affiche pas. */
.fraction { display: inline-flex; flex-direction: column; align-items: center; vertical-align: middle; line-height: 1.1; margin: 0 .15em; font-size: .95em; }
.fraction .num { border-bottom: 1.5px solid currentColor; padding: 0 .2em; }
.fraction .den { padding: 0 .2em; }
.fraction .barre { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.rappel { color: var(--texte-doux); font-size: .9rem; }

/* ── Exercice ────────────────────────────────────────────────────────────── */

.exercice-entete { display: flex; justify-content: space-between; gap: .8rem; flex-wrap: wrap; align-items: center; margin-bottom: .6rem; }
.enonce { font-size: 1.06rem; margin-bottom: .9rem; }
.consigne { font-weight: 600; margin-bottom: .7rem; }
.saisie-ligne { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.saisie-ligne input { max-width: 12rem; }
.unite { color: var(--texte-doux); font-weight: 600; }
.choix-liste { display: grid; gap: .5rem; }
.choix {
  display: flex; align-items: flex-start; gap: .6rem; padding: .6rem .8rem; cursor: pointer;
  border: 1px solid var(--bordure); border-radius: var(--rayon); background: var(--fond);
  font-weight: 500;
}
.choix:hover { border-color: var(--accent); }
.choix input { width: auto; margin-top: .28rem; }
.choix.selectionne { border-color: var(--accent); background: var(--accent-doux); }
.champs-multiples { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }

.tuteur { border-left: 3px solid var(--or); background: var(--or-doux); padding: .7rem .9rem; border-radius: 0 var(--rayon) var(--rayon) 0; margin: .8rem 0; }
.tuteur .qui { font-weight: 700; font-size: .82rem; text-transform: uppercase; letter-spacing: .03em; color: var(--or); }
.tuteur p { white-space: pre-wrap; margin: .3rem 0 0; }
.tuteur.eleve { border-color: var(--bleu); background: var(--bleu-clair); }
.tuteur.eleve .qui { color: var(--bleu); }
.tuteur.hors-sujet { border-color: var(--briace-grenat); background: #fbeeed; }
.tuteur.hors-sujet .qui { color: var(--briace-grenat); }

.progression-serie { display: flex; gap: .3rem; margin-bottom: 1rem; flex-wrap: wrap; }
.pastille {
  width: 1.7rem; height: 1.7rem; border-radius: 50%; display: grid; place-items: center;
  font-size: .8rem; font-weight: 700; background: var(--fond-doux); color: var(--texte-doux);
  border: 1px solid var(--bordure);
}
.pastille.juste { background: var(--succes-doux); color: var(--succes-fonce); border-color: var(--succes); }
.pastille.faux { background: var(--rouge-clair); color: var(--rouge); border-color: var(--rouge); }
.pastille.courante { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Diagnostic : la pastille dit « répondue », jamais « juste » ni « faux ». */
.pastille.repondue { background: var(--fond-doux); border-color: var(--texte-doux); }

.liste-nue { list-style: none; padding: 0; margin: 0; }
.liste-nue li { padding: .45rem 0; border-bottom: 1px solid var(--bordure); }
.liste-nue li:last-child { border-bottom: none; }
/* Les ouvertures d'auto-évaluation en cours, sur la carte de l'enseignant :
   chacune est un encadré à part — « .liste-nue li » lui ôtait son retrait et
   sa bordure. */
.liste-ouvertures li.ouverture-en-cours { padding: .8rem 1rem; margin-bottom: .6rem; border: 1px solid var(--succes); border-radius: var(--rayon); }
.liste-ouvertures li.ouverture-en-cours:last-child { border-bottom: 1px solid var(--succes); }
/* « Mes auto-évaluations » : trois colonnes, dont le score. Sur un téléphone, le
   tableau défilant prend sa largeur naturelle et la colonne du score sortait de
   l'écran — on le laisse se replier, et la séance passe à la ligne. */
@media (max-width: 46rem) {
  .tableau-defilant > table.tableau-auto-evaluations { min-width: 0; width: 100%; }
  .tableau-defilant > table.tableau-auto-evaluations td:first-child,
  .tableau-defilant > table.tableau-auto-evaluations th:first-child { position: static; box-shadow: none; }
  .tableau-auto-evaluations td, .tableau-auto-evaluations th { padding-inline: .45rem; }
}
/* Les demandes de reprise, sur un téléphone : chaque demande devient une fiche,
   comme au permis à points. Accorder et Refuser sont sous les yeux, au lieu
   d'être à trois écrans de défilement sur la droite. */
@media (max-width: 46rem) {
  .tableau-reprises thead { display: none; }
  .tableau-defilant > table.tableau-reprises { min-width: 0; width: 100%; }
  .tableau-reprises, .tableau-reprises tbody, .tableau-reprises tr, .tableau-reprises td { display: block; width: 100%; }
  .tableau-reprises tr { border: 1px solid var(--bordure); border-radius: var(--rayon); padding: .6rem .7rem; margin-bottom: .6rem; background: var(--fond-carte); }
  .tableau-defilant > table.tableau-reprises td, .tableau-defilant > table.tableau-reprises td:first-child {
    position: static; box-shadow: none; border: none; padding: .15rem 0; background: transparent;
  }
  .tableau-reprises .texte-libre-cellule { max-width: 100%; }
}
/* Ce que l'élève écrit, et le mot que l'enseignant lui répond : trois cents
   caractères sans espace (une adresse collée) ne doivent pas élargir la page.
   Dans une cellule de tableau, la largeur est plafonnée aussi : un tableau
   défilant prend la largeur de son contenu, et repousserait Accorder / Refuser
   à plusieurs écrans de là. */
.texte-libre { overflow-wrap: anywhere; min-width: 0; }
.texte-libre-cellule { overflow-wrap: anywhere; max-width: 22rem; min-width: 0; }
.liste-puces { padding-left: 1.1rem; margin: 0 0 .8rem; }
.liste-puces li { margin-bottom: .35rem; }

.stat { text-align: center; }
.stat .valeur { font-size: 1.9rem; font-weight: 700; color: var(--accent); line-height: 1.1; }
.stat .libelle { color: var(--texte-doux); font-size: .85rem; }

.activite { display: flex; gap: .18rem; align-items: flex-end; height: 3.4rem; margin-top: .5rem; }
.activite span { flex: 1 1 0; max-width: 1.6rem; background: var(--accent-doux); border-radius: 2px 2px 0 0; min-height: 3px; }
.activite { justify-content: flex-start; }
.activite span.pleine { background: var(--marque); }

.discret { color: var(--texte-doux); font-size: .88rem; }
.centre { text-align: center; }
.entre-deux { display: flex; justify-content: space-between; gap: .8rem; align-items: baseline; flex-wrap: wrap; }

/* ── La séance en trois temps ──────────────────────────────────────────────
   Le fil dit où l'on en est sans que l'élève ait à le demander : ce qui est
   fait, ce qui se joue maintenant, ce qui reste. */
.fil-seance {
  list-style: none; padding: 0; margin: 0 0 1.2rem;
  display: flex; gap: .5rem; flex-wrap: wrap;
}
.fil-seance .etape-fil {
  flex: 1 1 10rem; display: flex; align-items: center; gap: .5rem;
  padding: .55rem .8rem; border: 1px solid var(--bordure); border-radius: var(--rayon);
  background: var(--fond-doux);
}
.fil-seance .numero {
  width: 1.6rem; height: 1.6rem; flex: none; border-radius: 50%; display: grid; place-items: center;
  font-size: .8rem; font-weight: 700; background: var(--fond-carte); border: 1px solid var(--bordure);
  color: var(--texte-doux);
}
.fil-seance .libelle { font-weight: 600; }
.fil-seance .duree { margin-left: auto; }
.fil-seance .etape-fil.courante { border-color: var(--accent); background: var(--accent-doux); }
.fil-seance .etape-fil.courante .numero { background: var(--accent); border-color: var(--accent); color: var(--sur-accent); }
.fil-seance .etape-fil.faite { opacity: .7; }
.fil-seance .etape-fil.faite .numero { background: var(--succes-doux); border-color: var(--succes); color: var(--succes-fonce); }
/* Le fil se clique : chaque temps est un bouton qui remplit sa case. */
.fil-seance.cliquable .etape-fil { padding: 0; }
.fil-seance .etape-fil-bouton {
  all: unset; box-sizing: border-box; width: 100%; display: flex; align-items: center; gap: .5rem;
  padding: .55rem .8rem; cursor: pointer; border-radius: var(--rayon); color: inherit; font: inherit;
}
.fil-seance .etape-fil-bouton:hover, .fil-seance .etape-fil-bouton:focus-visible { background: var(--accent-doux); outline: 2px solid var(--accent); outline-offset: -2px; }
.fil-seance .etape-fil.courante .etape-fil-bouton { cursor: default; }
.fil-seance .etape-fil.courante .etape-fil-bouton:hover { background: transparent; outline: none; }

/* La méthode et l'exemple : ce qu'on lit avant de faire. */
ol.methode { margin: 0; padding-left: 1.2rem; }
ol.methode li { padding: .25rem 0; }
.etape-lecon {
  border-left: 3px solid var(--bleu); background: var(--bleu-clair);
  padding: .6rem .9rem; border-radius: 0 var(--rayon) var(--rayon) 0; margin: .6rem 0;
}
.etape-lecon .qui { font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; color: var(--bleu); }
.etape-lecon p { margin: .25rem 0 0; }
.etape-lecon.resultat { border-color: var(--succes); background: var(--succes-doux); }
.etape-lecon.resultat .qui { color: var(--succes-fonce); }

/* L'objectif de la séance : une phrase, mise en avant sans crier. */
.objectif {
  border-left: 3px solid var(--accent); background: var(--accent-doux);
  padding: .6rem .9rem; border-radius: 0 var(--rayon) var(--rayon) 0; margin: .8rem 0;
}
.objectif .qui { font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; color: var(--accent-fonce); }
.objectif p { margin: .25rem 0 0; }

/* La carte mentale : un centre, des branches. */
.carte-mentale .centre {
  text-align: center; padding: .7rem; border: 2px solid var(--accent);
  border-radius: var(--rayon); background: var(--accent-doux); margin-bottom: .9rem;
}
.carte-mentale .centre strong { display: block; font-size: 1.05rem; }
.carte-mentale .branches { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.carte-mentale .branche {
  border: 1px solid var(--bordure); border-radius: var(--rayon);
  padding: .6rem .8rem; background: var(--fond-doux);
}
.carte-mentale .branche h4 { margin: 0 0 .3rem; font-size: .9rem; color: var(--or); }
.carte-mentale .branche li { padding: .2rem 0; }

/* Le déroulé d'une période : ce qui est fait, ouvert, à venir.
   C'est aussi la porte d'entrée pour revoir une séance passée : celles qui ont
   déjà été enseignées sont des liens, assez hauts pour être touchés du doigt. */
ol.deroule-periode { list-style: none; padding: 0; margin: 0; }
ol.deroule-periode li { border-bottom: 1px solid var(--bordure); }
ol.deroule-periode li > div,
ol.deroule-periode li > a { padding: .45rem 0; }
ol.deroule-periode li { display: flex; align-items: center; gap: .6rem; }
ol.deroule-periode li > a,
ol.deroule-periode li > button,
ol.deroule-periode li > div { flex: 1 1 auto; min-width: 0; }
ol.deroule-periode li:last-child { border-bottom: none; }
/* Le bouton « Dérouler » du compte d'essai, au bout de chaque ligne du déroulé :
   la ligne devient une rangée, et se replie sur un écran étroit. */
body.mode-essai ol.deroule-periode li { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
body.mode-essai ol.deroule-periode li > a,
body.mode-essai ol.deroule-periode li > div { flex: 1 1 14rem; min-width: 0; }
.lancer-essai { flex: 0 0 auto; padding: .25rem .8rem; font-size: .85rem; }

ol.deroule-periode li.fermee { opacity: .55; }
ol.deroule-periode li.faite strong { color: var(--succes-fonce); }
ol.deroule-periode li.du-jour { background: var(--fond-zebre); }
ol.deroule-periode a.revoir,
ol.deroule-periode button.revoir {
  display: flex; gap: .6rem; align-items: center; text-decoration: none;
  color: inherit; border-radius: .4rem; padding-inline: .4rem;
  margin-inline: -.4rem; min-height: 2.6rem;
}
/* La séance qui attend l'élève est un bouton — il la commence — et doit se
   lire comme les autres lignes : ni fond, ni bordure, ni police de bouton. */
ol.deroule-periode button.revoir {
  width: 100%; background: none; border: 0; font: inherit; text-align: left;
  justify-content: space-between; cursor: pointer; padding-block: .45rem;
}
ol.deroule-periode a.revoir:hover,
ol.deroule-periode a.revoir:focus-visible,
ol.deroule-periode button.revoir:hover,
ol.deroule-periode button.revoir:focus-visible { background: var(--fond-doux); text-decoration: none; }
ol.deroule-periode a.revoir span:first-child,
ol.deroule-periode button.revoir span:first-child { text-decoration: underline; text-underline-offset: .18em; }

/* ── L'évaluation épinglée ───────────────────────────────────────────────────
   Côté enseignant, ce qui est épinglé en ce moment ; côté élève, la carte du
   haut avec son compte à rebours. « Épingler une évaluation avec un compte à
   rebours sur une classe. » */
.epingle-actuelle {
  border-left: 4px solid var(--accent); background: var(--fond-doux);
  border-radius: .4rem; padding: .6rem .9rem; margin: .6rem 0 1rem;
}
.epingle-actuelle p { margin: .2rem 0; }
.epingle-actuelle.passee { border-left-color: var(--bordure); opacity: .8; }

.carte.epingle { border-color: var(--accent); border-left-width: 5px; }
.carte.epingle.faite { border-color: var(--succes); }
.epingle-entete { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.epingle-entete .etiquette { margin: 0; }
.compte-a-rebours {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 1.35rem;
  color: var(--accent-fonce); letter-spacing: .02em;
}
.compte-a-rebours.urgent { color: var(--rouge); }
.epingle .mot { font-style: italic; color: var(--texte-doux); }

/* ── Ce qui attend l'enseignant ──────────────────────────────────────────────
   Les signalements des élèves et leurs demandes de reprise, sur place et non
   par courriel. Une ligne encore à voir se distingue d'une ligne classée. */
.liste-notifications { list-style: none; padding: 0; margin: .6rem 0 0; display: grid; gap: .4rem; }
.liste-notifications li {
  display: flex; gap: .8rem; align-items: center; justify-content: space-between;
  flex-wrap: wrap; padding: .5rem .7rem; border-radius: .4rem; border: 1px solid var(--bordure);
}
.liste-notifications li.a-voir { border-color: var(--accent); background: var(--fond-doux); }
.liste-notifications li > div:first-child { flex: 1 1 16rem; min-width: 0; overflow-wrap: anywhere; }

/* ── L'espace enseignant : une barre de pilotage, puis des onglets ──────────
   Huit cartes empilées obligeaient à dérouler toute la page pour atteindre la
   dernière. Un enseignant qui ouvre la plateforme en début d'heure cherche une
   chose précise : les onglets la lui donnent en un clic. */
.barre-pilotage {
  display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap;
  background: var(--fond-carte); border: 1px solid var(--bordure);
  border-radius: var(--rayon); padding: .8rem 1rem; margin-bottom: 1.2rem;
  box-shadow: var(--ombre);
}
/* Un menu déroulant de 1 300 px pour choisir une classe n'a pas de sens : la
   barre s'étire, pas ses champs. */
.barre-pilotage .champ { min-width: 16rem; max-width: 26rem; flex: 0 1 auto; }

.onglets { display: flex; gap: .25rem; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
.champ-sections { display: none; }
.onglet {
  border: 1px solid transparent; background: transparent; color: var(--texte-doux);
  font: inherit; font-weight: 600; cursor: pointer;
  padding: .45rem .8rem; border-radius: var(--rayon);
}
.onglet:hover { background: var(--fond-doux); color: var(--texte); }
.onglet.actif {
  background: var(--marque); border-color: var(--marque); color: var(--sur-marque);
}
.onglet.actif:hover { background: var(--marque-fonce); color: var(--sur-marque); }
/* Ce qui attend l'enseignant, en un nombre à côté du nom de l'onglet
   « Problèmes techniques ». La liste, elle, est dedans. */
.pastille-onglet {
  display: inline-block; margin-left: .4rem; min-width: 1.35rem; height: 1.35rem;
  padding: 0 .4rem; box-sizing: border-box; border-radius: 999px;
  background: var(--accent); color: var(--sur-accent, #fff);
  font-size: .74rem; font-weight: 700; line-height: 1.35rem; text-align: center;
  font-variant-numeric: tabular-nums; vertical-align: middle;
}
.onglet.actif .pastille-onglet { background: var(--sur-marque); color: var(--marque-fonce); }
/* Les trois temps d'une séance revue, toujours sous la main. */
.temps-revus { flex-wrap: wrap; gap: .5rem; margin: .6rem 0 .2rem; }
.temps-revus .bouton { flex: 1 1 10rem; }
.onglet:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 52 rem, et non 640 px : à 768 px — une tablette tenue en portrait, l'écran
   le plus probable dans une salle de classe — les huit onglets s'étalaient sur
   trois rangs et mangeaient le tiers de la page. En dessous de ce seuil, la
   barre passe en colonne et les sections deviennent un menu déroulant. */
@media (max-width: 52rem) {
  /* La barre reste une rangée qui se replie : les deux menus se mettent côte à
     côte tant qu'il y a la place, et l'un sous l'autre en dessous. Passer en
     colonne serait un piège — le `flex-wrap: wrap` hérité autoriserait alors le
     navigateur à créer une seconde colonne, chaque ligne se dimensionnant sur
     son contenu : la barre s'étalait ainsi sur 1 365 px, la largeur des huit
     onglets bout à bout, et poussait toute la page vers la droite. */
  .barre-pilotage .champ { min-width: 0; max-width: none; flex: 1 1 14rem; }
  /* `min-width: 0` n'est pas une coquetterie : sans lui, un conteneur flex en
     `nowrap` prend la largeur de son contenu — les huit onglets bout à bout,
     1 365 px — et pousse la page entière au lieu de défiler. La barre de
     pilotage débordait ainsi de mille pixels sur un téléphone. */
  /* Huit onglets ne tiennent pas sur la largeur d'un téléphone, et une bande
     qui défile cache la moitié des entrées : on passe au menu déroulant, qui
     les montre toutes et se manipule d'un pouce. La bande revient dès qu'il y
     a la place. */
  .onglets { display: none; }
  .champ-sections { display: block; }
}

/* Une animation, si discrète soit-elle, n'a pas à s'imposer à qui a réglé son
   système pour s'en passer. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
      transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* ── La classe d'un coup d'œil ─────────────────────────────────────────── */
.tuiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: .8rem; margin: .6rem 0 1rem; }
.tuile { border: 1px solid var(--bordure); border-radius: var(--rayon); padding: .7rem .9rem; background: var(--fond-carte); }
.tuile-valeur { font-size: 1.9rem; font-weight: 700; line-height: 1.1; letter-spacing: -.01em; }
.tuile-libelle { color: var(--texte-doux); margin-top: .15rem; }
.tuile-detail { color: var(--texte-doux); font-size: .82rem; margin-top: .25rem; }
/* Une tuile qui porte une date, pas un nombre : le corps d'un chiffre la ferait
   passer à la ligne et occuperait la place de trois. */
.tuile.date .tuile-valeur { font-size: 1.15rem; letter-spacing: 0; }
.graphique { margin: 1rem 0; min-width: 0; }
.graphique h3 { font-size: .95rem; margin: 0 0 .4rem; }
.graphiques-deux { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; align-items: start; }
@media (max-width: 800px) { .graphiques-deux { grid-template-columns: 1fr; } }
.graphe { width: 100%; height: auto; display: block; font-family: inherit; }
.graphe .grille { stroke: var(--bordure); stroke-width: 1; }
.graphe .axe { stroke: var(--texte-doux); stroke-width: 1; opacity: .6; }
.graphe .barre { fill: var(--graphe-2); }
.graphe .barre.fragile { fill: var(--graphe-3); }
.graphe .cible { fill: transparent; }
.graphe .marque:hover .barre { filter: brightness(.92); }
.graphe .etiquette-axe { font-size: 12px; fill: var(--texte); }
.graphe .etiquette-axe.discret { fill: var(--texte-doux); font-size: 11px; }
.graphe .valeur { font-size: 12px; fill: var(--texte); font-weight: 600; }
.graphe .valeur-dedans { font-size: 12px; fill: var(--briace-blanc); font-weight: 700; }
.graphe.empilee { height: 22px; }
.graphe .segment.a-jour { fill: var(--graphe-a-jour); }
.graphe .segment.en-retard { fill: var(--graphe-en-retard); }
.graphe .segment.pas-commence { fill: var(--graphe-neutre); }
.graphe .segment.pas-commence + .valeur-dedans, .graphe .marque:has(.segment.pas-commence) .valeur-dedans { fill: var(--texte); }
.legende { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: .4rem; font-size: .88rem; color: var(--texte-doux); }
.legende-item { display: inline-flex; align-items: center; gap: .35rem; }
.legende-pastille { width: .8rem; height: .8rem; border-radius: 3px; display: inline-block; background: var(--graphe-2); }
.legende-pastille.a-jour { background: var(--graphe-a-jour); }
.legende-pastille.en-retard { background: var(--graphe-en-retard); }
.legende-pastille.pas-commence { background: var(--graphe-neutre); }
/* Daltonisme : les états ne reposent pas sur la couleur seule. */
html[data-couleurs="daltonien"] .graphe .segment.en-retard { stroke: var(--texte); stroke-width: 1.5; stroke-dasharray: 4 3; }
html[data-couleurs="daltonien"] .legende-pastille.en-retard { outline: 1.5px dashed var(--texte); outline-offset: -1.5px; }
@media print { .graphe .cible { display: none; } }

/* ── Tournoi ───────────────────────────────────────────────────────────── */
.chrono { font-weight: 700; font-variant-numeric: tabular-nums; }
.groupe-tournoi { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: .6rem 0; border-bottom: 1px solid var(--bordure); }
.groupe-tournoi.mien { background: var(--accent-doux); border-radius: var(--rayon); padding: .6rem .8rem; }
.discussion { max-height: 16rem; overflow-y: auto; display: flex; flex-direction: column; gap: .35rem; padding: .5rem; border: 1px solid var(--bordure); border-radius: var(--rayon); background: var(--fond-doux); margin-bottom: .6rem; }
.bulle { align-self: flex-start; max-width: 85%; background: var(--fond-carte); border: 1px solid var(--bordure); border-radius: var(--rayon); padding: .35rem .6rem; }
.bulle.mienne { align-self: flex-end; background: var(--accent-doux); }
.bulle .qui { display: block; font-size: .78rem; color: var(--texte-doux); font-weight: 600; }
.classement { padding-left: 1.2rem; } .classement li { margin: .35rem 0; } .classement li.mien { background: var(--accent-doux); border-radius: var(--rayon); padding: .3rem .5rem; }
tr.mien td { background: var(--accent-doux); }

/* Le porte-parole : le groupe désigne qui valide sa réponse. Le désigné se
   voit du premier coup d'œil, sans que la couleur seule le dise. */
.porte-parole { margin: .8rem 0; padding: .6rem .8rem; border: 1px dashed var(--bordure); border-radius: var(--rayon); background: var(--fond-doux); }
.porte-parole p { margin: 0 0 .5rem; }
.porte-parole .champs-multiples { flex-wrap: wrap; gap: .5rem; }
.porte-parole-choix.designe { position: relative; padding-left: 2rem; }
.porte-parole-choix.designe::before { content: "\2713"; position: absolute; left: .8rem; font-weight: 700; }
.porte-parole-choix.designe[disabled] { opacity: 1; cursor: default; }

/* Le vote du groupe sur une question à choix : il conseille, il ne décide pas. */
.choix-vote { display: flex; flex-direction: column; gap: .45rem; }
.choix-vote .bouton, .choix-vote button { justify-content: flex-start; text-align: left; width: 100%; }
.choix-vote .compte-voix { color: var(--texte-doux); font-size: .85rem; }
.vote-choix.mien { border-color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); font-weight: 600; }
.choix-vote.reponses { margin-top: .4rem; }
/* Sur un bouton plein, le rappel des voix se lit dans la couleur du bouton. */
.choix-vote.reponses .compte-voix { color: inherit; opacity: .75; }

/* Le réglage du temps d'échange, côté enseignant : − et + de trente secondes. */
.reglage-reflexion { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; margin: .7rem 0; }
.reglage-reflexion .bouton { min-width: 2.75rem; font-size: 1.15rem; line-height: 1; padding: .4rem .6rem; }

/* ── Les avatars et leurs bulles ─────────────────────────────────────────────
   Trois compagnons dessinés en SVG (public/js/avatars.js). La bulle porte une
   phrase, deux au plus : c'est ce qui remplace les paragraphes dans la séance
   pour les élèves qui lisent difficilement. */
.avatar-bulle { display: flex; align-items: flex-start; gap: .8rem; margin: .4rem 0 1rem; }
.avatar { flex: 0 0 auto; line-height: 0; }
.avatar svg { display: block; width: 64px; height: 64px; }
.avatar-bulle .bulle-texte {
  position: relative; flex: 1 1 auto; background: var(--fond-doux); border: 1px solid var(--bordure);
  border-radius: 1rem; padding: .7rem .95rem; font-size: 1.08rem; line-height: 1.45;
}
.avatar-bulle .bulle-texte::before {
  content: ''; position: absolute; left: -9px; top: 22px; width: 14px; height: 14px;
  background: var(--fond-doux); border-left: 1px solid var(--bordure); border-bottom: 1px solid var(--bordure);
  transform: rotate(45deg);
}
.avatar-bulle .bulle-texte p { margin: 0; }
.avatar-bulle.grande .avatar svg { width: 88px; height: 88px; }
@media (max-width: 480px) { .avatar svg { width: 52px; height: 52px; } }

/* ── La leçon allégée ────────────────────────────────────────────────────────
   La méthode en quelques mots, gros et numérotés ; le détail se déplie. */
ol.etapes-courtes { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
ol.etapes-courtes li {
  display: flex; align-items: center; gap: .8rem; padding: .6rem .8rem;
  background: var(--fond-doux); border: 1px solid var(--bordure); border-radius: var(--rayon);
  font-size: 1.15rem; font-weight: 600; line-height: 1.35;
}
ol.etapes-courtes .numero {
  flex: 0 0 2.1rem; height: 2.1rem; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent); color: var(--sur-accent); font-weight: 700;
}
/* Une carte qu'on déplie — les comptes des élèves, l'import d'une liste.
   Sans style, son titre ressemblait à un titre mort : « je vois plus » la liste
   où l'on réinitialise un mot de passe. Le résumé se voit donc comme un bouton,
   avec son chevron, et dit ce qu'il ouvre. */
details.carte > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: .5rem;
  color: var(--accent-fonce); padding: .2rem 0; border-radius: .3rem;
}
details.carte > summary::-webkit-details-marker { display: none; }
details.carte > summary::before {
  content: '▸'; color: var(--accent); font-size: 1.1rem; line-height: 1;
  transition: transform .15s ease; flex: none;
}
details.carte[open] > summary::before { transform: rotate(90deg); }
details.carte > summary:hover,
details.carte > summary:focus-visible { text-decoration: underline; }
details.carte > summary .discret { font-weight: 400; }

/* Une carte repliée : le titre, et un « + » à droite qui devient « − » une fois
   ouverte. « On appuie sur un + pour afficher. » Le chevron des autres cartes
   dépliables ne s'applique pas ici. */
details.carte.repliable > summary { align-items: center; gap: .6rem; color: var(--texte); padding: 0; }
details.carte.repliable > summary::before { content: none; }
details.carte.repliable > summary > h2 { margin: 0; flex: 1 1 auto; }
details.carte.repliable > summary > .sous-titre { font-weight: 400; }
details.carte.repliable > summary > .plus {
  flex: none; width: 1.7rem; height: 1.7rem; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid var(--accent); color: var(--accent); font-weight: 700; font-size: 1.15rem; line-height: 1;
  background: var(--fond-carte);
}
details.carte.repliable > summary > .plus::before { content: '+'; }
details.carte.repliable[open] > summary > .plus::before { content: '−'; }
details.carte.repliable > summary:hover { text-decoration: none; }
details.carte.repliable > summary:hover > .plus,
details.carte.repliable > summary:focus-visible > .plus { background: var(--accent); color: var(--sur-accent); }
details.carte.repliable > .repli-contenu { margin-top: .9rem; }
details.carte.repliable .sous-carte { margin: 0 0 1.2rem; }
details.carte.repliable .sous-carte:last-child { margin-bottom: 0; }
details.carte.repliable .sous-carte > h3 { margin: 0 0 .5rem; }

/* La fenêtre de détail : une erreur, une question, par-dessus la page. */
.voile-fenetre {
  position: fixed; inset: 0; z-index: 70; background: rgba(35, 48, 58, .55);
  display: flex; align-items: flex-start; justify-content: center; padding: 2rem 1rem; overflow-y: auto;
}
.fenetre {
  background: var(--fond-carte); color: var(--texte); border-radius: calc(var(--rayon) * 2);
  width: min(44rem, 100%); max-height: calc(100vh - 4rem); overflow-y: auto;
  box-shadow: 0 1rem 3rem rgba(0,0,0,.3); padding: 1.2rem 1.4rem 1.4rem;
}
.fenetre-entete { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: .8rem; }
.fenetre-entete h2 { margin: 0; font-size: 1.15rem; }
body.fenetre-ouverte { overflow: hidden; }
/* La fiche d'une question revue : l'énoncé, ta réponse, la bonne, la correction. */
.fiche-question + .fiche-question { margin-top: 1.2rem; padding-top: 1.2rem; border-top: 1px solid var(--bordure); }
.fiche-question .enonce, .fiche-question .consigne { margin: .4rem 0; }
.fiche-question .reponses { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: .6rem; margin: .8rem 0; }
.fiche-question .reponses > div { padding: .6rem .8rem; border-radius: var(--rayon); border: 1px solid var(--bordure); background: var(--fond-doux); }
.fiche-question .reponses .qui { display: block; font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--texte-doux); margin-bottom: .2rem; }
.fiche-question .reponses .donnee.fausse { border-color: var(--rouge); }
.fiche-question .reponses .donnee.juste { border-color: var(--succes); }
.fiche-question .figure-revue svg { max-width: 100%; height: auto; }
@media (prefers-reduced-motion: no-preference) { .voile-fenetre { animation: apparaitre .12s ease-out; } }
@keyframes apparaitre { from { opacity: 0; } to { opacity: 1; } }

.details-lecon { margin-top: .8rem; }
.details-lecon > summary { cursor: pointer; font-weight: 600; color: var(--accent); padding: .3rem 0; }
.details-lecon > summary:hover { text-decoration: underline; }
.details-lecon .carte-mentale { margin-top: .8rem; }

/* ── Les étiquettes à remettre dans l'ordre ──────────────────────────────────
   Les étapes d'une technique, mélangées : l'élève les touche dans l'ordre. */
.etiquettes-melangees, .etiquettes-ordre { display: flex; flex-wrap: wrap; gap: .55rem; margin: .6rem 0; }
.etiquettes-ordre { min-height: 3.2rem; padding: .6rem; border: 2px dashed var(--bordure); border-radius: var(--rayon); }
.etiquettes-ordre:empty::before { content: 'Touche les étiquettes dans l’ordre : elles viennent se ranger ici.'; color: var(--texte-doux); font-size: .95rem; }
.etiquette-technique {
  border: 1.5px solid var(--accent); background: var(--fond-carte); color: var(--texte);
  border-radius: 999px; padding: .5rem .9rem; font-size: 1.05rem; font-weight: 600;
  cursor: pointer; display: inline-flex; align-items: center; gap: .5rem; text-align: left;
}
.etiquette-technique:hover { background: var(--accent-doux); }
.etiquette-technique:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.etiquette-technique .rang {
  width: 1.5rem; height: 1.5rem; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent); color: var(--sur-accent); font-size: .85rem; flex: 0 0 auto;
}
.etiquette-technique.juste { border-color: var(--succes); background: var(--succes-doux); }
.etiquette-technique.juste .rang { background: var(--succes); }
.etiquette-technique.fausse { border-color: var(--rouge); background: var(--rouge-clair); }
.etiquette-technique.fausse .rang { background: var(--rouge); }
.etiquette-technique[disabled] { cursor: default; opacity: .9; }

/* ── Où en est l'élève ───────────────────────────────────────────────────────
   Le chapitre et le numéro de la séance, au-dessus du fil, à chacun des trois
   temps : un élève arrivé à l'auto-évaluation ne savait plus quelle séance il
   faisait ni dans quel chapitre. */
.ou-en-est-on { margin: 0 0 .8rem; }
.ou-en-est-on .chapitre {
  margin: 0; font-size: .82rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--accent-fonce);
}
.ou-en-est-on .seance { margin: .15rem 0 0; display: flex; align-items: center; gap: .55rem; flex-wrap: wrap; font-size: 1.12rem; }
.ou-en-est-on .seance .numero {
  flex: 0 0 auto; min-width: 1.9rem; height: 1.9rem; border-radius: 50%;
  display: inline-grid; place-items: center; background: var(--accent);
  color: var(--sur-accent); font-weight: 700; font-size: .95rem;
}
.ou-en-est-on .seance .discret { font-size: .88rem; }
/* Les séances déjà faites, en pastilles, sous le titre : le raccourci que
   l'élève garde sous les yeux pendant qu'il travaille. Le déroulé complet n'est
   que sur l'accueil ; une fois entré dans le rituel, il n'avait plus aucun
   moyen de retourner à la séance 1. Assez grosses pour être touchées du doigt,
   assez discrètes pour ne pas concurrencer la séance en cours. */
.ou-en-est-on .raccourcis-seances {
  margin: .4rem 0 0; display: flex; align-items: center; gap: .35rem;
  flex-wrap: wrap; font-size: .88rem;
}
.ou-en-est-on .pastille-seance {
  min-width: 1.9rem; height: 1.9rem; padding: 0 .4rem; border-radius: 50%;
  display: inline-grid; place-items: center; text-decoration: none;
  border: 1px solid var(--accent); color: var(--accent-fonce);
  background: var(--fond-carte); font-weight: 700; font-size: .85rem;
}
.ou-en-est-on .pastille-seance:hover,
.ou-en-est-on .pastille-seance:focus-visible {
  background: var(--accent); color: var(--sur-accent); text-decoration: none;
}
/* Sur l'écran de révision, la séance qu'on revoit : pleine, comme un onglet ouvert. */
.ou-en-est-on .pastille-seance.active { background: var(--accent); color: var(--sur-accent); }

/* Le nom de la séance sous celui du chapitre, dans la liste des
   auto-évaluations passées : deux séries du même chapitre se distinguent. */
.seance-evaluation { font-size: .92rem; color: var(--accent-fonce); font-weight: 600; }

/* Les auto-évaluations rangées par chapitre : le nom du chapitre ouvre chaque
   groupe, les séances passées se lisent dessous. */
.groupe-chapitre + .groupe-chapitre { margin-top: .9rem; }
.titre-chapitre { margin: 0 0 .3rem; font-size: 1rem; color: var(--accent-fonce); }
.ligne-chapitre th { background: var(--fond-doux, transparent); color: var(--accent-fonce); font-size: .98rem; border-bottom: 2px solid var(--bordure); }

/* ── Signaler un problème ────────────────────────────────────────────────────
   Le bouton reste en retrait, sous l'exercice ou sous la méthode : il ne doit
   pas devenir la sortie de secours du premier exercice difficile. Une fois
   déplié, les motifs sont de vraies cibles pour un doigt. */
.signalement { margin-top: .9rem; border-top: 1px dashed var(--bordure); padding-top: .5rem; }
.signalement .bouton.signaler { font-size: .85rem; color: var(--texte-doux); }
.signalement .bouton.signaler:hover { color: var(--accent-fonce); }
.signalement-formulaire .question { margin: .2rem 0 .5rem; font-weight: 700; }
.signalement-formulaire .motifs { display: flex; flex-wrap: wrap; gap: .5rem; }
.signalement-formulaire .bouton.motif {
  background: var(--fond-doux); color: var(--texte); border: 2px solid var(--bordure);
  font-weight: 500; text-align: left;
}
.signalement-formulaire .bouton.motif:hover { border-color: var(--accent); background: var(--accent-doux); }
.signalement-formulaire .bouton.motif.choisi {
  border-color: var(--accent); background: var(--accent); color: var(--sur-accent);
}
.signalement-formulaire textarea { width: 100%; }

/* ── Les figures des énoncés ─────────────────────────────────────────────────
   Droite graduée, repère du plan : du SVG écrit par la banque, qui suit la
   couleur du texte et se réduit avec la largeur de l'écran. */
.figure {
  display: block; margin: .9rem auto; max-width: 100%; height: auto;
  color: var(--texte); overflow: visible;
}
.enonce .figure { margin-block: 1.1rem; }
/* Le nom d'un point se lit même posé sur une graduation : la lettre est
   entourée du fond de la page, quel que soit le thème. */
.figure text.nom { paint-order: stroke; stroke: var(--fond); stroke-width: 3px; stroke-linejoin: round; }
/* Les scènes des problèmes (generateurs/scenes.js) : un cerf-volant, une
   échelle, un arbre et son ombre. Leurs cotes s'écrivent par-dessus le dessin,
   entourées du fond de la carte où l'énoncé est posé ; une lettre de point,
   du même fond. Comme toute figure, la scène se réduit sur un téléphone
   (.figure : max-width 100 %, hauteur automatique). */
.figure-scene text.etiquette,
.figure-scene text.nom { paint-order: stroke; stroke: var(--fond-carte); stroke-width: 4px; stroke-linejoin: round; }
/* `etiquette` est aussi la classe des pastilles de l'interface (plus haut :
   petites, grises, en demi-gras) : sans cette règle, toutes les cotes d'une
   scène s'écrivaient à .76rem, en gris. Dans le dessin, une cote garde la
   couleur du texte, et la taille et la graisse que ses attributs SVG lui
   donnent (revert-layer rend la main aux attributs font-size, font-weight). */
.figure-scene text.etiquette { color: inherit; font-size: revert-layer; font-weight: revert-layer; }

/* ── À toi de trouver ────────────────────────────────────────────────────────
   La découverte ouvre la leçon : quelques calculs déjà faits, une question, et
   trois phrases parmi lesquelles l'élève reconnaît la règle. Les propositions
   sont de vraies cibles pour un doigt, et se colorent à la réponse. */
.liste-observer { list-style: none; padding: 0; margin: .6rem 0 1rem; display: grid; gap: .4rem; }
.liste-observer li {
  background: var(--fond-doux); border-left: 4px solid var(--accent);
  border-radius: .3rem; padding: .45rem .7rem; font-size: 1.05rem;
}
.question { font-weight: 700; margin: .8rem 0 .6rem; }
.propositions { display: grid; gap: .5rem; }
.propositions .bouton.proposition {
  background: var(--fond-carte); color: var(--texte); border: 2px solid var(--bordure);
  font-weight: 500; text-align: left; white-space: normal;
}
.propositions .bouton.proposition:hover:not([disabled]) { border-color: var(--accent); background: var(--accent-doux); }
.propositions .bouton.proposition.juste { border-color: var(--succes); background: var(--succes-doux); }
.propositions .bouton.proposition.fausse { border-color: var(--rouge); background: var(--rouge-clair); }
.propositions .bouton.proposition[disabled] { opacity: .95; cursor: default; }


/* ── Le permis à points ──────────────────────────────────────────────────────
   Trois boutons par élève, à cliquer pendant l'heure : ils doivent se viser
   d'un doigt sur une tablette, se distinguer les uns des autres au premier
   coup d'œil, et dire ce qu'ils coûtent sans qu'on ait à lire. D'où la pastille
   du nombre de points à gauche du libellé, et la couleur qui ne se déclare
   qu'au survol — un tableau de classe tout rouge se lit comme une sanction
   permanente, ce qu'il n'est pas. */
.retraits { display: flex; gap: .4rem; flex-wrap: wrap; }
.bouton-retrait {
  display: inline-flex; align-items: center; gap: .45rem;
  background: var(--fond-carte); color: var(--texte);
  border: 1px solid var(--bordure); border-radius: 999px;
  padding: .25rem .8rem .25rem .3rem; font-family: inherit; font-size: .86rem; font-weight: 600;
  line-height: 1.2; cursor: pointer; white-space: nowrap;
  transition: background-color .12s ease, border-color .12s ease, transform .06s ease;
}
.bouton-retrait .points {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.7rem; height: 1.7rem; border-radius: 999px;
  background: var(--fond-doux); color: var(--texte-doux);
  font-size: .82rem; font-variant-numeric: tabular-nums;
  transition: background-color .12s ease, color .12s ease;
}
.bouton-retrait:hover:not([disabled]) { border-color: var(--rouge); background: var(--rouge-clair); }
.bouton-retrait:hover:not([disabled]) .points { background: var(--rouge); color: var(--briace-blanc); }
.bouton-retrait:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; box-shadow: var(--halo);
}
.bouton-retrait:active:not([disabled]) { transform: translateY(1px); }
.bouton-retrait[disabled] { opacity: .5; cursor: progress; }

/* Le solde, à gauche des boutons : une pastille qui dit d'un regard où en est
   l'élève — au-dessus de zéro, au-dessous, ou tout juste. */
.solde-permis {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.4rem; padding: .2rem .55rem; border-radius: 999px;
  font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--fond-doux); color: var(--texte-doux);
}
.solde-permis.bon { background: var(--succes-doux); color: var(--succes-fonce); }
.solde-permis.bas { background: var(--rouge-clair); color: var(--rouge); }

/* Les derniers retraits, à annuler d'un clic quand on s'est trompé de ligne. */
.derniers-retraits { list-style: none; padding: 0; margin: .6rem 0 0; display: grid; gap: .35rem; }
.derniers-retraits li {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  background: var(--fond-doux); border-radius: var(--rayon); padding: .4rem .7rem;
  font-size: .88rem;
}
.derniers-retraits li > span:first-child { flex: 1 1 14rem; }

/* Sur une tablette tenue à la main, un tableau à trois colonnes se lit mal et
   se vise encore plus mal : chaque élève devient une fiche, et ses trois
   boutons occupent toute la largeur. C'est là qu'on s'en sert, en classe. */
@media (max-width: 46rem) {
  /* « overflow: visible » sans lever le plafond de hauteur du tableau
     défilant (78vh) : les fiches débordaient de leur carte et recouvraient ce
     qui est dessous — la carte des demandes, Accorder et Refuser compris. */
  .carte-permis .tableau-defilant { overflow: visible; max-height: none; }
  .carte-permis thead { display: none; }
  .carte-permis table, .carte-permis tbody, .carte-permis tr, .carte-permis td { display: block; width: 100%; }
  /* Le tableau en mode fiches n'est plus un tableau : la largeur minimale que
     les tableaux défilants se donnent plus haut (`min-width: max-content`) le
     faisait déborder de la page au lieu de se replier. */
  .carte-permis .tableau-defilant > table { min-width: 0; }
  .carte-permis tr {
    position: relative; border: 1px solid var(--bordure); border-radius: var(--rayon);
    padding: .6rem .7rem; margin-bottom: .5rem; background: var(--fond-carte);
  }
  .carte-permis td { border: none; padding: 0; }
  /* Le nom et son solde sur la même ligne, le solde calé à droite : la place
     qu'il occupe est réservée, pour qu'aucun mot ne passe dessous. */
  .carte-permis td:first-child { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; padding-right: 3.4rem; }
  .carte-permis td:nth-child(2) { position: absolute; top: .55rem; right: .7rem; width: auto; }
  .carte-permis .retraits { margin-top: .5rem; }
  .carte-permis .bouton-retrait { flex: 1 1 100%; justify-content: flex-start; padding-block: .4rem; }
  .derniers-retraits li > span:first-child { flex: 1 1 100%; }
}

/* La classe travaillée : le bandeau de l'élève, et la ligne de l'enseignant. */
.bandeau-classe { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem 1rem; }
.bandeau-classe p { margin: 0; }
.bandeau-classe .barre-actions { margin: 0; }
.classe-travaillee { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .6rem; margin-top: .3rem; }
.ecart-classes { display: grid; gap: .4rem 1.5rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); margin: .4rem 0 .8rem; }
.ecart-classes p { margin: 0 0 .2rem; }
.ecart-classes ul { margin: 0 0 .6rem; padding-left: 1.2rem; }
.ecart-classes .discret { grid-column: 1 / -1; }
/* Les noms des deux listes ne s'affichent pas d'eux-mêmes : le compte se lit,
   les noms s'ouvrent. Le résumé se voit donc comme un bouton, comme la carte. */
.ecart-liste > summary {
  cursor: pointer; list-style: none; color: var(--accent-fonce); padding: .1rem 0;
}
.ecart-liste > summary::-webkit-details-marker { display: none; }
/* Le titre est long — le nom de l'autre classe y tient tout entier — : le
   résumé reste du texte qui se replie ligne à ligne, et le chevron le suit. */
.ecart-liste > summary::before {
  content: '\25b8'; color: var(--accent); display: inline-block; margin-right: .35rem;
  transition: transform .15s ease;
}
.ecart-liste[open] > summary::before { transform: rotate(90deg); }
.ecart-liste > summary:hover,
.ecart-liste > summary:focus-visible { text-decoration: underline; }

/* Les défis entre élèves. */
.liste-defis { list-style: none; padding: 0; margin: 0; }
.defi-ligne { display: flex; align-items: center; justify-content: space-between; gap: .8rem; padding: .6rem 0; border-top: 1px solid var(--bordure); }
.defi-ligne:first-child { border-top: 0; }
.ligne-chrono { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .5rem; }
.chrono.presse { color: var(--rouge); }
/* Pendant une question, le texte ne se sélectionne pas : rien à copier. */
.sans-copie, .sans-copie * { -webkit-user-select: none; user-select: none; }
.sans-copie input { -webkit-user-select: text; user-select: text; }
.corrections-defi { list-style: none; padding: 0; margin: 0; }
.corrections-defi li { padding: .6rem 0 .6rem .8rem; border-left: 4px solid var(--bordure); margin-bottom: .6rem; }
.corrections-defi li.juste { border-left-color: var(--succes); }
.corrections-defi li.faux { border-left-color: var(--rouge); }
.corrections-defi .enonce { margin: .3rem 0; }
.carte.stat.bonus .valeur { color: var(--accent-fonce); }
.champ-case label { display: flex; align-items: center; gap: .5rem; font-weight: 600; }

/* La trace écrite : le lien du chapitre, et l'icône de chaque séance. */
.titre-ligne { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }
ol.deroule-periode li { display: flex; align-items: center; gap: .4rem; }
ol.deroule-periode li > div, ol.deroule-periode li > a.revoir { flex: 1 1 auto; }
.icone-doc { flex: 0 0 auto; text-decoration: none; font-size: 1.05rem; line-height: 1; padding: .3rem .4rem; border-radius: var(--rayon); border: 1px solid var(--bordure); background: var(--fond-carte, white); }
/* L'icône ne s'étire jamais, même sur la ligne du compte d'essai. */
ol.deroule-periode li > a.icone-doc, body.mode-essai ol.deroule-periode li > a.icone-doc { flex: 0 0 auto; padding: .3rem .45rem; min-width: 0; }
h2 .icone-doc { font-size: 1rem; font-weight: 400; }
.icone-doc:hover, .icone-doc:focus-visible { background: var(--accent-doux); text-decoration: none; }

/* Le salon des défis : les joueurs en ligne, leurs points sur l'avatar. */
.salon { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: .8rem; }
.joueur { display: flex; flex-direction: column; align-items: center; gap: .35rem; padding: .7rem .5rem; border: 1px solid var(--bordure); border-radius: var(--rayon); background: var(--fond-carte, white); text-align: center; }
.joueur.moi { border-color: var(--accent); background: var(--accent-doux); }
.joueur.occupe { opacity: .65; }
.joueur .avatar-points { position: relative; display: inline-block; }
.joueur .avatar-points .avatar svg { width: 56px; height: 56px; }
.badge-bonus { position: absolute; right: -.5rem; bottom: -.3rem; min-width: 1.6rem; padding: .1rem .4rem; border-radius: 1rem; background: var(--accent); color: white; font-weight: 700; font-size: .78rem; line-height: 1.3; box-shadow: 0 0 0 2px var(--fond-carte, white); }
.joueur .nom { font-weight: 700; }
.joueur .classe { font-size: .8rem; color: var(--texte-doux); }
.joueur .bouton { padding: .3rem .8rem; font-size: .9rem; }
.invitation { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem; padding: .8rem 1rem; border: 2px solid var(--accent); border-radius: var(--rayon); background: var(--accent-doux); margin-bottom: .8rem; }
.invitation .texte { flex: 1 1 12rem; }
.invitation .barre-actions { margin: 0; }

/* ── L'avatar composé par l'élève (profil, salon, en-tête) ─────────────── */
.navigation a.lien-profil { display: inline-flex; align-items: center; gap: .4rem; }
.navigation a.lien-profil .avatar svg { width: 28px; height: 28px; }
.apercu-avatar { display: flex; justify-content: center; margin: .5rem 0 .3rem; }
.nom-avatar { text-align: center; font-weight: 700; margin: 0 0 1rem; }
.grille-pieces { display: flex; flex-wrap: wrap; gap: .4rem; }
.piece { display: flex; flex-direction: column; align-items: center; gap: .25rem; min-width: 4.6rem; padding: .4rem .3rem; border: 2px solid var(--bordure); border-radius: var(--rayon); background: var(--fond-carte, white); color: inherit; font: inherit; font-size: .75rem; line-height: 1.2; cursor: pointer; }
.piece:hover { border-color: var(--accent); }
.piece.selectionne { border-color: var(--accent); background: var(--accent-doux); font-weight: 700; }
.piece .avatar svg { width: 48px; height: 48px; }
.piece .pastille { display: block; width: 36px; height: 36px; border-radius: 50%; border: 1px solid rgba(0, 0, 0, .15); }
.pieces-avatar { margin-bottom: .8rem; }

/* ── Le pouls des défis dans l'en-tête ─────────────────────────────────── */
.badge-nav { display: inline-block; min-width: 1.5rem; margin-left: .35rem; padding: 0 .4rem; border-radius: 1rem; background: var(--accent); color: white; font-size: .75rem; font-weight: 700; line-height: 1.5rem; text-align: center; vertical-align: middle; }
.badge-nav.vide { background: var(--bordure); color: var(--texte-doux); }
.badge-nav.alerte { background: #c9302c; animation: pouls-alerte 1.2s ease-in-out infinite; }
@keyframes pouls-alerte { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.15); } }
@media (prefers-reduced-motion: reduce) { .badge-nav.alerte { animation: none; } }

/* Une manipulation sur la machine : l'étiquette le dit, elle n'est pas un automatisme. */
.etiquette.niveau.sur-machine { background: var(--accent-doux); color: var(--accent-fonce); border-color: var(--accent); }

/* Le tournoi, côté enseignant : chaque élève avec son bouton de retrait ; et
   côté élève, le tour de rôle du porte-parole, celui de la question marqué. */
.membres-tournoi { display: flex; flex-wrap: wrap; gap: .25rem .6rem; }
.membre-tournoi { display: inline-flex; align-items: center; gap: .2rem; white-space: nowrap; }
.membre-tournoi .retrait { padding: 0 .35rem; line-height: 1.2; font-size: 1rem; }
.tour-de-role { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; padding: 0; margin: .3rem 0 0; counter-reset: tour; }
.tour-de-role li { padding: .2rem .6rem; border: 1px solid var(--bordure); border-radius: 999px; font-size: .9rem; }
.tour-de-role li::before { counter-increment: tour; content: counter(tour) ' · '; color: var(--texte-doux); }
.tour-de-role li.designe { background: var(--accent); color: var(--sur-accent); border-color: var(--accent); font-weight: 700; }
.tour-de-role li.designe::before { color: inherit; }

/* ── La course aux triangles ──────────────────────────────────────────────── */
.course-figure { margin: 0 0 .4rem; }
.numero-figure {
  display: inline-block; padding: .35rem .9rem; border-radius: 999px;
  background: var(--accent, #b5651d); color: #fff; font-weight: 800; font-size: 1.25rem; letter-spacing: .02em;
}
.regles-course ol { margin: .4rem 0 .8rem; padding-left: 1.3rem; }
.regles-course li { margin: .2rem 0; }
.saisie-egalite input { max-width: 16rem; font-size: 1.1rem; letter-spacing: .04em; }
.touches-egalite { display: inline-flex; gap: .3rem; }
.touches-egalite .touche { min-width: 2.4rem; font-size: 1.1rem; font-weight: 700; padding: .3rem .5rem; }
.figure-triangle { max-width: 100%; height: auto; display: block; margin: .3rem auto; }

/* ── Les réponses de l'enseignant aux signalements ────────────────────────── */
.reponses-signalements { margin-bottom: 1rem; }
.reponse-signalement { padding: .5rem 0; border-top: 1px solid var(--bordure); }
.reponse-signalement:first-child { border-top: none; padding-top: 0; }
.reponse-signalement .barre-actions { margin: .3rem 0 0; }
.reponse-au-signalement { margin-top: .5rem; min-width: 14rem; }
.reponse-au-signalement textarea { width: 100%; box-sizing: border-box; margin-top: .25rem; font: inherit; }
.message-eleve .texte-message { white-space: pre-line; margin: .2rem 0 .4rem; }

/* ── La vitrine : la page d'accueil des visiteurs ─────────────────────────── */
.vitrine { display: grid; gap: 2.4rem; }
.vitrine h2 { font-size: 1.45rem; margin: 0 0 1rem; letter-spacing: -.01em; }
.vitrine h3 { font-size: 1.05rem; margin: 0 0 .35rem; }
.vitrine h3 small { font-weight: 400; color: var(--texte-doux); font-size: .85rem; margin-left: .35rem; }
.vitrine p { margin: 0; }
.vitrine-hero {
  padding: 2.6rem 1.6rem 2.2rem; border-radius: calc(var(--rayon) * 1.6); text-align: center;
  background:
    radial-gradient(60rem 22rem at 20% -10%, var(--accent-doux), transparent 60%),
    radial-gradient(40rem 18rem at 100% 0, var(--succes-doux), transparent 55%),
    var(--fond-carte);
  border: 1px solid var(--bordure);
}
.vitrine-hero h1 { font-size: clamp(2.1rem, 5vw, 3.2rem); margin: .3rem 0 .6rem; letter-spacing: -.02em; }
.vitrine-kicker { text-transform: uppercase; letter-spacing: .08em; font-size: .78rem; font-weight: 700; color: var(--accent); }
.vitrine-lead { font-size: 1.15rem; max-width: 40rem; margin: 0 auto 1.4rem; color: var(--texte); }
.vitrine-actions { display: flex; gap: .7rem; justify-content: center; flex-wrap: wrap; margin: 0 0 1rem; }
.bouton.grand { padding: .8rem 1.5rem; font-size: 1.05rem; }
.vitrine-note { color: var(--texte-doux); font-size: .92rem; max-width: 40rem; margin: 0 auto; }
/* Le sommaire de la page : un lien par partie, pour sauter à ce qui intéresse. */
.vitrine-sommaire { display: flex; flex-wrap: wrap; gap: .4rem .5rem; justify-content: center; margin: -.4rem 0 .2rem; }
.vitrine-sommaire a {
  padding: .35rem .8rem; border: 1px solid var(--bordure); border-radius: 999px; text-decoration: none;
  color: var(--texte); background: var(--fond-carte); font-size: .92rem;
}
.vitrine-sommaire a:hover, .vitrine-sommaire a:focus-visible { border-color: var(--marque); color: var(--accent); }
.vitrine-bloc { scroll-margin-top: 5rem; }
.vitrine-grille { display: grid; gap: .9rem; }
.vitrine-grille.trois { grid-template-columns: repeat(3, 1fr); }
.vitrine-grille.deux { grid-template-columns: repeat(2, 1fr); }
.vitrine-carte {
  position: relative; background: var(--fond-carte); border: 1px solid var(--bordure);
  border-radius: var(--rayon); padding: 1.1rem 1.1rem 1.2rem; line-height: 1.5;
}
.vitrine-carte p { color: var(--texte-doux); font-size: .95rem; }
.vitrine-numero {
  display: inline-grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--accent); color: var(--sur-accent); font-weight: 800; margin-bottom: .6rem;
}
.vitrine-liste { margin: 0; padding: 0; list-style: none; display: grid; gap: .6rem; grid-template-columns: repeat(2, 1fr); }
.vitrine-liste li { background: var(--fond-carte); border: 1px solid var(--bordure); border-radius: var(--rayon); padding: .9rem 1rem; line-height: 1.5; }
.vitrine-liste strong { display: block; margin-bottom: .15rem; }
.vitrine-offre {
  background: var(--fond-doux); border: 1px solid var(--bordure); border-radius: calc(var(--rayon) * 1.4);
  padding: 1.6rem; text-align: center;
}
.vitrine-offre p { max-width: 42rem; margin: 0 auto 1.1rem; }
.vitrine-offre .vitrine-actions { margin: 0; }
.vitrine-connexion { scroll-margin-top: 5rem; }
.vitrine-connexion > .carte { max-width: 34rem; margin: 0 auto; }
@media (max-width: 760px) {
  .vitrine { gap: 1.8rem; }
  .vitrine-hero { padding: 1.8rem 1.1rem 1.6rem; }
  .vitrine-grille.trois, .vitrine-grille.deux, .vitrine-liste { grid-template-columns: 1fr; }
  .vitrine-actions .bouton { width: 100%; text-align: center; }
}
.illustration svg, .figure-armoire { display: block; width: 100%; max-width: 40rem; height: auto; margin: .4rem auto .6rem; }

/* ── L'onglet Chapitres ────────────────────────────────────────────────────── */
.chapitres { display: grid; gap: .8rem; }
.chapitres details.chapitre > summary { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem; flex-wrap: wrap; cursor: pointer; }
.chapitres details.chapitre > summary .titre-chapitre { font-size: 1.05rem; }
.chapitres details.chapitre > summary .etiquette { margin-left: .3rem; }
.chapitres .deroule-periode { margin-top: .6rem; }
.ou-en-est-on .lien-chapitres { margin-left: .6rem; white-space: nowrap; }

/* L'évaluation sur feuille : une ligne par notion à cocher, ses réglages à côté. */
.notions-a-evaluer { display: grid; gap: .5rem; margin: .6rem 0 1rem; }
.notion-a-evaluer { border: 1px solid var(--bordure); border-radius: var(--rayon); padding: .5rem .8rem; display: grid; gap: .35rem; }
.notion-a-evaluer .notion-titre { display: flex; align-items: center; gap: .4rem; cursor: pointer; }
.notion-a-evaluer .notion-titre input { width: 1.15rem; height: 1.15rem; }
.notion-reglages { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center; font-size: .92rem; }
.notion-reglages label { display: inline-flex; align-items: center; gap: .4rem; }
.notion-reglages select { max-width: 100%; }

/* Les erreurs rangées par chapitre : un titre de chapitre, puis sa liste. */
.groupe-chapitre { margin: .6rem 0 .2rem; }
.groupe-chapitre h3 { font-size: .95rem; margin: .8rem 0 .3rem; padding-bottom: .2rem; border-bottom: 1px solid var(--bordure); color: var(--accent); }
.groupe-chapitre + .groupe-chapitre { margin-top: 1rem; }
.carte-diagnostic { border-left: 4px solid var(--marque); }
.diagnostic-depart { margin-top: 1rem; border-top: 1px dashed var(--bordure); padding-top: .6rem; }
.diagnostic-depart summary { cursor: pointer; font-weight: 600; }

/* Les réglages d'affichage de la classe : quatre réglages côte à côte quand la place le permet. */
.reglages-affichage { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: .4rem 1.2rem; }
.reglages-affichage .liste-nue li { padding: .3rem 0; }

/* Pas de copie pour les élèves : le texte du site ne se sélectionne pas, les
   champs où l'on écrit restent normaux, et l'impression ne montre rien. */
html.sans-copie body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
html.sans-copie input, html.sans-copie textarea, html.sans-copie select, html.sans-copie [contenteditable="true"] {
  -webkit-user-select: text; user-select: text; -webkit-touch-callout: default;
}
html.sans-copie img, html.sans-copie svg { -webkit-user-drag: none; }
@media print {
  html.sans-copie body > * { display: none !important; }
  html.sans-copie body::after { content: 'L’impression est désactivée sur la Cabane à Maths.'; display: block; padding: 2rem; font: 1.2rem sans-serif; }
}
.avis-copie {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translateX(-50%); z-index: 80;
  padding: .6rem 1rem; border-radius: var(--rayon); background: #23303a; color: #fff; font-weight: 600;
  box-shadow: 0 .4rem 1.2rem rgba(0,0,0,.25);
}

/* Un bandeau système en haut du contenu : une mise à jour prête, un tournoi
   qui commence. Il se lit d'un coup d'œil et ne cache rien. */
.bandeau-systeme {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  box-sizing: border-box; width: min(62rem, 100%) ; margin: .9rem auto 0; padding: .7rem 1.2rem;
  border-radius: var(--rayon); background: var(--accent-doux); border: 1px solid var(--accent);
}
.bandeau-systeme .bouton { margin-left: auto; }
/* Le temps qui reste à une auto-évaluation ouverte pour un temps. */
.chrono-eval {
  font-weight: 700; font-variant-numeric: tabular-nums; font-size: 1.1rem; margin: 0 0 .6rem;
  padding: .4rem .8rem; border-radius: var(--rayon); background: var(--accent-doux); display: inline-block;
}
.chrono-eval.fragile { background: var(--rouge-clair); color: var(--rouge); }

/* La classe en pause : l'écran de l'élève se couvre, jusqu'à la reprise. */
.voile-pause { position: fixed; inset: 0; z-index: 50; background: rgba(35, 48, 58, .92); display: flex; align-items: center; justify-content: center; padding: 1rem; }
.voile-pause-carte { background: var(--fond-carte); color: var(--texte); border-radius: calc(var(--rayon) * 2); padding: 2rem 2.4rem; text-align: center; max-width: 30rem; box-shadow: 0 1rem 3rem rgba(0,0,0,.35); }
.voile-pause-titre { font-size: 2.4rem; font-weight: 800; margin: 0 0 .6rem; color: var(--accent); }
.voile-pause-message { font-size: 1.25rem; margin: 0 0 .8rem; }
.voile-pause-reste { color: var(--texte-doux); margin: 0; font-variant-numeric: tabular-nums; }
/* Qui est là : les élèves pas actifs en évidence, en haut de la classe. */
.presence-liste li { padding: .35rem .6rem; border-left: 4px solid var(--bordure); margin: .25rem 0; }
.presence-eleve.inactif { border-left-color: var(--marque); background: var(--accent-doux); }
.presence-eleve.hors-site { border-left-color: var(--rouge); background: var(--rouge-clair); }
.pause-actions { align-items: flex-end; }
/* Les points de chapitre : sur la carte du chapitre, et en tête de la liste. */
.points-chapitre { margin-left: .4rem; }
.points-de-chapitres { margin: 0 0 .6rem; }
.message.retard { border-color: var(--marque); background: var(--accent-doux); font-weight: 600; }

/* Le thermomètre de difficulté : quatre crans, une boule, à côté de l'étiquette. */
.difficulte { display: inline-flex; align-items: center; gap: .4rem; }
.thermo { display: inline-flex; align-items: center; gap: 0; }
.thermo-tube { display: inline-flex; gap: 2px; padding: 2px; border: 1.5px solid var(--texte-doux); border-radius: 999px 3px 3px 999px; }
.thermo-cran { width: .45rem; height: .55rem; border-radius: 2px; background: var(--bordure); }
.thermo-cran.plein { background: var(--succes); }
.thermo.niveau-2 .thermo-cran.plein { background: var(--or); }
.thermo.niveau-3 .thermo-cran.plein { background: var(--marque); }
.thermo.niveau-4 .thermo-cran.plein { background: var(--rouge); }
.thermo-boule { width: .8rem; height: .8rem; border-radius: 50%; border: 1.5px solid var(--texte-doux); margin-left: -2px; background: var(--fond-carte); }
.thermo.niveau-1 .thermo-boule { background: var(--succes); }
.thermo.niveau-2 .thermo-boule { background: var(--or); }
.thermo.niveau-3 .thermo-boule { background: var(--marque); }
.thermo.niveau-4 .thermo-boule { background: var(--rouge); }
.etiquette.niveau.expert { background: var(--rouge-clair); color: var(--rouge); }

/* ── La bataille navale ─────────────────────────────────────────────────── */
.choix-jeu { display: flex; gap: .4rem; margin: .6rem 0 .8rem; flex-wrap: wrap; }
.choix-jeu .onglet { border: 1px solid var(--bordure); border-radius: 999px; padding: .35rem .9rem; background: transparent; cursor: pointer; font: inherit; }
.choix-jeu .onglet.actif { background: var(--accent, #b5542d); color: #fff; border-color: transparent; }
.champs-navals { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1.2rem; align-items: start; margin: .8rem 0; }
.champ-bloc h3 { margin: 0 0 .4rem; font-size: 1.05rem; }
.champ-naval {
  --cases: 10;
  display: grid; grid-template-columns: 1.6rem repeat(calc(var(--cases) - 1), 1fr); grid-auto-rows: 1fr;
  gap: 1px; background: var(--bordure); border: 1px solid var(--bordure); border-radius: .5rem; overflow: hidden;
  max-width: 24rem; aspect-ratio: 1 / 1; user-select: none; font-variant-numeric: tabular-nums;
}
.champ-naval .graduation { display: grid; place-items: center; font-size: .72rem; color: var(--texte-discret, #6b6b6b); background: var(--fond-carte, #fff); }
.champ-naval .graduation.origine { font-style: italic; }
/* Au sonar : le tir à l'eau garde sa mesure, le carré de la distance. */
.champ-naval .case.mesure .sonar-case { font-size: .62rem; font-weight: 700; color: var(--accent-fonce); letter-spacing: -.02em; }
.tir-naval .encart-sonar { grid-column: 1 / -1; }
.encart-sonar { flex-basis: 100%; padding: .6rem .8rem; margin-bottom: .6rem; border-radius: var(--rayon); background: var(--accent-doux); border: 1px solid var(--accent); }
.encart-sonar p { margin: .2rem 0; }
.encart-sonar .sonar-titre { text-transform: uppercase; letter-spacing: .05em; font-size: .78rem; color: var(--accent-fonce); }
.sonar-decomposition { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; margin: .4rem 0; }
.sonar-decomposition input { width: 3.6rem; }
.sonar-mesures { font-size: .85rem; margin: .4rem 0 0; }
.sonar-mesures li { padding: .1rem 0; }
/* Rectangle ou pas ? Le triangle à juger, ses trois côtés bien lisibles. */
.triangle-a-juger { padding: .7rem 1rem; border-radius: var(--rayon); background: var(--fond-doux); border: 1px solid var(--bordure); margin: .6rem 0; }
.triangle-a-juger p { margin: 0 0 .3rem; }
.triangle-a-juger .cotes { display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.verification-pas-a-pas { margin: .4rem 0; }

/* ── L'arrondi : le nombre à arrondir, et la droite graduée d'une réponse fausse ──
   « Fais un jeu dans défi sur l'arrondi avec une explication visuelle derrière une
   réponse fausse » (public/js/vues/arrondi.js). Le chiffre du rang est souligné, le
   chiffre décisif surligné d'or, les suivants estompés ; sur la droite, le milieu en
   pointillés d'or, le nombre en brique, la flèche et la bonne borne en turquoise, la
   réponse de l'élève en grenat. La forme dit ce que dit la couleur (souligné,
   surligné, pointillés, encadré, ✓ et ✗) : rien ne repose sur la seule teinte.
   Que des variables de la charte : le mode sombre suit. */
.nombre-a-arrondir { display: inline-block; font-size: 2.2rem; font-weight: 700; letter-spacing: .02em; font-variant-numeric: tabular-nums; padding: .1rem .7rem; border-radius: var(--rayon); background: var(--fond-doux); border: 1px solid var(--bordure); }
.explication-arrondi { margin: .8rem 0 .2rem; padding: .8rem 1rem; border-radius: var(--rayon); background: var(--fond-carte); border: 1px solid var(--bordure); border-left: 4px solid var(--succes); }
.explication-arrondi .titre-explication { margin: 0 0 .4rem; }
.explication-arrondi .reponse-arrondi { margin: 0 0 .5rem; font-size: 1.05rem; }
.explication-arrondi .reponse-arrondi .barree { text-decoration: line-through; text-decoration-color: var(--rouge); text-decoration-thickness: 2px; color: var(--texte-doux); }
.explication-arrondi .erreur-arrondi { margin: .4rem 0 .6rem; }
.explication-arrondi .consigne-arrondi { margin: .2rem 0 0; color: var(--texte-doux); font-size: .9rem; }
.chiffres-arrondi { margin: .2rem 0 .3rem; font-size: 2rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.chiffres-arrondi .chiffre { display: inline-block; min-width: 1.15ch; text-align: center; padding: 0 .08em; border-radius: .25em; }
.chiffres-arrondi .chiffre.rang { text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: .18em; text-decoration-color: var(--accent); }
.chiffres-arrondi .chiffre.decisif { background: var(--or-doux); color: var(--or); outline: 2px solid var(--or); }
.chiffres-arrondi .chiffre.apres { opacity: .4; }
.legende-arrondi { display: flex; flex-wrap: wrap; gap: .2rem 1.2rem; margin: 0 0 .4rem; font-size: .92rem; }
.legende-arrondi li { display: flex; align-items: center; gap: .4rem; }
.legende-arrondi .echantillon { display: inline-block; width: 1.1rem; height: .9rem; border-radius: .2rem; }
.legende-arrondi .echantillon.rang { border-bottom: 3px solid var(--accent); }
.legende-arrondi .echantillon.decisif { background: var(--or-doux); outline: 2px solid var(--or); }
.droite-arrondi { display: block; width: 100%; max-width: 40rem; height: auto; margin: .3rem auto .5rem; overflow: visible; font-variant-numeric: tabular-nums; }
.droite-arrondi text { fill: var(--texte); font-size: 20px; font-family: inherit; }
.droite-arrondi .axe { stroke: var(--texte); stroke-width: 2.5; stroke-linecap: round; }
.droite-arrondi .graduation { stroke: var(--texte-doux); stroke-width: 1.5; }
.droite-arrondi .graduation.bout { stroke: var(--texte); stroke-width: 3; }
.droite-arrondi .milieu { stroke: var(--or); stroke-width: 2.5; stroke-dasharray: 5 4; }
.droite-arrondi .etiquette-milieu { fill: var(--or); font-size: 16px; }
.droite-arrondi .borne text { font-weight: 700; font-size: 22px; }
.droite-arrondi .borne.cible rect { fill: var(--succes-doux); stroke: var(--succes); stroke-width: 2; }
.droite-arrondi .borne.cible text { fill: var(--succes-fonce); }
.droite-arrondi .point { fill: var(--accent); stroke: var(--fond-carte); stroke-width: 2.5; }
.droite-arrondi .etiquette-nombre { fill: var(--accent); font-weight: 700; font-size: 22px; }
.droite-arrondi .repere-nombre { stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 2 3; }
.droite-arrondi .fleche { fill: none; stroke: var(--succes); stroke-width: 3; stroke-linecap: round; }
.droite-arrondi .pointe { fill: var(--succes); }
.droite-arrondi .ta-reponse { fill: var(--rouge); font-size: 16px; font-weight: 700; }
.droite-arrondi .etiquette-bonne { fill: var(--succes-fonce); font-size: 16px; font-weight: 700; }
.phrases-arrondi { margin: .2rem 0 0; padding-left: 1.3rem; }
.phrases-arrondi li { margin-bottom: .2rem; }
.explication-repliee { margin: .4rem 0 0; }
.explication-repliee summary { cursor: pointer; color: var(--accent); font-weight: 600; }
/* Sur un téléphone, le dessin se resserre avec l'écran : les chiffres gardent leur taille de lecture. */
@media (max-width: 30rem) {
  .nombre-a-arrondir { font-size: 1.9rem; }
  .explication-arrondi { padding: .6rem .7rem; }
  .chiffres-arrondi { font-size: 1.7rem; }
  .droite-arrondi text { font-size: 24px; }
  .droite-arrondi .borne text, .droite-arrondi .etiquette-nombre { font-size: 26px; }
  .droite-arrondi .etiquette-milieu, .droite-arrondi .ta-reponse, .droite-arrondi .etiquette-bonne { font-size: 20px; }
}
.champ-naval .case { position: relative; display: grid; place-items: center; background: #eef5fb; min-height: 0; font-size: .9rem; }
@media (prefers-color-scheme: dark) { .champ-naval .case { background: #1d2a36; } }
/* Les axes passent par le milieu de la ligne et de la colonne du zéro : un point, pas une case. */
.champ-naval .case.axe-x { background-image: linear-gradient(to bottom, transparent calc(50% - 1px), #334155 calc(50% - 1px), #334155 calc(50% + 1px), transparent calc(50% + 1px)); }
.champ-naval .case.axe-y { background-image: linear-gradient(to right, transparent calc(50% - 1px), #334155 calc(50% - 1px), #334155 calc(50% + 1px), transparent calc(50% + 1px)); }
.champ-naval .case.axe-x.axe-y { background-image: linear-gradient(to bottom, transparent calc(50% - 1px), #334155 calc(50% - 1px), #334155 calc(50% + 1px), transparent calc(50% + 1px)), linear-gradient(to right, transparent calc(50% - 1px), #334155 calc(50% - 1px), #334155 calc(50% + 1px), transparent calc(50% + 1px)); }
.champ-naval.mien .case.navire { background: #8fb3d9; }
.champ-naval.mien .case.navire.coule { background: #6b7280; }
.champ-naval.adverse .case.navire.coule { background: #6b7280; }
.champ-naval .case.eau .rond { color: #6b8db5; font-size: .8rem; }
.champ-naval.adverse .case.touche { background: #f3a712; }
.champ-naval.adverse .case.touche .impact { color: #7a2e0e; font-size: 1rem; }
.champ-naval.adverse .case.touche.coule { background: #e4572e; }
.champ-naval.mien .case.touche { background: #e4572e; }
/* La fumée : trois volutes qui montent de la case touchée chez moi. */
.champ-naval .fumee { position: absolute; inset: 0; pointer-events: none; }
.champ-naval .fumee i { position: absolute; left: 50%; bottom: 20%; width: 45%; height: 45%; border-radius: 50%; background: rgba(120, 120, 120, .85); transform: translateX(-50%); animation: fumee-monte 1.6s ease-out infinite; }
.champ-naval .fumee i:nth-child(2) { animation-delay: .5s; width: 35%; height: 35%; }
.champ-naval .fumee i:nth-child(3) { animation-delay: 1s; width: 55%; height: 55%; }
.champ-naval .case.recent .fumee i { animation-duration: 1.1s; }
@keyframes fumee-monte {
  0% { transform: translate(-50%, 0) scale(.5); opacity: .9; }
  100% { transform: translate(-30%, -90%) scale(1.4); opacity: 0; }
}
.champ-naval .case.recent { animation: case-recente .6s ease-out 2; }
@keyframes case-recente { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.5); } }
/* Les étoiles d'un navire coulé. */
.gerbe-etoiles { position: absolute; left: 50%; top: 50%; width: 0; height: 0; pointer-events: none; z-index: 5; }
.gerbe-etoiles i { position: absolute; left: 0; top: 0; font-style: normal; color: #f3a712; font-size: 1.1rem; text-shadow: 0 0 6px #fff; animation: etoile-jaillit 1.5s ease-out var(--delai, 0ms) forwards; opacity: 0; }
@keyframes etoile-jaillit {
  0% { transform: translate(-50%, -50%) scale(.4); opacity: 1; }
  70% { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.3) rotate(180deg); opacity: 0; }
}
/* Les confettis de la flotte coulée. */
.confettis { position: fixed; inset: 0; pointer-events: none; z-index: 1000; overflow: hidden; }
.confettis i { position: absolute; top: -3vh; left: var(--x); width: var(--taille); height: calc(var(--taille) * 1.6); background: var(--couleur); border-radius: 2px; opacity: 0; animation: confetti-tombe var(--duree) linear var(--delai) forwards; }
@keyframes confetti-tombe {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(106vh) rotate(var(--rot)); opacity: .9; }
}
.felicitations { text-align: center; padding: 1.2rem .6rem; }
.felicitations .mot { font-size: 2.2rem; font-weight: 800; margin: 0; letter-spacing: .02em; }
.felicitations.gagne .mot { color: #b5542d; animation: felicitations-saute .9s ease-in-out 3; }
@keyframes felicitations-saute { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
.felicitations .points { font-size: 1.5rem; font-weight: 700; margin: .3rem 0 .5rem; }
.flotte { list-style: none; padding: 0; margin: .5rem 0 0; font-size: .9rem; }
.flotte li.coule { color: var(--texte-discret, #6b6b6b); text-decoration: line-through; }
.flotte .navire-points { letter-spacing: .05em; color: #e4572e; }
.tir-naval { display: grid; grid-template-columns: auto 5.5rem auto 5.5rem auto; gap: .5rem; align-items: center; margin-top: .8rem; }
.tir-naval label { white-space: nowrap; font-weight: 600; }
.tir-naval input { width: 100%; }
@media (max-width: 520px) { .tir-naval { grid-template-columns: auto 1fr; } .tir-naval .bouton { grid-column: 1 / -1; } }
@media (prefers-reduced-motion: reduce) { .champ-naval .fumee i, .gerbe-etoiles i, .confettis i, .felicitations.gagne .mot, .champ-naval .case.recent { animation: none; opacity: 1; } }

/* ── La course aux triangles à l'écran : la figure flottante ─────────────── */
.figure-course { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; margin: .4rem 0 .8rem; }
.voile-figure { position: fixed; inset: 0; z-index: 60; background: rgba(35, 48, 58, .9); display: flex; align-items: center; justify-content: center; padding: 1rem; animation: voile-figure-entre .25s ease-out; }
@keyframes voile-figure-entre { from { opacity: 0; } to { opacity: 1; } }
.voile-figure-carte { background: var(--fond-carte); color: var(--texte); border-radius: calc(var(--rayon) * 2); padding: 1.2rem 1.6rem 1rem; text-align: center; max-width: 32rem; width: 100%; box-shadow: 0 1rem 3rem rgba(0,0,0,.35); animation: voile-figure-flotte 3s ease-in-out infinite; }
@keyframes voile-figure-flotte { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
.voile-figure-titre { margin: 0 0 .6rem; font-weight: 700; }
.voile-figure-dessin svg { width: min(100%, 24rem); height: auto; }
.voile-figure-reste { font-size: 2rem; font-weight: 800; color: var(--accent); margin: .4rem 0 .6rem; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .voile-figure, .voile-figure-carte { animation: none; } }

/* ── L'escalier de Blondel : la pluri Moasure de 1re AP ──────────────────── */
/* La coupe se lit à l'échelle ; le profil prend la couleur du verdict, et le
   verdict est toujours écrit en toutes lettres à côté. */
.coupe-escalier { display: block; width: 100%; max-width: 46rem; height: auto; margin: .6rem auto; }
.coupe-escalier .massif { fill: var(--fond-doux); stroke: none; }
.coupe-escalier .sol { stroke: var(--texte-doux); stroke-width: 2; }
.coupe-escalier .profil { fill: none; stroke: var(--texte); stroke-width: 3; stroke-linejoin: round; }
.coupe-escalier.confortable .profil { stroke: var(--succes); }
.coupe-escalier.inconfortable .profil { stroke: var(--rouge); }
.coupe-escalier .pente { stroke: var(--texte-doux); stroke-width: 1.5; stroke-dasharray: 6 5; }
.coupe-escalier .cote { stroke: var(--bleu); stroke-width: 1.2; }
.coupe-escalier .pointe { fill: var(--bleu); }
.coupe-escalier .attache { stroke: var(--texte-doux); stroke-width: .8; stroke-dasharray: 3 3; }
.coupe-escalier text { font-family: inherit; font-size: 14px; fill: var(--texte); }
.coupe-escalier .cote-texte.fort { font-weight: 700; fill: var(--bleu); }
.coupe-escalier .repere { fill: var(--texte-doux); font-style: italic; font-size: 13px; }
.coupe-escalier.mini { max-width: 100%; margin: .3rem 0; }
.coupe-escalier.mini .profil { stroke-width: 2.5; }
.bandeau-terrain { font-weight: 600; background: var(--bleu-clair); border-left: 4px solid var(--bleu); padding: .5rem .8rem; border-radius: var(--rayon); margin: 0 0 .8rem; }
.choix-terrain { display: grid; gap: .5rem; margin-bottom: .6rem; }
.option-terrain { display: flex; gap: .6rem; align-items: flex-start; font-weight: 400; cursor: pointer; }
.option-terrain input { width: auto; flex: 0 0 auto; margin-top: .3rem; accent-color: var(--accent); }
.mesures-binome { margin-top: .4rem; }
.erreur-champ { color: var(--rouge); font-weight: 600; margin: .3rem 0 0; }
.erreur-champ:empty { display: none; }
.choix-hauteur { display: grid; gap: .5rem; margin-bottom: .4rem; }
.choix-hauteur > label { font-weight: 600; }
.boutons-hauteur { display: flex; gap: .4rem; flex-wrap: wrap; }
.bouton-hauteur { min-width: 4.6rem; font-size: 1.05rem; padding: .6rem .8rem; }
.bouton-hauteur.actif, .bouton-hauteur.actif:hover { background: var(--accent); color: var(--sur-accent); border-color: var(--accent); }
.choix-hauteur input[type="range"] { width: 100%; max-width: 30rem; accent-color: var(--accent); }
.resultats-escalier { display: grid; gap: .1rem; margin: .4rem 0 .8rem; }
.resultat-ligne { display: grid; grid-template-columns: minmax(10rem, 16rem) 1fr; gap: .6rem; padding: .3rem 0; border-bottom: 1px solid var(--bordure); }
.resultat-ligne dt { color: var(--texte-doux); }
.resultat-ligne dd { margin: 0; }
.verdict-escalier p { margin: 0 0 .3rem; }
.verdict-escalier p:last-child { margin-bottom: 0; }
/* La ligne de la hauteur choisie : en gras, et **un seul** repère, une barre
   devant sa première cellule — une barre par cellule se lisait comme des
   séparateurs de colonnes. (Sur un écran étroit, cette cellule est aussi la
   colonne figée : on garde son filet à droite.) */
.tableau-essais tr.courant > td { font-weight: 600; }
.tableau-essais tr.courant > td:first-child { box-shadow: inset 4px 0 0 var(--accent), 1px 0 0 var(--bordure); }
.tableau-essais tr.ok > td.confort { color: var(--succes-fonce); font-weight: 700; }
.tableau-essais tr.non > td.confort { color: var(--rouge); }
/* « Faites glisser… » : seulement là où le tableau défile (voir la règle des
   tableaux sur un écran étroit, 46rem). */
.indice-defilement { display: none; margin: .3rem 0 0; }
@media (max-width: 46rem) { .indice-defilement { display: block; } }
.tableau-essais tr.cache > td { color: var(--texte-doux); font-style: italic; }
.pas-a-pas-escalier li { margin-bottom: .5rem; line-height: 1.5; }
.mise-en-equation .formule { font-size: 1.2rem; font-weight: 700; text-align: center; margin: .4rem 0; white-space: pre-wrap; }
.fiche-tableur code { font-size: .95rem; background: var(--fond-doux); padding: .1rem .3rem; border-radius: .3rem; white-space: nowrap; }
.citation { font-style: italic; margin: .4rem 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.carte-escalier { border-left: 5px solid var(--marque); }
.bouton.secondaire.danger { color: var(--rouge); border-color: var(--rouge); }
.solutions-escalier td.justification { min-width: 14rem; max-width: 26rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.solutions-escalier tr.ok > td:nth-child(8) { color: var(--succes-fonce); font-weight: 700; }
.solutions-escalier tr.non > td:nth-child(8) { color: var(--rouge); font-weight: 700; }
/* La projection : lisible du fond de la salle, aucun nom. */
.projection-escalier .regle-projection { font-size: 1.2rem; }
.grille-projection { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }
.solution-projetee { background: var(--fond-carte); border: 1px solid var(--bordure); border-top: 6px solid var(--texte-doux); border-radius: var(--rayon); padding: .8rem 1rem; box-shadow: var(--ombre); }
.solution-projetee.ok { border-top-color: var(--succes); }
.solution-projetee.non { border-top-color: var(--rouge); }
/* Une solution calculée sur d'anciennes mesures de la classe : à part, en
   pointillé, hors du décompte — et elle le dit en toutes lettres. */
.solution-projetee.ancienne { border-style: dashed; border-top-style: dashed; opacity: .85; }
.solution-projetee .mesures-anciennes { font-weight: 700; color: var(--rouge); }
.projection-escalier .titre-anciennes { margin: 1.4rem 0 .6rem; font-size: 1.3rem; }
.solutions-escalier tr.ancienne > td:nth-child(2) { color: var(--rouge); font-weight: 700; }
.solution-projetee h2 { margin: 0 0 .3rem; font-size: 1.5rem; }
.solution-projetee p { margin: .25rem 0; }
.solution-projetee .module-projete { font-size: 1.35rem; font-weight: 800; }
.etiquette-verdict { display: inline-block; font-weight: 700; padding: .15rem .6rem; border-radius: 999px; }
.etiquette-verdict.ok { background: var(--succes-doux); color: var(--succes-fonce); }
.etiquette-verdict.non { background: var(--rouge-clair); color: var(--rouge); }
main:fullscreen { background: var(--fond); overflow: auto; padding: 1.5rem; }
@media (max-width: 520px) {
  .resultat-ligne { grid-template-columns: 1fr; gap: 0; }
  .bouton-hauteur { min-width: 0; flex: 1 1 2.8rem; padding: .55rem .2rem; font-size: .95rem; }
}

/* « Où en est chaque élève » : les auto-évaluations regroupées par chapitre, le nom du chapitre en tête de chaque groupe. */
.groupe-autoeval + .groupe-autoeval { margin-top: .45rem; }
.titre-chapitre-eval { font-size: .8rem; font-weight: 700; color: var(--accent-fonce); line-height: 1.25; }
.titre-chapitre-eval.courant::after { content: ' · en cours'; font-weight: 400; color: var(--texte-discret, inherit); }

/* ── La leçon à compléter (3e de mathématiques) ──────────────────────────────
   La règle, les gestes et le résultat de l'exemple s'écrivent au lieu de se lire : des cases à remplir au fil du
   texte, une banque de mots dans le désordre, « Vérifier » et « Voir les réponses ». Une case juste devient verte et
   se verrouille, une case fausse devient rouge ; rien n'est noté. */
.texte-a-trous { line-height: 2.2; }
.regle-a-trous { margin: .5rem 0 .8rem; padding: .5rem .8rem; border-left: 4px solid var(--accent); background: var(--fond-doux); border-radius: 0 var(--rayon) var(--rayon) 0; line-height: 2.2; }
.texte-a-completer { line-height: 2.2; }
.trou-saisie {
  display: inline-block; width: auto; min-width: 4ch; margin: 0 .15em; padding: .1rem .35rem; font: inherit; text-align: center;
  border: 0; border-bottom: 2px solid var(--accent); border-radius: .3rem .3rem 0 0; background: var(--fond-carte, #fff); color: inherit;
}
.trou-saisie:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.trou-saisie.juste { border-bottom-color: var(--succes); background: var(--succes-doux); color: var(--succes-fonce); font-weight: 700; }
.trou-saisie.faux { border-bottom-color: #b3261e; background: #fdecea; color: #7a1a14; }
.trou-saisie.revele { border-bottom-style: dashed; background: var(--fond-doux); color: var(--texte-discret, inherit); font-style: italic; }
.bloc-a-trous { margin-top: .6rem; }
.banque-de-mots { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: .4rem 0 .7rem; padding: .5rem .7rem; border: 1px dashed var(--bordure); border-radius: var(--rayon); }
.banque-de-mots .etiquette-banque { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--texte-discret, inherit); }
.banque-de-mots .mot { font: inherit; font-weight: 600; padding: .2rem .65rem; border: 1px solid var(--accent); border-radius: 999px; background: var(--fond-carte, #fff); color: var(--accent-fonce); cursor: pointer; }
.banque-de-mots .mot:hover, .banque-de-mots .mot:focus-visible { background: var(--accent); color: var(--sur-accent); }
.retour-trous { margin: .5rem 0 0; font-weight: 600; min-height: 1.4em; }

/* Le salon vide : l'ordinateur prend la place d'un camarade. */
.jouer-ordinateur { margin: .8rem 0; padding: .7rem .9rem; border: 1px dashed var(--accent); border-radius: var(--rayon); background: var(--fond-doux); }
.jouer-ordinateur p { margin: 0 0 .5rem; }

/* Bilan et synthèses, chapitre par chapitre : le titre, la réussite et un résumé sur une ligne ; les compétences et les
   erreurs types dépliées en dessous. Le chapitre en cours est ouvert. */
.bilan-chapitres > h3 { font-size: .95rem; margin: 1.2rem 0 .5rem; }
.bilan-chapitre { border: 1px solid var(--bordure); border-left: 4px solid var(--accent); border-radius: var(--rayon); padding: .5rem .8rem; margin: .5rem 0; background: var(--fond-carte); }
.bilan-chapitre > summary { cursor: pointer; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .3rem 1rem; }
.bilan-chapitre-titre { display: inline-flex; align-items: center; gap: .5rem; }
.bilan-chapitre-resume { display: inline-flex; align-items: center; gap: .6rem; min-width: 14rem; }
.bilan-chapitre-resume .jauge { width: 6rem; margin: 0; }
.bilan-chapitre h4 { font-size: .9rem; margin: .8rem 0 .3rem; }
.liste-sous-moyenne { margin: .5rem 0 .2rem; }
.liste-sous-moyenne li { padding: .3rem 0; border-bottom: 1px solid var(--bordure); align-items: center; }
.liste-sous-moyenne li:last-child { border-bottom: none; }
.noms-sous-moyenne { margin: .3rem 0 .6rem; }
.noms-sous-moyenne > summary { cursor: pointer; color: var(--accent-fonce); font-weight: 600; }
/* « Mon travail par chapitre, comparé à ma classe » (Mes progrès) : un chapitre où l'élève est en retard se voit. */
.mes-chapitres li { padding: .5rem .7rem; border-left: 4px solid var(--succes); margin: .4rem 0; background: var(--fond-doux); border-radius: .4rem; }
.mes-chapitres li.en-retard { border-left-color: var(--rouge); }
.mes-chapitres li p { margin: .2rem 0 0; }
/* L'onglet « Rendez-vous parents » de l'enseignant. */
.jours-rdv { border: none; padding: 0; margin: .6rem 0; display: flex; flex-wrap: wrap; gap: .3rem 1rem; }
.jours-rdv legend { font-weight: 600; margin-bottom: .3rem; }
.rdv-prof { padding: .5rem 0; border-bottom: 1px solid var(--bordure); }
.rdv-prof p { margin: .2rem 0 0; }
.rdv-prof.annule strong { text-decoration: line-through; color: var(--texte-doux); }

/* ── Défis : « Le saut du renard », le jeu de plateforme (vues/sautDuRenard.js) ─── */
.visuellement-cache { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.scene-saut {
  position: relative; height: 300px; margin: .8rem 0; border-radius: var(--rayon); overflow: hidden;
  background: linear-gradient(#a9dcf7, #e4f5fd 75%); border: 2px solid var(--bordure); outline-offset: 3px;
  touch-action: manipulation; user-select: none;
}
.scene-saut:focus-visible { outline: 3px solid var(--marque); }
.scene-saut .nuage { position: absolute; background: #fff; border-radius: 999px; opacity: .85; }
.scene-saut .nuage::before, .scene-saut .nuage::after { content: ''; position: absolute; background: #fff; border-radius: 50%; }
.scene-saut .nuage-1 { width: 90px; height: 24px; top: 120px; left: 8%; }
.scene-saut .nuage-1::before { width: 40px; height: 40px; top: -20px; left: 14px; }
.scene-saut .nuage-1::after { width: 30px; height: 30px; top: -14px; left: 46px; }
.scene-saut .nuage-2 { width: 70px; height: 20px; top: 150px; right: 10%; }
.scene-saut .nuage-2::before { width: 32px; height: 32px; top: -16px; left: 12px; }
.scene-saut .nuage-2::after { width: 0; height: 0; }
.rangee-blocs { position: absolute; top: 20px; left: 0; right: 0; display: grid; justify-items: center; gap: .35rem; padding: 0 .4rem; }
.bloc-renard {
  position: relative; width: 100%; max-width: 128px; min-width: 0; min-height: 66px; padding: .9rem .3rem .45rem;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(#ffd24a, #f5b301); color: #1d1d1b; font-weight: 800; font-size: 1.05rem; line-height: 1.2;
  border: 3px solid #a34d05; border-radius: 9px; box-shadow: inset 0 -5px 0 rgba(0, 0, 0, .18), 0 3px 0 #7d3a03;
  cursor: pointer; overflow-wrap: anywhere;
}
.bloc-renard:hover:not(:disabled) { filter: brightness(1.06); }
.bloc-renard:disabled { cursor: default; }
.bloc-renard-numero { position: absolute; top: 2px; left: 6px; font-size: .7rem; opacity: .65; }
.bloc-renard-etiquette { position: relative; z-index: 1; }
.bloc-renard.faux .bloc-renard-etiquette { background: rgba(253, 251, 248, .85); border-radius: 4px; padding: 0 .25rem; color: #1d1d1b; }
.bloc-renard.cogne { animation: bloc-cogne .28s ease-out; }
.bloc-renard.juste { background: linear-gradient(#25a58c, #00705f); color: #fff; border-color: #00483d; }
.bloc-renard.faux { background: linear-gradient(#d9d4cc, #b9b2a8); color: #5b5b58; border-color: #8a8378; }
.bloc-renard.faux::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 46%, #5b5b58 47%, #5b5b58 49%, transparent 50%),
              linear-gradient(65deg, transparent 58%, #5b5b58 59%, #5b5b58 60.5%, transparent 61.5%);
}
.piece-renard {
  position: absolute; left: 50%; top: -6px; width: 26px; height: 26px; margin-left: -13px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff3b0, #f5b301 55%, #a36f00); border: 2px solid #8a6400;
  animation: piece-monte .9s ease-out forwards;
}
.renard-joueur {
  position: absolute; bottom: 46px; width: 64px; transform: translateX(-50%);
  transition: left .35s ease-in-out; display: flex; flex-direction: column; align-items: center; pointer-events: none;
}
.renard-joueur.saute { animation: renard-saute .56s ease-out; }
.renard-tete { position: relative; z-index: 2; line-height: 0; }
.renard-corps { width: 42px; height: 26px; margin-top: -10px; border-radius: 50% 50% 40% 40%; background: #e8740c; box-shadow: inset 0 -8px 0 #fdfbf8; }
.renard-queue { position: absolute; right: -14px; bottom: 16px; width: 28px; height: 13px; border-radius: 0 999px 999px 0; background: linear-gradient(90deg, #e8740c 70%, #fdfbf8 70%); transform: rotate(-24deg); }
.renard-pattes { display: flex; gap: 12px; margin-top: -2px; }
.renard-pattes span { width: 8px; height: 9px; border-radius: 0 0 4px 4px; background: #1d1d1b; }
.sol-saut {
  position: absolute; left: 0; right: 0; bottom: 0; height: 46px;
  background: linear-gradient(#5aa02c 0 9px, #3f7d1c 9px 12px, transparent 12px),
              repeating-linear-gradient(90deg, #a0522d 0 38px, #7d3f1f 38px 40px);
}
@keyframes renard-saute {
  0% { transform: translate(-50%, 0); }
  45% { transform: translate(-50%, -86px); }
  100% { transform: translate(-50%, 0); }
}
@keyframes bloc-cogne { 0% { transform: translateY(0); } 40% { transform: translateY(-10px); } 100% { transform: translateY(0); } }
@keyframes piece-monte { 0% { transform: translateY(0) scale(.6); opacity: 0; } 30% { opacity: 1; } 100% { transform: translateY(-58px) scale(1); opacity: 0; } }
@media (max-width: 520px) {
  .scene-saut { height: 280px; }
  .bloc-renard { font-size: .92rem; min-height: 60px; }
}
@media (prefers-reduced-motion: reduce) {
  .renard-joueur { transition: none; }
  .renard-joueur.saute, .bloc-renard.cogne, .piece-renard { animation: none; }
  .piece-renard { opacity: 1; transform: translateY(-30px); }
}
@media (prefers-color-scheme: dark) {
  .scene-saut { background: linear-gradient(#1b3a52, #2a4d66 75%); }
  .scene-saut .nuage, .scene-saut .nuage::before, .scene-saut .nuage::after { background: #c9d6df; opacity: .35; }
}

/* ── Défis : « La chasse au trésor » (contenus/tresor.js, vues/tresor.js) ────────── */
.enonce-tresor { display: grid; gap: .6rem; }
.enonce-tresor .carte-tresor, .carte-tresor-cadre .carte-tresor { display: block; width: 100%; max-width: 460px; height: auto; margin: 0 auto; border-radius: 10px; box-shadow: 0 1px 0 var(--bordure); }
.enonce-tresor p { margin: 0; }
.carte-tresor .lieu.atteint circle { fill: #fdf3d9; stroke: #a34d05; }
.carte-tresor .heros { transition: transform .4s ease; }
.explication-tresor { margin: .8rem 0; padding: .7rem .8rem; border: 2px solid var(--succes); border-radius: var(--rayon); background: var(--fond-carte); display: grid; gap: .5rem; }
.explication-tresor-titre { margin: 0; }
.explication-tresor-titre s { color: var(--rouge); }
.explication-tresor-erreur { margin: 0; padding: .45rem .65rem; border-radius: 8px; background: var(--or-doux); color: var(--texte); }
.explication-tresor-calcul { margin: 0; padding-left: 1.3rem; display: grid; gap: .25rem; }
@media (prefers-color-scheme: dark) {
  .enonce-tresor .carte-tresor, .carte-tresor-cadre .carte-tresor { filter: brightness(.92); }
}
