/* ------------------------------------------------------------------
   Stratégie d'entreprise — feuille de style commune à tout le parcours

   Charte IFC, reprise de Décarbochim : cartes blanches sur fond
   gris-bleu, accent bleu marine, en-têtes en dégradé bleu, barre de
   navigation sombre, police système Segoe UI (aucun CDN, aucune police
   tierce chargée à distance ; JetBrains Mono reste auto-hébergée pour
   les chiffres et codes). Rayons larges, ombres
   douces, jauges et puces de statut à l'appui — l'objectif est une
   lecture de la progression au premier coup d'œil (gamification légère,
   entièrement portée par les données réelles de suivi : aucun score ni
   badge n'est inventé côté affichage).

   Conformité visée : WCAG 2.1 niveau AA. Chaque couleur porteuse de
   texte ou de bordure fonctionnelle a été vérifiée au seuil requis
   (4,5:1 pour le texte courant, 3:1 pour les composants d'interface) ;
   le ratio retenu est noté en commentaire à côté de chaque jeton.
   Le bleu vif (--accent-vif, 4,3:1) est réservé aux aplats décoratifs
   (jauges, puces, filets) : il ne porte jamais seul du texte ni un
   contour fonctionnel — c'est --accent (bleu marine, 7,6:1 mini) qui
   joue ce rôle.
   ------------------------------------------------------------------ */

/* 0. Polices auto-hébergées ------------------------------------------
   Fichiers variables (une seule ressource par famille, poids 400 à 700
   selon la police) servis depuis commun/fonts/, chemin relatif à cette
   feuille. Licence SIL Open Font License. */

@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/outfit-variable.woff2") format("woff2");
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/archivo-variable.woff2") format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-variable.woff2") format("woff2");
}

/* 1. Jetons -------------------------------------------------------
   Charte reprise de Décarbochim (voir decarbochim/local/DOCUMENTATION.md,
   « Système visuel ») : fond gris-bleu, cartes blanches, bleu marine
   #1a5276 comme couleur d'interface, dégradé bleu pour les en-têtes et
   les boutons principaux, barre de navigation sombre #1a252f, police
   système Segoe UI. Les ratios de contraste sont notés à côté de chaque
   jeton porteur de texte ou de contour.                               */

:root {
  /* Fonds : le gris-bleu est le fond de page, les cartes blanches
     portent le contenu.                                               */
  --fond: #f0f4f8;
  --papier: #ffffff;
  --papier-creme: #ffffff;       /* fond des cartes                     */
  --fond-secondaire: #eaf1f7;    /* zones secondaires, en-têtes tableau */

  --encre: #1a252f;              /* texte courant : 15,6:1 sur blanc    */
  --encre-secondaire: #4a5568;   /* texte secondaire : 7,5:1 / 6,8:1 sur le fond */
  --encre-discrete: #7f8c8d;     /* décoratif seulement (≥18px, chiffres
                                     mono, jamais seul porteur de sens) */

  --filet: #7b8a99;              /* bordures fonctionnelles : 3,5:1     */
  --filet-fort: #1a252f;
  --filet-leger: #e2e8f0;        /* filets purement décoratifs          */

  /* Couleur d'interface : le bleu marine porte le texte et les contours
     qui doivent être lisibles ; le bleu vif ne sert qu'en aplat.      */
  --accent: #1a5276;             /* 8,4:1 sur blanc, 7,6:1 sur le fond  */
  --accent-teinte: #d6eaf8;      /* accent sur cette teinte : 6,8:1     */
  --accent-fonce: #133d58;       /* survol/actif : 11,4:1 sur blanc     */
  --accent-vif: #2980b9;         /* décoratif uniquement (jauges, filets) */

  /* Dégradés de la charte : en-têtes et boutons principaux. La fin du
     dégradé est assombrie par rapport à Décarbochim (#2980b9, 4,3:1)
     pour que le texte blanc reste à 4,5:1 au moins sur toute sa
     largeur.                                                          */
  --degrade-entete: linear-gradient(135deg, #1a5276 0%, #21618c 100%); /* blanc : ≥6,6:1 */
  --degrade-bouton: linear-gradient(135deg, #1a5276 0%, #2471a3 100%); /* blanc : ≥5,3:1 */

  /* Couleur secondaire — pour distinguer DEUX familles d'éléments qui
     n'ont rien à voir avec un niveau de stratégie ni un état de
     correction (ex. les deux faces d'une carte dans un jeu
     d'association). Le vert de Décarbochim, assombri pour le texte.
     Comme toujours, la couleur ne porte jamais l'info seule : un mot
     l'accompagne.                                                      */
  --secondaire: #196f3d;         /* 6,1:1 sur blanc */
  --secondaire-teinte: #e9f7ef;

  /* Trois niveaux de stratégie : bleu, vert, violet — un trio qui reste
     distinguable par la plupart des daltonismes. La couleur ne porte
     JAMAIS l'information seule : le nom du niveau est toujours écrit. */
  --niveau-1: #1b4a7a;           /* corporate    9,1:1 */
  --niveau-1-teinte: #e9eff6;
  --niveau-2: #0d6b57;           /* business     6,4:1 */
  --niveau-2-teinte: #e8f4f0;
  --niveau-3: #5b3a86;           /* fonctionnel  8,8:1 */
  --niveau-3-teinte: #efeaf7;

  /* États de correction, doublés d'un mot et d'un style de filet.      */
  --juste: #1f6b4e;              /* 6,4:1 sur blanc */
  --juste-teinte: #eaf5f0;
  --juste-vif: #27ae60;          /* décoratif (grands aplats) */
  --faux: #c0392b;               /* 5,4:1 sur blanc, 4,8:1 sur #fdecea */
  --faux-teinte: #fdecea;
  --faux-vif: #e74c3c;           /* décoratif (grands aplats) */
  --partiel: #8a5206;            /* 6,4:1 sur blanc */
  --partiel-teinte: #f8f0e3;

  --sans: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  --corps: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  --mono: "JetBrains Mono", "Cascadia Mono", Consolas, "DejaVu Sans Mono", monospace;

  --colonne: 42rem;              /* largeur de lecture confortable       */
  --page: 85rem;                 /* largeur du contenu ; au-delà, marges
                                     de respiration de chaque côté        */

  --rayon: 16px;                 /* cartes                               */
  --rayon-sm: 10px;              /* boutons, champs, encarts             */
  --rayon-xs: 8px;               /* puces, chips                         */
  --rayon-pilule: 999px;         /* badges de statut, jauges             */
  --ombre: 0 8px 32px rgba(0, 0, 0, 0.11);
  --ombre-sm: 0 4px 16px rgba(0, 0, 0, 0.07);

  --transition-rapide: 150ms ease;

  /* Hauteur réelle de .barre-nav, mesurée et tenue à jour par
     commun/accessibilite.js (voir ajusterHauteurBarre()) — la valeur
     ci-dessous n'est qu'un repli avant la première mesure ou sans
     JavaScript. */
  --hauteur-barre-nav: 3.5rem;
}

/* 2. Taille du texte (boutons A- / A+) -----------------------------
   La barre d'accessibilité ne fait que poser un attribut sur <html> :
   aucun style en ligne n'est écrit dans la page.                     */

html { font-size: 100%; }
html[data-taille="1"] { font-size: 87.5%; }
html[data-taille="2"] { font-size: 100%; }
html[data-taille="3"] { font-size: 112.5%; }
html[data-taille="4"] { font-size: 131.25%; }
html[data-taille="5"] { font-size: 150%; }

/* 3. Réinitialisation mesurée -------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { background: var(--fond); }

body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  font-family: var(--corps);
  font-size: 1.0625rem;
  line-height: 1.6;
}

img, svg, table { max-width: 100%; }
img { height: auto; }

/* 4. Mode dyslexie -------------------------------------------------
   Police sans empattement largement disponible en local, interlignage,
   espacement des caractères et des mots augmentés (WCAG 1.4.12).     */

html[data-dys="1"] body,
html[data-dys="1"] button,
html[data-dys="1"] input,
html[data-dys="1"] select,
html[data-dys="1"] textarea {
  font-family: Verdana, Tahoma, "Trebuchet MS", "Segoe UI", sans-serif;
  letter-spacing: 0.09em;
  word-spacing: 0.18em;
  line-height: 1.9;
}

/* Exception : la barre de navigation. C'est un bandeau d'outils tenu
   sur une seule ligne (voir .barre-nav__contenu plus bas), pas un texte
   à lire — l'espacement des lettres/mots n'y aide pas la lecture
   (intitulés courts, un ou deux mots) mais élargit assez chaque bouton
   et le badge « Connecté : ... » pour faire déborder la barre et forcer
   un défilement horizontal, justement ce que sa mise en page cherche à
   éviter. La police reste changée (cohérence visuelle avec le reste de
   la page en mode dyslexie) ; seuls les espacements qui poussent la
   largeur sont neutralisés, sur le conteneur ET tous ses descendants
   (héritage naturel de letter-spacing/word-spacing sinon insuffisant
   face aux déclarations directes de la règle ci-dessus sur
   button/input/select/textarea). */
html[data-dys="1"] .barre-nav,
html[data-dys="1"] .barre-nav * {
  letter-spacing: normal;
  word-spacing: normal;
}

/* 34rem d'origine + l'espacement des lettres/mots ci-dessus (déjà
   généreux, WCAG 1.4.12) cumulaient : chaque caractère prend nettement
   plus de place qu'en lecture normale, donc une largeur de colonne
   pensée pour le texte courant (--colonne, 42rem) devient beaucoup trop
   étroite une fois espacée — quelques mots par ligne, un effet
   d'escalier gênant à la lecture. 48rem compense cet espacement plutôt
   que de viser un compte de caractères fixe. */
html[data-dys="1"] p,
html[data-dys="1"] li { max-width: 48rem; }

html[data-dys="1"] p + p { margin-top: 1.5em; }

html[data-dys="1"] h1,
html[data-dys="1"] h2,
html[data-dys="1"] h3,
html[data-dys="1"] h4 { letter-spacing: 0.04em; }

/* 5. Titres et texte courant --------------------------------------- */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--sans);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 2rem 0 0.75rem;
  color: var(--encre);
}

