/* =========================================================================
   ColorLearn — css/app.css
   Composants ajoutés à la v1 : pied de page global, modal de génération,
   skeletons, panneau de configuration (wizard), filtres du sommaire,
   bibliothèque, tableau de bord, notifications.

   Règle absolue : tout ce qui est ici est de l'INTERFACE. Rien de tout cela
   ne s'imprime (bloc @media print en fin de fichier).
   ========================================================================= */

/* ---------- Utilitaires ---------- */

/* L'attribut `hidden` doit gagner. Sans cela, toute classe portant un
   `display` (.pile, .setup__grille…) le neutralise silencieusement — et un
   bloc censé être masqué, comme le champ de clé en mode serveur, reste
   affiché. */
[hidden] {
  display: none !important;
}

.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Le lien d'évitement : invisible tant qu'il n'a pas le focus, puis
   franchement visible. On le sort de l'écran plutôt que de le masquer
   avec `display:none`, qui le retirerait aussi de l'ordre de tabulation
   et le rendrait donc parfaitement inutile. */
.lien-evitement {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, -120%);
  z-index: 1000;
  padding: 10px 22px;
  border: 3px solid var(--encre);
  border-top: 0;
  border-radius: 0 0 14px 14px;
  background: var(--papier);
  color: var(--encre);
  font: 800 15px/1 var(--police-texte);
  text-decoration: none;
  transition: transform 140ms ease-out;
}

.lien-evitement:focus {
  transform: translate(-50%, 0);
}

/* La cible du saut ne doit jamais afficher de contour au clic — seul le
   parcours clavier a besoin du repère. */
main:focus {
  outline: none;
}

main:focus-visible {
  outline: 3px solid #1a73e8;
  outline-offset: 4px;
}

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

.pile {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

/* =========================================================================
   1. PIED DE PAGE GLOBAL (E1 · US1.1)
   ========================================================================= */
.pied-global {
  max-width: 210mm;
  margin: 28px auto 40px;
  padding: 18px 20px 20px;
  background: var(--papier);
  border: var(--trait-fin) solid var(--encre);
  border-radius: var(--rayon);
  box-shadow: 0 2px 14px rgb(0 0 0 / 0.1);
  font-size: 13px;
}

.pied-global__haut {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 18px;
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 2px dashed var(--encre);
}

.pied-global__marque {
  margin: 0;
  font-family: var(--police-titre);
  font-size: 19px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.pied-global__marque span {
  display: block;
  font-family: var(--police-texte);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.pied-global nav {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
}

.pied-global a {
  color: var(--encre);
  font-weight: 700;
  text-decoration: none;
  padding-bottom: 2px;
}

.pied-global__bas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  font-size: 12px;
}

.pied-global__bas p {
  margin: 0;
  max-width: 62ch;
}

.selecteur-langue {
  display: flex;
  gap: 6px;
  align-items: center;
}

.selecteur-langue > span {
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* =========================================================================
   2. MODAL DE GÉNÉRATION (E1 · US1.2)
   ========================================================================= */
.modal-gen {
  width: min(560px, calc(100vw - 32px));
  padding: 0;
  border: var(--trait-epais) solid var(--encre);
  border-radius: var(--rayon);
  background: var(--papier);
  color: var(--encre);
}

.modal-gen::backdrop {
  background: rgb(0 0 0 / 0.55);
}

.modal-gen__corps {
  padding: 18px 20px 20px;
}

.modal-gen h2 {
  margin: 0 0 2px;
  font-family: var(--police-titre);
  font-size: 21px;
  text-transform: uppercase;
}

.modal-gen__sous {
  margin: 0 0 14px;
  font-size: 13px;
}

.modal-gen__ligne {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 12px;
}

/* Vignette de la dernière image produite */
.modal-gen__vignette {
  flex: none;
  width: 88px;
  height: 88px;
  border: var(--trait-fin) dashed var(--encre);
  border-radius: 8px;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--papier);
}

.modal-gen__vignette img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.15);
}

.modal-gen__vignette--pleine {
  border-style: solid;
}

.modal-gen__infos {
  flex: 1;
  min-width: 0;
}

.modal-gen__cadre {
  margin: 0 0 6px;
  font-weight: 800;
  font-size: 14px;
  overflow-wrap: anywhere;
}

/* Barre de progression n/N, dessinée à l'encre */
.modal-gen__barre {
  height: 16px;
  border: var(--trait-fin) solid var(--encre);
  border-radius: 999px;
  overflow: hidden;
  background: var(--papier);
}

.modal-gen__barre i {
  display: block;
  height: 100%;
  width: 0%;
  background-image: repeating-linear-gradient(
    45deg,
    var(--encre) 0 3px,
    transparent 3px 7px
  );
  border-right: 2px solid var(--encre);
  transition: width 220ms var(--crayon-courbe, ease);
}

.modal-gen__compte {
  margin: 6px 0 0;
  font-size: 12.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.modal-gen__erreur {
  margin: 0 0 12px;
  padding: 8px 12px;
  border: var(--trait-fin) solid var(--encre);
  border-left-width: 6px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 700;
}

.modal-gen__erreur[hidden] {
  display: none;
}

.modal-gen__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

.modal-gen .btn {
  border-color: var(--encre);
}

.modal-gen .btn--ghost {
  color: var(--encre);
}

/* =========================================================================
   3. SKELETONS (E1 · US1.3) — shimmer noir & blanc, zéro layout shift
   ========================================================================= */
.image-coloriage.est-en-attente .image-coloriage__zone,
.skeleton {
  position: relative;
  overflow: hidden;
  background: repeating-linear-gradient(
    45deg,
    rgb(0 0 0 / 0.045) 0 6px,
    transparent 6px 12px
  );
}

.image-coloriage.est-en-attente .image-coloriage__zone::after,
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    transparent 24%,
    rgb(0 0 0 / 0.09) 46%,
    rgb(0 0 0 / 0.09) 54%,
    transparent 76%
  );
  transform: translateX(-100%);
  animation: chatoiement 1.5s ease-in-out infinite;
}

@keyframes chatoiement {
  to { transform: translateX(100%); }
}

/* La zone garde son ratio : l'image remplace le skeleton sans décalage. */
.image-coloriage__img {
  animation: apparition 140ms ease-out;
}

@keyframes apparition {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .image-coloriage.est-en-attente .image-coloriage__zone::after,
  .skeleton::after {
    animation: none;
    opacity: 0.5;
    transform: none;
  }
  .image-coloriage__img {
    animation: none;
  }
}

/* =========================================================================
   4. PANNEAU DE CONFIGURATION — le « setup » devient un wizard (E2)
   ========================================================================= */
.setup {
  max-width: 210mm;
  /* La barre d'outils est fixe : on dégage sa hauteur réelle, mesurée par
     js/ui.js dans --toolbar-hauteur (elle change en s'empilant sur mobile). */
  margin: calc(var(--toolbar-hauteur, 44px) + 22px) auto 18px;
  padding: 16px 20px 18px;
  background: var(--papier);
  border: var(--trait-epais) solid var(--encre);
  border-radius: var(--rayon);
  box-shadow: 0 4px 24px rgb(0 0 0 / 0.14);
}

/* La feuille garde ses 72 px de dégagement quand elle est seule sous la
   barre d'outils ; le panneau les a déjà pris, on resserre.
   @media screen est INDISPENSABLE : ce sélecteur (0-2-0) l'emporte sinon sur
   le `.feuille { margin: 0 }` (0-1-0) de styles.css et repousse le contenu
   d'une page à l'impression. */
@media screen {
  .setup + .feuille {
    margin-top: 26px;
  }
}

/* Sur fond blanc, un bouton « fantôme » doit s'écrire à l'encre : hérité
   de la v1, où .btn--ghost vit sur le noir de la barre d'outils. */
.setup .btn--ghost,
.modal-gen .btn--ghost,
.biblio .btn--ghost,
.pied-global .btn--ghost {
  color: var(--encre);
  border-color: var(--encre);
}

.setup__entete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  margin-bottom: 10px;
}

.setup h2 {
  margin: 0;
  font-family: var(--police-titre);
  font-size: 20px;
  text-transform: uppercase;
}

.setup__intro {
  margin: 0 0 12px;
  font-size: 13.5px;
  max-width: 78ch;
}

/* ---------- Le champ unique : « écris, l'IA fait le reste » ---------- */
.setup__demande {
  display: flex;
  gap: 10px;
  align-items: stretch;
  margin-bottom: 6px;
}

.setup__demande input {
  flex: 1;
  min-width: 0;
  font: 700 17px/1.2 var(--police-texte);
  padding: 14px 20px;
  border: var(--trait-epais) solid var(--encre);
  border-radius: 999px;
  background: var(--papier);
  color: var(--encre);
}

