/* ==========================================================================
   Nabla — chapitre.css
   Layout des pages chapitre + composants réutilisables (blocs DÉFINITION,
   PROPRIÉTÉ, MÉTHODE, À RETENIR, LES PIÈGES CLASSIQUES, tableaux, tableau
   de variations, exercices + corrigés, VERS LE BAC, cadres de widgets).
   Chaque composant est implémenté UNE fois et réutilisé par tous les
   chapitres. Toutes les couleurs viennent de tokens.css.
   ========================================================================== */

/* --- En-tête de chapitre --------------------------------------------------- */

.chap-entete {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: clamp(24px, 4vw, 48px) var(--pad-x) clamp(24px, 4vw, 40px);
}

.fil-ariane {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--faint);
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.fil-ariane a { color: var(--faint); }
.fil-ariane a:hover { color: var(--text); }

.chap-entete h1 {
  margin: 14px 0 0;
  font-size: clamp(34px, 6vw, 52px);
  line-height: 1.05;
  font-weight: 600;
  letter-spacing: -0.015em;
}

.chap-savoir {
  margin: 18px 0 0;
  font-size: clamp(16px, 2vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  max-width: 62ch;
}
.chap-savoir .savoir-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--text);
}

.chap-meta {
  margin-top: 16px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--faint);
}

/* --- Layout deux colonnes ---------------------------------------------------- */

.chap-layout {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--pad-x) 24px;
  display: flex;
  gap: clamp(32px, 4vw, 60px);
  align-items: flex-start;
}

.chap-contenu {
  flex: 1;
  min-width: 0;
  max-width: var(--content-max);
}

/* --- Sommaire (desktop) -------------------------------------------------------- */

.sommaire {
  position: sticky;
  top: 28px;
  width: var(--sommaire-w);
  flex-shrink: 0;
}
.sommaire .sommaire-titre {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--faint);
  margin-bottom: 12px;
}
.sommaire .sommaire-liens {
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--hair);
}
.sommaire .sommaire-liens a {
  padding: 6px 0 6px 14px;
  font-size: 14px;
  text-decoration: none;
  color: var(--muted);
}
.sommaire .sommaire-liens a:hover { color: var(--text); }
.sommaire .sommaire-liens a[aria-current="true"] { color: var(--accent); }

/* --- Sommaire (mobile) ----------------------------------------------------------- */

.sommaire-mobile {
  position: sticky;
  top: 8px;
  z-index: 5;
  border: 1px solid var(--hair);
  border-radius: var(--radius-block);
  background: var(--surface);
  margin-bottom: 28px;
}
.sommaire-mobile summary {
  cursor: pointer;
  padding: 12px 16px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  gap: 12px;
  list-style: none;
}
.sommaire-mobile summary::-webkit-details-marker { display: none; }
.sommaire-mobile .sommaire-liens {
  padding: 2px 16px 14px;
  display: flex;
  flex-direction: column;
}
.sommaire-mobile .sommaire-liens a {
  padding: 6px 0;
  font-size: 15px;
  text-decoration: none;
  color: var(--muted);
}
.sommaire-mobile .sommaire-liens a[aria-current="true"] { color: var(--accent); }

@media (max-width: 919px) {
  .sommaire { display: none; }
}
@media (min-width: 920px) {
  .sommaire-mobile { display: none; }
}

/* --- Sections & prose --------------------------------------------------------------- */

.chap-section { scroll-margin-top: 90px; }
.chap-section + .chap-section { margin-top: 56px; }
#pieges.chap-section, #essentiel.chap-section, #ex.chap-section { margin-top: 64px; }

.chap-section h2 {
  margin: 8px 0 18px;
  font-size: clamp(23px, 3.5vw, 28px);
  font-weight: 600;
}

.prose {
  margin: 0 0 18px;
  font-size: 17px;
  line-height: 1.7;
}
.prose strong { font-weight: 600; }

/* --- Maths (KaTeX) -------------------------------------------------------------------- */

/* Formule en vitrine : hauteur réservée pour éviter tout décalage de mise en
   page pendant le chargement de KaTeX. Centrage par marges auto sur l'enfant
   (et non justify-content) pour que le débordement reste défilable à gauche
   sur mobile. */
.math-vitrine {
  margin: 28px 0;
  display: flex;
  align-items: center;
  min-height: 3.6em;
  font-size: clamp(18px, 2.4vw, 21px);
  overflow-x: auto;
}
.math-vitrine > * { margin: 0 auto; }
.math-vitrine .katex-display { margin: 0 auto; }
.math-vitrine .katex { font-size: 1.1em; } /* 1,21 par défaut : déborde à 375 px */
.math-vitrine--grande {
  margin: 32px 0;
  font-size: clamp(19px, 2.6vw, 23px);
  min-height: 4em;
}

/* --- Figures graphiques statiques -------------------------------------------------------- */

.figure-graph { margin: 28px 0; }
.figure-graph svg { width: 100%; height: auto; display: block; }
.figure-graph figcaption {
  margin-top: 12px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}

/* Classes SVG partagées (figures statiques + widgets) */
.g-grid { stroke: var(--grid); stroke-width: var(--sw-grid); fill: none; }
.g-axis { stroke: var(--axis); stroke-width: var(--sw-grid); fill: none; }
.g-courbe { stroke: var(--chalk); stroke-width: var(--sw-curve); fill: none; stroke-linecap: round; }
.g-courbe-derivee { stroke: var(--accent); stroke-width: var(--sw-curve); fill: none; stroke-linecap: round; }
.g-tangente { stroke: var(--accent); stroke-width: var(--sw-tan); fill: none; stroke-linecap: round; }
.g-tangente-mini { stroke: var(--accent); stroke-width: var(--sw-tan-mini); fill: none; stroke-linecap: round; }
/* Tangente colorée par le signe de la pente (widget variations) */
.g-tangente.pente-pos, .g-tangente-mini.pente-pos { stroke: var(--good); }
.g-tangente.pente-neg, .g-tangente-mini.pente-neg { stroke: var(--bad); }
.g-tangente.pente-nulle, .g-tangente-mini.pente-nulle { stroke: var(--accent); }
.g-guide { stroke: var(--guide); stroke-width: var(--sw-grid); fill: none; }
.g-guide-accent { stroke: var(--accent); stroke-opacity: 0.4; stroke-width: var(--sw-grid); fill: none; }
.pt-halo { fill: none; stroke: var(--accent); stroke-opacity: 0.4; stroke-width: 1.5; }
.pt-point { fill: var(--accent); stroke: var(--surface); stroke-width: 2; }
.pt-fixe { fill: var(--text); stroke: var(--bg); stroke-width: 1.5; }
.pt-b { fill: var(--accent); stroke: var(--bg); stroke-width: 1.5; }
.pt-fixe--surface { stroke: var(--surface); }
.pt-derivee { fill: var(--accent); stroke: var(--surface); stroke-width: 1.5; }
.etiquette-math { font-family: var(--font-math); font-style: italic; fill: var(--text); }
.etiquette-math--muted { fill: var(--muted); }
.etiquette-math--accent { fill: var(--accent); }
.etiquette-mono { font-family: var(--font-mono); font-style: normal; }
.hit-zone { fill: transparent; stroke: none; cursor: grab; touch-action: none; }
.drag-actif .hit-zone, .hit-zone:active { cursor: grabbing; }
.hint-tag { pointer-events: none; }
.hint-tag .hint-fond { fill: var(--band-bg); }
.hint-tag .hint-fil { stroke: var(--band-bg); stroke-width: 1; fill: none; }
.hint-tag .hint-texte { font-family: var(--font-mono); font-size: 10.5px; fill: var(--band-fg); }

