/* ============================================================
   app.css — mobile d'abord.

   Le modèle : une chose par écran, un seul bouton, toujours au
   même endroit en bas. Le reste de la page ne sert qu'à porter
   le contenu. Cibles tactiles ≥ 44 px, thème clair et sombre.

   UNE seule police est téléchargée — Fraunces, 34,7 Ko, pour les
   titres. Tout le reste, et surtout tout ce qui porte un chiffre,
   reste en police système : voir le bloc « LA POLICE DES TITRES ».
   ============================================================ */

/* ============================================================
   LA POLICE DES TITRES — Fraunces 700, sous-ensemble latin.

   Hébergée ici, jamais chez Google : l'app doit se charger hors ligne,
   et une requête vers fonts.gstatic.com casserait la première visite
   d'un élève sans réseau. Le fichier est dans la coquille du service
   worker, au même titre que le CSS.

   34,7 Ko pour une graisse. La version variable 700–900 en coûtait
   65,7 : le double, pour des graisses que l'app n'utilise pas.

   LA RÈGLE, et elle n'a pas d'exception : Fraunces ne touche jamais un
   texte qui peut contenir un CHIFFRE. Ses chiffres sont à fort
   contraste et sa virgule est fine — sur « 0,75 » à 15 px, c'est un
   handicap, et cette app est une app de maths. Énoncés, champs de
   saisie, figures et jetons restent donc en police système.

   `swap` : le texte s'affiche immédiatement en police système, puis
   bascule. Sur une connexion lente, mieux vaut un titre lisible tout
   de suite qu'un titre absent pendant trois secondes.
   ============================================================ */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../polices/fraunces-700-latin.woff2') format('woff2');
  /* Latin de base + ponctuation : couvre les accents français, l'Œ de
     « Œil de lynx », l'espace fine insécable des milliers (U+202F) et le
     signe moins U+2212 des nombres relatifs. */
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
                 U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191,
                 U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ============================================================
     Charte Sankofa — cinq couleurs, plus deux couleurs de statut.
     Déduite du logo : le bois du tambour, la peau, l'ocre du bandeau.

     Tout est écrit en hexadécimal, jamais en color-mix() ni oklch() :
     un WebView Android ancien — la cible du projet — ne les connaît pas,
     et une valeur invalide fait retomber la propriété sur son initiale.
     Les nuances sont donc calculées ici une fois pour toutes.
     ============================================================ */

  --terre: #A65128;         /* principale : titres, objets manipulés, AVANCEMENT */
  --terre-clair: #F1E2D4;   /* la même, posée à 12 % sur le sable */
  --ocre: #E19A2E;          /* action : le bouton qu'on déclenche, et lui seul */
  --ocre-clair: #F7E7CE;
  --peau: #F3E0BC;          /* cartes, encadrés de leçon, zones de saisie */
  --sable: #FBF5EA;         /* fond général, moins fatigant que le blanc */
  --brun: #3A2418;          /* texte et icônes. Jamais de noir pur. */

  --juste: #297646;         /* bonne réponse — nulle part ailleurs */
  --juste-fond: #E2ECD9;
  --faux: #BA3519;          /* erreur — nulle part ailleurs */
  --faux-fond: #F6E0D3;

  /* rôles d'interface, tirés des cinq ci-dessus */
  --fond: var(--sable);
  --fond2: var(--peau);
  --carte: #FFFCF4;
  /* la carte d’un chapitre commencé : un souffle de terre, pas un cadre.
     Elle reste PLUS CLAIRE que le fond sable, sinon elle cesserait de
     se lire comme une surface posée dessus. */
  --carte-entamee: #FFF8EF;
  --texte: var(--brun);
  --doux: #8A694E;

  /* DEUX traits, pas un.
     `--ligne` borde sans séparer : elle est à un cheveu du fond (1,13:1),
     et c'est l'ombre qui détache la surface. `--ligne-nette` sert là où le
     trait porte le sens — le contour d'un champ à remplir, d'une option à
     choisir — et doit rester lisible en plein soleil. */
  --ligne: #F2E7D2;
  --ligne-nette: #E7D6B4;

  /* L'ombre : deux couches, une courte et dense pour le contact, une large
     et diluée pour la profondeur. Teintée en BRUN — une ombre noire sur du
     sable vire au gris et salit toute la charte. */
  --ombre: 0 1px 1px rgba(58, 36, 24, .045), 0 2px 6px rgba(58, 36, 24, .055);

  --plein: var(--ocre);     /* le bouton principal est ocre, pas noir */
  --plein-texte: var(--brun);
  --inerte: #EEE1CB;
  --inerte-texte: #AC9880;

  /* L'avancement se remplit en TERRE, pas en ocre.
     Mesuré : l'ocre ne contraste qu'à 1,84:1 avec son rail — invisible en
     plein soleil, invisible pour un daltonien. Aucun ocre ne dépasse 2,6.
     La terre atteint 4,25:1. D'où le partage : l'ocre est l'action qu'on
     déclenche, la terre est l'avancement qu'on a acquis. */
  --progres: var(--terre);


  /* ============================================================
     L'ÉCHELLE — dix pas, pas vingt-quatre.

     Chaque pas porte un rôle, pas un chiffre : on choisit « le texte
     secondaire d'une carte », jamais « 13,5 px ». C'est ce qui empêche
     la prochaine règle d'inventer un vingt-cinquième corps.

     Les figures gardent leurs tailles propres : elles sont calées sur
     la géométrie de chaque dessin, pas sur le rythme du texte.
     ============================================================ */
  --t-xs:   11.5px;   /* étiquettes capitales, numéro sur la vignette */
  --t-sm:   12.5px;   /* jetons, mentions, pied de page */
  --t-base: 13.5px;   /* texte secondaire des cartes */
  --t-md:   15px;     /* consignes, corps secondaire */
  --t-lg:   17px;     /* corps courant, titres de carte, options */
  --t-xl:   19px;     /* titres de section */
  --t-2xl:  21px;     /* énoncés, champs de saisie */
  --t-3xl:  24px;     /* grands nombres d'interface */
  --t-4xl:  30px;     /* titre de leçon */
  --t-5xl:  34px;     /* XP de bilan, hors-série */
  /* Le repli est complet : si les 34,7 Ko n'arrivent jamais — réseau
     coupé au premier chargement, WebView qui refuse woff2 — les titres
     s'affichent en serif du système, puis en sans-serif. Rien ne casse,
     l'app change seulement de voix. */
  --police-titre: 'Fraunces', 'Iowan Old Style', Georgia, 'Times New Roman', serif;

  --r: 16px;
  --bas: calc(96px + env(safe-area-inset-bottom, 0px));
}

/* Trois états, pas deux. Le réglage du système donne `prefers-color-scheme`
   et ne pose rien sur la racine ; un choix explicite de l'utilisateur pose
   `data-theme`. Le sombre s'applique donc dans deux cas — préférence système
   NON contredite par un choix clair, ou choix sombre explicite — et les deux
   listes de valeurs doivent rester identiques.

   L'app n'a pas encore de bouton de thème : ces règles sont inertes ici, et
   c'est voulu. Elles servent dès que la page est ouverte dans un contexte qui
   impose un thème (une page partagée, un lecteur intégré), et elles seront
   déjà en place le jour où le bouton arrive. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* le fond brun profond est l'un des quatre fonds validés par la charte.
       « Sur l'ocre et sur le brun, le bois s'éclaircit d'un cran. » */
    --terre: #D97C4A;
    --terre-clair: #4A2E20;
    --ocre-clair: #4A3620;
    --juste: #54B978;
    --juste-fond: #26361F;
    --faux: #EA7151;
    --faux-fond: #47231A;

    --fond: #2E1C12;
    --fond2: #4A3122;
    --carte: #3F2A1C;
    --carte-entamee: #47311F;
    --texte: var(--sable);
    --doux: #BCA48C;
    --ligne: #4A3222;
    --ligne-nette: #6B4B33;

    /* Sur fond sombre une ombre ne porte presque pas : la surface se
       détache surtout parce qu'elle est plus claire que le fond. Une
       couche unique, un peu plus dense, marque le contact. */
    --ombre: 0 1px 2px rgba(0, 0, 0, .30);

    --plein-texte: #2E1C12;
    --inerte: #4A3324;
    --inerte-texte: #94795F;
  }
}

/* Le choix explicite l'emporte sur la préférence système, dans les deux sens :
   sombre demandé sur un système clair (ici), clair demandé sur un système
   sombre (le `:not([data-theme="light"])` ci-dessus). Mêmes valeurs — toute
   modification se fait dans les deux blocs. */
:root[data-theme="dark"] {
  --terre: #D97C4A;
  --terre-clair: #4A2E20;
  --ocre-clair: #4A3620;
  --juste: #54B978;
  --juste-fond: #26361F;
  --faux: #EA7151;
  --faux-fond: #47231A;

  --fond: #2E1C12;
  --fond2: #4A3122;
  --carte: #3F2A1C;
  --carte-entamee: #47311F;
  --texte: var(--sable);
  --doux: #BCA48C;
  --ligne: #4A3222;
  --ligne-nette: #6B4B33;

  /* Sur fond sombre une ombre ne porte presque pas : la surface se
     détache surtout parce qu'elle est plus claire que le fond. Une
     couche unique, un peu plus dense, marque le contact. */
  --ombre: 0 1px 2px rgba(0, 0, 0, .30);

  --plein-texte: #2E1C12;
  --inerte: #4A3324;
  --inerte-texte: #94795F;
}

* { box-sizing: border-box; }

/* ============================================================
   L'ANNEAU DE FOCUS — un seul, partout.

   Il n'existait que cinq règles `:focus-visible` pour une vingtaine de
   types d'éléments cliquables : au clavier, on avançait à l'aveugle sur
   les boutons de chapitre, les touches du pavé, la croix de sortie, les
   modules repliables. Une seule règle, posée sur tout ce qui se focalise,
   règle le problème pour de bon — et pour tout ce qu'on ajoutera ensuite.

   `:focus-visible` et non `:focus` : le navigateur ne montre l'anneau que
   lorsqu'il vient du clavier, jamais après un tap. Le décalage de 2 px et
   l'ombre portée du fond garantissent qu'il reste lisible même posé sur
   une bordure de la même famille de couleur. */
:focus-visible {
  outline: 3px solid var(--terre);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Les surfaces à grand rayon gardent leur arrondi, sinon l'anneau coupe
   les angles de la carte qu'il entoure. */
.chapitre:focus-visible, .encart:focus-visible, .tuile:focus-visible,
.opt:focus-visible, .btn:focus-visible {
  border-radius: var(--r);
  outline-offset: 3px;
}

/* Sur fond ocre — le bouton principal — la terre se distingue mal : on
   passe au brun, qui contraste avec les deux. */
.btn:not(.btn--fantome):not(.btn--doux):focus-visible { outline-color: var(--brun); }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 400 var(--t-lg)/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: contain;
}

/* UN SOUFFLE D'OCRE SOUS LA BARRE (22/09/2026). Le sable est un fond
   reposant ; sur toute la hauteur d'un écran, c'est un mur. Un halo
   très pâle, posé une seule fois en haut de page et qui ne se répète
   pas, suffit à donner un sens de lecture — on sait d'où la page
   commence. Il vit sur `body` et non sur `.app` pour couvrir toute la
   largeur, et il reste sous la barre, qui est opaque. */
body::before {
  content: '';
  position: fixed;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 760px;
  max-width: 180vw;
  height: 420px;
  background: radial-gradient(60% 100% at 50% 0%,
    rgba(225, 154, 46, .16) 0%, rgba(225, 154, 46, 0) 72%);
  pointer-events: none;
  /* DERRIÈRE TOUT, et c'est ce qui règle le cas de la vitrine sans une
     ligne de plus : son héros est un aplat opaque de brun, il recouvre
     donc le halo au lieu de s'y superposer. Un z-index positif aurait
     peint la lueur PAR-DESSUS le héros. */
  z-index: -1;
}

.app {
  max-width: 560px;
  margin: 0 auto;
  padding: 0 20px var(--bas);
}

b, strong { font-weight: 700; }

/* Un vecteur, AB⃗ : la flèche est dessinée sur toute la largeur du nom —
   un trait, puis une pointe — au lieu de la flèche combinante U+20D7 que
   beaucoup de téléphones placent mal (defis.js, vecteurs()). */
.vecteur {
  position: relative;
  display: inline-block;
  padding-top: 0.34em;
  line-height: 1.05;
  white-space: nowrap;
  /* u⃗, i⃗ : une seule lettre étroite, la flèche garde une vraie longueur. */
  min-width: 0.66em;
  text-align: center;
}
.vecteur::before {
  content: "";
  position: absolute;
  left: 0.04em;
  right: 0.16em;
  top: 0.13em;
  border-top: 0.085em solid currentColor;
}
.vecteur::after {
  content: "";
  position: absolute;
  right: 0.02em;
  top: 0.035em;
  border-left: 0.26em solid currentColor;
  border-top: 0.135em solid transparent;
  border-bottom: 0.135em solid transparent;
}

.souligne {
  background: var(--ocre-clair);
  color: var(--terre);
  border-radius: 6px;
  padding: 0 5px;
  font-weight: 700;
}

code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  background: var(--fond2);
  border-radius: 6px;
  padding: 2px 6px;
}

/* ============================================================
   1. LES DEUX BARRES DU HAUT
   ============================================================ */

/* hors parcours : mascotte / retour, titre, jetons */
/* ============================================================
   LA BARRE — sombre depuis le 22/09/2026

   Elle était un ruban de sable sur un fond de sable : présente dans le
   balisage, invisible à l'œil. Un écran qui commence par rien donne
   l'impression que rien ne commence — c'est ce que Marc appelait « trop
   platonique ».

   Elle reprend donc le brun du héros de la vitrine. Deux gains, et
   aucun coût : l'application se tient enfin sous un bandeau qui la
   nomme, et la barre est la MÊME d'un bout à l'autre — vitrine, entrée,
   chapitres, leçon — parce que les trois coquilles partagent cette
   règle. Ses couleurs sont écrites en dur pour la même raison que le
   héros : elle est sombre dans les deux thèmes, et un jeton qui
   s'inverse l'aurait éclaircie sur une page déjà claire.

   LE DÉBORD. La barre vit dans `.app`, qui est une colonne de 560 px
   avec 20 px de marge intérieure. Un fond posé là s'arrêterait au bord
   de la colonne et laisserait deux bandes claires sur un écran large.
   On l'étale donc par une ombre portée horizontale — `box-shadow` avec
   un étalement de 50vw — plutôt qu'avec une largeur en `100vw`, qui
   aurait débordé de la largeur de l'ascenseur.
   ============================================================ */