h1 { font-size: 2rem; margin-top: 0; }
h2 {
  font-size: 1.4rem;
  border-bottom: 2px solid var(--filet-leger);
  padding-bottom: 0.4rem;
}
h3 { color: var(--accent); }
h3 { font-size: 1.15rem; }
h4 {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--encre-secondaire);
}

p, ul, ol, dl, table, figure, blockquote, pre { margin: 0 0 1rem; }
p, li { max-width: var(--colonne); }
/* Classe à ajouter au cas par cas sur un paragraphe précis (ex.
   S01-R03-apport) quand la colonne de lecture bridée à --colonne laisse,
   à côté de lui, un vide que la mise en page ne comble pas autrement
   (ex. juste avant la colonne latérale des ressources). Ne change ni la
   règle p/li ci-dessus ni aucune autre page : seuls les paragraphes qui
   portent cette classe en plus s'élargissent. */
p.texte-large, li.texte-large { max-width: 100%; }

ul, ol { padding-left: 1.4rem; }
li + li { margin-top: 0.35rem; }

dt { font-weight: 600; font-family: var(--sans); }
dd { margin: 0 0 0.75rem 1.4rem; }

strong, b { font-weight: 700; }
abbr[title] { text-decoration: underline dotted; cursor: help; }
small { font-size: 0.875em; }

blockquote {
  border-left: 3px solid var(--filet-leger);
  margin-left: 0;
  padding: 0.25rem 0 0.25rem 1rem;
  color: var(--encre-secondaire);
}

figure { margin-left: 0; margin-right: 0; }
figcaption {
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--encre-secondaire);
  border-top: 1px solid var(--filet-leger);
  padding-top: 0.4rem;
  margin-top: 0.4rem;
}

code, kbd, samp, pre { font-family: var(--mono); font-size: 0.92em; }
pre {
  background: var(--fond-secondaire);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon-xs);
  padding: 0.75rem;
  overflow-x: auto;
}

/* 6. Liens ---------------------------------------------------------- */

/* Pas de couleur :visited distincte : #6b4a86 (violet) n'appartenait pas
   à la palette du site (jetons ci-dessus) et n'a aucun sens ici — un
   lien « visité » par le navigateur ne veut pas dire une ressource
   terminée, ce que le site indique déjà par ses propres badges de
   statut (Ouverte/Fermée, Terminée…). Les liens gardent donc la même
   teinte, visités ou non. */
a { color: var(--accent); text-underline-offset: 0.18em; }
a:hover { color: var(--accent-fonce); text-decoration-thickness: 2px; }

/* 7. Focus visible (WCAG 2.4.7) ------------------------------------- */

:focus { outline: 3px solid var(--accent); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

.bouton--plein:focus-visible {
  outline-color: var(--papier);
  box-shadow: 0 0 0 5px var(--encre);
}

/* 8. Lien d'évitement ----------------------------------------------- */

.evitement {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--encre);
  color: var(--papier-creme);
  padding: 0.6rem 1rem;
  font-family: var(--sans);
  border-radius: 0 0 var(--rayon-xs) 0;
  z-index: 100;
}
.evitement:focus { left: 0; }

/* 9. Barre supérieure (accessibilité + navigation) --------------------
   Une seule barre, réunissant marque / accessibilité / compte connecté
   — auparavant deux barres empilées (accessibilité puis navigation),
   fusionnées ici pour prendre moins de hauteur en haut de page (voir
   barre_superieure() dans suivi.php). Le bloc .barre-nav__liens n'existe
   dans le DOM que pour un visiteur connecté, donc aucune règle « cachée
   par défaut » n'est nécessaire pour lui. */
.barre-nav {
  /* Barre sombre de la charte (#1a252f). Plutôt que de réécrire chaque
     composant de la barre, les jetons y sont redéfinis pour un fond
     sombre : boutons, liens, focus et badge en héritent, avec les mêmes
     exigences de contraste (ratios mesurés sur #1a252f).              */
  --fond-secondaire: #1a252f;
  --papier: #233240;             /* fond des boutons de la barre        */
  --papier-creme: #1a252f;       /* texte sur aplat clair (--accent)    */
  --encre: #ffffff;              /* 15,6:1 */
  --encre-secondaire: #c5d1dc;   /* 10:1 ; 8,5:1 sur --papier           */
  --filet: #8699ab;              /* bordures : 5,3:1 ; 4,5:1 sur --papier */
  --filet-leger: #2c3e50;
  --accent: #5dade2;             /* 6,3:1 ; 4,9:1 sur --accent-teinte   */
  --accent-teinte: #22384a;
  --accent-fonce: #85c1e9;       /* survol : 8:1 sous le texte sombre   */
  --accent-vif: #27ae60;         /* filet décoratif (vert Décarbochim)  */
  color: var(--encre);
  border-bottom: 1px solid var(--filet-leger);
  border-top: 4px solid var(--accent-vif);
  background: var(--fond-secondaire);
  /* Reste collée en haut de l'écran pendant le défilement plutôt que de
     disparaître avec le reste de la page. --hauteur-barre-nav est
     mesurée par commun/accessibilite.js (sa hauteur varie avec les
     réglages d'accessibilité — taille de texte, dyslexie) : les autres
     éléments collants du site (aside de navigation, plateau de
     classement) s'en servent pour ne pas passer sous elle. */
  position: sticky;
  top: 0;
  z-index: 20;
}

/* Passage à la ligne plutôt que défilement horizontal : au-delà de
   56em (voir media query plus bas pour en dessous, où un bouton
   « Menu » replie accès/compte à la place), si le contenu ne tient
   plus sur une ligne — texte agrandi, mode dyslexie... — il retombe à
   la ligne suivante plutôt que de faire déborder la barre sur le côté.
   Volontaire : avec un défilement horizontal, agrandir le texte peut
   faire sortir du cadre les boutons d'accessibilité eux-mêmes (A-,
   Réinitialiser), qu'il faudrait alors faire glisser pour les
   retrouver — jamais avec le passage à la ligne, tout reste visible.
   Pas de max-width ici contrairement à .page/.barre-nav__contenu avant
   fusion : une barre d'outils doit pouvoir utiliser toute la largeur
   disponible. */
.barre-nav__contenu {
  padding: 0.6rem 1.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* flex-end, pas space-between : depuis le retrait de la marque (nom du
     parcours), .barre-nav__bascule/.barre-nav__panneau sont les seuls
     enfants en flux normal — avec space-between, un enfant unique se
     cale à gauche, alors que le panneau mobile reste ancré à droite
     (right: 1.25rem, voir plus bas) : les deux doivent rester du même
     côté. */
  justify-content: flex-end;
  gap: 0.5rem 1.25rem;
  background-color: var(--fond-secondaire);
}

/* Bouton « Menu » : replie l'accès/le compte en dessous de 56em (voir
   media query plus bas). Au-delà, .barre-nav__panneau reste affiché en
   ligne (avec passage à la ligne si besoin, voir ci-dessus) : le bouton
   reste alors caché, inutile puisqu'il n'y a rien à déplier.
   Même mécanique d'accordéon que partout ailleurs sur le site
   (data-accordeon, câblée une fois pour toutes dans
   commun/accessibilite.js) : sans JavaScript, le panneau reste toujours
   visible (rien n'est jamais perdu), avec JavaScript il se replie par
   défaut sous 56em. */
.barre-nav__bascule {
  display: none;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 2.6rem;
  padding: 0 1rem 0 0.9rem;
  border: none;
  border-radius: var(--rayon-pilule);
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--papier-creme);
  /* --accent, pas --accent-vif : ce dernier est réservé au décoratif
     (jauges…) et ne garantit pas 3:1, alors qu'un bouton fonctionnel
     avec une icône blanche dessus en a besoin — voir les jetons en
     tête de fichier. */
  background: var(--accent);
}
.barre-nav__bascule:hover,
.barre-nav__bascule[aria-expanded="true"] { background: var(--accent-fonce); }
/* Icône « hamburger » : trois barres construites en CSS pur (aucune
   image), même principe que les puces ::after des accordéons — pas de
   police d'icônes à charger pour trois traits. */
.barre-nav__bascule-icone,
.barre-nav__bascule-icone::before,
.barre-nav__bascule-icone::after {
  display: block;
  width: 1.15rem;
  height: 2px;
  background: var(--papier-creme);
  border-radius: 2px;
}
.barre-nav__bascule-icone {
  position: relative;
  flex-shrink: 0;
  transition: background-color var(--transition-rapide);
}
.barre-nav__bascule-icone::before,
.barre-nav__bascule-icone::after {
  content: "";
  position: absolute;
  left: 0;
  transition: transform 200ms ease, top 200ms ease;
}
.barre-nav__bascule-icone::before { top: -0.4rem; }
.barre-nav__bascule-icone::after { top: 0.4rem; }
/* Hamburger → croix : le trait du milieu (le ::before/::after de
   .barre-nav__bascule-icone porte les traits haut/bas, l'élément
   lui-même porte celui du milieu) s'efface, les deux autres pivotent
   et se recentrent — confirme visuellement l'état ouvert sans mot en
   plus. Coupé pour qui préfère moins de mouvement.                     */
.barre-nav__bascule[aria-expanded="true"] .barre-nav__bascule-icone {
  background: transparent;
}
.barre-nav__bascule[aria-expanded="true"] .barre-nav__bascule-icone::before {
  top: 0;
  transform: rotate(45deg);
}
.barre-nav__bascule[aria-expanded="true"] .barre-nav__bascule-icone::after {
  top: 0;
  transform: rotate(-45deg);
}
@media (prefers-reduced-motion: reduce) {
  .barre-nav__bascule-icone,
  .barre-nav__bascule-icone::before,
  .barre-nav__bascule-icone::after { transition: none; }
}

.barre-nav__panneau {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.25rem;
}
/* Au-delà de 56em, .barre-nav__bascule est cachée (voir plus bas) donc
   personne ne peut de toute façon replier ce panneau — mais si
   JavaScript l'a replié plus tôt (fenêtre rétrécie puis ragrandie),
   cette règle prime sur l'attribut hidden et le garde affiché. */
.barre-nav__panneau[hidden] { display: flex; }

.barre-nav__acces {
  display: flex;
  flex-wrap: wrap;
  flex-shrink: 0;
  row-gap: 0.5rem;
  align-items: center;
  gap: 0.5rem 0.75rem;
  font-family: var(--sans);
  font-size: 0.9rem;
  white-space: nowrap;
}