/* --- Blocs de cours ------------------------------------------------------------------------ */

/* Étiquette flottante sur le bord haut d'un bloc cadré */
.bloc-tag {
  position: absolute;
  top: -9px;
  left: 16px;
  background: var(--bg);
  padding: 0 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  white-space: nowrap;
}

.bloc-definition {
  position: relative;
  border: 1px solid var(--edge);
  border-radius: var(--radius-block);
  padding: 24px 22px 18px;
  margin: 30px 0;
}
.bloc-definition p { margin: 0; font-size: 16.5px; line-height: 1.7; }

.bloc-retenir {
  position: relative;
  border: 1px solid var(--accent);
  border-radius: var(--radius-block);
  padding: 24px 22px 20px;
  margin: 34px 0;
  background: var(--accTint);
  text-align: center;
}
.bloc-retenir .bloc-tag {
  left: 50%;
  transform: translateX(-50%);
  color: var(--accent);
  padding: 0 10px;
}
.bloc-retenir p {
  margin: 0;
  font-size: clamp(17px, 2.3vw, 19px);
  line-height: 1.6;
  font-weight: 500;
}

.bloc-propriete {
  border-radius: var(--radius-block);
  padding: 18px 22px 20px;
  margin: 30px 0;
  background: var(--accTint);
}
.bloc-propriete .bloc-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 10px;
}
.bloc-propriete p { margin: 0 0 8px; font-size: 16.5px; line-height: 1.7; }
.bloc-propriete p:last-child { margin-bottom: 0; }
.bloc-propriete .math-vitrine { margin: 14px 0 4px; min-height: 2em; }

.bloc-methode {
  border: 1px dashed var(--dash);
  border-radius: var(--radius-block);
  padding: 18px 22px;
  margin: 30px 0;
}
.bloc-methode .bloc-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--muted);
  margin-bottom: 6px;
}
.methode-etape { display: flex; gap: 12px; margin-top: 12px; }
.methode-etape .etape-num {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--accent);
  flex-shrink: 0;
}
.methode-etape .etape-corps { font-size: 16px; line-height: 1.6; }

.bloc-pieges {
  position: relative;
  border: 1px solid var(--edge);
  border-radius: var(--radius-card);
  padding: 28px 22px 6px;
}
.piege {
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--hairIn);
}
.piege:last-child { padding-bottom: 22px; margin-bottom: 0; border-bottom: none; }
.piege p { margin: 0; font-size: 16px; line-height: 1.65; }
.piege strong { font-weight: 600; }

/* Exemple résolu : la méthode exécutée sous les yeux de l'élève. Même famille
   visuelle que le corrigé (étiquette intérieure, étapes), mais sur fond
   surface pour marquer « cours » et non « exercice ». */
.bloc-exemple {
  border: 1px solid var(--hair);
  border-radius: var(--radius-block);
  background: var(--surface);
  padding: 18px 20px;
  margin: 30px 0;
}
.bloc-exemple .exemple-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 12px;
}
.bloc-exemple p { margin: 0 0 12px; font-size: 16px; line-height: 1.7; }
.bloc-exemple p:last-child { margin-bottom: 0; }
.bloc-exemple .exemple-enonce { font-weight: 500; }
.exemple-item { padding: 14px 0; border-bottom: 1px solid var(--hairIn); }
.exemple-item:first-of-type { padding-top: 2px; }
.exemple-item:last-child { border-bottom: none; padding-bottom: 2px; }
.exemple-item p { margin: 0 0 8px; }
.exemple-item p:last-child { margin-bottom: 0; }

/* Aparté « POURQUOI ? » : l'intuition derrière la formule, en voix basse */
.bloc-pourquoi {
  margin: 28px 0;
  padding: 2px 0 2px 20px;
  border-left: 2px solid var(--accEdge);
}
.bloc-pourquoi .bloc-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 10px;
}
.bloc-pourquoi p { margin: 0 0 12px; font-size: 16px; line-height: 1.7; }
.bloc-pourquoi p:last-child { margin-bottom: 0; }

/* --- Tableaux (dérivées usuelles, opérations) -------------------------------------------------- */

.tableau {
  margin: 30px 0;
  border: 1px solid var(--edge);
  border-radius: var(--radius-block);
  overflow: hidden;
  background: var(--surface);
}
.tableau > figcaption,
.bande-inversee {
  background: var(--band-bg);
  color: var(--band-fg);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  padding: 10px 16px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.tableau > figcaption .bande-note,
.bande-inversee .bande-note { color: var(--band-muted); }
.tableau .defile { overflow-x: auto; }
.tableau table {
  width: 100%;
  border-collapse: collapse;
  font-size: 18px;
}
.tableau th {
  text-align: left;
  padding: 10px 18px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--faint);
  font-weight: 500;
  border-bottom: 1px solid var(--hair);
}
.tableau td { padding: 11px 18px; }
.tableau tr + tr td { border-top: 1px solid var(--hairIn); }
.tableau .note-cellule {
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--faint);
}
.tableau .cellule-vide { color: var(--faint); }

/* --- Tableaux de signes & de variations ---------------------------------------------------------
   Grille partagée .tab-grille : rangée x, rangée(s) de signes, et pour les
   variations une rangée de flèches. Les flèches sont des SVG en ligne
   (.var-fleche) — jamais les caractères ↗ / ↘, rendus en emoji sur mobile. */

.tab-grille {
  display: grid;
  grid-template-columns: minmax(58px, auto) 1fr 44px 1fr 44px 1fr;
  font-family: var(--font-math);
  font-size: 17px;
}
.tab-variations .tab-grille,
.tab-signes .tab-grille { min-width: 320px; }
.tab-grille .cel { padding: 10px 14px; }
.tab-grille .cel-entete { text-align: center; font-style: italic; border-right: 1.5px solid var(--edge); }
.tab-grille .bord-x { border-bottom: 1px solid var(--edge); }
.tab-grille .bord-signe { border-bottom: 1px solid var(--hair); }
.tab-grille .cel-centre { padding: 10px 0; text-align: center; }
.tab-grille .cel-gauche { text-align: left; }
.tab-grille .cel-droite { text-align: right; }
.tab-grille .cel-fleche {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 104px;
  position: relative;
  padding: 12px 10px;
}
.tab-grille .val-haut { display: flex; align-items: flex-start; justify-content: center; padding-top: 10px; font-weight: 600; }
.tab-grille .val-bas { display: flex; align-items: flex-end; justify-content: center; padding-bottom: 10px; font-weight: 600; }
.tab-grille .borne { position: absolute; font-size: 14px; color: var(--faint); }
.tab-grille .borne--bas-gauche { bottom: 8px; left: 12px; }
.tab-grille .borne--haut-droite { top: 8px; right: 12px; }

/* Flèche oblique de variation (SVG, s'adapte à la cellule sans déformation) */
.var-fleche { display: block; width: 100%; height: 100%; max-width: 170px; max-height: 76px; }
.var-fleche .fleche-trait { stroke: var(--text); stroke-width: var(--sw-tan-mini); fill: none; stroke-linecap: round; }
.var-fleche .fleche-pointe { fill: var(--text); stroke: none; }

/* Rangée produit d'un tableau de signes (légère emphase) */
.tab-grille .cel-produit { font-weight: 500; }

/* Variante compacte embarquée dans un widget (tableau vivant) */
.tab-grille--mini {
  font-size: 15px;
  grid-template-columns: minmax(44px, auto) 1fr 34px 1fr 34px 1fr;
  border: 1px solid var(--hairIn);
  border-radius: var(--radius-block);
  overflow: hidden;
}
.tab-grille--mini .cel { padding: 7px 10px; }
.tab-grille--mini .cel-centre { padding: 7px 0; }
.tab-grille--mini .cel-fleche { min-height: 60px; padding: 8px 8px; }
.tab-grille--mini .val-haut { padding-top: 7px; }
.tab-grille--mini .val-bas { padding-bottom: 7px; }
.tab-grille--mini .var-fleche { max-height: 44px; }