.barre {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  margin: 0 -16px 14px;
  position: sticky;
  top: 0;
  background: #2E1C12;
  /* LA BARRE SAIGNE JUSQU'AUX BORDS, À TOUTE LARGEUR.

     Elle le faisait par deux ombres décalées de 50vw — et une ombre
     décalée peint une COPIE de la barre, non une bande infinie. Sur un
     téléphone, la barre occupe presque toute la largeur : la copie
     recouvrait le bord, et l'illusion tenait. Sur un écran large, où la
     colonne de lecture ne fait que 740 px, la copie atterrissait
     320 px plus loin que le bord de la barre et laissait deux bandes
     de sable en plein milieu du bandeau sombre : la barre paraissait
     coupée en trois.

     Une ombre à ÉTALEMENT, elle, grandit dans toutes les directions et
     ne dépend d'aucune largeur. On la découpe ensuite verticalement au
     ras de la barre — le `clip-path` garde les 100vw de gauche et de
     droite, et coupe le haut et le bas. Il empêche du même coup le
     débordement de créer une barre de défilement horizontale. */
  box-shadow: 0 0 0 100vw #2E1C12;
  clip-path: inset(0 -100vw);
  z-index: 5;
}

.barre__retour {
  width: 40px; height: 40px;
  flex: none;
  border: 1px solid rgba(243, 224, 188, .22);
  border-radius: 12px;
  background: rgba(243, 224, 188, .08);
  color: #F3E0BC;
  font-size: var(--t-3xl);
  line-height: 1;
  cursor: pointer;
}
.barre__retour:hover { background: rgba(243, 224, 188, .16); }

.barre__titre {
  font-family: var(--police-titre);
  color: #FBF5EA;
  flex: 1;
  min-width: 0;
  font-weight: 700;
  font-size: var(--t-lg);
  letter-spacing: -.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La ligne secondaire de la barre redescend en police système : à 12,5 px,
   le serif s'épaissit et le sous-titre se met à peser autant que le titre
   qu'il accompagne. */
.barre__titre small {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  display: block;
  font-weight: 400;
  font-size: var(--t-sm);
  color: #B79B7C;
  overflow: hidden;
  text-overflow: ellipsis;
}

.jetons { display: flex; gap: 6px; flex: none; }

.jeton {
  font-size: var(--t-sm);
  font-weight: 700;
  padding: 6px 10px;
  border-radius: 999px;
  background: var(--fond2);
  color: var(--doux);
  white-space: nowrap;
}

.jeton--xp { color: var(--terre); background: var(--ocre-clair); }

/* dans un parcours : croix, jauge segmentée, XP — rien d'autre */
.entete-parcours {
  display: flex;
  align-items: center;
  /* 9 px et non 12 : l'entête porte maintenant cinq éléments — sortie,
     deux pas de navigation, jauge, XP — et sur 390 px de large la jauge
     doit garder de quoi montrer ses segments. */
  gap: 9px;
  padding: 12px 0 18px;
  position: sticky;
  top: 0;
  background: var(--fond);
  z-index: 5;
}

.croix {
  width: 36px; height: 36px;
  flex: none;
  border: 0;
  background: none;
  color: var(--doux);
  font-size: var(--t-2xl);
  cursor: pointer;
}

/* Les deux pas de navigation libre, dans l'entête du parcours.
   Discrets par défaut — ils ne doivent jamais concurrencer le bouton du
   bas, qui reste le seul geste pour avancer pour de bon — et franchement
   éteints quand ils ne mènent nulle part, plutôt que masqués : une flèche
   qui apparaît et disparaît déplace la jauge à chaque écran. */
.nav-pas {
  width: 34px; height: 34px;
  flex: none;
  border: 0;
  border-radius: 10px;
  background: var(--fond2);
  color: var(--terre);
  font-size: var(--t-xl);
  line-height: 1;
  cursor: pointer;
}

.nav-pas:disabled { background: none; color: var(--inerte); cursor: default; }
.nav-pas:not(:disabled):active { transform: translateY(1px); }

.jauge {
  flex: 1;
  display: flex;
  gap: 4px;
  min-width: 0;
}

.jauge span {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: var(--inerte);
  transition: background .25s ease-out;
}

.jauge span.fait { background: var(--progres); }
.jauge span.ici  { background: linear-gradient(90deg, var(--progres) 45%, var(--inerte) 45%); }

.mascotte { width: 36px; height: 36px; flex: none; display: block; }
.mascotte--grande { width: 116px; height: 116px; margin: 0 auto 14px; }

/* ============================================================
   2. LA SCÈNE
   ============================================================ */

.scene { padding: 4px 0 8px; }
.scene--intro, .scene--carte { padding-top: 12px; }

.titre-geant {
  font-family: var(--police-titre);
  font-size: var(--t-4xl);
  line-height: 1.18;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 16px;
}

.scene--intro .titre-geant,
.badge-neuf .titre-geant,
.bilan .titre-geant { text-align: center; }

/* le corps d'une carte de leçon : c'est le seul endroit où l'élève lit */
.corps { font-size: var(--t-xl); }
.corps p { margin: 0 0 14px; }
.corps p:last-child { margin-bottom: 0; }

.retenir {
  margin-top: 20px;
  padding: 16px 18px;
  border-radius: var(--r);
  background: var(--ocre-clair);
  border: 1px solid #E9C98F;
}

.retenir__t {
  font-size: var(--t-sm);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--terre);
  margin-bottom: 6px;
}

.retenir p { margin: 0; }

/* Le fil du « pourquoi » : deux temps, l'acquis puis le mur. La barre à
   gauche les tient ensemble et les distingue de l'accroche qui suit. */
.fil {
  border-left: 3px solid var(--ocre);
  padding: 2px 0 2px 14px;
  margin-bottom: 16px;
}
.fil p { margin: 0; font-size: var(--t-md); line-height: 1.45; }
.fil__acquis { color: var(--doux); }
.fil__mur { color: var(--texte); margin-top: 6px !important; }
.fil b { color: var(--terre); }

/* L’accroche RESTE en police système : mesuré, 37 % d’entre elles
   portent des chiffres — un prix, une population, une quantité — contre
   2 % des titres. C’est exactement la frontière posée plus haut. */
.accroche {
  font-size: var(--t-xl);
  color: var(--texte);
  background: var(--fond2);
  border-radius: var(--r);
  padding: 16px 18px;
  margin-bottom: 16px;
}

.enonce { font-size: var(--t-2xl); font-weight: 700; line-height: 1.35; margin: 2px 0 18px; }

.consigne { color: var(--doux); font-size: var(--t-md); margin: 0 0 16px; }

.type-tag {
  display: inline-block;
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--doux);
  margin-bottom: 12px;
}

.scene--intro .type-tag { display: block; text-align: center; }

/* ============================================================
   3. LA BARRE DU BAS ET LA FEUILLE DE RETOUR
   ============================================================ */

.pied-action {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 20;
  background: var(--fond);
  border-top: 1px solid var(--ligne);
  padding: 14px 20px calc(14px + env(safe-area-inset-bottom, 0px));
}

.pied-action > .btn,
.feuille__b { max-width: 520px; margin-left: auto; margin-right: auto; }

.btn {
  display: block;
  width: 100%;
  min-height: 54px;
  padding: 15px 20px;
  border: 0;
  border-radius: 999px;
  background: var(--plein);
  color: var(--plein-texte);
  font: 700 var(--t-lg)/1.2 inherit;
  cursor: pointer;
}

.btn:disabled { background: var(--inerte); color: var(--inerte-texte); cursor: default; }
.btn:not(:disabled):active { transform: translateY(1px); }

.btn--fantome {
  background: none;
  color: var(--doux);
  border: 2px solid var(--ligne-nette);
  min-height: 50px;
}

.btn--doux {
  background: var(--terre-clair);
  color: var(--terre);
  border: 2px solid #D9AE95;
}

.actions { margin-top: 18px; display: grid; gap: 10px; }

/* la feuille : elle prend la place de la barre pour porter le verdict */
.feuille { animation: monte .18s ease-out; }

@keyframes monte { from { transform: translateY(14px); opacity: .4; } }

.feuille--juste { background: var(--juste-fond); border-top-color: transparent; }
.feuille--faux  { background: var(--faux-fond);  border-top-color: transparent; }

/* Le verdict est centré, comme le bouton qui le suit et le texte qui
   l'explique : les trois partagent la même largeur et le même axe, si
   bien que l'œil descend en ligne droite du « Juste ! » au « Continuer »
   sans faire de zigzag. */
.feuille__t {
  font-family: var(--police-titre);
  max-width: 520px;
  margin: 0 auto 6px;
  font-size: var(--t-xl);
  font-weight: 700;
  text-align: center;
}

.feuille--juste .feuille__t { color: var(--juste); }
.feuille--faux  .feuille__t { color: var(--faux); }

.feuille__c {
  max-width: 520px;
  margin: 0 auto 14px;
  font-size: var(--t-md);
  line-height: 1.5;
  white-space: pre-line;
  text-align: center;
}

/* La réponse donnée après deux échecs. Elle se détache de l'aide qui la
   précède : l'aide dit pourquoi, celle-ci dit quoi — l'élève doit voir
   d'un coup d'œil laquelle des deux il est en train de lire. */
.feuille__reponse {
  max-width: 520px;
  margin: 0 auto 14px;
  padding: 10px 14px;
  border-radius: var(--r);
  background: var(--carte);
  font-size: var(--t-lg);
  font-weight: 800;
  line-height: 1.45;
  white-space: pre-line;
}

.feuille__b { display: grid; gap: 8px; }