.setup__demande input::placeholder {
  font-weight: 400;
  font-style: italic;
  opacity: 0.55;
}

.setup__demande input:focus-visible {
  outline: 3px solid #1a73e8;
  outline-offset: 2px;
}

.setup__go {
  flex: none;
  font: 800 15px/1 var(--police-texte);
  padding: 0 26px;
  border: var(--trait-epais) solid var(--encre);
  border-radius: 999px;
  background: var(--encre);
  color: var(--papier);
  cursor: pointer;
  white-space: nowrap;
}

.setup__go:hover {
  transform: translateY(-1px);
}

.setup__aide {
  margin: 0 0 8px;
  padding-left: 20px;
  font-size: 12.5px;
  font-style: italic;
  opacity: 0.75;
}

.setup__secondaire {
  margin: 0 0 4px;
  padding-left: 18px;
}

/* La ligne de statut ne réserve de la place que lorsqu'elle a quelque
   chose à dire — sinon elle creuse un vide au bas du panneau. */
.setup .panneau-ia__statut:empty {
  display: none;
}

/* ---------- Le reste, replié ---------- */
.setup__avance {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 2px dashed var(--encre);
}

.setup__avance > summary {
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 4px 0;
}

.setup__avance > summary:focus-visible {
  outline: 3px solid #1a73e8;
  outline-offset: 3px;
}

.setup__avance[open] > summary {
  margin-bottom: 10px;
}

@media (max-width: 560px) {
  .setup__demande {
    flex-direction: column;
  }
  .setup__go {
    padding: 14px 26px;
  }
}

.setup__grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px 14px;
  margin-bottom: 12px;
}

.setup__champ {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.setup__champ > span {
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.setup__champ input,
.setup__champ select {
  font: 700 14px/1.2 var(--police-texte);
  padding: 9px 12px;
  border: 2px solid var(--encre);
  border-radius: 999px;
  background: var(--papier);
  color: var(--encre);
  min-width: 0;
}

.setup__champ input:focus-visible,
.setup__champ select:focus-visible {
  outline: 3px solid #1a73e8;
  outline-offset: 2px;
}

.setup__champ--case {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

.setup__champ--case input {
  width: 20px;
  height: 20px;
  flex: none;
  accent-color: var(--encre);
}

.setup__prereglages {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding-top: 10px;
  margin-top: 4px;
  border-top: 2px dashed var(--encre);
}

.setup__prereglages > span {
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.setup__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 12px;
}

.setup__actions .btn {
  border-color: var(--encre);
}

.setup__actions .btn--ghost {
  color: var(--encre);
}

.setup__note {
  margin: 8px 0 0;
  font-size: 11.5px;
  font-style: italic;
}

.setup__graine {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* Squelette de fiche affiché avant qu'une notion ait été choisie (E2 · US2.1).
   On n'estompe QUE les zones réellement en attente : la planche de
   référence et l'en-tête, eux, sont utilisables tout de suite — les
   griser laisserait croire que la page ne sert à rien sans clé API. */
.fiche-en-attente #gen-cartes,
.fiche-en-attente #gen-seconde {
  opacity: 0.5;
}

.fiche-en-attente #gen-cartes::after {
  content: attr(data-attente);
  display: block;
  grid-column: 1 / -1;
  padding: 10px;
  border: var(--trait-fin) dashed var(--encre);
  border-radius: var(--rayon);
  text-align: center;
  font-weight: 800;
  font-size: 13px;
}

@media print {
  /* Sur le papier, une fiche vierge s'assume : elle se remplit au crayon. */
  .fiche-en-attente #gen-cartes,
  .fiche-en-attente #gen-seconde {
    opacity: 1;
  }
  .fiche-en-attente #gen-cartes::after {
    display: none;
  }
}

/* -------------------------------------------------------------------------
   UNE PAGE DE MATIÈRE EST UNE CATÉGORIE, PAS UNE FICHE

   Elle montrait le squelette d'une fiche vierge — six cadres d'images
   vides, une planche, un bouton « Imprimer la fiche » — avant même qu'on
   ait choisi un sujet. On croyait être tombé sur une fiche ratée.

   Tant qu'aucun sujet n'est choisi, le squelette n'est pas affiché : il
   n'a rien à montrer. Il réapparaît entier dès que le modèle a écrit
   quelque chose — script.js retire alors « fiche-en-attente », et la
   page redevient la fiche qu'on est venu chercher.
   ------------------------------------------------------------------------- */
body[data-categorie].fiche-en-attente .entete__identite,
body[data-categorie].fiche-en-attente #gen-cartes,
body[data-categorie].fiche-en-attente #gen-seconde,
body[data-categorie].fiche-en-attente .planche,
body[data-categorie].fiche-en-attente .feuille > .pied,
body[data-categorie].fiche-en-attente #btn-print,
body[data-categorie].fiche-en-attente #btn-reset {
  display: none;
}

/* La galerie occupe alors toute la page : elle EST le contenu. */
body[data-categorie].fiche-en-attente .galerie {
  margin-bottom: 0;
}

/* =========================================================================
   4 bis. LA PLANCHE DE RÉFÉRENCE
   -------------------------------------------------------------------------
   Table de Pythagore, planisphère, tableau périodique… C'est l'affiche de
   la fiche : elle occupe toute la largeur et ne se coupe jamais.
   ========================================================================= */
.planche {
  margin-top: 7mm;
}

.planche__cadre {
  margin: 0;
  border: var(--trait-epais) solid var(--encre);
  border-radius: var(--rayon);
  padding: 6px 8px 8px;
  break-inside: avoid;
  page-break-inside: avoid;
}

.planche__cadre svg {
  display: block;
  width: 100%;
  height: auto;
  /* Une planche large et basse (frise, système solaire) ne doit pas
     s'étirer sur toute la hauteur d'une page. */
  max-height: 155mm;
}

.planche__cadre figcaption {
  margin-top: 5px;
  text-align: center;
}

/* =========================================================================
   5. SOMMAIRE — filtres par niveau, badges (E11)
   ========================================================================= */
/* ---------- Le sommaire, rangé par matière ----------
   Une discipline se voit d'un coup d'œil : trois notions de
   mathématiques ne se confondent plus avec quatre de sciences. */
.hub-matiere {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 6mm 0 2.5mm;
  padding-bottom: 3px;
  border-bottom: var(--trait-epais) solid var(--encre);
  font-family: var(--police-titre);
  font-size: 19px;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  break-after: avoid;
  page-break-after: avoid;
}

.hub-matiere:first-of-type {
  margin-top: 2mm;
}

.hub-matiere > span {
  font-size: 22px;
}

/* Le titre d'une matière mène à sa page de catégorie. Le soulignement
   n'apparaît qu'au survol : sur papier, un titre souligné sous une barre
   déjà épaisse ne se lit plus. */
.hub-matiere a {
  color: inherit;
  text-decoration: none;
}

.hub-matiere a:hover,
.hub-matiere a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.hub-matiere small {
  margin-left: auto;
  font-family: var(--police-texte);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  opacity: 0.65;
}

/* Une matière et ses notions restent ensemble sur la même page. */
.hub-matiere + .hub {
  break-inside: avoid;
  page-break-inside: avoid;
}

/* La porte d'entrée d'une matière : une carte en pointillés, visiblement
   « à remplir », qui dit que les notions livrées ne sont pas une limite. */
.hub-carte--creer {
  border-style: dashed;
}

.hub-carte--creer h2 {
  font-style: italic;
}

@media print {
  /* Sur le papier, on ne crée rien : la carte n'a plus de sens. */
  .hub-carte--creer {
    display: none !important;
  }
}

.hub-filtres {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 5mm;
  padding: 10px 12px;
  border: var(--trait-fin) dashed var(--encre);
  border-radius: var(--rayon);
}