/* Colonne « tu es ici » du tableau vivant */
.tab-grille .zone-active { background: var(--accTint2); }
.tab-grille .zone-active .var-fleche .fleche-trait { stroke: var(--accent); }
.tab-grille .zone-active .var-fleche .fleche-pointe { fill: var(--accent); }
@media (prefers-reduced-motion: no-preference) {
  .tab-grille [data-zone] { transition: background-color 0.15s ease; }
}

@media (max-width: 480px) {
  .tab-grille { font-size: 15px; grid-template-columns: minmax(44px, auto) 1fr 34px 1fr 34px 1fr; }
  .tab-grille .cel { padding: 8px 10px; }
  .tab-grille .cel-fleche { min-height: 84px; }
  .tab-grille .borne { font-size: 12px; }
}

.site-footer--chapitre { margin-top: 40px; }

/* --- Exercices & corrigés ------------------------------------------------------------------------ */

.ex-tete { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.ex-tete h2 { margin: 0; }
.ex-compte { font-family: var(--font-mono); font-size: 12px; color: var(--faint); }
.ex-intro {
  margin: 14px 0 24px;
  font-size: 16.5px;
  line-height: 1.65;
  color: var(--muted);
}

.exercice { padding: 24px 0; border-top: 1px solid var(--hair); }
.exercice-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.exercice-label {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--accent);
}
.exercice-label .exercice-theme { color: var(--faint); letter-spacing: 0.04em; }
.exercice-niveau { display: inline-flex; align-items: center; gap: 8px; }
.exercice-niveau .niveau-nom { font-family: var(--font-mono); font-size: 11px; color: var(--faint); }
.niveau-barres { display: inline-flex; gap: 3px; align-items: center; }
.niveau-barres span {
  width: 10px;
  height: 3px;
  border-radius: 2px;
  background: var(--tick);
}
.niveau-barres span.plein { background: var(--text); }
.exercice-enonce { margin: 12px 0 0; font-size: 16.5px; line-height: 1.65; }

.corrige-toggle {
  background: none;
  border: none;
  padding: 0;
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--accent);
  cursor: pointer;
}
.corrige-toggle:hover { color: var(--text); }

.corrige {
  margin-top: 16px;
  border-radius: var(--radius-block);
  background: var(--accTint);
  padding: 18px 20px;
}
.corrige-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 12px;
}
.corrige p { margin: 0 0 12px; font-size: 16px; line-height: 1.7; }
.corrige p:last-child { margin-bottom: 0; }
.corrige .etape-label, .bloc-exemple .etape-label { font-family: var(--font-mono); font-size: 12px; color: var(--accent); }
.corrige .conclusion, .bloc-exemple .conclusion { font-weight: 600; }

.ex-reste {
  padding: 20px 0;
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
  font-size: 15px;
  color: var(--faint);
  font-style: italic;
}

/* VERS LE BAC */
.bac {
  margin-top: 32px;
  border: 1px solid var(--edge);
  border-radius: var(--radius-card);
  background: var(--surface);
  overflow: hidden;
  scroll-margin-top: 90px;
}
.bac .bande-inversee { padding: 12px 20px; letter-spacing: 0.16em; }
.bac .bande-note { letter-spacing: 0.1em; }
.bac-corps { padding: 22px 22px 24px; }
.bac-corps .prose { font-size: 16.5px; }
.bac-partie {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--muted);
  margin-bottom: 10px;
}
.bac-corps ol {
  margin: 0 0 20px;
  padding-left: 22px;
  font-size: 16px;
  line-height: 1.8;
}
.bac-corps ol:last-of-type { margin-bottom: 0; }

/* --- Pied de chapitre ------------------------------------------------------------------------------ */

.pied-chapitre {
  margin-top: 56px;
  border-top: 1px solid var(--edge);
  padding-top: 22px;
  display: flex;
  justify-content: space-between;
  gap: 16px 32px;
  flex-wrap: wrap;
  align-items: baseline;
}
.pied-chapitre .suivant-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--faint);
}
.pied-chapitre .suivant-titre {
  margin-top: 8px;
  font-size: 20px;
  font-weight: 600;
  color: var(--faint);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.pied-chapitre .pastille-bientot {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  font-weight: 400;
  color: var(--faint);
  border: 1px dashed var(--dash2);
  border-radius: 999px;
  padding: 3px 9px;
}
.pied-chapitre .pied-contact { font-size: 15.5px; }

/* --- Cadre de widget --------------------------------------------------------------------------------- */

.widget {
  margin: 32px 0;
  border: 1px solid var(--hair);
  border-radius: var(--radius-card);
  background: var(--surface);
  overflow: hidden;
}
.widget-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 18px;
  border-bottom: 1px solid var(--hairIn);
}
.widget-titre-groupe {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.pill-interactif {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--accent);
  border: 1px solid var(--accEdge);
  border-radius: 999px;
  padding: 3px 9px;
}
.widget-titre { font-weight: 600; font-size: 17px; }
.widget-titre .titre-math { font-family: var(--font-math); font-style: italic; }
.widget svg { width: 100%; height: auto; display: block; }
.widget .graph-scinde { border-top: 1px solid var(--hairIn); }

.widget-pied {
  padding: 14px 18px 16px;
  border-top: 1px solid var(--hairIn);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Contrôle segmenté (préréglages de h) */
.segmente {
  display: inline-flex;
  border: 1px solid var(--hair);
  border-radius: 999px;
  overflow: hidden;
}
.segmente button {
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 6px 12px;
  border: none;
  cursor: pointer;
  background: transparent;
  color: var(--muted);
}
.segmente button[aria-pressed="true"] {
  background: var(--accent);
  color: var(--bg);
  font-weight: 500;
}

/* Ligne de lecture (fraction du taux) */
.lecture-taux {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  font-family: var(--font-math);
  font-size: 18px;
}
.frac {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  line-height: 1.3;
  font-size: 0.92em;
}
.frac .frac-num { padding: 0 8px; }
.frac .frac-den {
  border-top: 1.5px solid currentColor;
  align-self: stretch;
  text-align: center;
}
.frac--mono { font-family: var(--font-mono); font-size: 14px; }
.taux-valeur {
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 500;
  color: var(--accent);
}

/* Chips de valeurs */
.chips { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.chips[hidden] { display: none; } /* display:flex l'emporterait sur l'attribut hidden (widget univers) */
.chip {
  font-family: var(--font-mono);
  font-size: 13px;
  background: var(--chip);
  border-radius: var(--radius-chip);
  padding: 5px 10px;
}
.chip--accent { background: var(--accTint2); color: var(--accent); }
.chip--good { background: var(--goodTint); color: var(--good); }
.chip--bad { background: var(--badTint); color: var(--bad); }

/* Équation en direct (widget tangente) */
.lecture-eq { font-family: var(--font-mono); font-size: 14px; color: var(--text); }
.lecture-eq .eq-t { color: var(--accent); margin-right: 4px; }

/* Légende révélée (état tangente du widget sécante) */
.widget-legende {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.6;
  font-style: italic;
  color: var(--muted);
}
.widget-legende strong { font-weight: 600; font-style: normal; color: var(--text); }
.widget-legende .terme-math { font-family: var(--font-math); font-style: normal; }
.widget-legende[hidden] { display: none; }

/* Curseur de a (widget tangente) */
.curseur-ligne { display: flex; align-items: center; gap: 14px; }
.curseur-ligne .curseur-label {
  font-family: var(--font-math);
  font-style: italic;
  font-size: 16px;
}
.curseur-ligne input[type="range"] {
  flex: 1;
  appearance: none;
  -webkit-appearance: none;
  height: 28px;                 /* zone tactile confortable, piste fine dessinée dessous */
  background: transparent;
  margin: 0;
  cursor: pointer;
}
.curseur-ligne input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 99px;
  background: linear-gradient(to right, var(--accent) 0%, var(--accent) var(--pos, 74%), var(--hair) var(--pos, 74%), var(--hair) 100%);
}
.curseur-ligne input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -7px;             /* (4 − 18) / 2 : centre le curseur sur la piste */
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  cursor: grab;
}
.curseur-ligne input[type="range"]::-moz-range-track {
  height: 4px;
  border-radius: 99px;
  background: linear-gradient(to right, var(--accent) 0%, var(--accent) var(--pos, 74%), var(--hair) var(--pos, 74%), var(--hair) 100%);
}
.curseur-ligne input[type="range"]::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  cursor: grab;
}