.feuille--juste .feuille__b .btn { background: var(--juste); color: #fff; }
.feuille--faux  .feuille__b .btn { background: var(--faux);  color: #fff; }
.feuille .btn--fantome { background: none; color: inherit; border-color: currentColor; opacity: .55; }

/* ============================================================
   4. L'ACCUEIL — modules et chapitres
   ============================================================ */

/* ============================================================
   LES MODULES, REPLIABLES

   <details> natif : le clavier, le lecteur d'écran et la recherche du
   navigateur le connaissent déjà — un dépliant maison aurait fallu
   recâbler les trois. On masque seulement le triangle par défaut, qui
   ne suit pas la charte, et on pose le nôtre à droite.
   ============================================================ */

.module { margin: 22px 0 8px; }

/* Aligné en HAUT, pas au centre : déplié, le sous-titre officiel fait
   trois lignes, et un alignement centré faisait flotter la pastille du
   module au milieu du paragraphe, loin du titre qu'elle désigne. */
.module__t {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  cursor: pointer;
  list-style: none;
}
.module__t::-webkit-details-marker { display: none; }

.module__id {
  flex: none;
  margin-top: 3px;
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: .08em;
  color: var(--terre);
  background: var(--ocre-clair);
  border-radius: 999px;
  padding: 3px 9px;
}

.module__titres { flex: 1; min-width: 0; }
.module__t h2 { font-family: var(--police-titre); font-size: var(--t-xl); font-weight: 700; margin: 0; letter-spacing: -.01em; }

/* Le sous-titre officiel est long et ne sert qu'une fois déplié : replié,
   le module doit tenir sur une ligne pour que les quatre se voient d'un
   coup — c'est tout l'intérêt de replier. */
.module__s { color: var(--doux); font-size: var(--t-base); margin: 2px 0 0; line-height: 1.4; }
.module:not([open]) .module__s { display: none; }

.module__compte {
  flex: none;
  margin-top: 2px;
  font-size: var(--t-base);
  font-weight: 700;
  color: var(--doux);
  font-variant-numeric: tabular-nums;
}

/* le chevron : il tourne, donc il annonce ce que fera le prochain tap */
.module__compte::after {
  content: "›";
  display: inline-block;
  margin-left: 8px;
  font-size: 18px;
  transform: rotate(90deg);
  transition: transform .18s ease-out;
}
.module:not([open]) .module__compte::after { transform: rotate(0deg); }

@media (prefers-reduced-motion: reduce) {
  .module__compte::after { transition: none; }
}

/* ============================================================
   LA VIGNETTE D'UN CHAPITRE

   Un emblème, pas une figure : il ne démontre rien, il fait
   reconnaître le chapitre avant qu'on ait lu son titre. Traits plus
   fins que ceux des figures de leçon — à 88 px, l'épaisseur 2,4
   empâterait le dessin — et aucune couleur en dur : tout vient de la
   charte, donc le thème sombre suit tout seul.
   ============================================================ */

.vignette { display: block; width: 100%; height: 100%; }

/* ============================================================
   LES GLYPHES D'INTERFACE

   Ils remplacent les émojis. `currentColor` fait tout le travail : posé
   dans un jeton ocre, le glyphe est ocre ; dans une carte, il est brun ;
   en thème sombre, il suit. Zéro variante à maintenir.

   Dimensionnés en `em` et non en pixels : ils grandissent avec le texte
   qu'ils accompagnent, y compris quand l'élève agrandit la police de son
   téléphone — ce qu'un émoji faisait naturellement et qu'une icône en
   taille fixe aurait cassé.
   ============================================================ */
.glyphe {
  width: 1.15em;
  height: 1.15em;
  flex: none;
  vertical-align: -.2em;
  color: inherit;
}

.gly-trait { fill: none; stroke: currentColor; stroke-width: 1.9;
             stroke-linecap: round; stroke-linejoin: round; }
.gly-plein { fill: currentColor; }

/* Un glyphe suivi d'un texte : l'espace se pose ici, jamais dans la
   chaîne de caractères — sinon il traîne aussi dans le lecteur d'écran. */
.glyphe + * { margin-left: .4em; }

/* La ligne « glyphe + texte », alignée sur la première ligne du texte. */
.avec-glyphe { display: inline-flex; align-items: baseline; gap: .4em; }
.avec-glyphe .glyphe { align-self: center; }

/* Un BOUTON qui porte un glyphe reste un bouton : pleine largeur et
   contenu centré. Sans cette règle, `inline-flex` reprenait la main sur
   le `display: block` du bouton, qui perdait sa largeur et tassait son
   texte à gauche. */
.btn.avec-glyphe {
  display: flex;
  width: 100%;
  justify-content: center;
  align-items: center;
}

.vig-trait { stroke: var(--texte); stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.vig-trait--fin { stroke-width: 1.4; }
.vig-trait--pointille { stroke-dasharray: 3 3; stroke: var(--doux); }
.vig-ferme { fill: none; }
.vig-axe { stroke: var(--texte); stroke-width: 1.8; }
.vig-axe--pointille { stroke-dasharray: 4 4; stroke: var(--terre); }
.vig-tick { stroke: var(--doux); stroke-width: 1.4; }
.vig-tick--maj { stroke: var(--texte); stroke-width: 1.8; }
.vig-fleche { fill: var(--texte); }
.vig-point { fill: var(--terre); }
.vig-plein { fill: var(--terre); }
.vig-plein-doux { fill: var(--terre-clair); stroke: var(--texte); stroke-width: 1.8; stroke-linejoin: round; }
.vig-arc { stroke: var(--terre); stroke-width: 2; fill: none; }
.vig-codage { stroke: var(--terre); stroke-width: 1.8; stroke-linecap: round; }
.vig-bloc { fill: none; stroke: var(--texte); stroke-width: 1.6; }
.vig-bloc--vif { fill: var(--terre-clair); }
.vig-texte { font: 800 13px/1 system-ui, sans-serif; fill: var(--texte); text-anchor: middle; }
.vig-texte--grand { font-size: 19px; fill: var(--terre); }
.vig-texte--petit { font-size: 11px; fill: var(--doux); }
.vig-texte--sombre { fill: var(--texte); }

/* ============================================================
   LE SEUIL — les deux portes

   Deux surfaces de même poids : rien ne doit suggérer que les cours
   valent plus que les épreuves, ni l'inverse. C'est un choix, pas une
   hiérarchie.
   ============================================================ */

.portes { display: grid; gap: 14px; margin-top: 8px; }

/* LES CARTES ONT DU RELIEF depuis le 22/09/2026. Elles étaient posées
   à plat sur le sable, à un cheveu de contraste : l'écran ressemblait à
   une liste, pas à un choix. Même traitement que les cartes de la
   vitrine — coin plus rond, ombre un peu plus franche, et un
   soulèvement au survol qui dit qu'on peut appuyer. Sur un téléphone il
   n'y a pas de survol : c'est `:active` qui répond, et il répondait
   déjà. */
.porte {
  width: 100%;
  text-align: left;
  padding: 20px 18px;
  border: 1px solid var(--ligne);
  border-radius: 20px;
  background: var(--carte);
  box-shadow: var(--ombre);
  color: var(--texte);
  font: inherit;
  cursor: pointer;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.porte:hover {
  transform: translateY(-2px);
  border-color: var(--ligne-nette);
  box-shadow: 0 2px 4px rgba(58, 36, 24, .05), 0 10px 22px rgba(58, 36, 24, .09);
}
.porte:active { background: var(--fond2); transform: none; }

.porte__t {
  font-family: var(--police-titre);
  font-size: var(--t-xl);
  font-weight: 700;
  color: var(--terre);
}
.porte__s { margin: 8px 0 0; font-size: var(--t-md); line-height: 1.45; color: var(--doux); }
.porte__e { margin-top: 10px; font-size: var(--t-base); font-weight: 700; }

/* ============================================================
   LES ÉPREUVES — le passage, puis la copie
   ============================================================ */

/* ============================================================
   L'ÉPREUVE EST MUETTE — aucun indicateur, jamais.

   Chaque rendeur marque la bonne et la mauvaise réponse à l'intérieur
   de son `valider()`, AVANT de rendre son verdict au dérouleur. Dans une
   leçon c'est exactement ce qu'il faut. Dans une épreuve, cela faisait
   clignoter du vert ou du rouge une fraction de seconde avant la
   question suivante — un indicateur involontaire, et sur un téléphone
   lent, parfaitement visible.

   On neutralise donc les couleurs de verdict pour toute la durée du
   passage, en CSS et sans toucher aux rendeurs : ils continuent de
   juger comme d'habitude, mais leur jugement ne se voit plus. La copie,
   elle, est rendue hors de ce conteneur — elle garde toutes ses
   couleurs.
   ============================================================ */
.epreuve-muette .opt--juste, .epreuve-muette .opt--faux,
.epreuve-muette .puce--juste, .epreuve-muette .puce--faux,
.epreuve-muette .champ--juste, .epreuve-muette .champ--faux,
.epreuve-muette .part--juste, .epreuve-muette .part--faux,
.epreuve-muette .morceau--juste, .epreuve-muette .morceau--faux {
  border-color: var(--ligne-nette);
  background: var(--carte);
  color: var(--texte);
}

.epreuve-muette .part--juste, .epreuve-muette .part--faux { background: var(--terre); }
.epreuve-muette .champ--juste, .epreuve-muette .champ--faux { border-style: dashed; }
.epreuve-muette .lecture--juste, .epreuve-muette .lecture--faux { color: var(--texte); }
.epreuve-muette .repart-case__v--faux { color: var(--texte); }
.epreuve-muette .pose--faux, .epreuve-muette .plan-pose--faux,
.epreuve-muette .retour--juste, .epreuve-muette .retour--faux { fill: var(--terre); stroke: var(--terre); }

/* « Passer cette question » : une sortie discrète, jamais aussi visible
   que le bouton principal. Sur une vraie épreuve on a le droit de
   laisser une question ; l'interdire pousserait à répondre au hasard. */
.epreuve-passer { margin: 18px 0 4px; }
.epreuve-passer .btn { min-height: 44px; font-size: var(--t-base); }

.copie-medaille {
  justify-content: center;
  font-size: var(--t-xl);
  font-weight: 700;
  color: var(--terre);
  margin-top: 6px;
}

/* Un VRAI tableau : c'est un tableau de statistiques, la balise porte le
   sens et le lecteur d'écran sait l'annoncer ligne par ligne. */
.copie-stats {
  width: 100%;
  margin: 22px 0 6px;
  border-collapse: collapse;
  font-size: var(--t-base);
}
.copie-stats caption {
  text-align: left;
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--terre);
  padding-bottom: 8px;
}
.copie-stats th, .copie-stats td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--ligne-nette);
  text-align: left;
}
.copie-stats thead th { color: var(--doux); font-size: var(--t-sm); font-weight: 700; }
.copie-stats tbody th { font-weight: 700; }
.copie-stats .num { text-align: right; font-variant-numeric: tabular-nums; }

.copie-titre {
  font-family: var(--police-titre);
  font-size: var(--t-xl);
  font-weight: 700;
  margin: 26px 0 10px;
}

.copie-item {
  border: 1px solid var(--ligne);
  border-radius: var(--r);
  background: var(--carte);
  box-shadow: var(--ombre);
  padding: 12px 14px;
  margin-bottom: 9px;
}
.copie-item--juste { background: var(--juste-fond); }
.copie-item--faux { background: var(--faux-fond); }

.copie-item__t { display: flex; align-items: baseline; gap: 10px; }
.copie-item__n {
  flex: none;
  min-width: 26px; height: 26px;
  border-radius: 8px;
  background: var(--fond2);
  color: var(--doux);
  font-size: var(--t-sm);
  font-weight: 800;
  display: inline-grid;
  place-items: center;
}
.copie-item__v { flex: 1; font-weight: 800; font-size: var(--t-base); }
.copie-item--juste .copie-item__v { color: var(--juste); }
.copie-item--faux .copie-item__v { color: var(--faux); }
.copie-item__p { font-size: var(--t-base); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--doux); }

/* Le nom de la compétence, pas l'énoncé recopié : « comparer deux
   décimaux » s'exploite, « Quelle est la réponse ? » ne s'exploite pas. */
.copie-item__c { margin-top: 6px; font-size: var(--t-base); color: var(--doux); }
.copie-item__r { margin-top: 8px; }

.copie-rep { display: flex; gap: 8px; align-items: baseline; margin-top: 4px; font-size: var(--t-base); }
.copie-rep__e { flex: none; min-width: 82px; color: var(--doux); font-weight: 700; }
.copie-rep__v { font-weight: 700; }
.copie-rep--juste .copie-rep__v { color: var(--juste); }
.copie-rep--faux .copie-rep__v { color: var(--faux); }

.chapitres { display: grid; gap: 10px; }

.chapitre {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 15px 16px;
  border: 1px solid var(--ligne);
  box-shadow: var(--ombre);
  border-radius: 18px;
  background: var(--carte);
  color: var(--texte);
  font: inherit;
  cursor: pointer;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}

/* Comme les portes : un chapitre qu'on peut ouvrir se soulève. Celui
   qui annonce « bientôt » ne bouge pas — il n'y a rien à ouvrir. */
button.chapitre:not(.chapitre--bientot):hover {
  transform: translateY(-2px);
  border-color: var(--ligne-nette);
  box-shadow: 0 2px 4px rgba(58, 36, 24, .05), 0 10px 22px rgba(58, 36, 24, .09);
}

.chapitre:not(.chapitre--bientot):active { background: var(--fond2); transform: none; }
.chapitre--bientot { opacity: .55; cursor: default; }

/* Un chapitre entamé se distingue au premier coup d'œil, sans lire :
   c'est là que l'élève retourne, il ne doit pas le chercher. */
/* Le chapitre déjà commencé ne porte AUCUN trait : il est simplement
   posé sur un fond très légèrement plus chaud, et son ombre passe du brun
   à la terre. Rien ne cerne la carte, rien ne barre son flanc — elle est
   seulement un peu plus vivante que ses voisines, et l'œil y revient sans
   qu'on ait eu à crier. */
.chapitre--entame {
  background: var(--carte-entamee);
  box-shadow: 0 1px 1px rgba(166, 81, 40, .07), 0 2px 8px rgba(166, 81, 40, .10);
}

/* --- l'emblème --- */

.chapitre__v {
  flex: none;
  position: relative;
  width: 88px; height: 64px;
  border-radius: 12px;
  background: var(--fond2);
  overflow: hidden;
}

/* le numéro se pose SUR la vignette, en petit : il sert à retrouver un
   chapitre nommé par le professeur, pas à occuper le premier plan */
.chapitre__num {
  position: absolute;
  left: 5px; top: 3px;
  font-size: var(--t-xs);
  font-weight: 800;
  color: var(--doux);
  font-variant-numeric: tabular-nums;
}

/* repli pour un chapitre sans motif — la 5ᵉ à venir, par exemple */
.chapitre__v--nu { display: grid; place-items: center; width: 44px; height: 44px; }

.chapitre__n {
  width: 38px; height: 38px;
  border-radius: 12px;
  background: var(--ocre);
  color: var(--plein-texte);
  font-weight: 800;
  font-size: var(--t-lg);
  display: grid;
  place-items: center;
}

.chapitre--bientot .chapitre__n { background: var(--inerte); color: var(--inerte-texte); font-size: var(--t-md); }

.chapitre__c { min-width: 0; flex: 1; }
.chapitre__t { font-family: var(--police-titre); font-weight: 700; font-size: var(--t-lg); line-height: 1.3; }
.chapitre__s { color: var(--doux); font-size: var(--t-base); margin-top: 3px; }
/* Ce que le livre réserve à certaines séries : lu sur la tuile, avant
   d’ouvrir le chapitre. */
.chapitre__series { color: var(--doux); font-size: var(--t-sm); margin-top: 3px; font-style: italic; }

/* --- ce que le chapitre a installé --- */

.chapitre__m {
  display: flex;
  flex-wrap: wrap;
  gap: 5px 6px;
  margin-top: 7px;
}

.marque {
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--doux);
  background: var(--fond2);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}

.marque--due { color: var(--terre); background: var(--ocre-clair); }

/* L'appel à l'action est un TEXTE, pas un <button> : toute la carte est
   déjà le bouton, et un bouton dans un bouton est un HTML invalide que
   les lecteurs d'écran annoncent de travers. */
.chapitre__a {
  margin-top: 8px;
  font-size: var(--t-base);
  font-weight: 700;
  color: var(--terre);
}

.entete { padding: 6px 0 18px; }
.entete h1 { margin: 0 0 8px; }
.entete p { color: var(--doux); font-size: var(--t-md); margin: 0 0 12px; }

.entete__jauge {
  height: 8px;
  border-radius: 999px;
  background: var(--inerte);
  overflow: hidden;
  margin-top: 8px;
}

.entete__jauge span { display: block; height: 100%; background: var(--progres); border-radius: 999px; transition: width .4s ease-out; }

/* Ce que le chapitre a réellement installé, sous la jauge d'avancement :
   la jauge compte les leçons traversées, cette ligne compte les notions
   tenues. Les deux ne disent pas la même chose. */
.entete__maitrise {
  margin-top: 8px;
  font-size: var(--t-base);
  color: var(--doux);
}

.encart {
  border: 1px solid var(--ligne);
  border-radius: var(--r);
  background: var(--fond2);
  padding: 16px 18px;
  margin: 16px 0;
  box-shadow: var(--ombre);
}

.encart h3 { font-family: var(--police-titre); margin: 0 0 6px; font-size: var(--t-lg); }
.encart p { margin: 0 0 14px; font-size: var(--t-md); color: var(--doux); }

/* ============================================================
   5. LE CHEMIN DES LEÇONS
   ============================================================ */

.chemin { list-style: none; margin: 0; padding: 0; }
.chemin li { display: flex; gap: 14px; align-items: flex-start; padding-bottom: 12px; position: relative; }

/* le trait qui relie les pastilles : c'est ce qui fait « chemin » */
.chemin li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 19px; top: 40px; bottom: 0;
  width: 2px;
  background: var(--ligne);
}

.pastille {
  flex: none;
  width: 40px; height: 40px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 800;
  background: var(--inerte);
  color: var(--inerte-texte);
  z-index: 1;
}

.pastille--ouverte { background: var(--ocre-clair); color: var(--terre); box-shadow: inset 0 0 0 2px var(--ocre); }
.pastille--faite { background: var(--terre); color: var(--sable); }

.tuile {
  flex: 1;
  min-width: 0;
  text-align: left;
  padding: 13px 16px;
  border: 1px solid var(--ligne);
  box-shadow: var(--ombre);
  border-radius: var(--r);
  background: var(--carte);
  color: var(--texte);
  font: inherit;
  cursor: pointer;
}

.tuile:disabled { opacity: .5; cursor: default; }
.tuile:not(:disabled):active { background: var(--fond2); }

/* La leçon d'essai (01/10/2026) — choisie à la première entrée d'un
   compte neuf. Les tuiles s'empilent ici, hors du chemin des leçons. */
.essai__liste { display: flex; flex-direction: column; gap: 10px; margin: 6px 0 14px; }
.essai__note {
  padding: 10px 12px;
  border-left: 3px solid var(--terre);
  background: var(--terre-clair);
  border-radius: 0 10px 10px 0;
  color: var(--texte);
}
.tuile__essai {
  margin-top: 6px;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--terre);
}
.tuile__t { font-family: var(--police-titre); font-weight: 700; font-size: var(--t-lg); }