.hub-filtres__titre {
  margin: 0 6px 0 0;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.hub-carte__meta {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-top: 2px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.hub-carte__niveau {
  border: 1.5px solid var(--encre);
  border-radius: 999px;
  padding: 1px 7px;
}

.hub-carte__nouveau {
  border: 1.5px solid var(--encre);
  border-radius: 999px;
  padding: 1px 7px;
  background: var(--encre);
  color: var(--papier);
}

.hub-carte[hidden] {
  display: none !important;
}

/* La matière d'une fiche, sur sa carte du sommaire : c'est ce qui
   empêche « Le corps humain & le vivant » de flotter sans discipline. */
.hub-carte__matiere {
  opacity: 0.7;
}

/* Les cartes de MATIÈRE ouvrent le sommaire. Leur emblème est l'emoji de
   la discipline, plus gros qu'une icône de fiche : on doit voir d'un coup
   d'œil que ces cartes-là ne sont pas des fiches. */
.hub-carte__emoji {
  font-size: 34px;
  line-height: 1.1;
}

.hub-carte--matiere {
  border-width: var(--trait-epais);
}

.hub-carte--matiere h2 {
  font-size: 17px;
}

/* Compteur d'étoiles par carte, rempli par le script */
.hub-carte__etoiles {
  font-size: 10.5px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* =========================================================================
   5 bis. LA GALERIE D'UNE CATÉGORIE

   Une matière est une catégorie : sa page montre ses sujets en cartes,
   filtrables par niveau, plutôt que d'ouvrir directement une fiche unique.

   Elle réutilise .hub et .hub-carte — mêmes cartes, même trait, même
   comportement au survol. Seuls l'état du sujet et le titre en h3
   demandent quelque chose de neuf.
   ========================================================================= */
.galerie {
  margin: 0 0 7mm;
}

.galerie__intro {
  margin: 0 0 4mm;
  font-size: 13px;
  max-width: 70ch;
}

.galerie__compte {
  margin: 0 0 3mm;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.galerie__vide {
  margin: 0 0 4mm;
  padding: 10px 12px;
  border: var(--trait-fin) dashed var(--encre);
  border-radius: var(--rayon);
  font-size: 12.5px;
}

/* Le titre d'une carte de galerie est un h3 : la page a déjà son h1, et
   la galerie son h2. La hiérarchie ne saute pas un niveau. */
.galerie-carte h3 {
  margin: 0;
  font-family: var(--police-titre);
  font-size: 15px;
  line-height: 1.1;
  text-transform: uppercase;
  /* Un intitulé du programme officiel peut être long : on le laisse
     respirer sur trois lignes plutôt que de le couper. */
  overflow-wrap: anywhere;
}

.galerie-carte p {
  font-size: 11px;
}

.galerie-carte__etat {
  border: 1.5px solid var(--encre);
  border-radius: 999px;
  padding: 1px 7px;
  border-style: dashed;
}

/* Ce qui est déjà écrit se voit d'un coup d'œil : plein contre pointillé. */
.galerie-carte__etat--prete {
  border-style: solid;
  background: var(--encre);
  color: var(--papier);
}

.galerie-carte--sujet svg {
  width: 50px;
  height: 50px;
}

/* La barre de niveaux est une NAVIGATION, pas un filtre : chaque niveau
   a son adresse. Trois états doivent se distinguer sans lire —
   accessible, ici, et vide. */
.crayon-pastille--ici {
  background: var(--encre);
  color: var(--papier);
  cursor: default;
}

/* Un niveau que la matière ne couvre pas reste visible mais éteint : le
   masquer laisserait croire à un oubli, et un lien qui déçoit est pire
   qu'un lien absent. */
.crayon-pastille--vide {
  opacity: 0.35;
  cursor: not-allowed;
}

a.crayon-pastille {
  text-decoration: none;
}

/* =========================================================================
   6. BIBLIOTHÈQUE (E10) — liste des fiches enregistrées
   ========================================================================= */
.biblio {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 3mm;
  margin: 0;
  padding: 0;
  list-style: none;
}

.biblio__item {
  border: var(--trait-fin) solid var(--encre);
  border-radius: var(--rayon);
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.biblio__item h3 {
  margin: 0;
  font-family: var(--police-titre);
  font-size: 16px;
  line-height: 1.15;
}

.biblio__meta {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.biblio__sujet {
  margin: 0;
  font-size: 12.5px;
}

.biblio__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: auto;
  padding-top: 6px;
}

.biblio__actions .btn {
  border-color: var(--encre);
  padding: 6px 12px;
  font-size: 12px;
}

.biblio__actions .btn--ghost {
  color: var(--encre);
}

.biblio__vide {
  border: var(--trait-fin) dashed var(--encre);
  border-radius: var(--rayon);
  padding: 18px;
  text-align: center;
  font-size: 13.5px;
}

/* =========================================================================
   7. TABLEAU DE BORD (E11)
   ========================================================================= */
.tdb-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 3mm;
  margin-bottom: 5mm;
}

.tdb-stat {
  border: var(--trait-epais) solid var(--encre);
  border-radius: var(--rayon);
  padding: 10px 14px 12px;
  text-align: center;
}

.tdb-stat b {
  display: block;
  font-family: var(--police-titre);
  font-size: 34px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.tdb-stat span {
  display: block;
  margin-top: 3px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Barres de progression par thème */
.tdb-themes {
  list-style: none;
  margin: 0 0 5mm;
  padding: 0;
  display: grid;
  gap: 6px;
}

.tdb-theme {
  display: grid;
  grid-template-columns: minmax(120px, 1.3fr) 3fr auto;
  align-items: center;
  gap: 10px;
  border: var(--trait-fin) solid var(--encre);
  border-radius: 10px;
  padding: 5px 10px;
  font-size: 13px;
}

.tdb-theme a {
  color: var(--encre);
  font-weight: 800;
  text-decoration: none;
}

.tdb-theme__jauge {
  height: 12px;
  border: 1.5px solid var(--encre);
  border-radius: 999px;
  overflow: hidden;
}

.tdb-theme__jauge i {
  display: block;
  height: 100%;
  background-image: repeating-linear-gradient(45deg, var(--encre) 0 2.5px, transparent 2.5px 6px);
  border-right: 2px solid var(--encre);
}

.tdb-theme__n {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
}

/* Régularité : une case par jour, 12 dernières semaines */
.tdb-heatmap {
  display: grid;
  grid-template-rows: repeat(7, 14px);
  grid-auto-flow: column;
  grid-auto-columns: 14px;
  gap: 3px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.tdb-heatmap i {
  border: 1.2px solid var(--encre);
  border-radius: 3px;
  background: var(--papier);
}

.tdb-heatmap i[data-n="1"] { background-image: repeating-linear-gradient(45deg, var(--encre) 0 1px, transparent 1px 5px); }
.tdb-heatmap i[data-n="2"] { background-image: repeating-linear-gradient(45deg, var(--encre) 0 1.5px, transparent 1.5px 4px); }
.tdb-heatmap i[data-n="3"] { background-image: repeating-linear-gradient(45deg, var(--encre) 0 2px, transparent 2px 3px); }
.tdb-heatmap i[data-n="4"] { background: var(--encre); }

/* Badges à colorier */
.tdb-badges {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 3mm;
}

.tdb-badge {
  border: var(--trait-fin) solid var(--encre);
  border-radius: var(--rayon);
  padding: 10px;
  text-align: center;
}

.tdb-badge__rond {
  width: 54px;
  height: 54px;
  margin: 0 auto 6px;
  border: var(--trait-epais) solid var(--encre);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--police-titre);
  font-size: 20px;
}

.tdb-badge.est-gagne .tdb-badge__rond {
  background-image: repeating-linear-gradient(45deg, var(--encre) 0 2.2px, transparent 2.2px 7px);
}

.tdb-badge:not(.est-gagne) {
  opacity: 0.5;
}

.tdb-badge h3 {
  margin: 0 0 2px;
  font-family: var(--police-titre);
  font-size: 14px;
}

.tdb-badge p {
  margin: 0;
  font-size: 11px;
}

/* =========================================================================
   8. NOTIFICATIONS (écran uniquement)
   ========================================================================= */
.toasts {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
}

.toast {
  max-width: min(92vw, 520px);
  padding: 10px 16px;
  border: var(--trait-fin) solid var(--papier);
  border-radius: 999px;
  background: var(--encre);
  color: var(--papier);
  font-weight: 700;
  font-size: 13px;
  box-shadow: 0 4px 18px rgb(0 0 0 / 0.3);
  animation: toast-entree 200ms ease-out;
}

.toast--alerte {
  background: var(--papier);
  color: var(--encre);
  border-color: var(--encre);
  border-width: var(--trait-epais);
}

@keyframes toast-entree {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; }
}

/* =========================================================================
   9. SÉCURITÉ DE LA CLÉ (E5) — bandeau BYOK
   ========================================================================= */
.byok {
  margin: 8px 0 0;
  padding: 8px 12px;
  border: var(--trait-fin) solid var(--encre);
  border-left-width: 6px;
  border-radius: 8px;
  font-size: 12px;
}

.byok b {
  font-family: var(--police-titre);
}

.byok__etat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 800;
}

.byok__etat::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--encre);
}

.byok__etat[data-etat="chiffree"]::before {
  background: var(--encre);
}

/* =========================================================================
   10. RESPONSIVE
   ========================================================================= */
@media (max-width: 760px) {
  .setup,
  .pied-global {
    margin-left: 10px;
    margin-right: 10px;
  }

  .tdb-theme {
    grid-template-columns: 1fr;
    gap: 4px;
  }

  .modal-gen__ligne {
    flex-direction: column;
    align-items: stretch;
  }

  .modal-gen__vignette {
    width: 100%;
    height: 120px;
  }
}

/* =========================================================================
   11. IMPRESSION — rien de tout cela n'existe sur le papier.
   ========================================================================= */
@media print {
  .pied-global,
  .modal-gen,
  .setup,
  .hub-filtres,
  .toasts,
  .byok,
  .biblio__actions,
  .fil-crayons,
  [data-ecran-seulement] {
    display: none !important;
  }

  .image-coloriage.est-en-attente .image-coloriage__zone::after,
  .skeleton::after {
    display: none !important;
  }

  .image-coloriage.est-en-attente .image-coloriage__zone,
  .skeleton {
    background: var(--papier) !important;
  }

  .hub-carte__meta {
    font-size: 8px;
  }

  .hub-carte__nouveau {
    background: none;
    color: var(--encre);
  }

  .tdb-stats,
  .tdb-themes,
  .tdb-badges,
  .tdb-heatmap {
    break-inside: avoid;
    page-break-inside: avoid;
  }
}

/* =========================================================================
   PROGRAMME OFFICIEL — pages de niveau et générateur de leçon
   -------------------------------------------------------------------------
   Deux documents très différents partagent ce bloc :

     · niveau-<x>.html  un catalogue à parcourir à l'écran, dont chaque
                        entrée est un lien vers la génération ;
     · professeur.html  une fiche de préparation qui doit tenir sur du
                        papier, parce qu'un enseignant la pose sur son
                        bureau et non sur un deuxième écran.

   D'où la règle qui gouverne tout ce fichier : le formulaire est marqué
   `data-ecran-seulement`, la leçon s'imprime seule.
   ========================================================================= */

.feuille--large {
  max-width: 232mm;
}

/* ------------------------------------------------------- pages de niveau */
.niveau-barre {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  margin: 0 0 8mm;
}

.niveau-barre a {
  border: 2px solid var(--encre);
  border-radius: 999px;
  padding: 3px 12px;
  font-weight: 800;
  font-size: 13px;
  text-decoration: none;
  color: inherit;
}

.niveau-barre a:hover,
.niveau-barre a:focus-visible {
  background: var(--encre);
  color: var(--papier);
}

.niveau-grille {
  display: grid;
  gap: 6mm;
  grid-template-columns: repeat(auto-fill, minmax(78mm, 1fr));
  align-items: start;
}

/* Au cycle 4, une matière porte jusqu'à quinze attendus : le bloc
   dépasse alors la page A4, et « ne jamais couper » devient impossible à
   tenir. L'unité insécable est donc le DOMAINE avec ses attendus — c'est
   lui qui perd son sens si on le sépare, pas la matière. */
.niveau-matiere {
  border: var(--trait-epais) solid var(--encre);
  border-radius: 12px;
  padding: 4mm 4mm 3mm;
}

.niveau-sujet {
  break-inside: avoid;
  page-break-inside: avoid;
}

.niveau-matiere__titre {
  margin: 0 0 3mm;
  font-family: var(--titre, inherit);
  font-size: 16px;
  border-bottom: 2px solid var(--crayon, var(--encre));
  padding-bottom: 2mm;
}

.niveau-matiere__absent {
  margin: 0;
  font-size: 12px;
  font-style: italic;
}

.niveau-sujets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 3mm;
}

.niveau-sujet > a {
  font-weight: 800;
  font-size: 13.5px;
  color: inherit;
  text-decoration-color: var(--crayon, var(--encre));
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.niveau-sujet--theme > a::before {
  content: "▸ ";
  color: var(--crayon, var(--encre));
}

.niveau-sujet__origine {
  display: block;
  font-size: 10.5px;
  opacity: 0.72;
}

/* Les attendus officiels : cités, donc jamais reformulés ni tronqués par
   la mise en page. Ils restent lisibles mais discrets — c'est la preuve,
   pas le titre. */
.niveau-attendus {
  margin: 1.5mm 0 0;
  padding-left: 4mm;
  font-size: 11px;
  line-height: 1.35;
}

.niveau-attendus li {
  margin-bottom: 0.8mm;
}

/* ------------------------------------------------- générateur de leçon */
.lecon-form {
  border: var(--trait-epais) solid var(--encre);
  border-radius: 14px;
  padding: 5mm;
  margin-bottom: 6mm;
  display: grid;
  gap: 4mm;
}

.lecon-form__ligne {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.lecon-form__ligne label {
  font-weight: 800;
  font-size: 12.5px;
}

.lecon-form select,
.lecon-form input {
  font: inherit;
  font-size: 14px;
  padding: 5px 8px;
  border: 2px solid var(--encre);
  border-radius: 8px;
  background: var(--papier);
  color: inherit;
}

.lecon-form__ligne--principale input {
  flex: 1 1 260px;
}

/* .btn est dessiné pour la barre d'outils sombre : bordure et fond en
   couleur « papier ». Posé sur du papier, il devient invisible. Sur cette
   page l'action principale est sur fond blanc, elle s'inverse donc. */
.lecon-form .btn {
  background: var(--encre);
  color: var(--papier);
  border-color: var(--encre);
}

.lecon-form .btn:disabled {
  opacity: 0.45;
  cursor: progress;
}

.lecon-form__ligne--cle input {
  flex: 1 1 200px;
}

.lecon-ancrage {
  margin: 0;
  font-size: 12px;
}

.lecon-ancrage--absent {
  font-weight: 700;
}

.lecon-ancrage--absent::before {
  content: "⚠ ";
}

.lecon-ancrage--ok::before {
  content: "✓ ";
}

/* ------------------------------------------------------ la leçon rendue */
.lecon__tete {
  border-bottom: var(--trait-epais) solid var(--encre);
  padding-bottom: 3mm;
  margin-bottom: 4mm;
}

.lecon__meta {
  margin: 0;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.lecon__titre {
  margin: 1mm 0 2mm;
  font-family: var(--titre, inherit);
  font-size: 26px;
  line-height: 1.1;
}

.lecon__objectif {
  margin: 0;
  font-size: 14px;
}

.lecon__bloc {
  margin-bottom: 4mm;
  break-inside: avoid;
  page-break-inside: avoid;
}

.lecon__bloc h3 {
  margin: 0 0 2mm;
  font-family: var(--titre, inherit);
  font-size: 15px;
  border-bottom: 2px solid var(--encre);
  padding-bottom: 1mm;
}

.lecon__bloc ul {
  margin: 0;
  padding-left: 5mm;
  font-size: 12.5px;
}

.lecon__bloc p {
  margin: 0 0 1.5mm;
  font-size: 12.5px;
}

.lecon__colonnes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5mm;
}

.lecon__programme {
  border: 2px dashed var(--encre);
  border-radius: 10px;
  padding: 3mm 4mm;
}

.lecon__source {
  font-size: 10.5px;
  font-style: italic;
  opacity: 0.75;
}

.lecon__phases {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: phase;
}

.lecon-phase {
  border-left: 4px solid var(--encre);
  padding: 0 0 2mm 4mm;
  margin-bottom: 3mm;
  break-inside: avoid;
  page-break-inside: avoid;
}

.lecon-phase__tete {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}

.lecon-phase__nom {
  font-family: var(--titre, inherit);
  font-size: 14px;
}

.lecon-phase__min {
  font-weight: 800;
  font-size: 12px;
  border: 2px solid var(--encre);
  border-radius: 999px;
  padding: 0 8px;
  white-space: nowrap;
}

/* La consigne est ce que le professeur PRONONCE : elle doit se retrouver
   d'un coup d'œil au milieu d'une séance, d'où le fond tramé. */
.lecon-phase__consigne {
  margin: 1mm 0;
  padding: 1.5mm 3mm;
  border-left: 3px solid var(--encre);
  background: rgba(0, 0, 0, 0.045);
  font-style: italic;
  font-size: 12.5px;
}

.lecon-phase__role {
  margin: 0.8mm 0 0;
  font-size: 12px;
}

.lecon__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}

.lecon__table th,
.lecon__table td {
  border: 1.5px solid var(--encre);
  padding: 2mm;
  text-align: left;
  vertical-align: top;
}

.lecon__table th {
  width: 42%;
  font-weight: 800;
}

.lecon__trace {
  border: var(--trait-epais) solid var(--encre);
  border-radius: 10px;
  padding: 3mm 4mm;
}

.lecon__pont {
  border-top: var(--trait-epais) dashed var(--encre);
  padding-top: 3mm;
}

.lecon__prolongements {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.lecon__prolongements span {
  border: 2px solid var(--encre);
  border-radius: 999px;
  padding: 1px 9px;
  font-size: 11.5px;
}

@media (max-width: 700px) {
  .lecon__colonnes {
    grid-template-columns: 1fr;
  }
}

@media print {
  /* Le formulaire et la barre de niveaux ne servent qu'à l'écran : les
     imprimer gâcherait une page et brouillerait la préparation. */
  .lecon-form,
  .niveau-barre {
    display: none !important;
  }

  .lecon__bloc h3,
  .lecon-phase__min,
  .lecon__table th,
  .lecon__table td,
  .niveau-barre a {
    border-color: #000;
  }

  .lecon-phase__consigne {
    background: none;
    border-left-width: 4px;
  }

  .niveau-grille {
    grid-template-columns: 1fr 1fr;
  }
}

/* =========================================================================
   CIBLES DE POINTAGE (WCAG 2.5.8 — 24 × 24 px)
   -------------------------------------------------------------------------
   La règle exempte les liens « dans une phrase ou un bloc de texte », et on
   s'appuie sur cette exemption : agrandir « Obtenir une clé Gemini » au
   milieu d'un paragraphe casserait l'interligne pour rien.

   Elle ne couvre en revanche PAS les listes de commandes — navigation de
   pied de page, liste des domaines d'une page de niveau, liste des notions
   d'une matière. Ce sont les liens qu'on vise au doigt sur une tablette,
   souvent debout devant une classe. Ils gagnent donc de la hauteur, sans
   bouger d'un pixel à l'écran puisque le remplissage remplace un espacement
   qui existait déjà.
   ========================================================================= */
.pied-global nav a,
.tdb-theme a,
.niveau-sujet > a,
.hub-mode-emploi li a {
  display: inline-block;
  padding-block: 4px;
}

/* La case à cocher du panneau : 20 px de côté, sous le seuil, et c'est la
   seule commande du wizard qu'on manque régulièrement. */
.setup__champ input[type="checkbox"] {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
}

@media print {
  /* Le remplissage ajouté ci-dessus ne sert qu'au doigt : sur papier il
     ne ferait qu'allonger les listes. */
  .pied-global nav a,
  .niveau-sujet > a,
  .hub-mode-emploi li a {
    padding-block: 0;
  }
}

/* =========================================================================
   PAGES D'ACCUEIL PAR USAGE
   -------------------------------------------------------------------------
   Aucun composant nouveau : on réemploie `.hub-carte`, `.section-titre` et
   `.entete` du design d'origine, pour qu'un visiteur qui arrive par une de
   ces pages soit déjà chez lui quand il ouvre une fiche.
   ========================================================================= */
.persona-etapes__liste {
  list-style: none;
  margin: 0 0 8mm;
  padding: 0;
  display: grid;
  gap: 5mm;
  grid-template-columns: repeat(auto-fit, minmax(62mm, 1fr));
  counter-reset: etape;
}

.persona-etape {
  position: relative;
  border: var(--trait-epais) solid var(--encre);
  border-radius: 14px;
  padding: 5mm 4mm 4mm;
  break-inside: avoid;
  page-break-inside: avoid;
}

/* Le numéro est un repère visuel, pas une information : il est déjà porté
   par la structure <ol>, d'où aria-hidden côté HTML. */
.persona-etape__n {
  position: absolute;
  top: -14px;
  left: 4mm;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: var(--trait-epais) solid var(--encre);
  border-radius: 999px;
  background: var(--papier);
  font: 800 15px/1 var(--police-titre, var(--police-texte));
}

.persona-etape h3 {
  margin: 0 0 2mm;
  font-family: var(--police-titre, inherit);
  font-size: 17px;
  line-height: 1.15;
}

.persona-etape p {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
}

.hub--portes {
  grid-template-columns: repeat(auto-fit, minmax(64mm, 1fr));
}

.hub-carte--porte {
  min-height: 0;
  padding: 5mm 4mm;
}

.hub-carte--porte h3 {
  margin: 0 0 2mm;
  font-family: var(--police-titre, inherit);
  font-size: 17px;
}

.persona-faq {
  margin-top: 8mm;
}

.persona-faq__item {
  border-bottom: 2px solid var(--encre);
  padding: 3mm 0;
  break-inside: avoid;
  page-break-inside: avoid;
}

/* Les questions restent dépliées. Un <details> replié ne s'imprime pas de
   façon fiable — les navigateurs masquent son contenu autrement qu'avec
   « display », et l'impression doit fonctionner sans JavaScript. Avec trois
   questions courtes, l'accordéon n'économisait aucune place utile. */
.persona-faq__item h3 {
  margin: 0;
  font-family: var(--police-titre, inherit);
  font-size: 15px;
  line-height: 1.2;
}

.persona-faq__item p {
  margin: 2mm 0 0;
  font-size: 13px;
  line-height: 1.5;
  max-width: 74ch;
}

.persona-autres {
  margin-top: 8mm;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}

.persona-autres p {
  margin: 0;
  font-weight: 800;
}

.persona-autres a {
  display: inline-block;
  border: 2px solid var(--encre);
  border-radius: 999px;
  padding: 4px 14px;
  text-decoration: none;
  color: inherit;
  font-weight: 700;
}

.persona-autres a:hover,
.persona-autres a:focus-visible {
  background: var(--encre);
  color: var(--papier);
}

@media print {
  /* Les liens « vous n'êtes pas au bon endroit ? » n'ont aucun sens une
     fois imprimés : sur du papier, ils ne mènent nulle part. */
  .persona-autres {
    display: none !important;
  }
}

/* Le bandeau « Vous venez pour… » en tête du sommaire : quatre portes,
   avant la grille des notions. C'est la première question qu'un visiteur
   se pose, et la grille ne pouvait pas y répondre. */
.personas__liste {
  display: grid;
  gap: 4mm;
  grid-template-columns: repeat(auto-fit, minmax(44mm, 1fr));
  margin-bottom: 8mm;
}

.persona-pastille {
  position: relative;
  display: grid;
  grid-template-columns: 34px 1fr;
  grid-template-areas: "ico nom" "ico txt";
  column-gap: 10px;
  align-items: center;
  border: var(--trait-epais) solid var(--encre);
  border-radius: 14px;
  padding: 4mm;
  text-decoration: none;
  color: inherit;
  background: var(--papier);
}

.persona-pastille svg {
  grid-area: ico;
  width: 34px;
  height: 34px;
}

.persona-pastille b {
  grid-area: nom;
  font-family: var(--police-titre, inherit);
  font-size: 16px;
}

.persona-pastille span {
  grid-area: txt;
  font-size: 12px;
  line-height: 1.35;
}

@media print {
  /* Ces portes ne servent qu'à naviguer : imprimées, elles occupent le
     haut de la première page du sommaire pour rien. */
  .personas {
    display: none !important;
  }
}

/* =========================================================================
   COMPTE ET CRÉDITS
   -------------------------------------------------------------------------
   Ce bloc remplace l'ancienne interface de saisie de clé. Il n'affiche
   plus un champ à remplir mais un ÉTAT : qui je suis, combien il me
   reste. Tout ce qui décide vraiment — l'identité, le solde, le débit —
   vit sur le serveur ; ces règles ne font que le montrer.
   ========================================================================= */
.compte-bandeau {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-top: 10px;
  padding: 8px 12px;
  border: var(--trait-fin) solid var(--encre);
  border-radius: 12px;
  font-size: 13px;
}

.compte-bandeau__etat {
  font-weight: 800;
}

.compte-bandeau__solde {
  border: 2px solid var(--encre);
  border-radius: 999px;
  padding: 2px 10px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* Un solde à zéro n'est pas une information neutre : c'est ce qui bloque
   la prochaine génération. */
.compte-bandeau[data-etat="deconnecte"] .compte-bandeau__etat::before { content: "○ "; }
.compte-bandeau[data-etat="connecte"] .compte-bandeau__etat::before { content: "● "; }
.compte-bandeau[data-etat="hors-service"] { border-style: dashed; }

.compte-bloc {
  margin-bottom: 8mm;
}

.compte-methodes {
  display: grid;
  gap: 5mm;
  grid-template-columns: repeat(auto-fit, minmax(62mm, 1fr));
  margin-top: 4mm;
}

.compte-methode {
  border: var(--trait-epais) solid var(--encre);
  border-radius: 14px;
  padding: 5mm 4mm;
  display: grid;
  gap: 3mm;
  align-content: start;
}

.compte-methode h3 {
  margin: 0;
  font-family: var(--police-titre, inherit);
  font-size: 17px;
}

.compte-methode p {
  margin: 0;
  font-size: 13px;
}

.compte-methode input {
  font: inherit;
  font-size: 14px;
  padding: 7px 12px;
  border: 2px solid var(--encre);
  border-radius: 999px;
  background: var(--papier);
  color: inherit;
  width: 100%;
}

.compte-methode .btn,
.compte-bloc .btn {
  background: var(--encre);
  color: var(--papier);
  border-color: var(--encre);
}

.compte-note {
  margin-top: 5mm;
  font-size: 12px;
  max-width: 78ch;
}

.compte-solde-carte {
  border: var(--trait-epais) solid var(--encre);
  border-radius: 14px;
  padding: 5mm;
  text-align: center;
  margin-bottom: 6mm;
}

.compte-solde-carte__n {
  margin: 0;
  font-family: var(--police-titre, inherit);
  font-size: 46px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.compte-solde-carte__l {
  margin: 1mm 0 0;
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.compte-solde-carte__id {
  margin: 2mm 0 0;
  font-size: 12px;
  opacity: 0.75;
}

.compte-packs {
  display: grid;
  gap: 4mm;
  grid-template-columns: repeat(auto-fit, minmax(52mm, 1fr));
  margin-bottom: 6mm;
}

.compte-pack {
  border: var(--trait-fin) solid var(--encre);
  border-radius: 12px;
  padding: 4mm;
  display: grid;
  gap: 2mm;
  align-content: start;
}

.compte-pack h3 {
  margin: 0;
  font-family: var(--police-titre, inherit);
  font-size: 16px;
}

.compte-pack__credits {
  margin: 0;
  font-weight: 800;
  font-size: 15px;
}

.compte-pack__detail {
  margin: 0;
  font-size: 12px;
}

.compte-pack__prix {
  margin: 0;
  font-family: var(--police-titre, inherit);
  font-size: 22px;
}

.compte-hist {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

.compte-hist th,
.compte-hist td {
  border: 1.5px solid var(--encre);
  padding: 2mm 3mm;
  text-align: left;
}

.compte-hist__delta {
  text-align: right;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.compte-indispo-texte {
  font-style: italic;
}

.lecon-form__compte {
  margin: 0;
  font-size: 12.5px;
}

/* Le reCAPTCHA de Firebase se dimensionne seul ; on l'empêche seulement
   de déborder d'une carte étroite. */
#compte-recaptcha {
  max-width: 100%;
  overflow-x: auto;
}

@media print {
  /* Un compte ne s'imprime pas : ni les moyens de connexion, ni les
     packs, ni le bandeau d'état sur une fiche. */
  .compte-bandeau,
  .compte-methodes,
  .compte-packs,
  #compte-recaptcha {
    display: none !important;
  }
}

/* =========================================================================
   RAYONS ET ADMINISTRATION
   ========================================================================= */
.tdb-rayon {
  margin-bottom: 4mm;
}

.tdb-rayon h3 {
  margin: 0 0 2mm;
  font-family: var(--police-titre, inherit);
  font-size: 14px;
}

.tdb-rayon__puces {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Une puce active doit se voir SANS couleur : le produit s'imprime en
   noir et blanc, et le contraste ne peut donc pas reposer sur la teinte. */
.tdb-puce {
  border: 2px solid var(--encre);
  border-radius: 999px;
  padding: 4px 12px;
  background: var(--papier);
  color: inherit;
  font: 700 12.5px var(--police-texte);
  cursor: pointer;
}

.tdb-puce b {
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

.tdb-puce[aria-pressed="true"] {
  background: var(--encre);
  color: var(--papier);
}

.tdb-puce[aria-pressed="true"] b {
  opacity: 0.85;
}

.admin-rayons {
  display: grid;
  gap: 4mm;
  grid-template-columns: repeat(auto-fit, minmax(52mm, 1fr));
}

.admin-rayon {
  border: var(--trait-fin) solid var(--encre);
  border-radius: 12px;
  padding: 3mm 4mm;
}

.admin-rayon h3 {
  margin: 0 0 2mm;
  font-family: var(--police-titre, inherit);
  font-size: 14px;
}

.admin-rayon ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 12.5px;
}

.admin-rayon li {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 1px 0;
}

.admin-rayon li b {
  font-variant-numeric: tabular-nums;
}

.admin-drapeaux {
  list-style: none;
  margin: 0 0 2mm;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 13px;
  font-weight: 700;
}

/* Un manque doit sauter aux yeux : c'est la seule information vraiment
   actionnable de cette liste. */
.admin-drapeaux li[data-ok="false"] {
  border: 2px solid var(--encre);
  border-radius: 999px;
  padding: 1px 10px;
}

.admin-meta {
  margin: 0 0 2mm;
  font-size: 12px;
}

.admin-table {
  font-size: 12px;
}

.admin-table small {
  opacity: 0.7;
  font-size: 10.5px;
}

.admin-actions {
  white-space: nowrap;
}

.admin-actions button {
  border: 2px solid var(--encre);
  border-radius: 999px;
  background: var(--papier);
  color: inherit;
  font: 700 11.5px var(--police-texte);
  padding: 2px 8px;
  margin-right: 3px;
  cursor: pointer;
}

.admin-actions button:disabled {
  opacity: 0.4;
  cursor: progress;
}

@media print {
  /* L'administration ne s'imprime pas, et les puces de filtre non plus :
     un filtre est une commande, pas une information. */
  .tdb-rayon__puces,
  .admin-actions,
  .admin-rayons {
    display: none !important;
  }
}

/* Les rayons partagent la mise en forme de la bibliothèque sans partager
   sa classe : même aspect, deux composants distincts. */
.rayon__item {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: center;
  border: var(--trait-fin) solid var(--encre);
  border-radius: 10px;
  padding: 2mm 3mm;
  margin-bottom: 2mm;
  font-size: 12.5px;
}

.rayon__item small {
  display: block;
  opacity: 0.75;
  font-size: 11px;
}

/* L'avertissement de mise en service : visible sans être alarmant, et
   surtout impossible à confondre avec le reste de la page. */
.compte-avertissement {
  border: var(--trait-epais) dashed var(--encre);
  border-radius: 12px;
  padding: 4mm;
  margin-bottom: 6mm;
  font-size: 13px;
  line-height: 1.45;
  max-width: 80ch;
}

/* =========================================================================
   5 ter. LA PAGE MODÈLE

   Le gabarit d'une matière, rendu lisible pour être relu avant toute
   production en série. Elle s'imprime : un modèle se valide sur papier,
   crayon en main.
   ========================================================================= */
.modele-bloc {
  border: var(--trait-fin) solid var(--encre);
  border-radius: var(--rayon);
  padding: 10px 14px;
  margin: 0 0 5mm;
  break-inside: avoid;
  page-break-inside: avoid;
}

.modele-liste {
  margin: 0;
  padding-left: 20px;
  font-size: 13px;
}

.modele-liste li {
  margin-bottom: 4px;
}

.modele__etiquette {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.75;
}

/* L'état saute aux yeux : c'est la seule information de la page qui
   décide si l'on peut lancer quatre-vingts générations. */
.modele-etat {
  border: var(--trait-epais) solid var(--encre);
  border-radius: var(--rayon);
  padding: 10px 14px;
  margin: 0 0 5mm;
}

.modele-etat--valide {
  background: var(--encre);
  color: var(--papier);
}

.modele-etat--valide code {
  color: inherit;
}

.modele-etat--attente {
  border-style: dashed;
}

/* Une fiche du catalogue a son texte écrit et relu par le filtre, mais
   ses cadres d'images restent vides : elles se génèrent à la demande, ou
   se dessinent au crayon. « Prête à imprimer » serait un abus de langage
   — c'est le reproche exact qu'on nous a fait sur les fiches vierges. */
.galerie-carte__etat--ecrite {
  border-style: solid;
}

/* -------------------------------------------------------------------------
   UNE MATIÈRE OCCUPE TOUTE LA LARGEUR

   Les blocs d'une page de niveau s'affichaient sur deux colonnes : un
   attendu du programme y tenait sur trois mots par ligne, et l'œil sautait
   d'une matière à l'autre au milieu d'une phrase.

   À l'écran, une matière prend donc toute la largeur. Sur PAPIER, les deux
   colonnes restent : elles économisent des feuilles, et le programme d'un
   niveau s'imprime déjà sur trois à quatre pages.
   ------------------------------------------------------------------------- */
@media screen {
  .niveau-grille {
    grid-template-columns: 1fr;
  }

  /* Les attendus, eux, respirent sur deux colonnes quand la place existe :
     ce sont des puces courtes, pas des paragraphes. */
  .niveau-attendus {
    columns: 2;
    column-gap: 8mm;
  }

  .niveau-attendus > li {
    break-inside: avoid;
  }
}

@media screen and (max-width: 900px) {
  .niveau-attendus {
    columns: 1;
  }
}

/* =========================================================================
   L'ASSISTANT — la bulle de création, en bas à droite

   Le formulaire s'étalait EN HAUT de chaque page génératrice, avant la
   fiche qu'on venait chercher : sur un téléphone, il fallait le faire
   défiler entièrement pour voir la première ligne de la leçon. Et il
   n'existait nulle part ailleurs — depuis le sommaire, rien ne permettait
   de demander une fiche.

   Il devient un tiroir ancré là où l'on a appris à chercher de l'aide :
   en bas à droite, au-dessus du pouce sur mobile. Rien de tout cela ne
   s'imprime.
   ========================================================================= */
.assistant {
  position: fixed;
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 900;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  max-width: min(440px, calc(100vw - 32px));
}

.assistant__bulle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* 48 px de haut, au-delà de la cible minimale de 24 px : on le vise au
     pouce, debout, dans une salle de classe. */
  min-height: 48px;
  padding: 0 18px;
  border: var(--trait-epais) solid var(--encre);
  border-radius: 999px;
  background: var(--encre);
  color: var(--papier);
  font: 800 15px/1 var(--police-texte);
  cursor: pointer;
  box-shadow: 4px 4px 0 rgb(0 0 0 / 0.25);
}

.assistant__bulle:focus-visible {
  outline: 3px solid #1a73e8;
  outline-offset: 3px;
}

.assistant__pastille { font-size: 19px; }

.assistant__tiroir {
  width: min(440px, calc(100vw - 32px));
  max-height: min(72vh, 620px);
  overflow: auto;
  overscroll-behavior: contain;
  border: var(--trait-epais) solid var(--encre);
  border-radius: var(--rayon);
  background: var(--papier);
  box-shadow: 6px 6px 0 rgb(0 0 0 / 0.22);
}

/* Le panneau DÉMÉNAGE dans le tiroir : il perd sa marge de page et son
   ombre propre, qui feraient double emploi avec celles du tiroir. */
.assistant__tiroir .setup {
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  max-width: none;
}

/* Sur un téléphone, le tiroir prend la largeur : un formulaire de 440 px
   sur un écran de 360 déborderait. */
@media (max-width: 520px) {
  .assistant {
    left: max(12px, env(safe-area-inset-left));
    right: max(12px, env(safe-area-inset-right));
    max-width: none;
  }
  .assistant__tiroir { width: 100%; max-height: 78vh; }
  .assistant__bulle { width: 100%; justify-content: center; }
}

@media print { .assistant { display: none !important; } }

/* =========================================================================
   L'EN-TÊTE GLOBAL, LE FIL D'ARIANE, LA RECHERCHE

   Le produit avait autant de navigations que de générateurs : une barre
   noire avec « ← Sommaire » sur une fiche, une autre sur une page de
   matière, rien de commun entre les deux. Un visiteur arrivé par un
   moteur de recherche sur « matiere-geographie-cm2.html » ne pouvait ni
   savoir où il était, ni remonter d'un cran, ni chercher autre chose.

   Un seul en-tête, identique sur les cent trente-sept pages, écrit par
   le build. Il tient ce qu'un visiteur attend d'un en-tête, dans l'ordre
   où il l'attend : la marque à gauche, la navigation au centre, la
   recherche et le compte à droite.

   La hauteur est une VARIABLE, et c'est ce qui permet de l'empiler
   au-dessus de la barre d'outils sans retoucher les marges de chaque
   gabarit : `body` reçoit la hauteur en padding, la barre d'outils s'y
   décale, et tout le reste garde les valeurs qu'il avait.
   ========================================================================= */

:root {
  --chapeau-h: 60px;
  --chapeau-fond: #fff;
  --chapeau-bord: #d9d9e3;
  --chapeau-doux: #6a6a78;
}

body {
  padding-top: var(--chapeau-h);
}

.chapeau {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 30;
  height: var(--chapeau-h);
  background: var(--chapeau-fond);
  border-bottom: 2px solid var(--encre);
}

/* La barre d'outils noire vient JUSTE en dessous. Elle était calée sur
   le haut de la fenêtre ; elle se cale maintenant sous l'en-tête. */
.toolbar {
  top: var(--chapeau-h);
}

.chapeau__barre {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 16px;
}

.chapeau__marque {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  color: var(--encre);
  font: 800 17px/1 var(--police-titre);
  text-decoration: none;
  white-space: nowrap;
}

.chapeau__logo {
  font-size: 20px;
  line-height: 1;
}

.chapeau__nav {
  flex: 1 1 auto;
  min-width: 0;
}

.chapeau__liens {
  display: flex;
  align-items: center;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chapeau__liens > li > a,
.chapeau__depliant > summary {
  display: flex;
  align-items: center;
  /* 44 px de haut : la cible tactile recommandée, au doigt comme au
     stylet. Un menu de 30 px se rate une fois sur trois sur un
     téléphone, et c'est une fois sur trois de trop. */
  min-height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  color: var(--encre);
  font: 700 14px/1 var(--police-texte);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.chapeau__liens > li > a:hover,
.chapeau__depliant > summary:hover {
  background: #f1f1f6;
}

/* La page où l'on se trouve se dit, elle ne se devine pas. */
.chapeau__liens a[aria-current="page"],
.chapeau__marque[aria-current="page"] {
  box-shadow: inset 0 -3px 0 var(--encre);
}

/* ---------- Les deux menus dépliants ---------- */

.chapeau__depliant {
  position: relative;
}

.chapeau__depliant > summary {
  list-style: none;
}

.chapeau__depliant > summary::-webkit-details-marker {
  display: none;
}

.chapeau__depliant > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  margin-left: 7px;
  border-right: 2px solid currentcolor;
  border-bottom: 2px solid currentcolor;
  transform: translateY(-2px) rotate(45deg);
}

.chapeau__depliant[open] > summary {
  background: #f1f1f6;
}

.chapeau__panneau {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 5;
  display: grid;
  grid-template-columns: repeat(2, minmax(150px, 1fr));
  gap: 2px;
  margin: 0;
  padding: 8px;
  list-style: none;
  background: var(--chapeau-fond);
  border: 2px solid var(--encre);
  border-radius: 14px;
  box-shadow: 0 12px 28px rgb(0 0 0 / 0.16);
}

.chapeau__panneau a {
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: 0 12px;
  border-radius: 8px;
  color: var(--encre);
  font: 700 14px/1.2 var(--police-texte);
  text-decoration: none;
}

/* Le crayon de la matière : le même code couleur que partout ailleurs
   dans le produit, pour qu'un menu ne soit pas un endroit à réapprendre. */
.chapeau__panneau a::before {
  content: "";
  width: 10px;
  height: 10px;
  margin-right: 9px;
  border-radius: 50%;
  background: var(--crayon, var(--chapeau-doux));
  flex: 0 0 auto;
}

.chapeau__panneau a:hover,
.chapeau__panneau a:focus-visible {
  background: #f1f1f6;
}

/* Les niveaux sont courts : trois colonnes plutôt que deux. */
#chapeau-niveaux {
  grid-template-columns: repeat(3, minmax(72px, 1fr));
}

/* ---------- La recherche ---------- */

.chapeau__recherche {
  position: relative;
  flex: 0 1 260px;
  min-width: 0;
}

.chapeau__recherche form {
  margin: 0;
}

.chapeau__recherche input {
  width: 100%;
  min-height: 40px;
  padding: 0 14px;
  border: 2px solid var(--chapeau-bord);
  border-radius: 999px;
  background: #f7f7fa;
  color: var(--encre);
  font: 600 14px/1 var(--police-texte);
}

.chapeau__recherche input:focus {
  outline: 3px solid #1a73e8;
  outline-offset: 1px;
  background: var(--papier);
}

.chapeau__resultats {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 5;
  width: min(420px, 92vw);
  max-height: 60vh;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--chapeau-fond);
  border: 2px solid var(--encre);
  border-radius: 14px;
  box-shadow: 0 12px 28px rgb(0 0 0 / 0.16);
}

.chapeau__resultats li a {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-height: 40px;
  padding: 8px 12px;
  border-radius: 8px;
  color: var(--encre);
  text-decoration: none;
  font: 600 14px/1.25 var(--police-texte);
}

.chapeau__resultats li a:hover,
.chapeau__resultats li[aria-selected="true"] a {
  background: #f1f1f6;
}

.chapeau__resultat-quoi {
  margin-left: auto;
  color: var(--chapeau-doux);
  font: 700 11px/1 var(--police-texte);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.chapeau__vide {
  padding: 14px 12px;
  color: var(--chapeau-doux);
  font: 600 14px/1.3 var(--police-texte);
}

/* ---------- Le compte et les crédits ---------- */

.chapeau__compte {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.chapeau__connexion {
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: 0 10px;
  color: var(--encre);
  font: 700 14px/1 var(--police-texte);
  text-decoration: none;
  white-space: nowrap;
}

.chapeau__inscription.btn {
  border-color: var(--encre);
  background: var(--encre);
  color: var(--papier);
  white-space: nowrap;
}

/* Connecté : les crédits d'abord — c'est la seule information qu'on
   vient chercher dans un en-tête, et elle décide si l'on peut générer. */
.chapeau__moi {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 10px 0 6px;
  border: 2px solid var(--chapeau-bord);
  border-radius: 999px;
  color: var(--encre);
  text-decoration: none;
  font: 700 13px/1 var(--police-texte);
}

.chapeau__moi:hover {
  border-color: var(--encre);
}

.chapeau__credits {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-radius: 999px;
  background: #fdf3d6;
  font-weight: 800;
  white-space: nowrap;
}

.chapeau__credits[data-vide="1"] {
  background: #ffe0e0;
}

.chapeau__qui {
  max-width: 15ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- La bascule mobile ---------- */

.chapeau__bascule {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 2px solid var(--encre);
  border-radius: 10px;
  background: var(--papier);
  cursor: pointer;
}

.chapeau__hamburger,
.chapeau__hamburger::before,
.chapeau__hamburger::after {
  display: block;
  width: 18px;
  height: 2.5px;
  background: var(--encre);
  border-radius: 2px;
}

.chapeau__hamburger::before,
.chapeau__hamburger::after {
  content: "";
  position: relative;
}

.chapeau__hamburger::before { top: -6px; }
.chapeau__hamburger::after { top: 3.5px; }

.chapeau__bascule[aria-expanded="true"] .chapeau__hamburger {
  background: transparent;
}

.chapeau__bascule[aria-expanded="true"] .chapeau__hamburger::before {
  top: -2.5px;
  transform: rotate(45deg);
}

.chapeau__bascule[aria-expanded="true"] .chapeau__hamburger::after {
  top: -5px;
  transform: rotate(-45deg);
}

/* =========================================================================
   LE FIL D'ARIANE
   ========================================================================= */

.fil-ariane {
  max-width: 1280px;
  margin: 0 auto;
  padding: 10px 16px 0;
}

.fil-ariane ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 8px;
  margin: 0;
  padding: 0;
  list-style: none;
  font: 600 13px/1.3 var(--police-texte);
  color: var(--chapeau-doux);
}

.fil-ariane li + li::before {
  content: "\203A";
  margin-right: 8px;
  color: var(--chapeau-bord);
}

.fil-ariane a {
  color: var(--chapeau-doux);
  text-decoration: none;
}

.fil-ariane a:hover {
  color: var(--encre);
  text-decoration: underline;
}

.fil-ariane [aria-current="page"] {
  color: var(--encre);
  font-weight: 800;
}

/* Le fil se pose entre l'en-tête et la barre d'outils, dans le flux :
   il n'a plus rien à contourner depuis que la barre est collante. */

/* =========================================================================
   ÉCRANS ÉTROITS — le tiroir
   ========================================================================= */

@media (max-width: 1080px) {
  :root {
    --chapeau-h: 56px;
  }

  .chapeau__bascule {
    display: flex;
    order: 4;
  }

  .chapeau__marque {
    order: 1;
  }

  /* Le tiroir : il descend sous l'en-tête, occupe toute la largeur et
     défile seul. Il n'est pas « masqué puis affiché » par une classe
     mais par l'attribut `hidden`, que rien ne peut neutraliser. */
  .chapeau__nav {
    order: 5;
    position: fixed;
    inset: var(--chapeau-h) 0 auto 0;
    max-height: calc(100dvh - var(--chapeau-h));
    overflow-y: auto;
    padding: 12px 16px 24px;
    background: var(--chapeau-fond);
    border-bottom: 2px solid var(--encre);
    box-shadow: 0 16px 32px rgb(0 0 0 / 0.18);
  }

  .chapeau__liens {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }

  .chapeau__liens > li > a,
  .chapeau__depliant > summary {
    min-height: 48px;
    font-size: 16px;
  }

  /* Dans le tiroir, un menu déplié pousse le reste vers le bas au lieu
     de flotter par-dessus : sur un téléphone, une couche flottante
     au-dessus d'une autre se referme toujours au mauvais moment. */
  .chapeau__panneau {
    position: static;
    box-shadow: none;
    border: 0;
    border-left: 3px solid var(--chapeau-bord);
    border-radius: 0;
    margin: 2px 0 6px 12px;
    padding: 4px 0 4px 8px;
  }

  .chapeau__recherche {
    order: 2;
    flex: 1 1 auto;
    margin-left: 4px;
  }

  .chapeau__resultats {
    right: auto;
    left: 0;
  }

  /* Les liens de connexion descendent dans le tiroir : en haut, il ne
     resterait ni la place de la recherche ni celle de la marque. Les
     crédits, eux, restent visibles — c'est l'information qu'on vient
     vérifier. */
  .chapeau__compte {
    order: 3;
  }

  .chapeau__qui {
    display: none;
  }

  .chapeau__moi {
    border: 0;
    padding: 0;
  }
}

@media (max-width: 640px) {
  .chapeau__nom {
    /* Le nom long ne tient pas : le crayon suffit à reconnaître la
       marque, et le lien garde son nom accessible. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

}

/* Le tiroir mobile n'existe pas sur grand écran : la navigation y est
   toujours visible, et l'attribut `hidden` ne doit pas la faire
   disparaître. */
@media (min-width: 1081px) {
  .chapeau__nav[hidden] {
    display: block;
  }
}

/* =========================================================================
   IMPRESSION — l'en-tête et le fil n'existent pas sur le papier, et la
   réserve de place qu'ils occupent non plus.
   ========================================================================= */
@media print {
  body {
    padding-top: 0;
  }
}

/* Le crayon de chaque matière dans le menu. Écrit une fois ici plutôt
   que recopié en style en ligne sur cent trente-sept pages. */
.chapeau__panneau a[data-m="mathematiques"]::before { background: #2A6FD0; }
.chapeau__panneau a[data-m="francais"]::before { background: #B93BA0; }
.chapeau__panneau a[data-m="sciences"]::before { background: #17997A; }
.chapeau__panneau a[data-m="informatique"]::before { background: #1583B8; }
.chapeau__panneau a[data-m="histoire"]::before { background: #B4682A; }
.chapeau__panneau a[data-m="geographie"]::before { background: #00959F; }
.chapeau__panneau a[data-m="langues"]::before { background: #4A54C4; }
.chapeau__panneau a[data-m="arts"]::before { background: #9440B5; }
.chapeau__panneau a[data-m="civique"]::before { background: #D23A6E; }
.chapeau__panneau a[data-m="economie"]::before { background: #7E9B1F; }

/* -------------------------------------------------------------------------
   L'ÉCHELLE DES LARGEURS

   Une barre d'en-tête ne « passe pas à la ligne » : elle se dégarnit dans
   un ordre décidé. Trois paliers, du plus large au plus étroit, et à
   chacun ce que l'on retire est ce dont on peut le mieux se passer :

     ≥ 1241 px  tout ;
     ≤ 1240 px  le bouton « Créer mon compte » — la page de compte le
                propose, et « Se connecter » y mène déjà ;
     ≤ 1080 px  la navigation entre dans un tiroir, et la connexion se
                réduit à son pictogramme.

   Sans cette échelle, « Enseignants » passait sous le champ de recherche
   dès 1280 px : deux éléments qui se recouvrent, c'est un lien qu'on ne
   peut plus cliquer.
   ------------------------------------------------------------------------- */

.chapeau__avatar {
  display: none;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border: 2px solid currentcolor;
  border-radius: 50%;
  position: relative;
}

/* Une silhouette : la tête et les épaules, dessinées au trait comme le
   reste du produit plutôt qu'importées d'une bibliothèque d'icônes. */
.chapeau__avatar::before,
.chapeau__avatar::after {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  background: currentcolor;
}

.chapeau__avatar::before {
  top: 3px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.chapeau__avatar::after {
  top: 11px;
  width: 12px;
  height: 7px;
  border-radius: 6px 6px 0 0;
}

@media (max-width: 1240px) {
  .chapeau__inscription {
    display: none;
  }
}

@media (max-width: 1080px) {
  .chapeau__connexion-texte {
    display: none;
  }

  .chapeau__avatar {
    display: block;
  }

  /* Le pictogramme seul doit rester une cible de doigt. */
  .chapeau__connexion {
    justify-content: center;
    min-width: 44px;
    padding: 0;
  }
}