/* Note de pied du widget « Construis f′ » */
.widget-note {
  padding: 12px 18px 14px;
  border-top: 1px solid var(--hairIn);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
  line-height: 1.6;
}

/* --- Quiz « Teste-toi » --------------------------------------------------------------------------------
   Réutilise le cadre de widget (.widget + .widget-tete). Une question =
   énoncé, boutons-réponses, retour. Mauvaise réponse : marquée et
   désactivée, on peut réessayer ; bonne réponse : question verrouillée,
   explication révélée. */

.quiz-corps { padding: 4px 18px 16px; }
.quiz-question { padding: 14px 0 4px; }
.quiz-question + .quiz-question { border-top: 1px solid var(--hairIn); }
.quiz-enonce { margin: 0 0 12px; font-size: 16.5px; line-height: 1.6; }
.quiz-num {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--faint);
  margin-right: 8px;
}
.quiz-reponses { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 12px; }
.quiz-reponse {
  font-family: var(--font-serif);
  font-size: 16px;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--hair);
  border-radius: var(--radius-block);
  padding: 8px 16px;
  min-height: 44px;
  cursor: pointer;
  text-align: left;
}
@media (hover: hover) {
  .quiz-reponse:not(:disabled):hover { border-color: var(--accent); }
}
.quiz-reponse:disabled { cursor: default; }
.quiz-reponse[data-etat="bonne"] { border-color: var(--good); background: var(--goodTint); }
.quiz-reponse[data-etat="fausse"] { border-color: var(--bad); background: var(--badTint); color: var(--muted); }
.quiz-reponse:disabled:not([data-etat]) { opacity: 0.45; }
@media (prefers-reduced-motion: no-preference) {
  .quiz-reponse[data-etat="fausse"] { animation: quiz-secousse 0.25s ease; }
  @keyframes quiz-secousse {
    25% { transform: translateX(-3px); }
    75% { transform: translateX(3px); }
  }
}
.quiz-retour { margin: 2px 0 12px; font-size: 15.5px; line-height: 1.6; color: var(--muted); }
.quiz-retour[hidden] { display: none; }
.quiz-retour .verdict {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  margin-right: 6px;
}
.quiz-retour .verdict--bonne { color: var(--good); }
.quiz-retour .verdict--fausse { color: var(--bad); }
.quiz-score { font-family: var(--font-mono); font-size: 12px; color: var(--faint); }

/* --- Lecture graphique de f′(a) ------------------------------------------------------------------------
   Réutilise les boutons et retours du quiz ; seuls les contrôles de manche
   sont propres au composant. */

.lecture-controles { display: flex; gap: 10px; flex-wrap: wrap; }
.lecture-controles .btn-pill[hidden] { display: none; }
/* Action principale (passer au point suivant) : bien visible */
.btn-pill--accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
  font-weight: 500;
  padding: 7px 16px;
}
.btn-pill--accent:hover { background: var(--accent); border-color: var(--text); color: var(--bg); }

/* --- Association f ↔ f′ ---------------------------------------------------------------------------------
   Cartes-graphiques appariables. Rangée du haut : f (craie) ; rangée du
   bas : candidates pour f′ (accent), mélangées. */

.associe-corps {
  padding: 14px 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.associe-rang-titre {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--faint);
}
.associe-rang { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.associe-carte {
  position: relative;
  padding: 14px 4px 4px;
  background: transparent;
  border: 1px solid var(--hair);
  border-radius: var(--radius-block);
  cursor: pointer;
}
.associe-carte svg { display: block; width: 100%; height: auto; }
@media (hover: hover) {
  .associe-carte:not(:disabled):hover { border-color: var(--accent); }
}
.associe-carte[aria-pressed="true"] { border-color: var(--accent); background: var(--accTint); }
.associe-carte[data-etat="fausse"] { border-color: var(--bad); background: var(--badTint); }
.associe-carte.est-associee { border-color: var(--good); background: var(--goodTint); cursor: default; }
.associe-etiquette {
  position: absolute;
  top: 5px;
  left: 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--faint);
}
.associe-carte.est-associee .associe-etiquette { color: var(--good); }
.g-courbe-mini { stroke: var(--chalk); stroke-width: var(--sw-tan-mini); fill: none; stroke-linecap: round; }
.g-courbe-mini--derivee { stroke: var(--accent); }
.g-axe-mini { stroke: var(--axis); stroke-width: 1; fill: none; }

/* --- Suites : classes SVG partagées ------------------------------------------------------------------------
   Le nuage de points (n ; u_n) est l'équivalent de la courbe : craie. Les
   constructions qui répondent aux réglages (marches, tiges) sont en accent. */

.pt-suite { fill: var(--chalk); stroke: var(--bg); stroke-width: 1.5; }
.widget .pt-suite { stroke: var(--surface); }
.g-marche { stroke: var(--accent); stroke-width: var(--sw-tan-mini); fill: none; stroke-linecap: round; }

/* Ligne de lecture mono (formule explicite instanciée, lecture de la somme) */
.lecture-formule {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--text);
  line-height: 1.7;
}
.lecture-formule .val-accent { color: var(--accent); font-weight: 500; }

/* --- La machine à termes (suites, §2) : explicite vs récurrence -------------------------------------------- */

.machine-corps {
  padding: 16px 18px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
@media (max-width: 620px) { .machine-corps { grid-template-columns: 1fr; } }
.machine-panneau {
  border: 1px solid var(--hairIn);
  border-radius: var(--radius-block);
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}
.machine-mode {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--accent);
}
.machine-regle { font-size: 17px; min-height: 1.7em; }
.machine-panneau .curseur-ligne { width: 100%; }
.machine-calcul {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.7;
  overflow-wrap: anywhere;
}
.machine-calcul strong, .machine-chaine strong { color: var(--accent); font-weight: 500; }
.machine-chaine {
  margin: 0;
  padding: 0;
  list-style: none;
  width: 100%;
  font-family: var(--font-mono);
  font-size: 13.5px;
  line-height: 1.7;
}
.machine-chaine li { padding: 3px 0; }
.machine-chaine li + li { border-top: 1px dashed var(--hairIn); }
.machine-chaine .machine-donne { color: var(--faint); }
.machine-note {
  margin: 0;
  font-size: 14.5px;
  font-style: italic;
  line-height: 1.55;
  color: var(--muted);
}

/* --- L'escalier de Gauss (suites, §3) ----------------------------------------------------------------------- */