.barre-acces__intitule {
  font-weight: 600;
  margin-right: 0.25rem;
}

.barre-acces__groupe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

.barre-acces__etat {
  color: var(--encre-secondaire);
  font-variant-numeric: tabular-nums;
  font-family: var(--mono);
  white-space: nowrap;
}

.barre-nav__liens {
  display: flex;
  flex-wrap: wrap;
  flex-shrink: 0;
  row-gap: 0.5rem;
  align-items: center;
  gap: 1.1rem;
  white-space: nowrap;
}

.barre-nav__compte {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--encre-secondaire);
}

/* 10. Boutons -------------------------------------------------------- */

.bouton,
button,
input[type="submit"],
input[type="button"] {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.3;
  color: var(--encre);
  background: var(--papier);
  border: 1px solid var(--filet);
  border-radius: var(--rayon-sm);
  padding: 0.6rem 1.1rem;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: background-color var(--transition-rapide),
              border-color var(--transition-rapide),
              transform var(--transition-rapide),
              box-shadow var(--transition-rapide);
}

.bouton:hover,
button:hover,
input[type="submit"]:hover { background: var(--fond-secondaire); }

.bouton--plein,
button.bouton--plein,
input[type="submit"].bouton--plein {
  background: var(--encre);
  border-color: var(--encre);
  color: var(--papier-creme);
}
.bouton--plein:hover {
  background: color-mix(in srgb, var(--encre) 85%, white);
  border-color: color-mix(in srgb, var(--encre) 85%, white);
  transform: translateY(-1px);
  box-shadow: var(--ombre-sm);
}
.bouton--plein:active { transform: translateY(0); box-shadow: none; }

/* Hors de la barre sombre, le bouton principal prend le dégradé bleu
   de la charte (texte blanc : 5,3:1 au point le plus clair). */
.page .bouton--plein,
.ecran-connexion .bouton--plein {
  background: var(--degrade-bouton);
  border-color: var(--accent);
  color: #ffffff;
}
.page .bouton--plein:hover,
.ecran-connexion .bouton--plein:hover {
  background: var(--degrade-bouton);
  border-color: var(--accent-fonce);
  opacity: 0.92;
}

/* « Mes cours »/« Gérer les cours » : traité comme une pastille pleine
   plutôt qu'un lien texte nu, pour se distinguer du reste de la barre. */
.barre-nav__lien {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.92rem;
  padding: 0.45rem 0.95rem;
  color: var(--accent);
  background: var(--accent-teinte);
  border: 1px solid transparent;
  font-family: inherit;
  cursor: pointer;
}
/* Pastille de comptage — « Modifications » (admin), signalements à
   traiter. Couleur d'état (--faux) plutôt que l'accent : c'est un
   compte qui appelle une action, pas une simple métadonnée. */
.barre-nav__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.35rem;
  height: 1.35rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--faux);
  color: #ffffff;                /* 5,4:1 sur --faux */
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.barre-nav__lien:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--papier-creme);
  text-decoration: none;
  transform: translateY(-1px);
  box-shadow: var(--ombre-sm);
}
.barre-nav__lien:active { transform: translateY(0); box-shadow: none; }

/* Variante « forte » — même taille que les autres pastilles de la barre
   (Signaler une modification, Gérer les cours), mais en aplat plein
   plutôt qu'en teinte légère, pour qu'un lien précis ressorte visuellement
   des autres sans devenir plus gros (demande explicite du commanditaire :
   « un bouton petit mais plus visible »). */
.barre-nav__lien--fort {
  background: var(--accent);
  color: var(--papier-creme);
  font-weight: 600;
}
.barre-nav__lien--fort:hover {
  background: color-mix(in srgb, var(--accent) 85%, black);
  border-color: color-mix(in srgb, var(--accent) 85%, black);
}

/* « Se déconnecter » : bouton fantôme, plus discret que .bouton--plein
   puisque ce n'est pas l'action que la barre met en avant. */
.barre-nav__deconnexion {
  padding: 0.45rem 0.9rem;
  font-size: 0.85rem;
  color: var(--encre-secondaire);
  border-color: var(--filet-leger);
}
.barre-nav__deconnexion:hover {
  background: var(--fond-secondaire);
  border-color: var(--encre-secondaire);
  color: var(--encre);
  transform: translateY(-1px);
  box-shadow: var(--ombre-sm);
}
.barre-nav__deconnexion:active { transform: translateY(0); box-shadow: none; }

/* Menu déroulant de la barre (« Gérer », « Comptes »… selon le rôle) :
   regroupe plusieurs destinations sous un seul bouton plutôt que
   d'ajouter un bouton par destination — la barre reste aussi compacte
   qu'avant même quand une nouvelle page (ex. création de compte)
   s'ajoute au site. Même mécanique d'accordéon que partout ailleurs
   (data-accordeon, commun/accessibilite.js) : sans JavaScript, le
   panneau reste replié par défaut (contrairement aux autres accordéons
   du site) mais chaque lien qu'il contient reste un <a> ordinaire,
   donc atteignable — voir le commentaire dans suivi.php sur le rendu
   sans JS de ce menu. */