/* « Reprendre là où tu t'es arrêté » : la carte en tête de l'accueil.
   Pleine largeur, et l'accent ocre de ce qui est en cours. */
.reprise { display: block; width: 100%; margin: 0 0 16px; border-left: 4px solid var(--ocre); }
.reprise__l { color: var(--ocre); font-weight: 700; font-size: var(--t-base); margin-bottom: 4px; }

/* Le bandeau de reprise sous la vidéo : ce qui s'est passé, et le moyen
   de le défaire. */
.lecteur__reprise {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin: 8px 0 0; font-size: var(--t-base);
}
.lecteur__reprise[hidden] { display: none; }
.lecteur__reprise-b {
  border: 1px solid var(--ligne); border-radius: 999px; background: var(--carte);
  color: inherit; font: inherit; padding: 6px 12px; cursor: pointer;
}
.tuile__s { color: var(--doux); font-size: var(--t-base); margin-top: 3px; }

.etoiles { font-size: var(--t-lg); color: var(--ocre); letter-spacing: 2px; margin-top: 6px; }
.etoiles i { color: var(--inerte); font-style: normal; }

.ligne {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--ligne);
  font-size: var(--t-md);
}

.ligne:last-child { border-bottom: 0; }
.ligne b { flex: none; color: var(--doux); font-size: var(--t-base); }

/* Les deux liens légaux, côte à côte, séparés par un point médian que
   le CSS pose : en mettre un dans le HTML obligerait à le retirer le
   jour où un troisième lien s'ajoute. */
.pied__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 14px;
  margin-top: 10px;
}
.pied__legal a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.pied__legal a:hover { color: var(--terre, inherit); }

/* Le choix entre les deux documents : une ligne de liens, celui qu'on
   lit étant simplement marqué. */
.legal__choix {
  display: flex;
  gap: 16px;
  margin: 0 0 18px;
  font-size: var(--t-base);
}
.legal__choix a { color: inherit; text-decoration: underline; text-underline-offset: 3px; opacity: .75; }
.legal__choix a:hover { opacity: 1; color: var(--terre, inherit); }
.legal__choix-actif { font-weight: 700; color: var(--terre, inherit); }

/* La page des conditions et de la confidentialité : une colonne de
   lecture, pas un écran d'application. */
.legal { max-width: 46rem; margin: 0 auto; }
.legal__maj { color: var(--texte-doux, #8A6B4E); font-size: var(--t-base); margin-top: -6px; }
.legal__s { margin-top: 26px; }
.legal__h2 {
  font-family: var(--police-titre);
  font-size: var(--t-xl);
  margin: 0 0 8px;
  color: var(--terre, inherit);
}
.legal__s p { margin: 0 0 10px; line-height: 1.6; }
.legal__l { margin: 0 0 10px; padding-left: 20px; }
.legal__l li { margin-bottom: 6px; line-height: 1.55; }

/* Le support et la boîte à suggestions. Même colonne de lecture que les
   pages légales — d'où les classes `legal__*` réemployées telles quelles
   pour les titres et les listes : deux jeux de règles identiques sous
   deux noms auraient divergé à la première retouche. Ce qui suit est ce
   que la boîte a de PROPRE : un formulaire, sur une page qui n'en avait
   jamais eu. */
.aide__contact {
  font-size: var(--t-lg);
  font-weight: 700;
  margin: 14px 0 0;
}
.aide__contact a { color: var(--terre, inherit); text-underline-offset: 3px; }

.aide__qr { margin-top: 20px; }
.aide__q {
  font-family: var(--police-titre);
  font-size: var(--t-lg);
  margin: 0 0 6px;
}
.aide__qr p { margin: 0; line-height: 1.6; }

.aide__boite {
  margin-top: 22px;
  padding: 18px;
  border: 2px solid var(--ligne-nette);
  border-radius: 18px;
  background: var(--carte, #FFFDF8);
}
.aide__l {
  display: block;
  margin: 14px 0 6px;
  font-weight: 700;
  font-size: var(--t-base);
}
.aide__l:first-child { margin-top: 0; }

/* Les champs héritent de la police de la page : sans cette ligne, le
   navigateur impose la sienne, et un message écrit dans la boîte ne
   ressemble pas au reste de l'écran. `width: 100%` avec `box-sizing`
   hérité du réglage global, sinon la bordure déborde de la carte. */
.aide__select,
.aide__texte,
.aide__champ {
  width: 100%;
  padding: 12px 14px;
  border: 2px solid var(--ligne-nette);
  border-radius: 14px;
  background: var(--fond, #FBF5EA);
  color: inherit;
  font: 400 var(--t-base)/1.5 inherit;
}
.aide__texte { resize: vertical; min-height: 140px; }
.aide__select { appearance: auto; }

.aide__boutons { margin-top: 18px; display: grid; gap: 10px; }

/* Le repli « Écrire avec ma messagerie » est un LIEN `mailto:` : `.btn`
   le dessine, ces trois lignes le font se comporter comme un bouton. */
.aide__envoyer,
.aide__messagerie {
  text-align: center;
  text-decoration: none;
  line-height: 24px;
}
.aide__messagerie[hidden] { display: none; }
/* L'adresse à qui l'on répondra, quand l'élève est connecté. */
.aide__qui { margin: 14px 0 0; font-size: var(--t-base); }
/* Tant que le message est vide, il n'y a rien à envoyer. On éteint le
   bouton plutôt que de le cacher : un bouton qui disparaît laisse croire
   qu'on a mal cherché. */
.btn--eteint { background: var(--inerte); color: var(--inerte-texte); pointer-events: none; }

.aide__dit { margin: 10px 0 0; font-size: var(--t-base); color: var(--terre, inherit); }

/* La ligne de droits d'un pied d'écran : détachée par un filet, plus
   discrète que le reste, et lisible sans être lue. */
.pied__droits {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--ligne);
  opacity: .8;
}

.pied {
  margin-top: 30px;
  padding-top: 18px;
  border-top: 1px solid var(--ligne);
  color: var(--doux);
  font-size: var(--t-sm);
  line-height: 1.6;
}

.pied .btn { margin-top: 16px; }

/* ============================================================
   6. BILAN ET BADGES
   ============================================================ */

.bilan { text-align: center; padding-top: 10px; }
.bilan__xp { font-size: var(--t-5xl); font-weight: 800; color: var(--terre); letter-spacing: -.02em; }
.bilan__l { color: var(--doux); font-size: var(--t-base); margin-top: 4px; }
.bilan__tab { margin: 22px 0 4px; text-align: left; }
.bilan .retenir { text-align: left; }

/* ---------- ce que l'élève sait faire ----------
   Les étoiles disent qu'une leçon a été traversée. Ce bloc-là dit ce qui
   est tenu, notion par notion, et quand chacune reviendra. C'est la seule
   réponse possible à « qu'est-ce que je sais faire, maintenant ? ».
   Pas de vert ni de rouge : ce ne sont pas des verdicts de réponse, ce
   sont des états d'avancement — la palette principale, donc. */
.maitrise {
  margin-top: 22px;
  padding: 14px 16px 6px;
  border-radius: var(--r);
  /* --fond2 bascule en thème sombre, --peau non : un bloc crème sur le brun
     profond serait illisible. */
  background: var(--fond2);
  text-align: left;
}

.maitrise__t {
  font-size: var(--t-sm);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--terre);
  margin-bottom: 4px;
}

.maitrise .ligne { border-bottom-color: var(--ligne); }

/* Une compétence tenue porte la couleur principale, une compétence encore
   fragile reste en texte doux : on signale, on ne sanctionne pas. */
.ligne--tenue b { color: var(--terre); font-weight: 800; }
.ligne--fragile span { color: var(--doux); }

.badge-neuf { text-align: center; padding: 26px 0; }
/* Le badge fraîchement obtenu : le glyphe occupe la place que tenait
   l'émoji, en couleur de la charte plutôt qu'en jaune du système. */
.badge-neuf__emo { font-size: 58px; color: var(--terre); line-height: 1; }

/* Le verdict du mini-jeu chronométré. */
.chrono-verdict { font-size: 34px; color: var(--terre); line-height: 1; margin-bottom: 6px; }
.badge-neuf__l { color: var(--doux); font-size: var(--t-base); text-transform: uppercase; letter-spacing: .08em; font-weight: 800; }
.badge-neuf p { color: var(--doux); font-size: var(--t-md); }

/* ---------- LE CHOIX DE LA CLASSE ----------
   Deux portes, comme le seuil. La classe se lit dans une pastille ocre,
   en police système : « 6ᵉ » porte un chiffre, et Fraunces n'en porte pas. */
.porte__t--classe { display: flex; align-items: center; gap: 12px; }
.classe__n {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  border-radius: 14px;
  background: var(--ocre);
  color: var(--plein-texte);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: var(--t-xl);
  font-weight: 800;
}

/* ============================================================
   7. LES FIGURES DES CARTES DE LEÇON
   ============================================================ */

.figure {
  margin: 4px 0 20px;
  padding: 18px 10px;
  border-radius: var(--r);
  background: var(--fond2);
  overflow-x: auto;
}

.fig { display: block; width: 100%; max-width: 340px; height: auto; margin: 0 auto; }

.fig-chiffre {
  font: 800 27px/1 system-ui, sans-serif;
  fill: var(--texte);
  text-anchor: middle;
}

.fig-chiffre--ajoute { fill: var(--ocre); }

.fig-legende {
  font: 600 12px/1 system-ui, sans-serif;
  fill: var(--doux);
  text-anchor: middle;
}

.fig-legende--pt { font-size: 10.5px; }

/* Le rang, écrit sous chaque chiffre : il doit tenir dans une colonne de
   44 px sans être abrégé — « centaines » abrégé en « cent. » ferait un mot
   de plus à décoder, juste là où l'élève apprend le mot entier. */
.fig-legende--rang { font-size: 9px; letter-spacing: -.2px; }

/* le trait qui relie le chiffre désigné à son nom complet */
.fig-rang-tige { stroke: var(--terre); stroke-width: 2; stroke-linecap: round; }

/* la virgule est un tracé, pas du texte : seule sa couleur se règle ici */
.fig-virgule { fill: none; stroke: var(--ocre); }

.fig-tranche { fill: var(--terre-clair); stroke: var(--terre); stroke-width: 2; }
.fig-tranche--1 { fill: var(--ocre-clair); stroke: var(--ocre); }
.fig-tranche--2 { fill: var(--sable); stroke: var(--brun); }

.fig-case { fill: var(--carte); stroke: var(--ligne); stroke-width: 2; }
.fig-case--dec { fill: var(--fond); stroke-dasharray: 4 3; }
.fig-case--vive { fill: var(--terre-clair); stroke: var(--terre); stroke-width: 2.5; }

.fig-part { fill: var(--carte); stroke: var(--ligne); stroke-width: 1.5; }
.fig-part--pleine { fill: var(--terre); }
.fig-part-bord { fill: none; stroke: var(--texte); stroke-width: 2.5; }

.fig-axe, .fig-tick { stroke: var(--texte); stroke-width: 2; }
.fig-tick--maj { stroke-width: 3; }
.fig-fleche { fill: var(--texte); }
.fig-point { fill: var(--terre); stroke: var(--carte); stroke-width: 2.5; }
.fig-etiquette { font: 800 15px/1 system-ui, sans-serif; fill: var(--terre); text-anchor: middle; }

/* ============================================================
   8. LES DÉFIS
   ============================================================ */

/* --- QCM --- */

.options { display: grid; gap: 10px; }

.opt {
  width: 100%;
  text-align: left;
  padding: 16px 18px;
  border: 2px solid var(--ligne-nette);
  border-radius: var(--r);
  background: var(--carte);
  color: var(--texte);
  font: 600 var(--t-lg)/1.35 inherit;
  cursor: pointer;
  transition: border-color .12s ease-out, background-color .12s ease-out, color .12s ease-out;
}

.opt:disabled { cursor: default; }
.opt--choisi { border-color: var(--terre); background: var(--terre-clair); color: var(--terre); }
.opt--juste { border-color: var(--juste); background: var(--juste-fond); color: var(--juste); }
.opt--faux { border-color: var(--faux); background: var(--faux-fond); color: var(--faux); }

/* --- saisie guidée --- */

.etape { margin-bottom: 16px; }
.etape--faite { opacity: .45; }
.etape__invite { font-size: var(--t-md); color: var(--doux); margin-bottom: 8px; }

.champs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: var(--t-2xl); font-weight: 700; }

.champ {
  min-width: 76px;
  min-height: 52px;
  padding: 8px 14px;
  border: 2px dashed var(--ligne-nette);
  border-radius: 12px;
  background: var(--carte);
  color: var(--texte);
  font: 800 var(--t-2xl)/1.2 inherit;
  cursor: pointer;
}

.champ--actif { border-style: solid; border-color: var(--terre); background: var(--terre-clair); }
.champ--juste { border-style: solid; border-color: var(--juste); background: var(--juste-fond); color: var(--juste); }
.champ--faux { border-style: solid; border-color: var(--faux); background: var(--faux-fond); color: var(--faux); }
.champ__curseur { color: var(--terre); animation: clignote 1s steps(2) infinite; }

@keyframes clignote { 50% { opacity: 0; } }

.pave {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 18px;
}

.pave--comp { grid-template-columns: repeat(3, 1fr); }

/* le clavier des relatifs a treize touches : l’effacement prend la
   dernière ligne entière, ce qui en fait la plus grosse cible du pavé */
.pave--rel button:last-child { grid-column: span 3; }

.pave button {
  min-height: 54px;
  border: 1px solid var(--ligne-nette);
  border-radius: 12px;
  background: var(--fond2);
  color: var(--texte);
  font: 700 var(--t-2xl)/1 inherit;
  cursor: pointer;
}

.pave button:active { background: var(--terre-clair); }

/* --- tri et ordre --- */

.reserve {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 56px;
  padding: 12px;
  border-radius: var(--r);
  background: var(--fond2);
  margin-bottom: 14px;
}

.puce {
  padding: 11px 16px;
  border: 2px solid var(--ligne-nette);
  border-radius: 999px;
  background: var(--carte);
  color: var(--texte);
  font: 700 var(--t-lg)/1.2 inherit;
  min-height: 44px;
  cursor: pointer;
}

.puce--choisie { border-color: var(--terre); background: var(--terre-clair); color: var(--terre); }
.puce--juste { border-color: var(--juste); background: var(--juste-fond); color: var(--juste); }
.puce--faux { border-color: var(--faux); background: var(--faux-fond); color: var(--faux); }

.zones { display: grid; gap: 10px; }

.zone {
  border: 2px dashed var(--ligne-nette);
  border-radius: var(--r);
  padding: 12px 14px;
  min-height: 74px;
}

.zone--cible { border-color: var(--terre); background: var(--terre-clair); }
.zone__t { font-size: var(--t-sm); color: var(--doux); font-weight: 700; margin-bottom: 8px; }
.zone__c { display: flex; flex-wrap: wrap; gap: 8px; min-height: 44px; }

.echelle {
  display: flex;
  justify-content: space-between;
  font-size: var(--t-sm);
  color: var(--doux);
  font-weight: 700;
  margin-bottom: 8px;
}

/* --- droite graduée --- */

.droite {
  display: block;
  width: 100%;
  height: auto;
  background: var(--fond2);
  border-radius: var(--r);
  padding: 6px 0;
  touch-action: manipulation;
  cursor: pointer;
}

.droite .axe, .droite .tick { stroke: var(--texte); stroke-width: 1.6; }
.droite .tick--maj { stroke-width: 2.6; }
.droite text { font: 600 11px/1 system-ui, sans-serif; fill: var(--doux); text-anchor: middle; }
.droite .pose circle { fill: var(--terre); }
.droite .pose text { font-weight: 800; font-size: 13px; fill: var(--terre); }
.droite .pose--faux circle { fill: var(--faux); }
.droite .pose--faux text { fill: var(--faux); }

/* La valeur RÉELLEMENT posée, sous l'axe. Elle est plus grosse que les
   graduations et de la couleur du point : c'est elle que l'élève doit
   lire pour savoir où il vient de se mettre. */
.droite .pose-v, .droite text.droite-pose-v {
  font: 800 15px/1 system-ui, sans-serif;
  fill: var(--terre);
}
.droite .pose--faux text.droite-pose-v { fill: var(--faux); }

/* La valeur visée au clavier, avant de poser. */
.droite text.droite-vise {
  font: 700 13px/1 system-ui, sans-serif;
  fill: var(--ocre);
}
.droite .rate circle { fill: var(--faux); opacity: .55; }

.cible-info { text-align: center; color: var(--doux); font-size: var(--t-md); margin: 12px 0 0; }

/* --- colorier : on tape, ça se remplit --- */

.colorier {
  display: grid;
  grid-template-columns: repeat(var(--c), 1fr);
  gap: 3px;
  border: 3px solid var(--texte);
  border-radius: 8px;
  overflow: hidden;
  background: var(--texte);
  touch-action: manipulation;
}

.colorier--barre .part { height: 84px; }
.colorier--grille .part { aspect-ratio: 1; }

.part {
  border: 0;
  padding: 0;
  background: var(--carte);
  cursor: pointer;
  /* la couleur qui monte : c'est l'animation qui fait le lien entre
     le geste et la quantité. 150 ms — assez pour être vue, trop court
     pour qu'on l'attende. */
  transition: background-color .15s ease-out, transform .12s ease-out;
}

.part--pleine { background: var(--terre); }
.part--juste { background: var(--juste); }
.part--faux { background: var(--faux); }
.part:not(:disabled):active { transform: scale(.92); }

.compteur {
  margin-top: 14px;
  text-align: center;
  font-size: var(--t-2xl);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--terre);
}