.som-case { fill: var(--chip); stroke: var(--guide); }
.som-copie .som-case { fill: var(--accTint2); stroke: var(--accEdge); }
.som-copie { opacity: 0; transform: translateY(-14px); }
.som-copie.visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: no-preference) {
  .som-copie { transition: opacity 0.35s ease, transform 0.35s ease; }
}
.som-dim { font-family: var(--font-mono); font-size: 12px; fill: var(--muted); }
.som-num { font-family: var(--font-mono); font-size: 11px; fill: var(--faint); }

/* --- Pied de chapitre : chapitre suivant cliquable ----------------------------------------------------------- */

.pied-chapitre .suivant-titre a {
  color: var(--text);
  text-decoration: none;
}
.pied-chapitre .suivant-titre a:hover { color: var(--accent); }

/* --- Probabilités : population de points (figure §1, widgets univers & indépendance) ---------------------
   L'univers est un nuage de 40 points-élèves : l'appartenance à B (musique)
   se lit au remplissage accent, l'appartenance à A (théâtre) à la position
   dans le cadre pointillé. Restreindre l'univers = effacer les autres. */

.pt-pop { fill: var(--chip); stroke: var(--guide); stroke-width: 1; }
.pt-pop--b { fill: var(--accent); stroke: none; }
.pt-efface { opacity: 0.16; }
@media (prefers-reduced-motion: no-preference) {
  .pt-pop, .pt-vp, .pt-fn, .pt-fp, .pt-vn { transition: opacity 0.3s ease; }
}
.cadre-univers { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 7 5; }
.pop-dim { font-family: var(--font-mono); font-size: 12.5px; fill: var(--muted); }
.pop-dim--accent { fill: var(--accent); }

/* Question du widget univers (au-dessus de la ligne de lecture) */
.widget-question { margin: 0; font-size: 16px; line-height: 1.6; }

/* --- Probabilités : arbre pondéré -------------------------------------------------------------------------- */

.arbre-branche { stroke: var(--guide); stroke-width: var(--sw-tan-mini); fill: none; stroke-linecap: round; }
.arbre-branche.chemin-actif { stroke: var(--accent); stroke-width: var(--sw-tan); }
.pt-noeud { fill: var(--guide); }
.arbre-evt { font-family: var(--font-serif); font-size: 16px; fill: var(--text); }
.arbre-proba { font-family: var(--font-mono); font-size: 13px; fill: var(--faint); }
.arbre-proba.chemin-actif { fill: var(--accent); font-weight: 500; }
.arbre-feuille-val { font-family: var(--font-mono); font-size: 13.5px; fill: var(--faint); }
.arbre-feuille-val.chemin-actif { fill: var(--accent); font-weight: 500; }

/* Barre de proportion sous l'arbre : aire = probabilité */
.seg-cadre { fill: none; stroke: var(--hair); }
.seg-plein { fill: var(--accent); }
.seg-vide { fill: var(--chip); }

/* Feuilles cliquables (chemins de l'arbre) */
.arbre-feuilles { display: flex; flex-wrap: wrap; gap: 8px; }
.feuille-btn {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
  background: var(--chip);
  border: 1px solid transparent;
  border-radius: var(--radius-chip);
  padding: 9px 12px;
  cursor: pointer;
}
@media (hover: hover) {
  .feuille-btn:hover { border-color: var(--accent); }
}
.feuille-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accTint2);
  color: var(--accent);
}

/* Curseur avec libellé long (P(pluie), P(retard) sachant pluie…) */
.curseur-ligne--libelle { flex-wrap: wrap; gap: 8px 14px; }
.curseur-ligne--libelle .curseur-legende {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
  flex: 0 0 218px;
}
.curseur-ligne--libelle input[type="range"] { min-width: 160px; }
@media (max-width: 560px) {
  .curseur-ligne--libelle .curseur-legende { flex-basis: 100%; }
}

/* --- Probabilités : dépistage (1 000 points, quatre sorts) ------------------------------------------------- */

.pt-vp { fill: var(--bad); }
.pt-fn { fill: none; stroke: var(--bad); stroke-width: 1.5; }
.pt-fp { fill: var(--accent); }
.pt-vn { fill: var(--tick); }

/* Puces de légende (HTML) accordées aux points du SVG */
.puces-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
}
.puces-legende span { white-space: nowrap; }
.puce {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: -1px;
}
.puce--vp { background: var(--bad); }
.puce--fn { background: transparent; box-shadow: inset 0 0 0 1.5px var(--bad); }
.puce--fp { background: var(--accent); }
.puce--vn { background: var(--tick); }
.puce--b { background: var(--accent); }

/* --- Probabilités : jauges de comparaison (widget indépendance) -------------------------------------------- */

.jauge-fond { fill: var(--chip); stroke: var(--hair); }
.jauge-plein { fill: var(--accent); }
.jauge-repere { stroke: var(--text); stroke-width: 1.5; stroke-dasharray: 3 4; }

/* --- Tableau croisé d'effectifs : rangée et colonne des totaux --------------------------------------------- */

.tableau td.total, .tableau th.total { color: var(--faint); }
.tableau .sep-total { border-left: 1px solid var(--hair); }
.tableau tr.ligne-total td { border-top: 1px solid var(--hair); }

/* --- L'essentiel -----------------------------------------------------------------------------------------
   Le chapitre en cinq lignes, juste avant les exercices. */

.bloc-essentiel {
  position: relative;
  border: 1px solid var(--edge);
  border-radius: var(--radius-card);
  padding: 28px 22px 10px;
}
.essentiel-ligne {
  display: flex;
  gap: 16px;
  align-items: baseline;
  padding: 13px 0;
  border-bottom: 1px solid var(--hairIn);
}
.essentiel-ligne:last-child { border-bottom: none; padding-bottom: 20px; }
.essentiel-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--accent);
  flex: 0 0 132px;
}
.essentiel-ligne p { margin: 0; font-size: 16.5px; line-height: 1.7; }
@media (max-width: 560px) {
  .essentiel-ligne { flex-direction: column; gap: 6px; }
  .essentiel-label { flex: none; }
}

/* --- Produit scalaire : vecteurs, ombre et angles -----------------------------------------------------------
   Les traits des vecteurs réutilisent .g-courbe (craie = le vecteur de
   référence) et .g-courbe-derivee (accent = celui qui répond au geste) ;
   seules les pointes triangulaires, l'arc d'angle et la marque d'angle
   droit sont nouveaux. Couleurs et épaisseurs : tokens uniquement. */

.vec-pointe { fill: var(--chalk); }
.vec-pointe--accent { fill: var(--accent); }
.arc-angle { stroke: var(--accent); stroke-width: var(--sw-tan-mini); fill: none; }
.marque-droit { stroke: var(--accent); stroke-width: var(--sw-tan-mini); fill: none; }
/* Petite flèche au-dessus de la lettre d'un vecteur (etiquetteVecteur) */
.etiquette-vec-fleche { fill: none; stroke: var(--text); stroke-width: 1.2; }
.etiquette-vec-fleche--accent { stroke: var(--accent); }
.etiquette-vec-fleche--muted { stroke: var(--muted); }

/* --- Avancement (physique-chimie) : barres d'espèces, tableau vivant, droites n(x) --------------------------
   Même partage des rôles que courbe/tangente : les réactifs sont des barres
   « craie » (contour craie, fond chip), les produits répondent en accent.
   Couleurs et épaisseurs : tokens uniquement. */