.barre-nav__menu {
  position: relative;
  display: inline-flex;
}
.barre-nav__menu-bouton {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.barre-nav__menu-caret {
  display: inline-block;
  width: 0;
  height: 0;
  border-left: 0.32em solid transparent;
  border-right: 0.32em solid transparent;
  border-top: 0.36em solid currentColor;
  transition: transform var(--transition-rapide);
}
.barre-nav__menu-bouton[aria-expanded="true"] .barre-nav__menu-caret {
  transform: rotate(180deg);
}
.barre-nav__menu-panneau {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  min-width: 13rem;
  background: var(--papier);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 0.4rem;
  white-space: nowrap;
}
.barre-nav__menu-panneau[hidden] { display: none; }
/* a ET button : « Signaler une modification » (ouvre la modale, voir
   commun/signalement.js) vit aussi dans ce menu, à côté des vrais liens. */
.barre-nav__menu-panneau a,
.barre-nav__menu-panneau button {
  display: block;
  width: 100%;
  padding: 0.55rem 0.75rem;
  border: none;
  border-radius: var(--rayon-sm);
  background: none;
  color: var(--encre);
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.9rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.barre-nav__menu-panneau a:hover,
.barre-nav__menu-panneau a:focus-visible,
.barre-nav__menu-panneau button:hover,
.barre-nav__menu-panneau button:focus-visible {
  background: var(--accent-teinte);
  color: var(--accent);
}

/* Sous 56em : plus de défilement horizontal (rien ne signalait qu'on
   pouvait faire glisser, et « Se déconnecter »/les boutons
   d'accessibilité restaient hors champ) — à la place, un bouton rond
   (icône hamburger) ouvre un panneau flottant en carte, ancré sous lui
   à droite de la barre. */
@media (max-width: 56em) {
  .barre-nav__contenu {
    position: relative;   /* ancre le panneau flottant ci-dessous */
    overflow: visible;    /* sans quoi le panneau, absolute, serait
                              rogné par le overflow-x:auto par défaut */
    background-image: none;
  }
  .barre-nav__bascule { display: inline-flex; }

  .barre-nav__panneau {
    position: absolute;
    top: calc(100% + 0.75rem);
    right: 1.25rem;
    left: 1.25rem;
    z-index: 30;
    flex-direction: column;
    align-items: stretch;
    gap: 1.1rem;
    background: var(--papier);
    border: 1px solid var(--filet-leger);
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 1.25rem;
    transform-origin: top right;
    animation: barre-nav-panneau-apparition 180ms ease both;
  }
  .barre-nav__panneau[hidden] { display: none; }
  @media (prefers-reduced-motion: reduce) {
    .barre-nav__panneau { animation: none; }
  }
  @keyframes barre-nav-panneau-apparition {
    from { opacity: 0; transform: translateY(-0.4rem) scale(0.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
  }
  /* Petite pointe reliant visuellement la carte au bouton qui l'ouvre —
     même teinte et même filet que la carte, un triangle CSS pur (pas
     d'image). */
  .barre-nav__panneau::before {
    content: "";
    position: absolute;
    top: -0.5rem;
    right: 1.05rem;
    width: 0.9rem;
    height: 0.9rem;
    background: var(--papier);
    border-left: 1px solid var(--filet-leger);
    border-top: 1px solid var(--filet-leger);
    transform: rotate(45deg);
    border-radius: 2px 0 0 0;
  }

  /* « Affichage » traité comme un petit intitulé de section (même
     esprit que .entete__surtitre) plutôt qu'un mot brut au fil du
     texte : la carte a la place d'un vrai en-tête, contrairement à la
     barre inline d'origine. */
  .barre-acces__intitule {
    display: block;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--encre-secondaire);
    margin: 0 0 0.6rem;
  }
  .barre-nav__acces { flex-wrap: wrap; row-gap: 0.5rem; }
  .barre-acces__groupe { flex-wrap: wrap; }
  /* Boutons d'accès en pilule dans le panneau flottant (au lieu du
     coin légèrement arrondi --rayon-sm habituel des boutons) : c'est
     ce même panneau qui porte le style « carte de menu » recherché. */
  .barre-acces__groupe button { border-radius: var(--rayon-pilule); }

  /* Séparateur avant le bloc compte, pour distinguer visuellement
     « réglages d'affichage » de « compte » dans la carte. */
  .barre-nav__liens {
    flex-direction: column;
    align-items: stretch;
    gap: 0.6rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--filet-leger);
  }
  .barre-nav__compte { margin-bottom: 0.15rem; }
  .barre-nav__lien,
  .barre-nav__deconnexion {
    width: 100%;
    text-align: center;
    justify-content: center;
    border-radius: var(--rayon-pilule);
    padding-top: 0.65rem;
    padding-bottom: 0.65rem;
  }

  /* Le menu déroulant (« Gérer », « Comptes »…) perd son flottement :
     dans la carte mobile déjà repliable, un second niveau de panneau
     flottant par-dessus serait superflu et risquerait de déborder de la
     carte. .barre-nav__menu-bouton garde le style pilule ci-dessus (il
     porte aussi la classe .barre-nav__lien) ; son panneau s'intègre
     simplement à la suite, en retrait. */
  .barre-nav__menu { display: contents; }
  .barre-nav__menu-panneau {
    position: static;
    min-width: 0;
    margin-top: 0.4rem;
    padding: 0.4rem 0 0.4rem 1rem;
    border: none;
    border-left: 2px solid var(--filet-leger);
    border-radius: 0;
    box-shadow: none;
    white-space: normal;
  }
  .barre-nav__menu-panneau a { text-align: left; }
}

/* ------------------------------------------------------------------
   Modale « Signaler une modification » (formateur) — commun/signalement.js.
   Même principe que .nova-modal (sequence-01/S01-R09-mini-jeu/nova.css) :
   overlay fixe + panneau, repris ici car ce composant est partagé par
   toutes les pages (barre de navigation), pas propre à une ressource.
   ------------------------------------------------------------------ */

.signalement-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(26, 37, 47, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 100;
}
.signalement-modal-overlay[hidden] { display: none; }
.signalement-modal {
  background: var(--papier);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  width: 100%;
  max-width: 32rem;
  max-height: 88vh;
  overflow-y: auto;
}
.signalement-modal:focus { outline: none; }
.signalement-modal__entete {
  position: sticky;
  top: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  background: var(--papier);
  border-bottom: 1px solid var(--filet-leger);
  padding: 1rem 1.25rem;
}
.signalement-modal__entete h2 { margin: 0; font-size: 1.15rem; }
.signalement-modal__fermer {
  all: unset;
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.4rem 0.6rem;
  border-radius: var(--rayon-xs);
  color: var(--encre-secondaire);
}
.signalement-modal__fermer:hover { background: var(--fond-secondaire); color: var(--encre); }
.signalement-modal__fermer:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.signalement-modal__corps { padding: 1.25rem; }
.signalement-modal__corps form[hidden] { display: none; }

@media (max-width: 30em) {
  .signalement-modal-overlay { padding: 0; align-items: flex-end; }
  .signalement-modal { max-width: 100%; max-height: 92vh; border-radius: var(--rayon) var(--rayon) 0 0; }
}

/* ------------------------------------------------------------------
   Onglets-filtre (admin/modifications.php : « À traiter » / « Traité »).
   De vrais liens (URL ?onglet=...), pas un composant ARIA tab/tablist
   piloté au clavier : chaque onglet recharge la page sur une vue
   filtrée différente, donc aria-current="page" (navigation) est la
   sémantique correcte, pas role="tab" (qui suppose un panneau unique
   basculé en JS sans rechargement). Fonctionne entièrement sans JS.
   ------------------------------------------------------------------ */

.filtre-onglets {
  display: flex;
  gap: 0.5rem;
  margin: 1rem 0 1.25rem;
  border-bottom: 1px solid var(--filet-leger);
}
.filtre-onglets__lien {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 0.9rem;
  font-family: var(--sans);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--encre-secondaire);
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
}
.filtre-onglets__lien:hover { color: var(--encre); text-decoration: none; }
.filtre-onglets__lien[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.filtre-onglets__compte {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.3rem;
  height: 1.3rem;
  padding: 0 0.3rem;
  border-radius: 999px;
  background: var(--fond-secondaire);
  color: var(--encre-secondaire);
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.filtre-onglets__lien[aria-current="page"] .filtre-onglets__compte {
  background: var(--accent-teinte);
  color: var(--accent);
}

.bouton[aria-pressed="true"],
button[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--papier-creme);
}
/* L'état actif n'est pas porté par la seule couleur (WCAG 1.4.1) :
   un repère typographique le double.                                  */
.bouton[aria-pressed="true"]::before,
button[aria-pressed="true"]::before { content: "\2713\00a0"; }

button[disabled],
.bouton[aria-disabled="true"] {
  color: var(--encre-secondaire);
  border-color: var(--filet-leger);
  border-style: dashed;
  cursor: not-allowed;
}

.bouton--discret {
  border: none;
  border-radius: 0;
  border-bottom: 1px solid var(--encre);
  padding: 0.1rem 0;
  background: transparent;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 1.5rem 0;
}

/* 11. Charpente de page ---------------------------------------------
   .page occupe toute la largeur de la fenêtre — plus de carte centrée
   flottant sur le fond tan (le fond crème reste plein cadre). Son
   contenu (en-tête, contenu principal, pied), lui, est plafonné à
   --page et centré : sur un grand écran, un texte borné à --colonne
   sans cette limite laisse un vide disproportionné à droite de la
   colonne de lecture. p/li restent en outre plafonnés à --colonne,
   indépendamment de la largeur de ce conteneur.                      */

.page {
  width: 100%;
  /* Fond gris-bleu de la charte : les cartes blanches s'en détachent. */
  background: var(--fond);
  padding: 0 1.5rem 4rem;
}

.page > .entete,
.page > main,
.page > .pied {
  max-width: var(--page);
  margin-left: auto;
  margin-right: auto;
}

.entete {
  /* Bandeau en dégradé bleu de la charte, texte blanc. Les jetons sont
     redéfinis pour ce fond (ratios mesurés sur #21618c, le point le
     plus clair du dégradé). */
  --encre: #ffffff;              /* 6,6:1 */
  --encre-secondaire: #e3eef7;   /* 5,6:1 */
  --accent: #ffffff;
  --accent-teinte: rgba(255, 255, 255, 0.16);
  --filet-leger: transparent;
  color: var(--encre);
  background: var(--degrade-entete);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-sm);
  padding: 2rem 2.25rem 1.75rem;
  margin-top: 1.5rem;
  margin-bottom: 1.75rem;
}
.entete a { color: #ffffff; }

.entete__surtitre {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-teinte);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  display: inline-block;
  margin: 0 0 0.75rem;
}

.entete__meta {
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--encre-secondaire);
  margin: 0.5rem 0 0;
}
.entete__meta span + span::before { content: " — "; }

.fil-ariane {
  font-family: var(--sans);
  font-size: 0.875rem;
  padding: 0.75rem 0 0;
}
.fil-ariane ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
}
.fil-ariane li + li::before { content: "/"; margin-right: 0.35rem; color: var(--encre-secondaire); }

.pied {
  border-top: 1px solid var(--filet-leger);
  margin-top: 3rem;
  padding-top: 1rem;
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--encre-secondaire);
}

/* 11bis. Écran de connexion — deux panneaux ---------------------------
   Propre à connexion.php (page_debut y est appelé avec sans_entete :
   ce composant fournit son propre repère de marque et son propre
   titre, la bannière .entete générique serait redondante). */

.ecran-connexion {
  max-width: 66rem;
  margin: 2.5rem auto;
  background: var(--papier-creme);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr 25rem;
}
@media (max-width: 56em) {
  .ecran-connexion { grid-template-columns: 1fr; margin: 1rem auto; }
}
/* Variante sans panneau de présentation (connexion.php) : le
   formulaire seul, en carte étroite centrée. */
.ecran-connexion--seul {
  grid-template-columns: 1fr;
  max-width: 28rem;
}

.ecran-connexion__intro {
  background: var(--fond-secondaire);
  padding: 2.75rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2rem;
}

.ecran-connexion__marque {
  display: flex;
  align-items: center;
}
.ecran-connexion__marque-nom {
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--encre);
  letter-spacing: -0.01em;
}

.ecran-connexion__pitch { display: flex; flex-direction: column; gap: 1.4rem; }
.ecran-connexion__pitch h1 {
  font-family: var(--sans);
  font-size: 2.4rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--encre);
  margin: 0;
}
.ecran-connexion__pitch p {
  font-family: var(--corps);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--encre-secondaire);
  margin: 0;
  max-width: 24rem;
}

.ecran-connexion__info {
  background: var(--papier);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon-sm);
  padding: 1.25rem 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  max-width: 22rem;
}
.ecran-connexion__info-etiquette {
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
}
.ecran-connexion__info-titre {
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--encre);
}
.ecran-connexion__info-meta {
  font-family: var(--corps);
  font-size: 0.85rem;
  color: var(--encre-secondaire);
}

.ecran-connexion__bas {
  font-family: var(--corps);
  font-size: 0.82rem;
  color: var(--encre-secondaire);
}

.ecran-connexion__form {
  padding: 3rem 2.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.4rem;
}
.ecran-connexion__form h1,
.ecran-connexion__form h2 {
  font-family: var(--sans);
  font-size: 1.7rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--encre);
  margin: 0;
  border-bottom: none;
  padding-bottom: 0;
}
.ecran-connexion__form > p { margin: 0; color: var(--encre-secondaire); }
.ecran-connexion__form .champ { margin-bottom: 0; }
.ecran-connexion__form input[type="password"] { padding: 0.9rem 1rem; font-size: 1rem; }
.ecran-connexion__form .actions { margin: 1.25rem 0 0; }
.ecran-connexion__form .actions .bouton--plein { width: 100%; padding: 0.95rem; }
.ecran-connexion__aide {
  font-family: var(--corps);
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--encre-secondaire);
  margin: 0;
}

@media (max-width: 40em) {
  .ecran-connexion__intro,
  .ecran-connexion__form { padding: 2rem 1.5rem; }
}

/* 12. Sections et encarts -------------------------------------------- */

.section { margin: 2.5rem 0; }

.encart {
  border: 1px solid var(--filet-leger);
  border-left: 4px solid var(--accent);
  border-radius: var(--rayon-sm);
  padding: 1rem 1.25rem;
  margin: 1.5rem 0;
  background: var(--papier);
}
.encart > :last-child { margin-bottom: 0; }
/* Variante à ajouter au cas par cas (ex. S01-R03-apport) : la boîte
   elle-même occupe déjà toute la largeur de sa colonne, mais son texte
   reste bridé à --colonne comme n'importe quel paragraphe du site — ce
   qui, DANS une bordure visible, laisse un vide qui se voit (contrairement
   au même vide hors de toute bordure, qui se lit comme une marge de page
   normale). N'affecte que les encarts qui portent cette classe en plus :
   ni les encarts déjà en place ailleurs, ni la largeur des pages. */
.encart--large p,
.encart--large li { max-width: 100%; }
.encart__titre {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin: 0 0 0.5rem;
}

.objectif {
  border: none;
  border-left: 4px solid var(--accent-vif);
  border-radius: var(--rayon-sm);
  background: var(--accent-teinte);
  padding: 0.9rem 1.1rem;
}