.compteur--vide { color: var(--doux); font-weight: 600; }

/* --- curseur : on fait glisser, la figure suit --- */

.lecture {
  text-align: center;
  font-size: 42px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  color: var(--terre);
  margin-bottom: 6px;
}

.lecture--juste { color: var(--juste); }
.lecture--faux { color: var(--faux); }

.curseur {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 6px;
}

.curseur__b {
  font-size: var(--t-base);
  font-weight: 700;
  color: var(--doux);
  flex: none;
  font-variant-numeric: tabular-nums;
}

.curseur__r {
  flex: 1;
  min-width: 0;
  -webkit-appearance: none;
  appearance: none;
  height: 10px;
  border-radius: 999px;
  background: var(--inerte);
  outline: none;
  touch-action: pan-y;
}

/* le pouce : 32 px, bien au-delà des 24 px d'un curseur natif —
   c'est une cible de doigt, pas de souris */
.curseur__r::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--terre);
  border: 4px solid var(--carte);
  box-shadow: 0 1px 5px rgba(0, 0, 0, .28);
  cursor: grab;
}

.curseur__r::-moz-range-thumb {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--terre);
  border: 4px solid var(--carte);
  cursor: grab;
}

.curseur__r:focus-visible { box-shadow: 0 0 0 3px var(--terre-clair); }

/* --- mini-jeu chronométré --- */

.chrono__haut { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.chrono__temps { font-size: 30px; font-weight: 800; font-variant-numeric: tabular-nums; }
.chrono__temps.presse { color: var(--faux); }
.chrono__score { font-size: var(--t-base); color: var(--doux); font-weight: 700; }

.chrono__item {
  display: grid;
  place-items: center;
  text-align: center;
  min-height: 130px;
  border-radius: var(--r);
  background: var(--fond2);
  font-size: 28px;
  font-weight: 800;
  padding: 16px;
}

.chrono__flash { animation: flashOk .3s ease-out; }
.chrono__flash--faux { animation: flashNon .3s ease-out; }

@keyframes flashOk  { from { background: var(--juste-fond); } }
@keyframes flashNon { from { background: var(--faux-fond); } }

.chrono__btns { display: grid; grid-auto-flow: column; gap: 10px; margin-top: 14px; }

/* --- notes d'étape (saisie en plusieurs temps) --- */

.retour { border-radius: var(--r); padding: 12px 16px; margin-top: 14px; font-size: var(--t-md); }
.retour p { margin: 4px 0 0; }
.retour__t { font-weight: 800; }
.retour--info { background: var(--terre-clair); color: var(--terre); }
.retour--juste { background: var(--juste-fond); color: var(--juste); }
.retour--faux { background: var(--faux-fond); color: var(--faux); }
/* la réponse donnée, à l'intérieur d'un problème */
.retour__reponse {
  margin-top: 10px !important;
  padding: 8px 12px;
  border-radius: var(--r);
  background: var(--carte);
  font-weight: 800;
  white-space: pre-line;
}

/* ============================================================
   9. DIVERS
   ============================================================ */

.hs { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

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

@media (min-width: 620px) {
  .titre-geant { font-size: var(--t-5xl); }
  .app { padding-left: 0; padding-right: 0; }
  .barre, .entete-parcours { padding-left: 0; padding-right: 0; }
}

/* la barre de comparaison des fractions : une seconde teinte, pour que
   deux quantités différentes ne se confondent pas sur la même figure */
.fig-part--autre { fill: var(--ocre); }
.fig-etiquette--gauche { text-anchor: end; fill: var(--texte); font-size: 16px; }

/* le tableau de proportionnalité : c'est la flèche qui porte le sens,
   pas la grille — elle est donc la seule chose colorée en ocre */
.fig-tab-case { fill: var(--carte); stroke: var(--ligne); stroke-width: 2; }
.fig-tab-case--haut { fill: var(--peau); }
.fig-tab-case--vide { stroke-dasharray: 5 4; }
.fig-tab-val { font: 800 20px/1 system-ui, sans-serif; fill: var(--texte); text-anchor: middle; }
.fig-tab-etiq { font: 700 13px/1 system-ui, sans-serif; fill: var(--doux); text-anchor: end; }
.fig-tab-fleche { fill: none; stroke: var(--ocre); stroke-width: 3; }
.fig-tab-pointe { fill: var(--ocre); }
.fig-tab-coef { font: 800 16px/1 system-ui, sans-serif; fill: var(--terre); text-anchor: start; }

/* la géométrie : un seul trait, une seule épaisseur. Ce qui distingue
   les objets, c'est leur forme, pas leur couleur — une figure lue en
   deux tons doit rester lisible. */
.fig-geo-trait { stroke: var(--texte); stroke-width: 2.4; fill: none; stroke-linecap: round; }
.fig-geo-trait--pointille { stroke-dasharray: 6 5; stroke: var(--doux); }
.fig-geo-codage { stroke: var(--terre); stroke-width: 2.4; stroke-linecap: round; }
.fig-geo-angle { stroke: var(--terre); stroke-width: 2.4; fill: none; }
.fig-geo-point { fill: var(--texte); }
.fig-geo-nom { font: 800 17px/1 system-ui, sans-serif; fill: var(--texte); text-anchor: middle; }
.fig-geo-nom--fin { fill: var(--doux); font-size: 14px; }
.fig-geo-cote { font: 700 14px/1 system-ui, sans-serif; fill: var(--terre); text-anchor: middle; }

/* la figure qu'on peut toucher */
.plan-actif {
  background: var(--fond2);
  border-radius: var(--r);
  padding: 8px 0;
  touch-action: manipulation;
  cursor: pointer;
}

.plan-pose circle { fill: var(--terre); stroke: var(--carte); stroke-width: 2.5; }
.plan-pose text { font: 800 15px/1 system-ui, sans-serif; fill: var(--terre); text-anchor: middle; }
.plan-pose--faux circle { fill: var(--faux); }
.plan-pose--faux text { fill: var(--faux); }

/* l'astuce d'épreuve : le conseil qui sauve des points le jour de la
   composition. Volontairement distincte du « à retenir » — l'un dit ce
   qu'il faut savoir, l'autre comment s'en servir sous la pression. */
/* Pas de barre latérale : elle découpait le bloc en deux et pesait plus
   lourd que le conseil qu'elle encadrait. C'est une ombre teintée terre
   — la même couleur, mais posée sous la surface au lieu d'être plantée
   sur son flanc — qui détache maintenant l'astuce du texte courant. */
.astuce {
  margin-top: 16px;
  padding: 14px 16px;
  border-radius: var(--r);
  background: var(--terre-clair);
  box-shadow: 0 1px 2px rgba(166, 81, 40, .10), 0 3px 10px rgba(166, 81, 40, .12);
}

.astuce__t {
  font-size: var(--t-sm);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--terre);
  margin-bottom: 6px;
}

.astuce p { margin: 0; font-size: var(--t-lg); }

/* l'arc : le seul trait de la figure qui soit en couleur, parce qu'il
   désigne UN morceau de cercle parmi deux possibles */
.fig-geo-arc { stroke: var(--terre); stroke-width: 5; fill: none; stroke-linecap: round; }

/* le rapporteur : transparent, pour qu'on voie l'angle à travers */
.fig-rap-corps { fill: var(--ocre-clair); stroke: var(--terre); stroke-width: 2; opacity: .75; }
.fig-rap-tick { stroke: var(--terre); stroke-width: 1.4; }
.fig-rap-tick--maj { stroke-width: 2.4; }
.fig-rap-nombre { font: 700 12px/1 system-ui, sans-serif; fill: var(--terre); text-anchor: middle; }

/* ---------- solides et patrons (module 4) ---------- */
/* Les arêtes cachées sont le seul indice de la troisième dimension :
   elles doivent se voir comme un trait, et se lire comme un derrière. */
.fig-sol-arete { stroke: var(--texte); stroke-width: 2.4; fill: none; stroke-linecap: round; }
.fig-sol-arete--cachee { stroke: var(--doux); stroke-width: 2; stroke-dasharray: 6 5; }
.fig-sol-vide { fill: none; }
.fig-sol-face { fill: var(--terre-clair); stroke: none; }

/* Un patron : bords pleins, plis pointillés. Confondre les deux, c'est
   découper le solide en morceaux au lieu de le plier. */
.fig-pat-face { fill: var(--carte); stroke: var(--texte); stroke-width: 2.4; }
.fig-pat-face--vive { fill: var(--terre-clair); }
.fig-pat-pli { stroke: var(--ocre); stroke-width: 2; stroke-dasharray: 5 4; }
.fig-pat-etiq { font: 700 11px/1 system-ui, sans-serif; fill: var(--doux); text-anchor: middle; }

/* ---------- l'invariant, pendant la manipulation ---------- */
/* La règle reste sous la main tant que l'élève cherche. Repliée par
   défaut : sur 360 px, un encadré ouvert mangerait la figure. */
.invariant {
  margin: 10px 0 2px;
  border: 1px solid #E9C98F;
  border-radius: var(--r);
  background: var(--ocre-clair);
}
.invariant__t {
  padding: 9px 14px;
  min-height: 44px;              /* cible tactile — §3 de la spécification */
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-sm);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--terre);
  cursor: pointer;
  list-style: none;
}
.invariant__t::-webkit-details-marker { display: none; }
.invariant__t::after {
  content: 'voir';
  margin-left: auto;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--doux);
}
.invariant[open] .invariant__t::after { content: 'masquer'; }
.invariant__c {
  margin: 0;
  padding: 0 14px 13px;
  font-size: var(--t-md);
  line-height: 1.45;
  color: var(--texte);
}
/* Le tiroir « Propriétés du cours » d'une étape : ce qu'on te donne,
   puis la règle. Même geste que « Ton exercice » — l'élève sait déjà
   l'ouvrir. */
.invariant__corps { padding: 0 14px 13px; }
.invariant__corps .invariant__c { padding: 0; }
.invariant__st {
  margin-bottom: 4px;
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--terre);
}
.invariant__corps .prop { background: var(--carte); }

/* ---------- le pari, avant la manipulation ---------- */
/* Le geste est barré tant que l'élève ne s'est pas engagé. */
.pari {
  margin: 12px 0 4px;
  padding: 16px 16px 14px;
  border-radius: var(--r);
  background: var(--carte);
  border: 2px dashed var(--ocre);
}
.pari__t {
  font-size: var(--t-sm);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ocre);
  margin-bottom: 10px;
}
.pari__q { font-size: var(--t-lg); font-weight: 700; line-height: 1.35; margin-bottom: 12px; }
.pari__opts { display: flex; flex-direction: column; gap: 9px; }

/* Une fois posé, le pari reste affiché : c'est à lui que la réussite
   renverra. Sans ce rappel, l'élève oublie ce qu'il avait annoncé. */
.pari-pose {
  display: flex;
  align-items: baseline;
  gap: 9px;
  flex-wrap: wrap;
  margin: 10px 0 14px;
  padding: 10px 14px;
  border-radius: var(--r);
  background: var(--ocre-clair);
  border: 1px solid #E9C98F;
}
.pari-pose__t {
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--terre);
}
.pari-pose__v { font-weight: 700; }

/* Le pourquoi du comment, posé juste après le pari. Un filet à gauche
   plutôt qu'un cadre : c'est une note de marge, pas un nouvel exercice —
   l'élève doit pouvoir la lire sans croire qu'on lui redemande quelque
   chose. Cinq lignes au plus, c'est la règle du contenu. */