.avc-barre-reactif { fill: var(--chip); stroke: var(--chalk); stroke-width: var(--sw-grid); }
.avc-barre-produit { fill: var(--accTint2); stroke: var(--accent); stroke-width: var(--sw-grid); }
.avc-repere { stroke: var(--guide); stroke-width: var(--sw-grid); stroke-dasharray: 3 4; fill: none; }
.avc-fleche { stroke: var(--muted); stroke-width: var(--sw-tan-mini); fill: none; }
.avc-fleche-pointe { fill: var(--muted); }
.avc-valeur { font-family: var(--font-mono); font-size: 13px; fill: var(--text); }
.avc-nom { font-family: var(--font-mono); font-size: 13.5px; fill: var(--muted); }
.avc-nom--accent { fill: var(--accent); }
.avc-candidat { font-family: var(--font-mono); font-size: 12px; fill: var(--faint); }
.avc-impossible { fill: var(--faint); }

/* Tableau d'avancement vivant (widget avancement) : trois lignes — état
   initial, expressions littérales, ligne « où tu en es » mise à jour en
   direct. Défile horizontalement sur mobile. */
.avc-tableau { overflow-x: auto; border: 1px solid var(--hairIn); border-radius: var(--radius-block); }
.avc-tableau table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 13px; }
.avc-tableau th, .avc-tableau td { padding: 8px 10px; text-align: center; white-space: nowrap; }
.avc-tableau thead th { font-weight: 500; font-size: 12.5px; color: var(--text); border-bottom: 1px solid var(--hair); background: var(--chip); }
.avc-tableau tbody tr + tr td { border-top: 1px solid var(--hairIn); }
.avc-tableau th:first-child, .avc-tableau td:first-child { text-align: left; color: var(--muted); font-size: 12px; }
.avc-tableau .ligne-vive td { color: var(--accent); font-weight: 500; background: var(--accTint); }

/* Boutons d'espèce (réutilisent .feuille-btn) + indices chimiques compacts */
.especes-boutons { display: flex; flex-wrap: wrap; gap: 8px; }
.chip sub, .lecture-formule sub, .avc-tableau sub, .feuille-btn sub, .quiz-reponse sub { line-height: 0; }

/* Correctif partagé : la copie MathML de KaTeX (position: absolute) posée
   dans une cellule de tableau s'échappait du conteneur défilant .defile
   (non positionné) et élargissait la page à 375 px. Ancrée ici, elle reste
   rognée dans la zone de défilement. */
.tableau .defile { position: relative; }

/* --- Composition d'un système (physique-chimie) : verre de dilution, lecture d'étalonnage -------------------
   La pesée réutilise les barres .avc-* (barre choisie = accent, comme
   courbe/tangente), la jauge de concentration réutilise .jauge-*, les
   boutons d'espèces .feuille-btn. Nouveaux ici : le verre (contour craie,
   liquide accent dont seule l'opacité varie — la teinte vient des tokens)
   et la valeur accent lue sur les axes de la droite d'étalonnage.
   Couleurs et épaisseurs : tokens uniquement. */

.dil-verre { fill: none; stroke: var(--chalk); stroke-width: var(--sw-curve); stroke-linecap: round; }
.dil-liquide { fill: var(--accent); }
.etl-valeur { font-family: var(--font-mono); font-size: 13px; fill: var(--accent); }
.chip sup { line-height: 0; }

/* --- Ondes mécaniques (physique-chimie) : crochets de mesure + point craie -----------------------------------
   La corde et les sinusoïdes réutilisent .g-courbe (craie), la pince et la
   crête marquée .pt-halo/.pt-point (accent), les rails .g-guide, le front
   .g-guide-accent, la flèche de célérité .g-courbe-derivee +
   .vec-pointe--accent, les valeurs .etl-valeur. Nouveau ici : le crochet
   de mesure accent (λ, T, distance d'avance — trait + serifs).
   Couleurs et épaisseurs : tokens uniquement. */

.ond-mesure { stroke: var(--accent); stroke-width: var(--sw-tan); fill: none; }

/* Correctif partagé : etalonnage.js (chapitre composition) pose des points
   .pt-craie dans ses SVG, mais la classe n'existait que scopée à
   .carte-motif dans base.css — les étalons héritaient du fill noir par
   défaut, invisibles en thème sombre. Même recette que .pt-suite. */
.pt-craie { fill: var(--chalk); stroke: var(--surface); stroke-width: 1.5; }

/* --- Mouvement d'un système (physique-chimie) : la caisse du chariot ----------------------------------------
   Chronophotographies et vecteurs : tout réutilise l'existant (.pt-craie,
   .g-courbe/.g-tangente + pointes .vec-pointe(--accent), étiquettes mono
   .avc-nom/.avc-candidat, valeurs .etl-valeur). Nouveau ici : les caisses
   du chariot de la section 5 (fond chip, contour craie — même partage des
   rôles que les barres du chapitre avancement). */

.mvt-caisse { fill: var(--chip); stroke: var(--chalk); stroke-width: var(--sw-grid); }

/* --- Énergie mécanique (physique-chimie) : la part dissipée du compte ---------------------------------------
   La rampe, le compte à barres, la caisse tirée et le freinage réutilisent
   l'existant (.g-courbe, .pt-halo/.pt-point, .jauge-*, .avc-barre-*,
   .mvt-caisse, .arc-angle, .ond-mesure, étiquettes .avc-nom et .etl-valeur).
   Nouveau ici : la part de la cagnotte partie en chaleur — barres éteintes,
   même rôle que les niveaux non allumés des jauges. */

.nrj-dissipe { fill: var(--tick); }

/* --- Second degré : portions de courbe signées + tableau à un sommet ----------------------------------------
   Le widget parabole-signe peint la parabole par le signe du trinôme :
   même paire sémantique good/bad que les pentes de tangente (positif =
   vert, négatif = rouge), épaisseur de courbe standard. Le tableau de
   variations d'une parabole n'a qu'un point remarquable (le sommet) :
   variante à 4 colonnes de la grille partagée .tab-grille. */

.g-signe-pos { stroke: var(--good); stroke-width: var(--sw-curve); fill: none; stroke-linecap: round; }
.g-signe-neg { stroke: var(--bad); stroke-width: var(--sw-curve); fill: none; stroke-linecap: round; }

.tab-grille--sommet { grid-template-columns: minmax(58px, auto) 1fr 44px 1fr; }
@media (max-width: 480px) {
  .tab-grille--sommet { grid-template-columns: minmax(44px, auto) 1fr 34px 1fr; }
}

/* --- Trigonométrie : compatibilité KaTeX dans les widgets ----------------- */
/* `.widget svg` et `.figure-graph svg` (height: auto) écrasent le
   `.katex svg { height: inherit }` de KaTeX — même spécificité, mais
   chapitre.css est chargé après lui. Or les éléments étirables de KaTeX
   (radicaux \sqrt, barres \overline) sont des SVG : ils s'aplatissaient dans
   les boutons et explications de quiz. On rend la main à KaTeX ici, en
   dernier dans le fichier. */
.widget .katex svg, .figure-graph .katex svg { width: 100%; height: inherit; }

/* --- Variables aléatoires : la roue de la kermesse --------------------------------------------------------
   10 secteurs équiprobables ; la teinte code la valeur du gain net X
   (neutre = −2 €, accent léger = 0 €, accent fort = +3 €). Choisir une
   valeur de X estompe les secteurs des autres issues (.roue-hors) —
   regrouper les issues, c'est construire la loi. */

.roue-sect { stroke: var(--bg); stroke-width: 2; }
.roue-v0 { fill: var(--chip); }
.roue-v2 { fill: var(--accTint); }
.roue-v5 { fill: var(--accTint2); }
.roue-val { font-family: var(--font-mono); font-size: 14.5px; fill: var(--text); }
.roue-pointe { fill: var(--accent); }
.roue-moyeu { fill: var(--bg); stroke: var(--hair); }
.roue-hors { opacity: 0.15; }
@media (prefers-reduced-motion: no-preference) {
  .roue-sect, .roue-val { transition: opacity 0.25s ease; }
}