/* Vidéo intégrée (YouTube, etc.) — cadre responsive en 16:9 par simple
   ratio CSS, sans bibliothèque. L'iframe elle-même porte la lecture ;
   ce cadre ne fait que la contraindre proprement dans la page. Largeur
   plafonnée et centrée : sans max-width, le cadre s'étirait à la pleine
   largeur de sa colonne (.ressource-ecran__principal, en 1fr — donc non
   bridée), ce qui rendait la vidéo disproportionnée sur un écran large.
   Masquée à l'impression au même titre que le reste du pilotage écran
   (voir print.css, règle @media print). */
.video-integree__cadre {
  position: relative;
  width: 100%;
  max-width: 50rem;
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  border-radius: var(--rayon-sm);
  overflow: hidden;
  border: 1px solid var(--filet-leger);
  background: var(--encre);
}
.video-integree__cadre iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* 12bis. Écran de ressource — colonne de navigation de séquence --------
   Ouvert par ressource_ouvrir(), refermé par ressource_fermer(). La
   colonne latérale liste les ressources de la même séquence : elle ne
   fait qu'afficher des données déjà chargées (parcours()), aucune
   navigation n'est inventée. */

.ressource-ecran {
  display: grid;
  grid-template-columns: 1fr 20rem;
  gap: 2.5rem;
  align-items: start;
}
@media (max-width: 56em) {
  .ressource-ecran { grid-template-columns: 1fr; }
}
.ressource-ecran__principal { min-width: 0; }

.ressource-ecran__aside {
  background: var(--fond-secondaire);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon);
  padding: 1.25rem;
  position: sticky;
  top: calc(var(--hauteur-barre-nav) + 1rem);
}
@media (max-width: 56em) {
  .ressource-ecran__aside { position: static; margin-top: 1.5rem; }
}

.nav-sequence__entete {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--encre-secondaire);
  margin: 0 0 1rem;
}

.nav-sequence { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }

.nav-sequence__lien {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.55rem;
  border-radius: var(--rayon-sm);
  text-decoration: none;
  color: inherit;
  transition: background-color var(--transition-rapide);
}
a.nav-sequence__lien:hover { background: var(--papier); }
span.nav-sequence__lien { cursor: default; }
.nav-sequence__item--courante .nav-sequence__lien {
  background: var(--papier);
  box-shadow: 0 0 0 1px var(--filet-leger) inset;
}

.nav-sequence__numero {
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: var(--rayon-xs);
  background: var(--filet-leger);
  color: var(--encre);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
}
.nav-sequence__numero--fait { background: var(--juste); color: var(--papier-creme); }
.nav-sequence__numero--encours { background: var(--accent); color: var(--papier-creme); }

.nav-sequence__texte { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; padding-top: 0.15rem; }
.nav-sequence__titre { font-family: var(--sans); font-size: 0.88rem; font-weight: 600; color: var(--encre); line-height: 1.3; }
.nav-sequence__meta { font-family: var(--corps); font-size: 0.78rem; color: var(--encre-secondaire); }
.nav-sequence__item--courante .nav-sequence__titre { color: var(--accent); }

/* 13. Accordéon (encart pédagogique formateur, notions repliables) ---- */

.accordeon {
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon-sm);
  overflow: hidden;
  margin: 1.5rem 0;
}

.accordeon__bouton {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  width: 100%;
  text-align: left;
  border: none;
  border-radius: 0;
  border-bottom: 1px solid transparent;
  background: var(--fond-secondaire);
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 600;
  padding: 0.8rem 1.1rem;
}
.accordeon__bouton::before { content: none; }
.accordeon__bouton::after { content: "+"; font-size: 1.2rem; line-height: 1; color: var(--accent); }
.accordeon__bouton:hover { background: var(--accent-teinte); }
.accordeon__bouton[aria-expanded="true"] {
  border-bottom-color: var(--filet-leger);
  background: var(--accent-teinte);
  color: var(--accent-fonce);
}
.accordeon__bouton[aria-expanded="true"]::after { content: "\2212"; }

.accordeon__panneau { padding: 1.1rem; background: var(--papier); }
.accordeon__panneau > :last-child { margin-bottom: 0; }
.accordeon__panneau[hidden] { display: none; }

.encart-formateur { border-color: var(--accent-fonce); }
.encart-formateur .accordeon__bouton,
.encart-formateur .accordeon__bouton[aria-expanded="true"] {
  background: var(--accent-fonce);
  color: var(--papier-creme);
}
.encart-formateur .accordeon__bouton::after,
.encart-formateur .accordeon__bouton[aria-expanded="true"]::after { color: var(--papier-creme); }
.encart-formateur .accordeon__bouton:focus-visible {
  outline-color: var(--papier);
  box-shadow: 0 0 0 5px var(--encre);
}
.encart-formateur .accordeon__panneau dt { font-family: var(--sans); }

/* 14. Formulaires ---------------------------------------------------- */

fieldset {
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon-sm);
  padding: 0 1.25rem 1rem;
  margin: 0 0 1.5rem;
}
/* La légende est rendue en bloc : sur deux lignes, une légende en
   position native voit le filet du fieldset lui passer au milieu. */
legend {
  float: left;
  width: 100%;
  padding: 0.85rem 0 0.6rem;
  font-family: var(--sans);
  font-weight: 600;
}
legend + * { clear: both; }

label { font-family: var(--sans); font-size: 0.95rem; display: inline-block; }

.champ { margin-bottom: 1.1rem; max-width: var(--colonne); }
.champ > label { display: block; font-weight: 600; margin-bottom: 0.3rem; }
.champ__aide {
  display: block;
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--encre-secondaire);
  margin-bottom: 0.3rem;
}

input[type="text"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="email"],
input[type="password"],
input[type="search"],
select,
textarea {
  font-family: var(--corps);
  font-size: 1rem;
  color: var(--encre);
  background: var(--papier);
  border: 1px solid var(--filet);
  border-radius: var(--rayon-sm);
  padding: 0.55rem 0.65rem;
  width: 100%;
  max-width: 100%;
}
textarea { min-height: 8rem; resize: vertical; }

.choix { display: flex; align-items: flex-start; gap: 0.6rem; padding: 0.35rem 0; }
.choix input { margin-top: 0.25rem; flex: none; width: 1.05rem; height: 1.05rem; }
.choix label { max-width: var(--colonne); font-weight: normal; }

.champ--erreur input,
.champ--erreur select,
.champ--erreur textarea { border-width: 3px; border-color: var(--faux); }

.message-erreur {
  font-family: var(--sans);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--faux);
  display: block;
  margin-top: 0.3rem;
}
.message-erreur::before { content: "Erreur : "; }

/* 15. Feedback d'activité -------------------------------------------- */

.feedback {
  border: 1px solid var(--filet-leger);
  border-left: 6px solid var(--filet);
  border-radius: var(--rayon-sm);
  padding: 0.9rem 1.1rem;
  margin: 1.25rem 0;
  max-width: var(--colonne);
  background: var(--papier);
}
.feedback > :last-child { margin-bottom: 0; }

.feedback__titre {
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 700;
  margin: 0 0 0.4rem;
}
/* Le mot du titre dit déjà l'état ; la couleur et le style de filet ne
   font que le confirmer (WCAG 1.4.1 : jamais la couleur seule).       */
.feedback--juste   { border-left-color: var(--juste);   background: var(--juste-teinte); }
.feedback--faux    { border-left-color: var(--faux);    background: var(--faux-teinte); }
.feedback--partiel { border-left-color: var(--partiel); background: var(--partiel-teinte); }
.feedback--info    { border-left-color: var(--accent);  background: var(--accent-teinte); }
.feedback--juste   .feedback__titre { color: var(--juste); }
.feedback--faux    .feedback__titre { color: var(--faux); }
.feedback--partiel .feedback__titre { color: var(--partiel); }
.feedback--info    .feedback__titre { color: var(--accent); }
/* Le statut est écrit en toutes lettres dans le titre : il n'est jamais
   porté par la seule couleur ni par un pictogramme décoratif.          */
.feedback--juste { border-left-style: solid; }
.feedback--faux { border-left-style: double; border-left-width: 8px; }
.feedback--partiel { border-left-style: dashed; }
.feedback--info { border-left-style: dotted; }
.feedback + .feedback { margin-top: 0.75rem; }

.reponse-attendue {
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--encre-secondaire);
}

/* 16. Verrouillage d'une ressource non ouverte ----------------------- */

.verrou {
  border: 1px solid var(--filet-leger);
  border-top: 4px solid var(--accent-vif);
  border-radius: var(--rayon-sm);
  background: var(--papier);
  padding: 1.5rem;
  max-width: var(--colonne);
  margin: 2rem 0;
}
.verrou__titre { margin-top: 0; }

/* 17. Score et progression -------------------------------------------- */

.score {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.1rem;
  font-weight: 600;
}

.jauge {
  border: none;
  background: var(--filet-leger);
  border-radius: 999px;
  height: 0.85rem;
  max-width: var(--colonne);
  padding: 2px;
}
.jauge__part {
  background: var(--accent-vif);
  border-radius: 999px;
  height: 100%;
  display: block;
}
/* Une progression amorcée mais inférieure au premier palier doit rester
   visible : sinon la jauge paraît vide alors que le travail a commencé. */
.jauge__part.part-0 { width: 0; }
.jauge__part:not(.part-0) { min-width: 8px; }
.jauge__legende {
  font-family: var(--sans);
  font-size: 0.9rem;
}
/* Largeur par pas de 5 % : la valeur vient du serveur sous forme de
   classe, aucun attribut style= n'est écrit dans le HTML.              */
.part-0   { width: 0; }
.part-5   { width: 5%; }
.part-10  { width: 10%; }
.part-15  { width: 15%; }
.part-20  { width: 20%; }
.part-25  { width: 25%; }
.part-30  { width: 30%; }
.part-35  { width: 35%; }
.part-40  { width: 40%; }
.part-45  { width: 45%; }
.part-50  { width: 50%; }
.part-55  { width: 55%; }
.part-60  { width: 60%; }
.part-65  { width: 65%; }
.part-70  { width: 70%; }
.part-75  { width: 75%; }
.part-80  { width: 80%; }
.part-85  { width: 85%; }
.part-90  { width: 90%; }
.part-95  { width: 95%; }
.part-100 { width: 100%; }

/* 18. Tableaux --------------------------------------------------------- */