.pari-pourquoi {
  margin: -6px 0 14px;
  padding: 2px 0 2px 12px;
  border-left: 3px solid var(--terre);
  font-size: var(--t-md);
  line-height: 1.5;
  opacity: .9;
}

/* Le retour, dans la feuille de verdict. */
.pari-bilan {
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: var(--r);
  background: rgba(255, 255, 255, .22);
}
.pari-bilan__t { font-size: var(--t-sm); font-weight: 800; margin-bottom: 5px; opacity: .85; }
.pari-bilan__c { margin: 0; font-size: var(--t-md); line-height: 1.45; }

/* ---------- le mini-jeu ne part pas sans prévenir ---------- */
/* Le compte à rebours partait au rendu : l'élève perdait ses premières
   secondes à comprendre l'écran. On annonce la règle, il démarre. */
.chrono-depart {
  margin: 14px 0;
  padding: 20px 18px;
  border-radius: var(--r);
  background: var(--carte);
  border: 2px solid var(--ocre);
  text-align: center;
}
.chrono-depart__t {
  font-size: var(--t-base);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ocre);
  margin-bottom: 10px;
}
.chrono-depart__c { margin: 0 0 10px; font-size: var(--t-lg); line-height: 1.45; }
.chrono-depart .btn { margin-top: 6px; }

/* le jeu reste visible mais éteint tant qu'on n'a pas démarré */
.chrono--attente { opacity: .35; pointer-events: none; }

/* ---------- repère à deux axes : escalier, courbe, histogramme ---------- */
.fig-grille { stroke: var(--ligne); stroke-width: 1; opacity: .55; }

/* L'escalier : ce sont les SAUTS qui enseignent, pas les marches. */
.fig-esc-marche { stroke: var(--terre); stroke-width: 3.4; stroke-linecap: butt; }
.fig-esc-inclus { fill: var(--terre); }
.fig-esc-exclu { fill: var(--carte); stroke: var(--terre); stroke-width: 2.4; }
.fig-esc-lecture { stroke: var(--ocre); stroke-width: 2; stroke-dasharray: 5 4; }

/* La courbe : le plateau est la partie utile, il se voit en premier. */
.fig-courbe { fill: none; stroke: var(--terre); stroke-width: 3; stroke-linejoin: round; }
.fig-palier { fill: var(--ocre-clair); opacity: .7; }
.fig-palier-t { font: 800 11px/1 system-ui, sans-serif; fill: var(--ocre); text-anchor: middle; }

/* L'histogramme : les barres portent les données, les repères portent l'idée. */
.fig-histo { fill: var(--terre-clair); stroke: var(--terre); stroke-width: 1.6; }
.fig-histo--vive { fill: var(--ocre); }
.fig-repere { stroke-width: 2.4; stroke-dasharray: 7 5; }
.fig-repere--0 { stroke: var(--ocre); }
.fig-repere--1 { stroke: var(--brun); }
.fig-repere-t { font: 800 11px/1 system-ui, sans-serif; text-anchor: end; }
.fig-repere-t--0 { fill: var(--ocre); }
.fig-repere-t--1 { fill: var(--brun); }
.fig-etiquette--debut { text-anchor: start; }

/* ---------- le clavier ---------- */
/* Le viseur n'apparaît qu'à la première flèche : une marque de plus à
   l'écran, pour qui ne s'en sert pas, ne serait que du bruit. */
.droite .viseur { stroke: var(--ocre); stroke-width: 2.5; stroke-dasharray: 4 3; }
.plan-actif .viseur { stroke: var(--ocre); stroke-width: 2.5; }
/* Un focus qui ne se voit pas ne sert à personne : on le rend franc. */
/* ---------- surligner : désigner sur un support ---------- */
.surligne-support {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 14px 0 10px;
  padding: 14px;
  border-radius: var(--r);
  background: var(--carte);
  border: 1px solid var(--ligne);
  box-shadow: var(--ombre);
  font-size: var(--t-xl);
  line-height: 1.5;
}
.morceau {
  min-height: 44px;                 /* cible tactile — §3 */
  padding: 8px 12px;
  border: 2px solid transparent;
  border-radius: 10px;
  background: transparent;
  font: inherit;
  color: var(--texte);
  cursor: pointer;
}
.morceau--pris { background: var(--ocre-clair); border-color: var(--ocre); font-weight: 700; }
.morceau--juste { background: var(--vert-clair, #D8E8D0); border-color: #6E9B5B; }
.morceau--faux { background: #F3D9D4; border-color: #B4685A; text-decoration: line-through; }
.morceau:disabled { cursor: default; }

/* ---------- répartir : distribuer une quantité ---------- */
.repart-stock {
  margin: 12px 0 10px;
  padding: 11px 14px;
  border-radius: var(--r);
  background: var(--ocre-clair);
  border: 1px solid #E9C98F;
  font-weight: 700;
  text-align: center;
}
.repart-stock--vide { background: var(--carte); border-color: var(--ligne); color: var(--doux); }
.repart-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 10px; }
.repart-case {
  padding: 12px 10px;
  border-radius: var(--r);
  background: var(--carte);
  border: 2px solid var(--ligne-nette);
  text-align: center;
}
.repart-case__t { font-size: var(--t-base); font-weight: 700; color: var(--doux); }
.repart-case__v { font: 800 var(--t-4xl)/1.2 system-ui, sans-serif; color: var(--texte); margin: 6px 0 8px; }
.repart-case__v--faux { color: #B4685A; }
.repart-case__b { display: flex; gap: 8px; justify-content: center; }
.repart-btn {
  min-width: 48px; min-height: 44px;   /* cibles tactiles */
  border: 2px solid var(--terre);
  border-radius: 12px;
  background: var(--carte);
  font: 800 var(--t-2xl)/1 system-ui, sans-serif;
  color: var(--terre);
  cursor: pointer;
}
.repart-btn:disabled { opacity: .3; cursor: default; }

/* Une mise a jour bloquee doit se voir, sur les deux parcours. */
.version-bloquee { color: var(--faux); font-weight: 700; }

/* Indices et exposants : « z_A », « a^n ». Sans cette règle, un indice
   écarte la ligne qui le porte, et un paragraphe d'énoncé se met à
   respirer de travers là où il y a des affixes. */
sub, sup { font-size: 0.72em; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.48em; }
sub { bottom: -0.22em; }

/* ============================================================
   L'ENTRÉE — ton pays, ta classe, ton prénom

   Trois écrans qu'on ne voit qu'une fois, et qui réutilisent tout le
   vocabulaire des portes : le pays est une porte, une place est une
   porte. Ce qui suit n'ajoute que ce qui n'existait pas — un champ à
   remplir, une rangée d'actions, et la pastille d'un drapeau.
   ============================================================ */

.entree__aide {
  margin: 6px 0 0;
  font-size: var(--t-md);
  line-height: 1.45;
  color: var(--doux);
}

/* Le drapeau remplit sa pastille au lieu de flotter dedans : c'est lui
   qu'on reconnaît avant de lire le nom du pays. Fond neutre — un ocre
   derrière un drapeau en changerait les couleurs. */
.classe__n--drapeau {
  background: var(--fond2);
  font-size: 30px;
  line-height: 1;
  /* Le dessin est en 3:2 et la pastille est carrée : le coin est donc
     arrondi ici, et non dans le SVG, pour que le drapeau garde ses
     angles droits partout ailleurs. */
  overflow: hidden;
  padding: 0 3px;
}

/* ============================================================
   LES DRAPEAUX — dessinés, jamais écrits

   Un emoji de drapeau n'est pas un caractère mais une paire de lettres
   que la police assemble ; Windows ne le fait pas, et « 🇨🇲 Cameroun »
   s'y lisait « CM Cameroun ». On les dessine donc (js/drapeaux.js), et
   ce qui suit ne fait que leur donner une taille selon l'endroit.
   ============================================================ */

.drapeau {
  display: block;
  width: 100%;
  height: auto;
}

/* Au fil d'une ligne de texte — sous une place, dans l'écran du compte.
   Calé sur la hauteur des minuscules plutôt que sur la ligne entière,
   sans quoi il monte au-dessus du texte qu'il accompagne. */
.drapeau--ligne {
  display: inline-block;
  width: 1.45em;
  height: auto;
  vertical-align: -0.16em;
  margin-right: 0.35em;
}

/* AU BOUT DU TITRE de l'écran des chapitres — 25/09/2026. Il remplace
   une phrase et un menu déroulant : « Les leçons de 3ᵉ 🇹🇩 » dit le
   programme sur lequel on travaille sans prendre une ligne de plus.

   Sa taille est en `em` : le titre est géant et il rétrécit d'un cran
   sur les petits écrans (voir `--t-4xl`) ; un drapeau en pixels y serait
   un timbre à 390 px et une vignette perdue à 1 200. La marge est AVANT,
   et non après : c'est le titre qui le précède, pas lui qui annonce un
   texte — et elle remplace l'espace, qu'on ne met pas, pour qu'un titre
   trop long ne renvoie jamais le drapeau seul à la ligne. */
.drapeau--titre {
  display: inline-block;
  width: 0.9em;
  height: auto;
  vertical-align: -0.02em;
  margin-left: 0.28em;
}

/* L'e-mail d'un parent, facultatif (15/10/2026) : sa note colle au champ. */
.entree__aide--champ { margin: -6px 0 0; font-size: var(--t-sm); }
.entree__forme [hidden] { display: none; }

.entree__forme {
  display: grid;
  gap: 12px;
  margin-top: 18px;
}

.entree__champ {
  font: inherit;
  font-size: var(--t-xl);
  color: var(--texte);
  background: var(--carte);
  border: 1px solid var(--ligne-nette);
  border-radius: var(--r);
  padding: 14px 16px;
  /* 56 px : on écrit son prénom avec le pouce, souvent debout. */
  min-height: 56px;
  width: 100%;
}
.entree__champ:focus-visible { outline: 2px solid var(--ocre); outline-offset: 2px; }

.entree__valider {
  font: inherit;
  font-size: var(--t-lg);
  font-weight: 700;
  color: var(--plein-texte);
  background: var(--plein);
  border: none;
  border-radius: var(--r);
  padding: 16px;
  min-height: 56px;
  cursor: pointer;
}
.entree__valider:disabled {
  background: var(--inerte);
  color: var(--inerte-texte);
  cursor: default;
}

/* Le bouton posé seul sur un écran, sans formulaire autour pour
   l'étirer ni pour l'espacer. « Se connecter » est le seul cas : c'est
   le seul écran où l'unique action ne demande rien à remplir. */
.entree__valider--seul { width: 100%; margin-top: 24px; }

.entree__erreur {
  margin: 0;
  font-size: var(--t-md);
  line-height: 1.45;
  color: var(--faux);
}
/* Vide, il ne doit pas réserver de place : le message d'erreur
   n'existe que le jour où il a quelque chose à dire. */
.entree__erreur:empty { display: none; }

/* Une rangée d'actions sous une place : trois verbes courts, et la
   suppression qu'on ne confond pas avec eux. */
.entree__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}
.entree__action {
  font: inherit;
  font-size: var(--t-base);
  color: var(--texte);
  background: var(--fond2);
  border: 1px solid var(--ligne-nette);
  border-radius: 10px;
  padding: 10px 14px;
  min-height: 44px;
  cursor: pointer;
}
.entree__action:disabled { color: var(--inerte-texte); background: var(--inerte); cursor: default; }
.entree__action--danger { color: var(--faux); border-color: var(--faux); background: var(--faux-fond); }
.entree__action--danger:disabled { color: var(--inerte-texte); border-color: var(--ligne-nette); background: var(--inerte); }

.entree__confirme { display: grid; gap: 10px; }

/* Un lien, pas un bouton : « Modifier les places » est une porte de
   service, et ne doit pas peser autant que les vignettes au-dessus. */
.entree__lien {
  display: block;
  margin: 18px auto 0;
  font: inherit;
  font-size: var(--t-md);
  color: var(--doux);
  background: none;
  border: none;
  text-decoration: underline;
  min-height: 44px;
  cursor: pointer;
}

/* ============================================================
   LE COMPTE, en haut de « Se connecter »

   NI VERT NI ROUGE, ET C'EST DÉLIBÉRÉ. `--juste` et `--faux` sont
   réservés à la bonne et à la mauvaise réponse — « nulle part ailleurs »,
   dit la palette. Un abonnement actif peint en vert volerait au verdict
   d'un exercice la seule couleur qui lui appartienne, et un élève
   apprendrait à lire le vert comme « tout va bien » plutôt que comme
   « c'est juste ». L'état se dit donc en mots, et ce qui réclame un geste
   porte la couleur principale — la terre — sur le bord gauche.
   ============================================================ */

.compte {
  margin-top: 18px;
  padding: 16px;
  background: var(--carte);
  border: 1px solid var(--ligne-nette);
  border-radius: var(--r);
  box-shadow: var(--ombre);
}

/* Une étiquette, pas un titre : le bloc s'annonce et s'efface. Le titre
   de l'écran, c'est « Se connecter ». */
.compte__t {
  margin: 0 0 10px;
  font-family: inherit;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--doux);
}

/* Le numéro : c'est lui qu'on cherche des yeux pour vérifier qu'on est
   sur le bon compte. */
.compte__numero {
  margin: 0;
  font-size: var(--t-xl);
  font-weight: 700;
  color: var(--texte);
}

.compte__etat {
  margin: 8px 0 0;
  font-size: var(--t-md);
  line-height: 1.45;
  color: var(--doux);
}

/* Abonnement actif : rien à faire, donc rien qui attire l'œil. */
.compte__etat--bon { color: var(--texte); }

/* Il faut se reconnecter : le seul cas qui demande un geste, et le seul
   qui se colore. */
.compte__etat--attention {
  padding: 10px 12px;
  border-left: 3px solid var(--terre);
  background: var(--terre-clair);
  border-radius: 0 10px 10px 0;
  color: var(--texte);
}

/* Le pays qui servira à lire le numéro tapé : sans lui, un Sénégalais
   qui écrit « 77 … » ne comprendrait pas pourquoi on lui parle du
   Cameroun. */
.compte__pays {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: var(--t-base);
  color: var(--doux);
}

/* « Lequel de ces élèves es-tu ? » — le bloc qui ne paraît que
   lorsqu'un deuxième téléphone rejoint un compte déjà habité. */
.compte--rattacher { margin-top: 12px; }
.compte--rattacher[hidden] { display: none; }

.rattacher + .rattacher {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--ligne);
}
.rattacher__qui {
  margin: 0;
  font-size: var(--t-lg);
  font-weight: 700;
  color: var(--texte);
}
/* Le lien « quelqu'un de nouveau » se range à gauche sous les choix, et
   non centré comme les autres liens : ce n'est pas l'issue de l'écran,
   c'est la dernière réponse d'une liste de réponses. */