/* Boutons de jeu désactivés (plafond de 1 000 parties atteint) */
.btn-pill:disabled { opacity: 0.45; cursor: default; }

/* Le groupe de valeurs de X non utilisé (2 ou 3 lancers) est masqué :
   display:flex l'emporterait sur l'attribut hidden (cf. .chips[hidden]) */
.arbre-feuilles[hidden] { display: none; }

/* Script Python à lire (exercice 13 — le programme demande de la lecture
   de code, pas d'exécution : site statique) */
.bloc-code {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.65;
  background: var(--chip);
  border-radius: var(--radius-block);
  padding: 14px 16px;
  overflow-x: auto;
  margin: 16px 0;
}
.bloc-code pre { margin: 0; }

/* --- Oxydoréduction (physique-chimie) : transfert d'électrons, équilibrage, titrage ------------------------
   Le bécher, la burette, la fiole et leurs liquides réutilisent l'existant
   (.dil-verre, .dil-liquide — seule l'opacité varie), le clou craie
   .avc-barre-reactif et son dépôt accent .avc-barre-produit (même partage
   des rôles que réactif/produit), les étiquettes .avc-nom/.avc-candidat/
   .etl-valeur, la pointe .vec-pointe--accent, les droites .g-courbe (craie)
   et .g-courbe-derivee (accent). Nouveaux ici : le trait du flux
   d'électrons, la rangée demi-équation + multiplicateur du widget
   d'équilibrage, et des gardes d'interligne pour les exposants d'ions
   dans les lectures. Couleurs et épaisseurs : tokens uniquement. */

.rdx-electrons { stroke: var(--accent); stroke-width: var(--sw-tan-mini); fill: none; }

.rdx-demi { display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap; }
.rdx-stepper { display: inline-flex; align-items: center; gap: 8px; flex: none; }
.rdx-mult {
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 500;
  color: var(--accent);
  min-width: 2ch;
  text-align: center;
}

.lecture-formule sup, .avc-tableau sup, .feuille-btn sup, .quiz-reponse sup,
.widget-note sub, .widget-note sup, .widget-legende sub, .widget-legende sup { line-height: 0; }

/* --------------------------------------------------------------------------
   Lentilles, images et couleurs (physique-chimie) — banc d'optique et
   synthèse des couleurs. Le banc réutilise l'existant : .g-grid/.g-axis,
   .g-courbe (lentille et flèche objet, craie) + pointes .vec-pointe,
   .g-courbe-derivee (flèche image, accent) + .vec-pointe--accent,
   .g-tangente (les rayons), .g-guide-accent (prolongements virtuels),
   .pt-halo/.pt-point/.hit-zone, .etiquette-math, .etl-valeur,
   .avc-candidat/.avc-nom, .feuille-btn, .segmente, classes quiz du jeu.
   Nouveaux ici : le tiret virtuel des flèches image, les scènes fixes du
   widget de synthèse (pièce noire / feuille blanche — couleurs physiques
   de tokens.css, identiques dans les deux thèmes) et ses disques mélangés
   par mix-blend-mode.
   -------------------------------------------------------------------------- */

.opt-virtuel .g-courbe-derivee { stroke-dasharray: 6 5; }

.scene-add { fill: var(--scene-noir); stroke: var(--hair); }
.scene-sous { fill: var(--scene-blanc); stroke: var(--hair); }
.disque-lum { mix-blend-mode: screen; }
.disque-filtre { mix-blend-mode: multiply; }

/* Scènes statiques du jeu « De quelle couleur le vois-tu ? » : moitié
   lumière blanche / moitié lumière colorée. Étiquettes lisibles sur les
   fonds FIXES des scènes (pas des couleurs de thème). */
.jeu-cone { opacity: 0.5; }
.jeu-etiquette { font-family: var(--font-mono); font-size: 12.5px; fill: var(--scene-blanc); }
.jeu-etiquette--sombre { fill: var(--scene-noir); }
.jeu-etiquette--grande { font-size: 26px; }

/* --------------------------------------------------------------------------
   Le photon et les spectres (physique-chimie) — spectre électromagnétique
   et niveaux d'énergie. Réutilise l'existant : .g-axis/.g-guide(-accent),
   .pt-halo/.pt-point, la flèche accent (creerVecteur : .g-courbe-derivee +
   .vec-pointe--accent), .avc-nom/.avc-candidat, .feuille-btn, .segmente,
   .scene-add (fond noir des raies d'émission, chapitre lentilles), les
   classes quiz du jeu. Nouveaux ici : la bande arc-en-ciel (stops du
   dégradé en tokens --phys-*), les raies spectrales, la vague-photon,
   les étiquettes de domaines et la petite onde au-dessus du curseur.
   Couleurs et épaisseurs : tokens uniquement.
   -------------------------------------------------------------------------- */

.spx-onde { stroke: var(--accent); stroke-width: var(--sw-tan-mini); fill: none; }
.spx-visible { fill: var(--accTint2); }
.spx-domaine { font-family: var(--font-mono); font-size: 12px; fill: var(--faint); }
.spx-domaine--actif { fill: var(--accent); font-weight: 500; }
.spx-bande { stroke: var(--hair); }
.spx-niveau { stroke: var(--chalk); stroke-width: var(--sw-curve); fill: none; }
.spx-raie { stroke-width: var(--sw-curve); fill: none; }
.spx-raie--noire { stroke: var(--scene-noir); }
.spx-photon { stroke: var(--accent); stroke-width: var(--sw-tan-mini); fill: none; }

.stop-violet { stop-color: var(--phys-violet); }
.stop-bleu { stop-color: var(--phys-bleu); }
.stop-cyan { stop-color: var(--phys-cyan); }
.stop-vert { stop-color: var(--phys-vert); }
.stop-jaune { stop-color: var(--phys-jaune); }
.stop-orange { stop-color: var(--phys-orange); }
.stop-rouge { stop-color: var(--phys-rouge); }

.spx-c-violet { stroke: var(--phys-violet); }
.spx-c-bleu { stroke: var(--phys-bleu); }
.spx-c-cyan { stroke: var(--phys-cyan); }
.spx-c-vert { stroke: var(--phys-vert); }
.spx-c-jaune { stroke: var(--phys-jaune); }
.spx-c-orange { stroke: var(--phys-orange); }
.spx-c-rouge { stroke: var(--phys-rouge); }
.spx-c-invisible { stroke: var(--guide); stroke-dasharray: 4 4; }

/* --------------------------------------------------------------------------
   La polarité des entités (physique-chimie) — schémas de Lewis, géométries
   et bras de fer électronique. Réutilise l'existant : .pt-craie (points des
   doublets non liants), .pt-halo/.pt-point (le doublet partagé qui glisse),
   .arc-angle, .etl-valeur, .avc-candidat, .feuille-btn, classes quiz.
   Nouveaux ici : les lettres d'atomes (mono, corps texte), les traits de
   liaison et de doublet (craie), les lobes des doublets non liants
   (pointillé + teinte accent) et les charges partielles δ (accent).
   Couleurs et épaisseurs : tokens uniquement.
   -------------------------------------------------------------------------- */

.chim-atome { font-family: var(--font-mono); font-size: 21px; fill: var(--text); }
.chim-trait { stroke: var(--chalk); stroke-width: var(--sw-curve); fill: none; }
.chim-lobe { stroke: var(--guide); stroke-width: var(--sw-grid); stroke-dasharray: 4 4; fill: var(--accTint); }
.chim-delta { font-family: var(--font-mono); font-size: 14px; fill: var(--accent); }
.chim-atome--accent { fill: var(--accent); }