.tableau { width: 100%; border-collapse: separate; border-spacing: 0; font-family: var(--sans); font-size: 0.95rem; }
.tableau caption {
  text-align: left;
  font-weight: 600;
  padding-bottom: 0.5rem;
}
.tableau th, .tableau td {
  border-bottom: 1px solid var(--filet-leger);
  padding: 0.6rem 0.7rem;
  text-align: left;
  vertical-align: top;
}
.tableau thead th {
  background: var(--fond-secondaire);
  color: var(--accent);
  font-weight: 600;
  border-bottom: 1px solid var(--filet-leger);
}
.tableau tbody tr:nth-child(even) th,
.tableau tbody tr:nth-child(even) td { background: var(--fond-secondaire); }
.tableau-defilant { overflow-x: auto; border-radius: var(--rayon-sm); }

/* Recherche/filtre au-dessus d'un tableau — formulaire GET
   (?q=..., ?filtre_role=...), donc un lien partageable et un
   rechargement classique plutôt qu'un filtre en JavaScript : cohérent
   avec le reste du site, fonctionne aussi sans JS. Repris par les
   tableaux de suivi des comptes (admin/comptes.php,
   responsable/comptes.php — filtre par rôle). */
.reponses-recherche {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin: 1rem 0 1.5rem;
}
.reponses-recherche label { font-weight: 600; }
.reponses-recherche input[type="search"] {
  flex: 1 1 16rem;
  min-width: 12rem;
  margin: 0;
}
.reponses-recherche select { margin: 0; }

/* Lien vers une ressource (sous-séquence) dans le sommaire d'une séquence
   (sequence.php) : le lien reste un <a href> ordinaire, seul son habillage
   change — bouton plein, pleine largeur dans sa cellule, flèche ajoutée en
   ::after pour ne toucher ni le texte du lien ni sa destination. Fond
   beige clair (--accent-teinte) avec texte doré foncé (8,5:1) : le doré
   plein ne sert plus qu'au contour, y compris au survol — le fond ne
   bascule jamais en brun foncé, seuls la bordure, l'ombre et le
   déplacement signalent le survol. */
.ressource-lien,
.ressource-lien:visited {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  box-sizing: border-box;
  padding: 0.75rem 1.15rem;
  border: 1px solid var(--accent);
  border-radius: var(--rayon-sm);
  background: var(--accent-teinte);
  color: var(--accent-fonce);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--transition-rapide),
              transform var(--transition-rapide),
              box-shadow var(--transition-rapide);
}
.ressource-lien::after {
  content: "→";
  flex-shrink: 0;
  color: var(--accent-fonce);
  transition: transform var(--transition-rapide);
}
.ressource-lien:hover {
  border-color: var(--accent-fonce);
  box-shadow: var(--ombre-sm);
  transform: translateY(-2px);
  text-decoration: none;
}
.ressource-lien:hover::after { transform: translateX(4px); }
.ressource-lien:active { transform: translateY(0); box-shadow: none; }

/* 19. Utilitaires ------------------------------------------------------ */

.invisible {
  position: absolute;
  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;
}

.liste-nue { list-style: none; padding-left: 0; }
.mesure { max-width: var(--colonne); }
.nombre { font-variant-numeric: tabular-nums; font-family: var(--mono); }

/* 20. Grille souple (deux colonnes qui retombent en une) ---------------- */

.duo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.25rem;
}
.duo > * { min-width: 0; }

/* 20bis. Catalogue de formations — cartes cliquables ---------------------
   Aperçu de design uniquement à ce stade (voir echange en cours) : ces
   classes ne sont pas encore reliées à une vraie liste de formations en
   base — une seule formation existe réellement (Stratégie d'entreprise). */

.grille-formations {
  display: grid;
  /* auto-fill et non auto-fit : une carte seule (ou deux, trois) garde
     la largeur d'une colonne au lieu de s'étirer sur toute la ligne. */
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 1.25rem;
  margin: 1.5rem 0;
}

.carte-formation {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  position: relative;
  overflow: hidden;
  background: var(--papier);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-sm);
  padding: 1.75rem 1.5rem 1.5rem;
  text-decoration: none;
  color: inherit;
  transition: transform var(--transition-rapide),
              box-shadow var(--transition-rapide),
              border-color var(--transition-rapide);
}
/* Filet de couleur en tête de carte, comme sur Décarbochim — purement
   décoratif (l'état de la carte est toujours écrit en toutes lettres). */
.carte-formation::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 5px;
  background: var(--accent-vif);
}
.carte-formation--indisponible::before { background: var(--filet-leger); }
a.carte-formation:hover {
  border-color: var(--accent);
  box-shadow: var(--ombre-sm);
  transform: translateY(-2px);
}
.carte-formation--indisponible { cursor: default; opacity: 0.72; }

.carte-formation__entete { display: flex; justify-content: space-between; align-items: center; }
.carte-formation__niveau {
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent);
}
.carte-formation__compte { font-family: var(--mono); font-size: 0.72rem; color: var(--encre-secondaire); }
.carte-formation__titre { font-family: var(--sans); font-size: 1.2rem; font-weight: 600; color: var(--encre); margin: 0; line-height: 1.25; border-bottom: none; padding-bottom: 0; }
.carte-formation__desc { font-family: var(--corps); font-size: 0.9rem; color: var(--encre-secondaire); line-height: 1.5; flex: 1; margin: 0; }
.carte-formation__pied {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--filet-leger);
  padding-top: 0.75rem;
  font-family: var(--sans);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--encre);
}
.carte-formation__statut { font-family: var(--sans); font-size: 0.78rem; color: var(--encre-secondaire); font-weight: 600; }

/* 21. Adaptations ------------------------------------------------------- */

@media (min-width: 40.01em) {
  .page {
    padding: 0 3rem 4rem;
  }
}

@media (max-width: 40em) {
  .page { padding-left: 1rem; padding-right: 1rem; }
  h1 { font-size: 1.6rem; }
  .actions { flex-direction: column; align-items: stretch; }
  .actions .bouton, .actions button { width: 100%; }
  .barre-acces__groupe .bouton,
  .barre-acces__groupe button { padding: 0.4rem 0.7rem; font-size: 0.85rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media (forced-colors: active) {
  .bouton, button { border: 1px solid ButtonText; }
  .jauge__part { background: Highlight; }
  .page { box-shadow: none; }
}

/* 21bis. Puces de statut, cartes-stat, jauge héroïque -------------------
   Composants additifs : ils ne changent aucune donnée, seulement leur
   présentation. Chaque puce redit son état en toutes lettres (WCAG
   1.4.1) — la couleur et le point ne font que le confirmer. */

.badge-statut {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--sans);
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.3rem 0.7rem 0.3rem 0.6rem;
  border-radius: var(--rayon-pilule);
  background: var(--fond-secondaire);
  color: var(--encre-secondaire);
  white-space: nowrap;
}
.badge-statut::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.badge-statut--fait    { background: var(--juste-teinte);   color: var(--juste); }
.badge-statut--ouvert  { background: var(--juste-teinte);   color: var(--juste); }
.badge-statut--encours { background: var(--accent-teinte);  color: var(--accent); }
.badge-statut--attente { background: var(--fond-secondaire); color: var(--encre-secondaire); }
.badge-statut--ferme   { background: var(--fond-secondaire); color: var(--encre-secondaire); }
/* Rouge/vert francs, réservés au statut d'une séquence entière (carte
   cliquable dans « Mes cours ») — plus appuyés que --ouvert/--ferme,
   qui restent le style neutre des ressources individuelles. */
.badge-statut--seq-ouverte { background: var(--juste-teinte); color: var(--juste); }
.badge-statut--seq-fermee  { background: var(--faux-teinte);  color: var(--faux); }

/* Jauge héroïque : même logique que .jauge (classes .part-N côté
   serveur), présentation plus marquée pour l'écran « Où j'en suis ». */
.jauge { background: var(--filet-leger); }
.jauge__part {
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-vif) 100%);
  transition: width 400ms ease;
}
.progression-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.75rem;
  background: var(--papier);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon);
  padding: 1.5rem 1.75rem;
  margin: 1.5rem 0;
}
.progression-hero__chiffre {
  font-family: var(--sans);
  font-size: 2.6rem;
  font-weight: 600;
  color: var(--encre);
  letter-spacing: -0.02em;
  line-height: 1;
}
.progression-hero__detail { flex: 1 1 16rem; min-width: 0; }
.progression-hero__legende {
  font-family: var(--corps);
  font-size: 0.9rem;
  color: var(--encre-secondaire);
  margin: 0.6rem 0 0;
}
.progression-hero .jauge { height: 0.9rem; max-width: none; }

.stat-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.9rem;
  margin: 1.25rem 0;
}
.stat-carte {
  background: var(--papier);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon-sm);
  padding: 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.stat-carte__label {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--encre-secondaire);
}
.stat-carte__valeur {
  font-family: var(--sans);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--encre);
}
.stat-carte--vide .stat-carte__valeur { color: var(--encre-discrete); }

/* Puce « x/y terminées » à côté d'un titre de séquence. */
.compte-sequence {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--encre-secondaire);
  background: var(--fond-secondaire);
  padding: 0.2rem 0.6rem;
  border-radius: var(--rayon-pilule);
  vertical-align: middle;
  margin-left: 0.6rem;
}
.compte-sequence--complete { background: var(--juste-teinte); color: var(--juste); }

/* Marque de repère dans l'en-tête de page (cf. .marque sur l'écran de
   connexion) : un simple carré arrondi, aucune image chargée. */
.marque-puce {
  display: inline-block;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 0.55rem;
  background: var(--encre);
  vertical-align: -0.35rem;
  margin-right: 0.6rem;
}

/* 22. Schémas (SVG local, aucune image distante) --------- */

.schema {
  margin: 1.5rem 0;
  max-width: var(--colonne);
}
.schema svg, .schema img { width: 100%; height: auto; display: block; }
/* Variante plus petite, à ajouter au cas par cas sur les schémas qui
   n'ont pas besoin de toute la largeur de lecture (ex. S01-R03-apport) —
   n'affecte que les schémas qui portent cette classe en plus. */
.schema--compact { max-width: 30rem; }

/* Schéma + légende côte à côte (ex. S01-R03-apport, le triaxe d'Abell) :
   un schéma plus étroit que la colonne de lecture (.schema--compact)
   laissait un vide sur sa droite avant de retomber, en dessous, sur son
   texte d'accompagnement — les deux se partagent maintenant la largeur.
   flex + wrap plutôt qu'une grille : l'image garde sa taille naturelle
   (jusqu'à 30rem) et se recentre dans sa propre colonne si celle-ci est
   plus large qu'elle, au lieu d'être étirée. Empile en dessous de 34rem
   sans media query, comme .duo — ne touche à aucune marge de page. */