.rattacher .entree__lien { margin: 8px 0 0; }

/* Les comptes de la famille (01/10/2026) — dans « Mon compte », une
   liste et non des portes : on y lit qui est là, on ne l'ouvre pas ici. */
.comptes { list-style: none; margin: 0 0 12px; padding: 0; }
.comptes__ligne {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--ligne);
}
.comptes__ligne:last-child { border-bottom: 0; }
.comptes__qui { font-size: var(--t-lg); font-weight: 700; color: var(--texte); }
.comptes__classe { flex: 1; font-size: var(--t-base); color: var(--doux); }
.comptes__ici {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--terre);
}
/* Ce qui reste à chaque élève abonné (« 23 jours »), au bout de la ligne. */
.comptes__reste { font-size: var(--t-sm); color: var(--doux); font-variant-numeric: tabular-nums; }

/* ============================================================
   LE COMPTE À REBOURS (01/10/2026) — js/compte/rebours.mjs

   Les couleurs de l'application ont chacune UN sens (le vert, c'est la
   bonne réponse et rien d'autre) : le compteur n'en emprunte donc aucune
   qui dirait « juste » ou « faux ». Loin de l'échéance il est brun et
   calme ; la dernière semaine il prend l'ocre de l'action — il y a un
   geste à faire, renouveler ; le dernier jour, la terre, pleine. La
   phrase change en même temps : la couleur ne parle jamais seule.
   ============================================================ */
.rebours__cases { display: flex; gap: 8px; }
.rebours__case {
  flex: 1;
  min-width: 0;
  padding: 10px 4px 8px;
  text-align: center;
  background: var(--fond);
  border: 1px solid var(--ligne-nette);
  border-radius: 12px;
}
.rebours__valeur {
  display: block;
  font-family: var(--police-titre);
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--texte);
}
.rebours__unite {
  display: block;
  margin-top: 4px;
  font-size: var(--t-xs);
  color: var(--doux);
}
.rebours__phrase { margin: 10px 0 0; font-size: var(--t-md); line-height: 1.45; color: var(--texte); }
.rebours[data-ton="proche"] .rebours__case { border-color: var(--ocre); background: var(--ocre-clair); }
.rebours[data-ton="urgent"] .rebours__case { border-color: var(--terre); background: var(--terre-clair); }
.rebours[data-ton="urgent"] .rebours__valeur { color: var(--terre); }
.rebours[data-ton="fini"] .rebours__phrase {
  padding: 10px 12px;
  border-left: 3px solid var(--terre);
  background: var(--terre-clair);
  border-radius: 0 10px 10px 0;
}
.rebours--compact .rebours__cases { gap: 4px; }
.rebours--compact .rebours__case { padding: 4px 2px; border-radius: 8px; }
.rebours--compact .rebours__valeur { font-size: 15px; }
.rebours--compact .rebours__unite { margin-top: 1px; font-size: 10px; }

/* Sous une porte de « Choisis ton compte » : ouvert ailleurs, ou sur ce
   téléphone seulement. Une précision, pas une alerte. */
.porte__s--ailleurs { font-size: var(--t-sm, var(--t-base)); color: var(--terre); }

/* Le prénom dans la barre du haut : le seul chemin vers « Qui
   travaille ? ». Discret — c'est un repère, pas une action qu'on
   propose. Sur le brun de la barre depuis le 22/09, comme le
   « Se connecter » de la vitrine : c'est le même geste, dire qui l'on
   est, et il doit se reconnaître d'un écran à l'autre. */