/* --------------------------------------------------------------------------
   Cohésion et solubilité (physique-chimie) — cristal qui se défait, concours
   de fusion, savon. Réutilise l'existant : .pt-point (cations accent),
   .pt-craie (anions et molécules d'eau), .spx-visible (l'eau du bécher),
   .nrj-dissipe (la graisse), .chim-trait/.chim-atome (molécules), .g-guide
   (interactions faibles en pointillé), .jauge-*, .feuille-btn, classes quiz.
   Nouveau ici : le signe porté par un ion (tracé en creux, couleur surface).
   -------------------------------------------------------------------------- */

.ion-signe { stroke: var(--surface); stroke-width: 2; fill: none; }

/* --------------------------------------------------------------------------
   Terminale — Les suites : récurrence et limites. Réutilise l'existant :
   .pt-suite, .g-guide(-accent), .g-tangente, .segmente, .curseur-ligne,
   .lecture-formule, classes quiz du jeu. Nouveaux ici : les dominos de la
   récurrence (chute animée sauf mouvement réduit) et la bande de capture
   de la définition de limite. Couleurs et épaisseurs : tokens uniquement.
   -------------------------------------------------------------------------- */

.dom-piece rect { fill: var(--chip); stroke: var(--guide); stroke-width: 1.5; }
.dom-piece--tombe rect { fill: var(--accTint2); stroke: var(--accent); }
@media (prefers-reduced-motion: no-preference) {
  .dom-piece { transition: transform 0.45s cubic-bezier(0.5, 0, 0.7, 1); }
}

.bande-zone { fill: var(--accTint); }
.pt-suite--capture { fill: var(--accent); }

/* --------------------------------------------------------------------------
   Terminale — La continuité et le TVI. Réutilise l'existant : .bande-zone
   (zone de recherche de la dichotomie), .g-marche (l'escalier du point
   fixe), .pt-derivee (solutions de f(x) = k), .g-guide (courbe estompée
   hors restriction), classes segmenté/curseur/quiz. Nouveaux ici : le
   point creux du raccord (limite non atteinte) et le journal mono de la
   dichotomie. Couleurs et épaisseurs : tokens uniquement.
   -------------------------------------------------------------------------- */

.pt-ouvert { fill: var(--surface); stroke: var(--chalk); stroke-width: 2; }

.journal-dico {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--muted);
  display: grid;
  gap: 4px;
}
.journal-dico:not(:empty) {
  border-top: 1px solid var(--hairIn);
  padding-top: 10px;
}

/* --------------------------------------------------------------------------
   Terminale — La fonction logarithme népérien. Réutilise l'existant :
   .g-courbe-derivee (la courbe de ln en accent, miroir de exp),
   .pt-derivee (le reflet A′), .g-guide(-accent), .pt-suite(--capture)
   (points et capture du seuil), classes segmenté/curseur/quiz. Nouveau
   ici : les segments de la règle logarithmique (longueurs ln a et ln b
   mises bout à bout). Couleurs et épaisseurs : tokens uniquement.
   -------------------------------------------------------------------------- */

.regle-seg { fill: var(--accTint2); stroke: var(--accEdge); stroke-width: 1; }

/* --------------------------------------------------------------------------
   Terminale — Le calcul intégral. Réutilise l'existant : .regle-seg (les
   rectangles de la méthode des rectangles), .bande-zone (aire accumulée),
   .g-tangente(-mini), .pt-derivee, classes segmenté/curseur/quiz. Nouveaux
   ici : les aires signées (au-dessus / en dessous de l'axe), remplies avec
   les teintes sémantiques good/bad. Couleurs : tokens uniquement.
   -------------------------------------------------------------------------- */

.aire-pos { fill: var(--goodTint); }
.aire-neg { fill: var(--badTint); }
.regle-seg--second { fill: var(--accTint); }

/* --------------------------------------------------------------------------
   Terminale — Géométrie dans l'espace (chapitres espace, orthogonalité et
   représentations paramétriques) : classes 3D partagées, servies par
   assets/js/nabla-espace.js. Réutilise l'existant : .g-grid/.g-guide
   (-accent), .g-courbe(-derivee), .g-tangente, .pt-*, .hit-zone,
   .vec-pointe(--accent), .etiquette-*, classes segmenté/curseur/quiz.
   Nouveaux ici : arêtes visibles/cachées des solides et faces translucides
   des plans. Couleurs et épaisseurs : tokens uniquement.
   -------------------------------------------------------------------------- */

.ar3 { stroke: var(--chalk); stroke-width: var(--sw-curve); fill: none; stroke-linecap: round; }
.ar3--cache { stroke-width: var(--sw-grid); stroke-dasharray: 5 5; }
.face3 { fill: var(--accTint); stroke: none; }
.face3--bord { fill: var(--accTint); stroke: var(--accEdge); stroke-width: 1; }
.face3--neutre { fill: var(--chip); stroke: none; }

/* --------------------------------------------------------------------------
   Terminale — Combinatoire et dénombrement. Réutilise l'existant :
   .som-case (les cases de la machine à cases), .segmente, .curseur-ligne,
   .lecture-formule, .feuille-btn (les titres de la playlist), .chip,
   classes quiz. Nouveaux ici : les créneaux de la playlist, les cartes de
   tirages/combinaisons et les cases-boutons du triangle de Pascal.
   Couleurs et épaisseurs : tokens uniquement.
   -------------------------------------------------------------------------- */

/* La playlist de révision : créneaux à remplir + cartes-titres */
.playlist-corps {
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.playlist-slots { display: flex; flex-wrap: wrap; gap: 8px; }
.playlist-slot {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--faint);
  border: 1px dashed var(--dash);
  border-radius: var(--radius-chip);
  padding: 8px 12px;
}
.playlist-slot--plein {
  color: var(--accent);
  background: var(--accTint2);
  border: 1px solid var(--accEdge);
}
.playlist-cartes { display: flex; flex-wrap: wrap; gap: 8px; }
.playlist-cartes .feuille-btn:disabled { opacity: 0.45; cursor: default; }

/* Du tirage ordonné au groupe : cartes de tirages, cartes-combinaisons */
.groupes-corps {
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.groupes-grille { display: flex; flex-wrap: wrap; gap: 6px; }
.tirage-carte {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--muted);
  background: var(--chip);
  border-radius: var(--radius-chip);
  padding: 5px 9px;
}
.tirage-carte--combi {
  color: var(--accent);
  background: var(--accTint2);
  border: 1px solid var(--accEdge);
}
.tirage-badge {
  font-size: 10.5px;
  color: var(--faint);
  margin-left: 6px;
  letter-spacing: 0;
}

/* Le triangle de Pascal : une case = un bouton */
.pascal-corps {
  padding: 16px 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}
.pascal-rang { display: flex; justify-content: center; gap: 4px; }
.pascal-case {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--muted);
  background: var(--chip);
  border: 1px solid transparent;
  border-radius: var(--radius-chip);
  min-width: 36px;
  min-height: 34px;
  padding: 5px 4px;
  cursor: pointer;
}
@media (hover: hover) {
  .pascal-case:hover { border-color: var(--accent); }
}
.pascal-case[aria-pressed="true"] {
  background: var(--accent);
  color: var(--bg);
  font-weight: 500;
}
.pascal-case--parent {
  background: var(--goodTint);
  color: var(--good);
  border-color: var(--good);
}
.pascal-case--miroir {
  background: var(--accTint2);
  color: var(--accent);
  border-color: var(--accEdge);
}
@media (max-width: 400px) {
  .pascal-case { min-width: 33px; font-size: 12px; }
}