.schema-avec-legende {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem 2rem;
  margin: 1.5rem 0;
}
.schema-avec-legende__schema {
  flex: 1 1 18rem;
  margin: 0;
  display: flex;
  justify-content: center;
}
.schema-avec-legende__legende {
  flex: 1 1 16rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.schema-avec-legende__legende .cas { margin: 0; }

.schema__cadre { fill: none; stroke: var(--encre); stroke-width: 1.5; }
.schema__cadre--interieur { stroke-width: 1.5; }
/* Mêmes couleurs de niveau que dans les mini-jeux : le code couleur est
   le même d'une ressource à l'autre de la séquence. */
.schema__cadre--n0 { stroke: var(--niveau-1); }
.schema__cadre--n1 { stroke: var(--niveau-2); }
.schema__cadre--n2 { stroke: var(--niveau-3); }
/* Spécificité doublée : la règle générique .schema__niveau vient plus
   bas dans la feuille et l'emporterait à égalité. */
.schema__niveau.schema__niveau--n0 { fill: var(--niveau-1); }
.schema__niveau.schema__niveau--n1 { fill: var(--niveau-2); }
.schema__niveau.schema__niveau--n2 { fill: var(--niveau-3); }
.schema__fleche { fill: none; stroke: var(--encre); stroke-width: 1; }
.schema__pointe { fill: var(--encre); }

.schema__niveau {
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 600;
  fill: var(--encre);
}
.schema__question {
  font-family: var(--sans);
  font-size: 13px;
  fill: var(--encre);
}
.schema__note {
  font-family: var(--sans);
  font-size: 12px;
  fill: var(--encre-secondaire);
}

/* 23. Dépliants de contenu (variante d'accordéon pour les apports) ------ */

.deplaint { margin-bottom: 0.75rem; }
.deplaint .accordeon__bouton { font-size: 1rem; }
.deplaint--n0 { border-color: var(--niveau-1); }
.deplaint--n1 { border-color: var(--niveau-2); }
.deplaint--n2 { border-color: var(--niveau-3); }
.deplaint--n0 .accordeon__bouton[aria-expanded="true"] {
  background: var(--niveau-1-teinte); color: var(--niveau-1); border-bottom-color: var(--niveau-1-teinte);
}
.deplaint--n1 .accordeon__bouton[aria-expanded="true"] {
  background: var(--niveau-2-teinte); color: var(--niveau-2); border-bottom-color: var(--niveau-2-teinte);
}
.deplaint--n2 .accordeon__bouton[aria-expanded="true"] {
  background: var(--niveau-3-teinte); color: var(--niveau-3); border-bottom-color: var(--niveau-3-teinte);
}
.deplaint--n0 .cas { border-left-color: var(--niveau-1); }
.deplaint--n1 .cas { border-left-color: var(--niveau-2); }
.deplaint--n2 .cas { border-left-color: var(--niveau-3); }
.deplaint--n0 .cas__titre { color: var(--niveau-1); }
.deplaint--n1 .cas__titre { color: var(--niveau-2); }
.deplaint--n2 .cas__titre { color: var(--niveau-3); }
.deplaint__chapeau {
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--encre-secondaire);
  margin: 0 0 1rem;
}
.cas {
  border-left: 4px solid var(--accent);
  padding-left: 1rem;
  margin: 1rem 0;
}
.cas__titre {
  font-family: var(--sans);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 0.4rem;
}

/* Renvoi vers le cube du schéma triaxe d'Abell (S01-R03-apport,
   « Exemple : Amazon ») : reprend les trois teintes déjà présentes dans
   triaxe-abell-amazon-2.png, propres à ce schéma — pas des jetons de
   palette du site. Le nom de la couleur reste toujours écrit à côté de
   la pastille : celle-ci ne porte jamais l'information seule. */
.cas__cube {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--encre-secondaire);
}
.pastille-cube {
  display: inline-block;
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 3px;
  border: 1px solid var(--filet);
  flex: none;
}
.pastille-cube--bleu   { background: #9fc5e8; }
.pastille-cube--orange { background: #ffab40; }
.pastille-cube--jaune  { background: #ffe599; }

/* Logo de marque cité en exemple — identification visuelle seule, jamais
   seul porteur du nom (toujours à côté du texte, jamais à sa place). */
.marque-logo {
  height: 1.15em;
  width: auto;
  max-width: 4.5em;
  vertical-align: -0.25em;
  margin-right: 0.35em;
  display: inline-block;
}

/* 23bis. Niveaux interactifs (S01-R06-apport) --------------------------
   Remplace un schéma statique par un sélecteur (colonne de gauche, un
   onglet par niveau) + un panneau de détail (colonne de droite), plutôt
   que des cadres emboîtés : utilise toute la largeur de la colonne de
   lecture au lieu de laisser un vide à droite. Piloté par commun/
   niveaux-interactifs.js, sans dépendance — MAIS le HTML de départ est
   déjà complet et lisible sans lui : les trois panneaux .niveau-detail
   sont tous visibles, empilés (voir la règle de marge plus bas). Le
   script les transforme en un seul panneau + des onglets uniquement
   s'il s'exécute (classe .niveaux-cadre--actif, ajoutée par le script) —
   même principe de dégradation gracieuse que commun/classement.js. */

.niveaux-cadre { margin: 1.5rem 0; }
.niveaux-cadre > .niveau-detail + .niveau-detail { margin-top: 1rem; }

.niveaux-cadre.niveaux-cadre--actif {
  display: grid;
  grid-template-columns: minmax(15rem, 20rem) 1fr;
  gap: 1.5rem;
  align-items: start;
  max-width: none;
}
.niveaux-cadre.niveaux-cadre--actif > .niveau-detail + .niveau-detail { margin-top: 0; }
@media (max-width: 40em) {
  .niveaux-cadre.niveaux-cadre--actif { grid-template-columns: 1fr; }
}

.niveaux-liste {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
}
.niveaux-liste__fleche {
  align-self: center;
  color: var(--encre-discrete);
  font-size: 0.9rem;
  line-height: 1;
}

.niveau-tab {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  width: 100%;
  text-align: left;
  background: var(--papier);
  border: 1px solid var(--filet-leger);
  border-left: 4px solid var(--filet-leger);
  border-radius: var(--rayon-sm);
  padding: 0.8rem 1rem;
  cursor: pointer;
  opacity: 0.62;
  transition: opacity var(--transition-rapide), border-color var(--transition-rapide),
              box-shadow var(--transition-rapide), background-color var(--transition-rapide);
}
.niveau-tab:hover, .niveau-tab:focus-visible { opacity: 1; box-shadow: var(--ombre-sm); }
.niveau-tab:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.niveau-tab[aria-selected="true"] {
  opacity: 1;
  border-left-width: 6px;
  background: var(--fond-secondaire);
  box-shadow: var(--ombre-sm);
}
.niveau-tab--n0 { border-left-color: var(--niveau-1); }
.niveau-tab--n1 { border-left-color: var(--niveau-2); }
.niveau-tab--n2 { border-left-color: var(--niveau-3); }

.niveau-tab__rang {
  flex: none;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 0.82rem;
  color: var(--papier-creme);
}
.niveau-tab--n0 .niveau-tab__rang { background: var(--niveau-1); }
.niveau-tab--n1 .niveau-tab__rang { background: var(--niveau-2); }
.niveau-tab--n2 .niveau-tab__rang { background: var(--niveau-3); }

.niveau-tab__corps { min-width: 0; }
.niveau-tab__titre {
  display: block;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--encre);
}
.niveau-tab__question {
  display: block;
  font-size: 0.8rem;
  color: var(--encre-secondaire);
  margin-top: 0.15rem;
}

.niveau-detail {
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-radius: var(--rayon-sm);
  padding: 1.25rem 1.4rem;
  border-left: 4px solid var(--filet-leger);
  background: var(--fond-secondaire);
  height: 100%;
  box-sizing: border-box;
}
.niveau-detail[hidden] { display: none; }
.niveau-detail--n0 { border-left-color: var(--niveau-1); background: var(--niveau-1-teinte); }
.niveau-detail--n1 { border-left-color: var(--niveau-2); background: var(--niveau-2-teinte); }
.niveau-detail--n2 { border-left-color: var(--niveau-3); background: var(--niveau-3-teinte); }
.niveau-detail__titre {
  margin: 0 0 0.5rem;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.niveau-detail--n0 .niveau-detail__titre { color: var(--niveau-1); }
.niveau-detail--n1 .niveau-detail__titre { color: var(--niveau-2); }
.niveau-detail--n2 .niveau-detail__titre { color: var(--niveau-3); }
.niveau-detail p:last-child { margin-bottom: 0; }

/* 23ter. Texte + image (S01-R06-apport) ---------------------------------
   Schéma ou vidéo placé à droite du texte d'introduction : comble
   l'espace resté vide à droite d'un texte borné à --colonne sur un
   écran large (.ressource-ecran__principal n'est, lui, pas borné).
   Repasse sous le texte dès que la place manque (flex-wrap), sans
   media query dédiée. Aligné en haut (le texte démarre juste sous le
   titre, comme n'importe quel autre paragraphe du site) : un centrage
   vertical a été essayé, mais il pousse un texte court vers le bas et
   ouvre un vide entre le titre et le texte — pire que le problème
   d'origine. */
.texte-avec-image {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1.75rem;
  margin-bottom: 1.5rem;
}
.texte-avec-image__texte { flex: 1 1 20rem; min-width: 0; }
.texte-avec-image__texte > :last-child { margin-bottom: 0; }

/* Schéma fourni (image), pas un composant du site : cadre simple,
   largeur bornée pour rester lisible et ne pas écraser le texte à
   côté, hauteur laissée libre (aspect-ratio du fichier respecté). Le
   texte de la ressource contient lui-même beaucoup de petits détails
   (« Qui décide, Horizon, Exemples de décisions »), donc plus grand =
   plus lisible : grandit deux fois plus vite que le texte (flex-grow: 2
   contre 1) et plafond relevé en conséquence. */
.texte-avec-image__figure {
  flex: 2 1 26rem;
  max-width: 44rem;
  margin: 0;
}
.texte-avec-image__figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--rayon-sm);
  border: 1px solid var(--filet-leger);
}

/* 24. Classement (mini-jeux : glisser-déposer accessible) --------------
   Sans JavaScript, seules les cartes et leurs boutons radio existent :
   le formulaire reste complet. Le plateau de zones n'apparaît que si
   classement.js s'exécute (classe .classement--actif).

   Chaque niveau a sa couleur, reprise par la zone, par la carte une
   fois placée et par la correction. La couleur ne remplace jamais le
   texte : le nom du niveau est écrit partout où elle apparaît.     */

.classement { margin: 1.5rem 0; }

/* Le plateau restait autrefois collé en haut de l'écran pendant le
   défilement (position: sticky), pour rester atteignable avec beaucoup
   de cartes — mais .classement__pile (les cartes à classer) suit juste
   après lui dans le DOM : à l'usage, ce plateau collant, opaque et
   au-dessus du reste (z-index), finissait par recouvrir les cartes
   restantes au lieu de rester simplement visible à côté d'elles,
   les rendant impossibles à saisir en glisser-déposer pendant qu'on
   descend la page — sur ordinateur comme sur mobile. Retiré : le
   plateau défile normalement avec le reste. */
.classement__zones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.5rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--filet-leger);
}