.barre__place {
  flex: none;
  font: inherit;
  font-size: var(--t-base);
  font-weight: 700;
  color: #F3E0BC;
  background: rgba(243, 224, 188, .08);
  border: 1px solid rgba(243, 224, 188, .3);
  border-radius: 999px;
  padding: 8px 14px;
  min-height: 44px;
  max-width: 34vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

/* ============================================================
   LA VITRINE — la page qui dit ce qu'est Scolia

   CE N'EST PAS UN ÉCRAN, C'EST UNE PAGE, et c'est ce qui commande
   tout ce qui suit. Les autres écrans tiennent dans la colonne de
   560 px de `.app` : une chose à la fois, un bouton en bas, rien qui
   distraie — c'est fait pour quelqu'un qui TRAVAILLE. Une vitrine,
   personne ne la travaille : on la parcourt, souvent d'un pouce,
   souvent avant d'avoir rien décidé. Elle sort donc de la coquille et
   se déroule en bandes pleine largeur.

   CE QU'ELLE EMPRUNTE AUX SITES D'AUJOURD'HUI : une barre collante et
   floutée, un héros sombre avec un halo, l'aperçu de l'application
   dans un téléphone, des cartes qui se soulèvent, des étapes
   numérotées, un pied de page. CE QU'ELLE NE LEUR EMPRUNTE PAS :
   leurs polices — Fraunces est dans le dépôt, et une requête vers
   fonts.googleapis.com casserait la première visite d'un élève sans
   réseau. Les couleurs sont celles de la charte Sankofa.

   LE HÉROS EST SOMBRE DANS LES DEUX THÈMES, et c'est voulu : le brun
   profond est l'un des fonds de la charte, il fait ressortir l'ocre du
   bouton, et il évite qu'une page de présentation soit un mur de
   sable. Ses couleurs sont donc écrites en dur plutôt que prises aux
   jetons — un jeton qui s'inverse en thème sombre rendrait ici un
   héros clair posé sur une page claire.
   ============================================================ */

/* La coquille s'ouvre. Posée par ecranVitrine, retirée par app.js dès
   qu'on la quitte : la classe ne survit jamais à un autre écran. */
.app--large { max-width: none; padding-left: 0; padding-right: 0; }

/* Le seul endroit où la largeur du texte se décide. Tout ce qui est
   une bande de couleur la traverse ; tout ce qui est du texte s'y
   arrête. */
.vitrine__in {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ---------- la barre collante ---------- */

.vitrine__barre {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(46, 28, 18, .82);
  /* Le flou est un agrément, pas une dépendance : un WebView qui ne le
     connaît pas garde un fond opaque à 82 %, et la barre reste lisible. */
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(243, 224, 188, .14);
}

.vitrine__barre-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 10px;
  padding-bottom: 10px;
}

.vitrine__marque { display: flex; align-items: center; gap: 10px; }

.vitrine__logo {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  display: block;
}

.vitrine__nom {
  font-family: var(--police-titre);
  font-size: var(--t-xl);
  font-weight: 700;
  letter-spacing: -.01em;
  color: #FBF5EA;
}

/* Cerclé et non plein : le bouton plein de cette page est
   « Commencer », et il ne doit y en avoir qu'un. */
.vitrine__connexion {
  flex: none;
  font: inherit;
  font-size: var(--t-base);
  font-weight: 700;
  color: #F3E0BC;
  background: rgba(243, 224, 188, .08);
  border: 1px solid rgba(243, 224, 188, .32);
  border-radius: 999px;
  padding: 10px 18px;
  min-height: 44px;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease;
}
.vitrine__connexion:hover {
  background: rgba(243, 224, 188, .16);
  border-color: rgba(243, 224, 188, .5);
}

/* ---------- le héros ---------- */

.vitrine__hero {
  position: relative;
  overflow: hidden;
  background: #2E1C12;
  color: #FBF5EA;
  padding: 48px 0 56px;
}

/* Le halo. Décoratif au sens propre : il ne porte aucune information,
   et ne doit donc jamais intercepter un toucher. */
.vitrine__hero::before {
  content: '';
  position: absolute;
  top: -320px;
  left: 50%;
  transform: translateX(-50%);
  width: 780px;
  height: 780px;
  background: radial-gradient(circle, rgba(225, 154, 46, .22) 0%, rgba(225, 154, 46, 0) 62%);
  pointer-events: none;
}

.vitrine__hero-in { position: relative; }

.vitrine__pastille {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 18px;
  padding: 6px 14px;
  background: rgba(225, 154, 46, .14);
  border: 1px solid rgba(225, 154, 46, .32);
  border-radius: 999px;
  color: #E19A2E;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.vitrine__pastille::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #E19A2E;
}

.vitrine__titre {
  margin: 0 0 18px;
  font-family: var(--police-titre);
  font-weight: 700;
  /* clamp : le même titre tient sur un 360 px et remplit un écran
     large, sans qu'on ait à écrire trois points de rupture. */
  font-size: clamp(31px, 7.4vw, 56px);
  line-height: 1.08;
  letter-spacing: -.025em;
}

.vitrine__accent { color: #E19A2E; font-style: italic; }

.vitrine__phrase {
  margin: 0 0 28px;
  max-width: 34em;
  font-size: var(--t-lg);
  line-height: 1.6;
  color: #DCC7A8;
}

.vitrine__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.vitrine__commencer {
  font: inherit;
  font-size: var(--t-lg);
  font-weight: 700;
  color: #3A2418;
  background: var(--ocre);
  border: none;
  border-radius: 14px;
  padding: 16px 30px;
  min-height: 56px;
  cursor: pointer;
  box-shadow: 0 8px 26px rgba(225, 154, 46, .28);
  transition: transform .15s ease, box-shadow .2s ease, background .2s ease;
}
.vitrine__commencer:hover {
  background: #EDAA44;
  transform: translateY(-1px);
  box-shadow: 0 12px 30px rgba(225, 154, 46, .38);
}
.vitrine__commencer:active { transform: none; }

.vitrine__second {
  display: inline-flex;
  align-items: center;
  font-size: var(--t-md);
  font-weight: 700;
  color: #F3E0BC;
  text-decoration: none;
  border: 1px solid rgba(243, 224, 188, .3);
  border-radius: 14px;
  padding: 15px 22px;
  min-height: 56px;
  box-sizing: border-box;
}
/* La flèche est séparée par une marge et non par une espace : une
   espace dans `content` se ramasse, et le signe venait se coller au
   dernier mot. */
.vitrine__second::after { content: '↓'; margin-left: 9px; }
.vitrine__second:hover { background: rgba(243, 224, 188, .1); }

.vitrine__prix {
  margin: 16px 0 0;
  font-size: var(--t-base);
  color: #B79B7C;
}

/* ---------- l'application dans un téléphone ---------- */

.vitrine__vue {
  position: relative;
  margin-top: 40px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
}

.vitrine__tel {
  flex: none;
  width: 246px;
  background: #1C110A;
  border: 2px solid rgba(243, 224, 188, .12);
  border-radius: 34px;
  padding: 9px;
  box-shadow: 0 30px 60px rgba(0, 0, 0, .45), 0 0 0 7px rgba(225, 154, 46, .05);
}

.vitrine__ecran {
  background: var(--sable);
  border-radius: 26px;
  padding: 16px 14px;
  /* Le contenu de l'aperçu est une maquette : il garde les couleurs de
     l'application CLAIRE dans les deux thèmes, parce qu'il montre ce
     qu'on verra, pas ce qu'on regarde. */
  color: #3A2418;
}

.vitrine__ecran-barre {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 700;
  color: #8A694E;
  line-height: 1.25;
}

.vitrine__ecran-classe {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px; height: 26px;
  border-radius: 8px;
  background: var(--ocre);
  color: #3A2418;
  font-size: 12px;
}

.vitrine__enonce {
  margin-top: 12px;
  background: #FFFCF4;
  border: 1px solid #F2E7D2;
  border-radius: 14px;
  padding: 12px;
}
.vitrine__enonce-t {
  margin: 0 0 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #A65128;
}
.vitrine__enonce-c { margin: 0; font-size: 16px; font-weight: 600; }

.vitrine__ecran-aide {
  margin: 12px 0 8px;
  font-size: 11px;
  color: #8A694E;
}

.vitrine__marche {
  border-radius: 12px;
  padding: 9px 10px;
  margin-bottom: 7px;
  background: #F3E0BC;
  font-size: 12px;
  line-height: 1.35;
}
.vitrine__marche--encours {
  background: #FFFCF4;
  border: 1px dashed #E7D6B4;
}
.vitrine__marche-t { display: flex; align-items: center; gap: 8px; font-weight: 600; }
.vitrine__marche-p { margin: 5px 0 0 26px; font-size: 10.5px; color: #8A694E; }

.vitrine__coche {
  flex: none;
  display: grid;
  place-items: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: #297646;
  color: #FFFCF4;
  font-size: 11px;
  font-weight: 700;
}
.vitrine__marche--encours .vitrine__coche { background: #E7D6B4; color: #8A694E; }

.vitrine__ecran-bouton {
  margin-top: 10px;
  border-radius: 12px;
  background: var(--ocre);
  color: #3A2418;
  text-align: center;
  padding: 11px;
  font-size: 13px;
  font-weight: 700;
}

/* La mascotte se tient DEBOUT à côté du téléphone : son dessin pose la
   pointe du stylo sur une ligne de sol, et la décoller la ferait
   flotter. D'où l'alignement par le bas de la rangée. */
.vitrine__mascotte {
  flex: none;
  width: 92px;
  height: auto;
  margin-bottom: -6px;
}

/* ---------- les chiffres ---------- */

.vitrine__chiffres { background: var(--fond2); }

.vitrine__chiffres-in {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 4px;
  padding-top: 22px;
  padding-bottom: 22px;
}

.vitrine__chiffre {
  flex: 1 1 88px;
  text-align: center;
  padding: 4px 6px;
}

/* En police système, sans exception : Fraunces ne porte jamais un
   texte qui contient un chiffre — ses chiffres sont à fort contraste
   et sa virgule est fine. « 12 000 » est exactement le cas visé. */
.vitrine__n {
  display: block;
  font-size: var(--t-3xl);
  line-height: 1.1;
  color: var(--terre);
  letter-spacing: -.02em;
}
.vitrine__quoi {
  display: block;
  margin-top: 2px;
  font-size: var(--t-base);
  color: var(--doux);
}

/* ---------- les sections ---------- */

.vitrine__section { padding: 56px 0; }
.vitrine__section--creme { background: var(--fond2); }

.vitrine__entete { margin-bottom: 28px; }

.vitrine__oeil {
  margin: 0 0 10px;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--terre);
}

.vitrine__h2 {
  margin: 0;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: clamp(25px, 5.4vw, 38px);
  line-height: 1.16;
  letter-spacing: -.02em;
  max-width: 18em;
}

/* ---------- les cartes ---------- */

.vitrine__blocs {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
}

.vitrine__bloc {
  background: var(--carte);
  border: 1px solid var(--ligne);
  border-radius: 20px;
  padding: 22px;
  box-shadow: var(--ombre);
  transition: transform .18s ease, border-color .18s ease;
}
.vitrine__bloc:hover { transform: translateY(-2px); border-color: var(--ligne-nette); }

.vitrine__bloc-i {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border-radius: 13px;
  background: var(--ocre-clair);
  color: var(--terre);
  margin-bottom: 14px;
}
.vitrine__bloc-i .glyphe { width: 24px; height: 24px; }

.vitrine__bloc-t {
  margin: 0 0 8px;
  font-family: var(--police-titre);
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: 1.22;
}

.vitrine__bloc-c {
  margin: 0;
  font-size: var(--t-md);
  line-height: 1.55;
  color: var(--doux);
}

/* ---------- les trois étapes ---------- */

.vitrine__etapes {
  display: grid;
  gap: 22px;
  grid-template-columns: 1fr;
}

.vitrine__etape { position: relative; }

.vitrine__etape-i {
  width: 74px;
  height: auto;
  display: block;
  margin-bottom: 8px;
}

.vitrine__num {
  display: block;
  margin-bottom: 4px;
  font-size: var(--t-base);
  font-weight: 700;
  letter-spacing: .14em;
  color: var(--terre);
}

/* ---------- le compte qu'il n'y a pas ---------- */

.vitrine__note {
  background: var(--fond2);
  border-radius: 22px;
  padding: 26px;
}
.vitrine__section--creme .vitrine__note { background: var(--carte); }

.vitrine__note-t {
  margin: 0 0 10px;
  font-family: var(--police-titre);
  font-size: var(--t-xl);
  font-weight: 700;
}
.vitrine__note-c {
  margin: 0;
  max-width: 46em;
  font-size: var(--t-md);
  line-height: 1.55;
  color: var(--doux);
}
.vitrine__note-c + .vitrine__note-c { margin-top: 12px; }

/* ---------- le dernier mot ---------- */

.vitrine__fin {
  background: #2E1C12;
  color: #FBF5EA;
  text-align: center;
  padding: 56px 0;
}

.vitrine__fin-t {
  margin: 0 0 22px;
  font-family: var(--police-titre);
  font-weight: 700;
  font-size: clamp(25px, 5.4vw, 38px);
  line-height: 1.16;
  letter-spacing: -.02em;
}

/* ---------- le pied ---------- */

.vitrine__pied {
  background: #241409;
  color: #B79B7C;
  padding: 26px 0;
  font-size: var(--t-base);
  text-align: center;
}
.vitrine__pied p { margin: 0; }
.vitrine__pied-s { margin-top: 5px; color: #8A6B4E; }

/* La ligne de droits, séparée par un filet : c est une mention légale,
   pas une phrase de présentation, et l oeil doit pouvoir la sauter. */
.vitrine__pied-droits {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--ligne);
  font-size: var(--t-sm);
  color: var(--inerte-texte, var(--texte-doux));
  opacity: .85;
}

/* ---------- l'écran large ----------
   Un seul point de rupture, et il tombe là où le héros cesse d'être
   lisible en une colonne : sous 900 px on empile, au-dessus le
   téléphone se met à côté du titre. */
@media (min-width: 900px) {
  .vitrine__in { padding: 0 32px; }

  .vitrine__hero { padding: 72px 0 84px; }
  .vitrine__hero-in {
    display: grid;
    grid-template-columns: 1.05fr .95fr;
    gap: 48px;
    align-items: center;
  }
  .vitrine__vue { margin-top: 0; }
  .vitrine__tel { width: 288px; }
  .vitrine__mascotte { width: 132px; }

  .vitrine__section { padding: 84px 0; }
  .vitrine__entete { margin-bottom: 40px; }

  /* SIX CARTES, DEUX RANGÉES DE TROIS. Elles étaient cinq, et la
     seconde rangée demandait d'être recentrée à la main ; le bloc des
     professeurs (22/09) a réglé ça tout seul. Trois colonnes franches
     suffisent donc de nouveau. */
  .vitrine__blocs { grid-template-columns: repeat(3, 1fr); gap: 18px; }

  .vitrine__etapes { grid-template-columns: repeat(3, 1fr); gap: 32px; }
  .vitrine__note { padding: 34px; }
  .vitrine__fin { padding: 84px 0; }
}

/* Sur un écran très large, la phrase du héros peut respirer. */
@media (min-width: 1200px) {
  .vitrine__phrase { font-size: var(--t-xl); }
}

/* Quelqu'un qui a demandé moins d'animations n'en veut pas ici non
   plus : le soulèvement des cartes et celui du bouton disparaissent. */
@media (prefers-reduced-motion: reduce) {
  .vitrine__bloc, .vitrine__commencer { transition: none; }
  .vitrine__bloc:hover, .vitrine__commencer:hover { transform: none; }
}


/* ============================================================
   OÙ J'EN SUIS — l'écran que le parent vient lire

   Des phrases, pas des jauges : ni barre de progression, ni
   pourcentage, ni couleur de statut. Ce qu'un parent veut savoir se lit
   en dix secondes, et rien ici ne doit ressembler à un bulletin.
   ============================================================ */

.bilan__bloc { margin-top: 24px; }

.bilan__t {
  margin: 0 0 8px;
  font-family: var(--police-titre);
  font-size: var(--t-lg);
  color: var(--terre);
}

.bilan__ligne { margin: 0 0 12px; }

.bilan__fait {
  margin: 0;
  font-size: var(--t-lg);
  line-height: 1.35;
  color: var(--texte);
}

/* L'explication sous un chiffre : ce que « maîtrisée » veut dire, ce
   qu'une épreuve compte. Plus petite, mais pas grise au point d'être
   illisible en plein soleil. */
.bilan__note {
  margin: 4px 0 0;
  font-size: var(--t-md);
  line-height: 1.45;
  color: var(--doux);
}

.bilan__liste {
  margin: 0;
  padding-left: 20px;
  font-size: var(--t-lg);
  line-height: 1.5;
  color: var(--texte);
}

.bilan__vide {
  margin: 12px 0 0;
  font-size: var(--t-lg);
  line-height: 1.45;
  color: var(--doux);
}

/* « Vous êtes parent ? » (15/10/2026) : le lien que le parent ouvre chez
   lui. Un cadre, pour qu'il ne se lise pas comme une ligne du bilan. */
.suivi-parents {
  padding: 16px;
  border: 1px solid var(--ligne-nette);
  border-radius: var(--r);
  background: var(--fond2);
}
.suivi-parents__lien {
  display: block;
  box-sizing: border-box;
  width: 100%;
  margin: 12px 0 10px;
  padding: 10px 12px;
  font: inherit;
  font-size: var(--t-md);
  color: var(--texte);
  background: var(--fond);
  border: 1px solid var(--ligne-nette);
  border-radius: 10px;
  resize: none;
  word-break: break-all;
  line-height: 1.4;
}
.suivi-parents__envoi { display: grid; gap: 10px; margin-top: 12px; }
.suivi-parents__ou { margin-top: 16px; }
.suivi-parents .entree__valider { width: 100%; }
.suivi-parents__message:empty { display: none; }
.suivi-parents .entree__lien { margin-top: 6px; }
.suivi-parents .entree__lien[hidden] { display: none; }

/* La page du parent : ce qui se dit sous le bilan. */
.suivi__pied { margin-top: 32px; }

/* ============================================================
   CE QUI EST FERMÉ — 25/09/2026

   Le bloc qui remplace une leçon, un exercice ou une épreuve réservés
   (js/verrou-ecran.js). Il ressemble à une CARTE, pas à une alerte : ce
   n'est pas une erreur, c'est une offre. Le verrou est débrayé jusqu'au
   paiement, donc personne ne voit ces styles aujourd'hui — sauf par
   « ?verrou=1 », qui sert à les regarder.
   ============================================================ */

.ferme {
  margin-top: 18px;
  padding: 18px;
  background: var(--carte);
  border: 1px solid var(--ligne-nette);
  border-radius: var(--r);
  box-shadow: var(--ombre);
}

/* « Réservé » en petites capitales plutôt qu'un cadenas dessiné : un
   dessin de moins à maintenir, et un mot qu'un lecteur d'écran lit. */
.ferme__etiquette {
  margin: 0 0 8px;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--doux);
}

.ferme__t {
  margin: 0 0 10px;
  font-family: Fraunces, Georgia, serif;
  font-size: var(--t-2xl);
  line-height: 1.15;
  color: var(--texte);
}

.ferme__d {
  margin: 0 0 12px;
  font-size: var(--t-md);
  line-height: 1.5;
  color: var(--texte);
}

/* Le prix se lit sans être crié : c'est un renseignement, pas un appel. */
.ferme__prix {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--ligne);
  font-size: var(--t-md);
  line-height: 1.5;
  color: var(--texte);
}

.ferme__aide {
  margin: 8px 0 0;
  font-size: var(--t-base);
  line-height: 1.45;
  color: var(--doux);
}

/* Une tuile d'exercice fermée reste TOUCHABLE — c'est en la touchant
   qu'on apprend ce qui l'ouvre. Elle s'annonce par sa ligne du dessous
   (« Réservé aux abonnés »), et non par un gris qui ressemble à une
   panne. */
.exo--ferme .exo__n { opacity: .55; }

/* ============================================================
   L'ONGLET « TARIFS » — 02/10/2026, lancement au Cameroun

   Quatre formules en cartes qu'on touche, puis le dépôt. Aucune
   formule n'est « recommandée » en couleur : la grille se lit telle
   quelle, et l'économie se dit en francs sous chaque prix.
   ============================================================ */

.tarifs__liste {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 14px 0;
}

.tarifs__formule {
  display: grid;
  gap: 4px;
  text-align: left;
  font: inherit;
  color: var(--texte);
  background: var(--fond2);
  border: 2px solid var(--ligne-nette);
  border-radius: var(--r);
  padding: 14px;
  min-height: 96px;
  cursor: pointer;
}
.tarifs__formule:hover, .tarifs__formule:focus-visible { border-color: var(--terre); }
.tarifs__formule:focus-visible { outline: 2px solid var(--ocre); outline-offset: 2px; }

.tarifs__duree { font-size: var(--t-md); font-weight: 700; color: var(--terre); }
.tarifs__prix { font-size: var(--t-xl); font-weight: 800; }
.tarifs__detail { font-size: var(--t-sm); color: var(--doux); line-height: 1.35; }

.tarifs__pour { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.tarifs__pour .entree__aide { width: 100%; margin: 0; }
.tarifs__pour--actif { border-color: var(--terre); background: var(--terre-clair); color: var(--terre); font-weight: 700; }

.tarifs__montant { margin: 0 0 8px; font-size: var(--t-3xl); font-weight: 800; color: var(--texte); }
.tarifs__etapes { margin: 8px 0 0; padding-left: 1.3em; line-height: 1.55; font-size: var(--t-md); }
.tarifs__etapes li + li { margin-top: 6px; }
.tarifs__numero { font-size: var(--t-lg); letter-spacing: .02em; white-space: nowrap; }
.tarifs__verifier { margin-top: 14px; }
/* Le paiement en ligne (15/10/2026) : le bouton large, puis le dépôt
   manuel sous un titre qui dit qu'il s'agit d'une autre voie. */
.tarifs__enligne { margin: 4px 0 18px; }
.tarifs__enligne .entree__aide { margin-top: 0; }
.tarifs__payer { width: 100%; }
.tarifs__ou { margin: 6px 0 4px; font-size: var(--t-md); font-weight: 700; color: var(--doux); }
.tarifs__historique { margin: 0; padding-left: 1.1em; line-height: 1.6; font-size: var(--t-md); }

/* QUATRE ONGLETS sur un téléphone de 360 px : on resserre plutôt que de
   faire défiler la rangée — un onglet caché à droite n'existe pas. */
.onglets .onglet { min-width: 0; }
@media (max-width: 420px) {
  .onglets { gap: 6px; }
  .onglets .onglet { padding: 10px 4px; font-size: var(--t-sm); }
}

/* « Voir les tarifs et s'abonner », sous le prix d'un écran fermé : un
   lien habillé en bouton, parce qu'il change d'écran. */
.ferme__tarifs {
  display: block;
  margin-top: 14px;
  text-align: center;
  text-decoration: none;
}

/* « Composer #150*47# » : le clavier du téléphone s'ouvre, code tapé. */
.tarifs__composer {
  display: inline-flex;
  align-items: center;
  margin-top: 10px;
  text-decoration: none;
  font-weight: 700;
}

/* LA FORMULE TEST (administrateur seul) : en pointillés, pour qu'on ne
   la prenne jamais pour une offre. */
.tarifs__formule--test { border-style: dashed; background: var(--carte); }

/* ============================================================
   « RÉSERVÉ AUX ABONNÉS » — 02/10/2026, demandé par Marc

   Une étiquette qu'on voit AVANT de toucher : sur les tuiles de leçon
   fermées, sur les exercices, et en tête du tableau de bord d'un élève
   pas encore abonné. L'ocre, pas le rouge : ce n'est pas une erreur.
   ============================================================ */
.marque-abonnes {
  display: inline-block;
  margin-top: 6px;
  padding: 2px 10px;
  border-radius: 999px;
  border: 1px solid var(--ocre);
  background: var(--ocre-clair);
  color: var(--texte);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.onglet__reserve { font-size: .85em; }
/* Le compte à rebours et le bandeau, en tête du tableau de bord. */
.compte--tableau { margin: 12px 0; padding: 12px 14px; }
.compte--tableau .compte__t { font-size: var(--t-md); margin: 0 0 8px; }
.compte--non-abonne .entree__aide { margin: 8px 0; }

/* L'œil du mot de passe (02/10/2026). 44 px : une cible de pouce. */
.champ-passe { position: relative; }
.champ-passe .entree__champ { padding-right: 56px; }
.champ-passe__oeil {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; display: grid; place-items: center;
  background: none; border: 0; border-radius: var(--r); color: var(--texte); cursor: pointer;
}
.champ-passe__oeil:focus-visible { outline: 2px solid var(--ocre); outline-offset: 2px; }

/* « Qu'est-ce que Scolia ? » (02/10/2026) : le cinquième onglet passe sous
   les quatre autres, sur toute la largeur — cinq pastilles sur un écran
   de 390 px n'auraient plus laissé lire aucun mot. */
.onglets { flex-wrap: wrap; }
.onglets .onglet--scolia { flex-basis: 100%; }