.classement__barre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-family: var(--sans);
  font-size: 0.9rem;
  margin-bottom: 0.75rem;
}
.classement__compteur { font-weight: 600; font-variant-numeric: tabular-nums; font-family: var(--mono); }
.classement__jauge {
  flex: 1 1 6rem;
  height: 0.5rem;
  border: none;
  background: var(--filet-leger);
  border-radius: 999px;
  padding: 1px;
  min-width: 5rem;
  max-width: 20rem;
}
.classement__barre [data-remise] { flex: 0 0 auto; }
/* Un bouton momentanément inutile reste discret, sans filet pointillé. */
.bouton--discret[disabled] {
  border-bottom-color: var(--filet-leger);
  color: var(--encre-secondaire);
  border-style: solid;
}
.classement__jauge span { display: block; height: 100%; border-radius: 999px; background: var(--accent-vif); }

.zone {
  border: 2px dashed var(--filet);
  border-top: 4px solid var(--filet);
  border-radius: var(--rayon-sm);
  padding: 0.7rem 0.8rem;
  min-height: 6rem;
  background: var(--papier);
}
.zone--survol {
  border-style: solid;
  background: var(--accent-teinte);
}
.zone__titre {
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--filet-leger);
}
.zone__compte {
  font-weight: normal;
  font-size: 0.85rem;
  font-family: var(--mono);
  color: var(--encre-secondaire);
  float: right;
  font-variant-numeric: tabular-nums;
}
.zone__liste { margin: 0; }
.zone__liste:empty::after {
  content: "Déposez ici, ou cochez le niveau sur une carte.";
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--encre-secondaire);
}

/* Une teinte par niveau : la zone, puis la carte qu'on y range. */
.zone--n0 { border-color: var(--niveau-1); background: var(--niveau-1-teinte); }
.zone--n1 { border-color: var(--niveau-2); background: var(--niveau-2-teinte); }
.zone--n2 { border-color: var(--niveau-3); background: var(--niveau-3-teinte); }
.zone--n0 .zone__titre { color: var(--niveau-1); }
.zone--n1 .zone__titre { color: var(--niveau-2); }
.zone--n2 .zone__titre { color: var(--niveau-3); }

.classement__pile { margin: 0; padding: 0; list-style: none; }
.classement--actif .classement__pile:empty::after {
  content: "Toutes les décisions sont classées. Demandez la correction.";
  font-family: var(--sans);
  font-size: 0.9rem;
  color: var(--juste);
  font-weight: 600;
}

.carte {
  border: 1px solid var(--filet-leger);
  border-left: 5px solid var(--filet);
  border-radius: var(--rayon-sm);
  background: var(--papier);
  padding: 0.8rem 1rem;
  margin: 0 0 0.75rem;
  max-width: none;
}
.carte:last-child { margin-bottom: 0; }
.carte--deplacable { cursor: grab; }
.carte--deplacable:hover { border-left-color: var(--accent); background: var(--fond-secondaire); }
.carte--en-cours { opacity: 0.45; cursor: grabbing; }
.carte--placee-n0 { border-left-color: var(--niveau-1); }
.carte--placee-n1 { border-left-color: var(--niveau-2); }
.carte--placee-n2 { border-left-color: var(--niveau-3); }

.carte__enonce { margin: 0 0 0.6rem; max-width: none; }
.carte__numero {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--papier-creme);
  background: var(--filet-fort);
  padding: 0.15rem 0.5rem;
  border-radius: var(--rayon-xs);
  display: block;
  width: fit-content;
  margin-bottom: 0.5rem;
}
.carte--placee-n0 .carte__numero { background: var(--niveau-1); }
.carte--placee-n1 .carte__numero { background: var(--niveau-2); }
.carte--placee-n2 .carte__numero { background: var(--niveau-3); }

.carte fieldset { border: none; padding: 0; margin: 0; }
.carte legend { float: none; width: auto; padding: 0; }
.carte .choix { padding: 0.2rem 0; }

/* Dans une zone, la carte est déjà classée : présentation compacte, les
   boutons radio restant disponibles pour la reclasser au clavier. */
.zone .carte {
  padding: 0.55rem 0.65rem;
  font-size: 0.92rem;
  margin-bottom: 0.5rem;
}
.zone .carte .carte__enonce { margin-bottom: 0.35rem; }
.zone .carte fieldset { font-size: 0.85rem; }

/* Étiquette de niveau dans la correction. */
.etiquette-niveau {
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--papier);
  padding: 0.15rem 0.55rem;
  border-radius: var(--rayon-xs);
  display: inline-block;
}
.etiquette-niveau--n0 { background: var(--niveau-1); }
.etiquette-niveau--n1 { background: var(--niveau-2); }
.etiquette-niveau--n2 { background: var(--niveau-3); }

/* Corrigé d'un texte à trous (S01-R21-synthese) : marque chaque mot
   choisi dans le texte reconstitué, en réutilisant les couleurs d'état
   de correction (--juste/--faux) — jamais les couleurs de niveau
   ci-dessus, réservées aux trois niveaux de stratégie. La couleur ne
   porte jamais l'info seule (WCAG 1.4.1) : le mot attendu est réécrit à
   côté de toute réponse fausse (voir le gabarit PHP). */
.mot-trou { font-weight: 600; border-radius: var(--rayon-xs); padding: 0 0.2rem; }
.mot-trou--juste { color: var(--juste); background: var(--juste-teinte); }
.mot-trou--faux { color: var(--faux); background: var(--faux-teinte); }

/* 24bis. Comptes de test (pages de connexion, en local uniquement) --
   Voir comptes_test() dans commun/suivi.php. */

/* Liste des comptes de test, affichée en local uniquement. Filet
   pointillé : on voit d'un coup d'œil que ce bloc ne fait pas partie
   du site réel. */
.comptes-test {
  max-width: 66rem;
  margin: 0 auto 2.5rem;
  padding: 1.5rem 1.75rem;
  background: var(--papier-creme);
  border: 2px dashed var(--filet);
  border-radius: var(--rayon);
}
.comptes-test h2 {
  font-family: var(--sans);
  font-size: 1.1rem;
  margin: 0 0 0.4rem;
  border-bottom: none;
  padding-bottom: 0;
  color: var(--accent);
}
.comptes-test > p { margin: 0 0 1rem; color: var(--encre-secondaire); }
.comptes-test__code {
  font-family: var(--mono);
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

@media (max-width: 40em) {
  .comptes-test { padding: 1.25rem 1rem; margin: 0 1rem 1.5rem; }
}

/* 24ter. Quiz chronométré (S01-R04-quiz, commun/quiz.js) ----------- */

.quiz-chrono {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
  padding: 0.6rem 1rem;
  font-family: var(--sans);
  font-size: 0.95rem;
  color: var(--encre-secondaire);
  background: var(--papier);
  border: 1px solid var(--filet-leger);
  border-radius: var(--rayon-sm);
  box-shadow: var(--ombre-sm);
}
.quiz-chrono__valeur {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* Questions une par une : quiz.js pose l'attribut hidden sur les étapes
   non affichées ; .actions étant en flex, hidden doit l'emporter. */
.quiz-etape[hidden],
[data-quiz-fin][hidden] { display: none; }

/* Classement (S01-R05-corrige, vue formateur). */
.tableau td.nombre,
.tableau th.nombre { text-align: right; font-variant-numeric: tabular-nums; }

/* 24quater. Gestion d'une séquence (formateur/sequence.php) ----------
   Colonne « État » : pastille d'état + bouton Ouvrir maintenant /
   Fermer. Fermer est en rouge (--faux) : l'action retire l'accès. */

.etat-ressource {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
.etat-ressource button { padding: 0.45rem 0.9rem; font-size: 0.88rem; }
.bouton--fermer {
  color: var(--faux);
  border-color: var(--faux);
  background: var(--papier);
}
.bouton--fermer:hover { background: var(--faux-teinte); }

/* Bouton « Se déconnecter » de la barre : un formulaire POST (voir
   barre_superieure()), qui ne doit rien changer à la mise en page. */
.barre-nav__form-deconnexion { display: inline-flex; margin: 0; }

/* 25. Impression : le parcours redevient noir et blanc ------------------
   Les fiches de révision (revision.html/.pdf) ont leur propre feuille,
   print.css, indépendante de ces jetons. Ce bloc-ci ne s'applique qu'à
   l'impression directe d'une page du parcours (cours.php, ressources…). */

@media print {
  .zone, .carte, .encart, .feedback, .accordeon, .objectif, .verrou,
  .tableau thead th, .tableau tbody tr:nth-child(even) th,
  .tableau tbody tr:nth-child(even) td {
    background: #ffffff !important;
    color: #000000 !important;
  }
  .zone, .carte, .encart, .feedback, .accordeon, .verrou {
    border-color: #000000 !important;
  }
  .carte__numero, .etiquette-niveau, .entete__surtitre {
    background: #ffffff !important;
    color: #000000 !important;
    border: 1pt solid #000000;
  }
  .page { box-shadow: none; background: #ffffff; }
}
