@font-face {
  font-family: "Shantell Sans";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("/polices/shantell-sans-latin.woff2") format("woff2");
}

/* Shantell Sans ne contient pas l'alphabet grec. Sans ce visage limité à π,
   Safari iPad complète le glyphe avec sa police cursive système et affiche un
   symbole calligraphié difficile à lire. Les polices mathématiques/sérif sont
   locales à l'appareil : aucun chargement réseau n'est nécessaire. */
@font-face {
  font-family: "Symbole Pi mathsmaths";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src:
    local("STIX Two Math"),
    local("STIX Math"),
    local("Times New Roman");
  unicode-range: U+03C0;
}

/* Accueil connecté : le graphique est désormais la surface principale. */
.accueil {
  --espacement-sections-progres: clamp(2rem, 4vw, 3.5rem);
  --espacement-bilan-classements: clamp(1.5rem, 3vw, 2.5rem);
  display: block;
  min-height: 0;
}

.accueil .accueil-bilan {
  display: block;
  width: min(66rem, 100%);
  margin: 0 auto var(--espacement-bilan-classements);
}

.accueil .accueil-progression-graphe {
  min-height: 17rem;
}

.accueil .accueil-courbe-svg {
  max-height: 19rem;
}

.accueil-point-lien {
  cursor: pointer;
  outline: none;
}

.accueil-point > path {
  fill: var(--fond);
  stroke: var(--cyan);
  stroke-width: 2.2;
  transition: fill 160ms ease, stroke-width 160ms ease;
  vector-effect: non-scaling-stroke;
}

.accueil-point .accueil-point-cible {
  fill: transparent;
  stroke: none;
  pointer-events: all;
}

.accueil-point .accueil-point-reprise {
  fill: none;
  stroke: color-mix(in srgb, var(--cyan) 38%, transparent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.accueil-point-lien:is(:hover, :focus-visible) .accueil-point > path {
  fill: color-mix(in srgb, var(--cyan) 24%, var(--fond));
  stroke-width: 3.2;
}

.accueil-point-lien:focus-visible .accueil-point-cible {
  fill: color-mix(in srgb, var(--cyan) 12%, transparent);
}

.accueil-progression-liens {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-top: 0.65rem;
}

.accueil-progression-liens .accueil-voir-tout {
  min-height: 2.75rem;
  margin: 0;
  color: var(--cyan);
}

/* Chargement progressif de l'historique complet. */
.historique-chargement {
  display: grid;
  min-height: 5rem;
  margin-top: 1rem;
  place-items: center;
  color: var(--texte-secondaire);
  text-align: center;
}

.historique-etat {
  margin: 0;
  font-size: 0.92rem;
}

.historique-suite {
  min-height: 2.8rem;
  margin-top: 0.5rem;
  padding: 0.45rem 1rem;
  border: 1.5px solid color-mix(in srgb, var(--lavande) 65%, transparent);
  border-radius: 49% 51% 46% 54% / 55% 45% 53% 47%;
  background: transparent;
  color: var(--lavande);
  font: inherit;
  cursor: pointer;
  rotate: -0.25deg;
}

.historique-suite:is(:hover, :focus-visible) {
  background: color-mix(in srgb, var(--lavande) 9%, transparent);
  outline: 2px solid color-mix(in srgb, var(--lavande) 35%, transparent);
  outline-offset: 3px;
}

/* Tableaux de données sémantiques bordés par un calque SVG main levée, comme
   dans les listes de l'application prof. */
.visuellement-cache {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.tableau-hote {
  width: 100%;
  padding: 0.35rem 0.25rem 0.7rem;
  overflow-x: auto;
  scrollbar-color: color-mix(in srgb, var(--lavande) 42%, transparent) transparent;
}

.tableau-donnees-croquis {
  position: relative;
  width: max-content;
  min-width: 100%;
  color: var(--encre-structurelle, var(--encre));
}

/* Ces deux tableaux ont une largeur connue. Sans cette largeur explicite,
   max-content et le width:100% du tableau s'alimentent mutuellement et Safari
   peut finir par calculer une surface SVG gigantesque. */
.tableau-classement-croquis {
  width: calc(100% - 0.6rem);
  min-width: 0;
  margin-inline: 0.3rem;
}

.tableau-sessions-eleve-croquis {
  width: 100%;
  min-width: 38rem;
}

.tableau-donnees {
  width: 100%;
  min-width: 100%;
  margin: 0;
  border: 0;
  border-collapse: collapse;
  border-spacing: 0;
  background: transparent;
  color: var(--encre-structurelle, var(--encre));
}

.tableau-donnees > :is(thead, tbody, tfoot) > tr > :is(th, td) {
  position: relative;
  padding: 0.56rem 0.78rem;
  border: 0;
  background: transparent;
  text-align: left;
  vertical-align: middle;
}

.tableau-donnees > :is(thead, tbody, tfoot) > tr > th {
  height: 3rem;
  color: var(--couleur-classement, var(--cyan));
  font-size: 0.92rem;
  font-weight: 600;
}

.tableau-donnees > tbody > tr {
  height: 3.15rem;
}

.tableau-donnees > tbody > tr:hover > :is(th, td) {
  background: color-mix(in srgb, var(--couleur-classement, var(--lavande)) 6%, transparent);
}

.tableau-donnees > :is(thead, tbody, tfoot) > tr > :is(th, td):last-child {
  text-align: right;
}

.traces-tableau-donnees {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.traces-tableau-donnees .tableau-donnees-trait {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.15;
  opacity: 0;
}

.tableau-donnees-trace .tableau-donnees-trait {
  animation: tracer-tableau-eleve 240ms ease-out var(--delai-trait) forwards;
}

.tableau-donnees-sans-animation .tableau-donnees-trait {
  opacity: 1;
  animation: none;
}

@keyframes tracer-tableau-eleve {
  from { opacity: 0; stroke-dasharray: 1; stroke-dashoffset: 1; }
  to { opacity: 1; stroke-dasharray: 1; stroke-dashoffset: 0; }
}

.tableau-classement {
  min-width: 0;
  table-layout: fixed;
}

.tableau-classement > :is(thead, tbody) > tr > :is(th, td):nth-child(1) { width: 72%; }
.tableau-classement > :is(thead, tbody) > tr > :is(th, td):nth-child(2) { width: 28%; text-align: center; }

.progres-classement .tableau-hote {
  margin-top: 0.7rem;
  padding-inline: 0;
}

.progres-automatisme-choix {
  width: 100%;
  min-height: 2.2rem;
  padding: 0.2rem 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--encre-structurelle, var(--encre));
  font: inherit;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  filter: none;
  translate: 0;
  rotate: 0deg;
}

.progres-automatisme-choix:is(:hover, :focus-visible) {
  color: var(--couleur-classement);
  outline: 0;
  box-shadow: none;
}

.tableau-classement > tbody > tr:has(.progres-automatisme-choix:focus-visible)
  > :is(th, td) {
  background: color-mix(in srgb, var(--couleur-classement) 10%, transparent);
}

.progres-tableau-score {
  color: var(--couleur-classement);
  font-size: 1.1rem;
  font-weight: 600;
}

.historique-sessions .liste-sessions.tableau-hote {
  display: block;
  width: min(52rem, 100%);
  margin: 2.5rem auto 0;
}

.tableau-sessions-eleve {
  min-width: 38rem;
  table-layout: fixed;
}

.tableau-sessions-eleve > :is(thead, tbody) > tr > :is(th, td):nth-child(1) { width: 52%; }
.tableau-sessions-eleve > :is(thead, tbody) > tr > :is(th, td):nth-child(2) { width: 24%; text-align: center; }
.tableau-sessions-eleve > :is(thead, tbody) > tr > :is(th, td):nth-child(3) { width: 24%; text-align: right; }

.session-tableau-lien {
  color: inherit;
  text-decoration-color: color-mix(in srgb, var(--cyan) 46%, transparent);
  text-decoration-thickness: 1.4px;
  text-underline-offset: 0.22rem;
}

.session-tableau-lien:is(:hover, :focus-visible) {
  color: var(--cyan);
}

.tableau-chargement {
  color: var(--texte-secondaire);
  text-align: center !important;
}

/* Analyse des automatismes évalués pendant les sessions. */
.progres-automatismes {
  width: min(68rem, 100%);
  margin: 0 auto;
  padding-bottom: 4rem;
  color: var(--encre);
  container: progression / inline-size;
  font-family: var(--police-main);
}

.progres-contenu > .vide {
  color: var(--texte-secondaire);
  text-align: center;
}

.progres-classements {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
}

/* L'iPad conserve les deux classements côte à côte. Seul un écran réellement
   étroit les empile ; la mesure porte sur le composant, pas sur le viewport. */
@container progression (max-width: 40rem) {
  .progres-classements {
    grid-template-columns: minmax(0, 1fr);
  }
}

.progres-classement {
  --couleur-classement: var(--orange-note);
}

.progres-classement.reussi {
  --couleur-classement: var(--cyan);
}

.progres-classement h3,
.progres-suivi h2 {
  width: fit-content;
  margin: 0;
  color: var(--couleur-classement, var(--lavande));
  font-size: clamp(1.5rem, 2.5vw, 2.05rem);
  font-weight: 500;
  rotate: -0.35deg;
}

.progres-graphe-resume p {
  margin: 0.35rem 0 1.1rem;
  color: var(--texte-secondaire);
}

.progres-suivi {
  min-height: 27rem;
  margin-top: var(--espacement-sections-progres, clamp(2rem, 4vw, 3.5rem));
  scroll-margin-top: 1rem;
}

.progres-suivi-tete {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 2rem;
  margin-bottom: 1.5rem;
}

.progres-selecteur-automatisme {
  display: grid;
  min-width: min(22rem, 100%);
  gap: 0.25rem;
  color: var(--texte-secondaire);
  font-size: 0.86rem;
}

.progres-selecteur-libelle {
  font-weight: 600;
}

.selecteur-automatisme-zone {
  position: relative;
  display: block;
  width: 100%;
}

.selecteur-automatisme-cadre {
  position: relative;
  isolation: isolate;
  display: inline-grid;
  width: 100%;
  min-width: 0;
  color: var(--encre-structurelle, var(--encre));
  transition: color 160ms ease;
}

button.selecteur-automatisme-bouton,
button.selecteur-automatisme-bouton:is(:hover, :active, :focus-visible) {
  position: relative;
  z-index: 1;
  width: 100%;
  min-height: 2.85rem;
  padding: 0.55rem 3rem 0.55rem 0.75rem;
  border: 0;
  border-radius: 0;
  outline: 0;
  background: transparent;
  box-shadow: none;
  color: var(--encre-structurelle, var(--encre));
  font: inherit;
  font-size: 1rem;
  font-weight: 400;
  text-align: left;
  filter: none;
  translate: 0;
  rotate: 0deg;
}

.selecteur-automatisme-cadre:has(> :focus-visible) {
  color: var(--lavande);
}

.traces-selecteur-automatisme {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.selecteur-automatisme-trait {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.75;
  opacity: 0;
}

.selecteur-automatisme-trace .selecteur-automatisme-trait {
  animation: tracer-selecteur-automatisme 240ms ease-out var(--delai-trait) forwards;
}

@keyframes tracer-selecteur-automatisme {
  from { opacity: 0; stroke-dasharray: 1; stroke-dashoffset: 1; }
  to { opacity: 1; stroke-dasharray: 1; stroke-dashoffset: 0; }
}

.chevron-selecteur-automatisme {
  position: absolute;
  top: 50%;
  right: 0.82rem;
  z-index: 3;
  width: 1.28rem;
  height: 0.95rem;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
  translate: 0 -50%;
  rotate: -1.5deg;
  transition: rotate 160ms ease, translate 160ms ease;
}

.chevron-selecteur-trait { stroke-width: 1.9; }

.chevron-selecteur-reprise {
  stroke-width: 0.72;
  opacity: 0.32;
  translate: 0.35px 0.45px;
}

.selecteur-automatisme-cadre:hover .chevron-selecteur-automatisme {
  rotate: 1deg;
  translate: 0.05rem -45%;
}

.selecteur-automatisme-options {
  position: fixed;
  inset: auto;
  position-area: block-end span-inline-end;
  position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
  width: min(anchor-size(self-inline), calc(100dvw - 1rem));
  max-height: 17.5rem;
  margin-block: 0.38rem;
  margin-inline: 0;
  padding: 0.42rem;
  overflow: auto;
  border: 1.8px solid color-mix(in srgb, var(--encre-legere) 68%, transparent);
  border-radius: 0.38rem 0.18rem 0.48rem 0.22rem / 0.2rem 0.46rem 0.18rem 0.42rem;
  background: var(--papier-note);
  box-shadow: 0.26rem 0.3rem 0 color-mix(in srgb, var(--encre) 13%, transparent);
  color: var(--encre);
  font-family: var(--police-main);
  rotate: -0.2deg;
}

.selecteur-automatisme-options::backdrop {
  background: transparent;
}

button.option-automatisme,
button.option-automatisme:is(:hover, :active, :focus-visible) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1.45rem;
  gap: 0.55rem;
  align-items: center;
  width: 100%;
  min-height: 2.55rem;
  padding: 0.42rem 0.55rem;
  border: 0;
  border-radius: 0.22rem 0.4rem 0.2rem 0.36rem;
  background: transparent;
  box-shadow: none;
  color: var(--encre);
  font: inherit;
  font-size: 1rem;
  font-weight: 500;
  text-align: left;
  filter: none;
  translate: 0;
  rotate: 0deg;
  transition: color 130ms ease, background-color 130ms ease;
}

button.option-automatisme:hover,
button.option-automatisme:focus-visible,
button.option-automatisme[aria-selected="true"] {
  background: color-mix(in srgb, var(--lavande) 13%, transparent);
  color: var(--lavande);
}

button.option-automatisme:focus-visible {
  outline: 1.5px dashed var(--lavande);
  outline-offset: -2px;
}

.option-automatisme > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.coche-option-automatisme {
  width: 1.4rem;
  height: 1.4rem;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
  opacity: 0;
}

.coche-option-automatisme .trace-reprise {
  stroke-width: 0.72;
  opacity: 0.32;
}

.option-automatisme[aria-selected="true"] .coche-option-automatisme {
  opacity: 1;
}

.progres-graphe {
  min-height: 22rem;
  padding-top: 0.5rem;
  border-top: 1.4px solid color-mix(in srgb, var(--lavande) 30%, transparent);
}

.progres-graphe-resume {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  margin: 1rem 0 0.5rem;
}

.progres-graphe-resume h3 {
  margin: 0;
  color: var(--lavande);
  font-size: clamp(1.2rem, 2vw, 1.55rem);
  font-weight: 500;
}

.progres-graphe-resume p {
  margin: 0;
  text-align: right;
}

.progres-graphe-defilement {
  width: 100%;
  min-height: 16rem;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-color: color-mix(in srgb, var(--lavande) 48%, transparent) transparent;
}

.progres-courbe {
  display: block;
  max-width: none;
  height: auto;
  min-height: 16rem;
  overflow: visible;
}

.progres-courbe text {
  fill: var(--texte-secondaire);
  font-family: var(--police-main);
}

.progres-repere {
  stroke: color-mix(in srgb, var(--encre-legere) 28%, transparent);
  stroke-width: 1;
  stroke-dasharray: 4 7;
  vector-effect: non-scaling-stroke;
}

.progres-axe,
.progres-fleche-axe {
  fill: none;
  stroke: var(--texte-secondaire);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
  vector-effect: non-scaling-stroke;
}

.progres-axe-valeur {
  font-size: 13px;
  text-anchor: end;
}

.progres-courbe-trait {
  fill: none;
  stroke: var(--lavande);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.progres-point-lien {
  cursor: pointer;
  outline: none;
}

.progres-point-cible {
  fill: transparent;
  pointer-events: all;
}

.progres-point {
  fill: var(--fond);
  stroke: var(--lavande);
  stroke-width: 2.5;
  transition: fill 160ms ease, stroke-width 160ms ease;
  vector-effect: non-scaling-stroke;
}

.progres-point-lien:is(:hover, :focus-visible) .progres-point {
  fill: color-mix(in srgb, var(--lavande) 24%, var(--fond));
  stroke-width: 3.5;
}

.progres-point-lien:focus-visible .progres-point-cible {
  fill: color-mix(in srgb, var(--lavande) 12%, transparent);
}

.progres-point-valeur {
  fill: var(--lavande) !important;
  font-size: 14px;
  text-anchor: middle;
}

.progres-point-date {
  font-size: 12px;
  text-anchor: middle;
}

/* Le détail ciblé reste une colonne de la page d'accueil. Comme le panneau du
   cache, le dialogue natif conserve le focus et se referme avec Échap. */
.progres-session-panneau {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(42rem, 100vw);
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  overflow: hidden;
  border: 0;
  border-left: 2px solid var(--encre-structurelle, var(--encre));
  background-color: var(--papier);
  background-image:
    repeating-linear-gradient(
      transparent 0 calc(var(--pas-quadrillage) - 1px),
      var(--quadrillage) var(--pas-quadrillage)
    ),
    repeating-linear-gradient(
      90deg,
      transparent 0 calc(var(--pas-quadrillage) - 1px),
      var(--quadrillage) var(--pas-quadrillage)
    );
  color: var(--encre);
  box-shadow: -0.8rem 0 2.2rem color-mix(in srgb, var(--ombre-papier) 72%, transparent);
  font-family: var(--police-main);
}

.progres-session-panneau[open] {
  animation: progres-session-panneau-entree 240ms cubic-bezier(0.22, 1, 0.36, 1);
}

.progres-session-panneau::backdrop {
  background: color-mix(in srgb, var(--bureau) 42%, transparent);
}

@keyframes progres-session-panneau-entree {
  from { opacity: 0.75; translate: 100% 0; }
  to { opacity: 1; translate: 0; }
}

.progres-session-panneau-contenu {
  height: 100%;
  padding: clamp(1.25rem, 3vw, 2.25rem);
  box-sizing: border-box;
  overflow-y: auto;
}

.progres-session-panneau-contenu > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.6rem;
}

.progres-session-panneau-contenu > header h2 {
  margin: 0;
  color: var(--lavande);
  font-size: clamp(1.65rem, 3vw, 2.15rem);
  font-weight: 600;
  rotate: -0.45deg;
}

.progres-session-panneau-fermer {
  display: grid;
  flex: 0 0 2.75rem;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0 0 0.15rem;
  place-items: center;
  border: 2px solid var(--encre-structurelle, var(--encre));
  border-radius: 48% 52% 44% 56% / 53% 45% 55% 47%;
  background: color-mix(in srgb, var(--papier) 86%, transparent);
  color: var(--encre-structurelle, var(--encre));
  font: inherit;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
  rotate: 2deg;
}

.progres-session-panneau-fermer:is(:hover, :focus-visible) {
  border-color: var(--lavande);
  color: var(--lavande);
}

.progres-session-panneau-fermer:focus-visible {
  outline: 2px solid var(--lavande);
  outline-offset: 3px;
}

.progres-session-panneau-attente {
  margin: 2rem 0;
  color: var(--texte-secondaire);
  text-align: center;
}

.progres-session-panneau .historique-detail {
  width: 100%;
  font-size: 1rem;
}

.progres-session-panneau .session-bilan-tete {
  margin-top: 0;
}

.session-filtre-actif {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem 0.7rem;
  margin: 0 0 1.35rem;
  color: var(--texte-secondaire);
}

.historique-detail-filtre .session-bilan-tete {
  margin-bottom: 0.9rem;
}

.session-filtre-actif span {
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.025em;
  text-transform: uppercase;
}

.session-filtre-actif strong {
  color: var(--lavande);
  font-size: 1.08rem;
  font-weight: 600;
}

@container (max-width: 720px) {
  .progres-suivi-tete,
  .progres-graphe-resume {
    align-items: flex-start;
    flex-direction: column;
  }
  .progres-selecteur-automatisme {
    width: 100%;
  }

  .progres-graphe-resume p {
    text-align: left;
  }

  .progres-graphe {
    min-height: 25rem;
  }
}

:root {
  color-scheme: light dark;
  --fond: light-dark(#eff1f5, #1e1e2e);
  --fond-secondaire: light-dark(#e6e9ef, #181825);
  --surface-0: light-dark(#ccd0da, #313244);
  --overlay-0: light-dark(#9ca0b0, #6c7086);
  --texte: light-dark(#4c4f69, #cdd6f4);
  --texte-secondaire: light-dark(#6c6f85, #a6adc8);
  --cyan: light-dark(#179299, #94e2d5);
  --lavande: light-dark(#7287fd, #b4befe);
  --rose: light-dark(#dd7878, #f5c2e7);
  --jaune: light-dark(#df8e1d, #f9e2af);
  --rouge: light-dark(#d20f39, #f38ba8);
  --vert: light-dark(#40a02b, #a6e3a1);
}

/* Conteneur de requête racine : la mise en page s'adapte à la largeur de la page
   (container queries). Cf. le bloc @container « page étroite » en bas. */
html {
  container-type: inline-size;
}

body {
  margin: 0;
  display: flex;
  height: 100dvh;
  overflow: hidden;
  background-color: var(--fond);
  color: var(--texte);
  font-family: "Shantell Sans", cursive;
  /* Taille courante de l'application. Les titres, questions et touches ont
     leurs propres font-size explicites plus bas et restent donc inchangés. */
  font-size: 1.05rem;
  line-height: 1.6;
  gap: 1em;
}

/* Une session ouverte devient l'unique écran accessible jusqu'à son terme. */
body.session-verrouillee {
  gap: 0;
}

body.session-verrouillee nav {
  display: none;
}

body.session-verrouillee main {
  /* Le clavier est fixe mais reste enfant de <main>. Safari peut rogner un
     descendant fixe au bord de l'ancêtre défilant, surtout lorsqu'un onglet
     secondaire reprend la main. Le cadre défilant couvre donc tout l'écran ;
     seule la fiche pédagogique conserve sa largeur de lecture ci-dessous. */
  max-width: none;
  margin-inline: 0;
  box-sizing: border-box;
}

body.session-verrouillee .exo.session {
  max-width: 64rem;
  margin-inline: auto;
}

.nav-points-serieux {
  position: relative;
  display: grid;
  width: 2.25rem;
  height: 2.25rem;
  border: 2px solid currentColor;
  border-radius: 48% 52% 46% 54% / 52% 47% 53% 48%;
  color: var(--vert-note);
  place-items: center;
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1;
  rotate: -2deg;
}

.nav-points-serieux::after {
  position: absolute;
  inset: 0.12rem -0.12rem -0.08rem 0.08rem;
  border: 1px solid currentColor;
  border-radius: 54% 46% 52% 48% / 47% 55% 45% 53%;
  content: "";
  opacity: 0.38;
  rotate: 4deg;
}

.nav-points-serieux[data-niveau="attention"] { color: var(--jaune); }
.nav-points-serieux[data-niveau="alerte"] { color: var(--rouge); }

a {
  text-decoration: none;
  color: inherit;
}

/* Sur Safari tactile, deux activations rapprochées d'un contrôle peuvent être
   interprétées comme un double-tap de zoom. Cette valeur conserve le pincement
   d'accessibilité et le défilement, mais donne la priorité à l'activation des
   boutons et des liens. Les surfaces de dessin qui ont besoin de `none` gardent
   leurs règles plus spécifiques. */
:where(button, a, [role="button"]) {
  touch-action: manipulation;
}

/* --- Contenu principal --------------------------------------------------- */

main {
  flex: 1;
  min-width: 0;
  padding: 1.25rem 2.5rem 2rem;
  overflow-y: auto;
}

main h1 {
  margin-top: 0;
}

/* --- Permis de sérieux -------------------------------------------------- */

.serieux-eleve {
  width: min(62rem, 100%);
  margin-inline: auto;
  padding-bottom: 3rem;
}

.serieux-eleve > h1 {
  margin: 0 0 2rem;
  color: var(--cyan);
  font-size: clamp(2rem, 4vw, 3.2rem);
  font-weight: 550;
  line-height: 1.08;
}

.serieux-retenue {
  padding: 0.85rem 1rem;
  border-left: 4px solid var(--rouge);
  background: color-mix(in srgb, var(--rouge) 11%, transparent);
  color: var(--rouge);
}

.serieux-historique.tableau-hote,
.serieux-historique > .tableau-donnees-croquis {
  width: 100%;
}

.tableau-serieux-eleve {
  min-width: 38rem;
  table-layout: fixed;
}

.tableau-serieux-eleve > :is(thead, tbody) > tr > :is(th, td):nth-child(1) { width: 25%; }
.tableau-serieux-eleve > :is(thead, tbody) > tr > :is(th, td):nth-child(2) { width: 45%; }
.tableau-serieux-eleve > :is(thead, tbody) > tr > :is(th, td):nth-child(3) { width: 15%; text-align: center; }
.tableau-serieux-eleve > :is(thead, tbody) > tr > :is(th, td):nth-child(4) { width: 15%; text-align: right; }

.tableau-serieux-eleve .gain { color: var(--vert-note); }
.tableau-serieux-eleve .perte { color: var(--rouge); }

/* --- Liste des leçons ---------------------------------------------------- */

.theme {
  margin: 2rem 0 0.75rem;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--texte-secondaire);
}

.grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}

.carte {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.1rem;
  border-radius: 1rem;
  background-color: var(--fond-secondaire);
  border: 1px solid var(--surface-0);
  transition:
    transform 0.18s ease,
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}

.carte:hover {
  transform: translateY(-3px);
  border-color: var(--lavande);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--lavande) 22%, transparent);
}

.anneau .piste {
  fill: none;
  stroke: var(--surface-0);
  stroke-width: 3;
}

.anneau .jauge {
  fill: none;
  stroke: var(--cyan);
  stroke-width: 3;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.4s ease;
}

.anneau .pourcent {
  fill: var(--texte-secondaire);
  font-size: 0.62rem;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: central;
}

.carte .titre {
  font-weight: 600;
  color: var(--texte);
}

/* --- Étoiles de difficulté ----------------------------------------------- */

.etoiles {
  display: inline-flex;
  gap: 2px;
}

.etoile {
  fill: none;
  stroke: var(--overlay-0);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

.etoile.pleine {
  fill: var(--jaune);
  stroke: var(--jaune);
}

/* --- Contenu individuel (leçon, exercice…) ------------------------------- */

.retour {
  display: inline-block;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  color: var(--texte-secondaire);
}

.retour:hover {
  color: var(--lavande);
}

.contenu h1 {
  margin-top: 0;
}

.contenu h2 {
  font-size: 1.1rem;
  color: var(--cyan);
}

.contenu {
  max-width: 60rem;
  margin-inline: auto;
}

/* --- Blocs de leçon (définition, exemple, règle…) ------------------------ */

.bloc {
  display: flow-root;
  margin: 1.5rem 0;
}

.bloc > h2 {
  margin: 0 0 0.6rem;
  font-size: 1.1rem;
}

/* Boîtes pleines : définition (lavande) et règle (rose). */
.bloc.definition,
.bloc.regle {
  padding: 1.1rem 1.4rem;
  border-radius: 1rem;
  background: var(--fond-secondaire);
}

.bloc.definition > h2 {
  color: var(--lavande);
}

.bloc.regle > h2 {
  color: var(--rose);
}

/* Bloc à liseré : exemple (cyan). */
.bloc.exemple {
  padding-left: 1.25rem;
  border-left: 3px solid var(--cyan);
}

.bloc.exemple > h2 {
  color: var(--cyan);
}

.bloc p {
  margin: 0.5rem 0;
}

/* Listes à flèches. Le même SVG irrégulier que celui de la navigation remplace
   la flèche typographique, trop géométrique à côté des tracés au crayon. */
:is(.fleches, .puces) {
  margin: 0.5rem 0;
  padding: 0;
  list-style: none;
}

:is(.fleches, .puces) > li {
  position: relative;
  margin: 0.4rem 0;
  padding-left: 2.45rem;
}

.puce-fleche-manuscrite {
  position: absolute;
  left: 0;
  top: 0.42em;
  width: 1.25em;
  height: 0.9em;
  color: var(--rose);
  stroke-width: 2.2;
}

.contenu :is(.fleches, .puces) > li.element-liste-vide {
  display: none;
}

/* --- Tableaux de leçon --------------------------------------------------- */

.contenu table {
  width: 100%;
  margin: 1rem 0;
  border-collapse: collapse;
}

.contenu th,
.contenu td {
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--surface-0);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.contenu th {
  background: var(--fond-secondaire);
  font-weight: 600;
}

.contenu th.vertical {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-weight: 500;
}

/* --- Équations (MathML natif) -------------------------------------------- */

.contenu math {
  font-size: 1.15rem;
}

.contenu math[display="block"] {
  margin: 0.75rem 0;
  font-size: 1.3rem;
}

.contenu .figure-geometrique {
  display: grid;
  width: min(100%, 48rem);
  margin: 1.25rem auto;
  place-items: center;

  & > svg {
    width: auto;
    max-width: 100%;
    height: auto;
    max-height: min(48vh, 19rem);
    overflow: visible;
  }

  & > figcaption {
    margin-top: 0.55rem;
    color: var(--texte-secondaire);
    font-size: 0.9em;
    text-align: center;
  }
}

.contenu .figure-geometrique > svg.figure-geometrique-cadree {
  overflow: hidden;
}

.contenu .figure-geometrique:is(.figure-gauche, .figure-droite) {
  width: min(42%, 18rem);
  margin-block: 0.3rem 0.85rem;
}

.contenu .figure-geometrique.figure-gauche {
  float: inline-start;
  margin-inline: 0 1.2rem;
}

.contenu .figure-geometrique.figure-droite {
  float: inline-end;
  margin-inline: 1.2rem 0;
}

@media (max-width: 640px) {
  .contenu .figure-geometrique:is(.figure-gauche, .figure-droite) {
    float: none;
    width: min(100%, 18rem);
    margin: 1rem auto;
  }
}

/* Lien d'entraînement depuis une leçon vers un automatisme. */
.lien-entrainement {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  isolation: isolate;
  margin-top: 0.5rem;
  padding: 0.18rem 0.35rem;
  color: color-mix(in srgb, var(--turquoise-entrainement) 72%, var(--encre));
  font-weight: 500;
  transition: color 160ms ease, translate 160ms ease;
}

.lien-entrainement::before {
  position: absolute;
  z-index: -1;
  top: -0.02em;
  right: -0.4rem;
  bottom: -0.02em;
  left: -0.3rem;
  background: color-mix(in srgb, var(--turquoise-entrainement) 28%, transparent);
  clip-path: polygon(
    0 10%, 9% 3%, 24% 8%, 42% 1%, 60% 7%,
    79% 2%, 100% 9%, 98% 91%, 78% 97%, 57% 91%,
    37% 99%, 17% 93%, 1% 98%
  );
  content: "";
  rotate: -0.7deg;
  transition: background-color 160ms ease, scale 160ms ease;
}

.lien-entrainement:hover {
  color: var(--turquoise-entrainement);
  translate: 0 -0.08rem;
}

.lien-entrainement:hover::before {
  background: color-mix(in srgb, var(--turquoise-entrainement) 40%, transparent);
  scale: 1.02 1;
}

.lien-entrainement:focus-visible {
  border-radius: 0.25rem;
  outline: 1.5px solid currentColor;
  outline-offset: 0.3rem;
}

.lien-entrainement .lien-entrainement-fleche {
  width: 1.75rem;
  height: 1.2rem;
  color: currentColor;
  stroke-width: 1.8;
  transition: translate 160ms ease;
}

.lien-entrainement:hover .lien-entrainement-fleche {
  translate: 0.18rem 0;
}

.consigne {
  margin: 0 0 0.5rem;
  font-weight: 600;
}

/* Items repérés par lettres : a) b) c)… sur une grille compacte. */
.lettres {
  list-style: none;
  counter-reset: item;
  display: grid;
  grid-template-columns: var(--cols-lettres, repeat(auto-fill, minmax(5rem, 1fr)));
  gap: 0.3rem 0.9rem;
  margin: 0.4rem 0 0;
  padding: 0;
}

/* Forcer un nombre de colonnes fixe quand l'auto-fill ne convient pas. */
.lettres.colonnes-1 {
  --cols-lettres: 1fr;
}

.lettres.colonnes-2 {
  --cols-lettres: repeat(2, 1fr);
}

.lettres.colonnes-3 {
  --cols-lettres: repeat(3, 1fr);
}

.lettres li {
  counter-increment: item;
}

.lettres li::before {
  content: counter(item, lower-alpha) ") ";
  color: var(--texte-secondaire);
  font-weight: 600;
}

.lettres.fractions {
  grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
  align-items: center;
}

/* Sous-questions numérotées. */
.questions {
  margin: 0.4rem 0 0;
  padding-left: 1.3rem;
}

.questions li {
  margin: 0.3rem 0;
}

/* Carte de session : grande, statut coloré{
  display: flex;
  align-items: center;
  gap: 0.9rem;
  color: inherit;
  text-decoration: none;
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}
/* Ouverte : nettement colorée (bleu) + halo{
  background: color-mix(in srgb, var(--lavande) 32%, var(--fond));
  border-color: var(--lavande);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--lavande) 25%, transparent);
}

/* Rangée de cartes (progression + dernier quizz){
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

/* « Mes sessions » : en-tête avec lien « voir tout »{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}
/* Dans le tableau de bord{
  margin: 0;
  padding: 0.55rem 0;
  border: none;
  border-bottom: 1px solid color-mix(in srgb, var(--surface-0) 70%, transparent);
  border-radius: 0;
  background: none;
}

/* --- Exercice interactif -------------------------------------------------- */

.exo .enonce {
  margin: 1.5rem 0;
  font-size: 2rem;
  font-weight: 600;
}

/* Le calcul et la zone de réponse sont centrés dans la zone de contenu, dans les
   deux latéralités : ça les écarte du clavier collé à un bord et donne le même
   rendu pour un droitier comme pour un gaucher. L'en-tête (flèche de retour,
   titre/type de l'automatisme) garde, lui, son alignement à gauche. */
.exo .enonce,
.exo .aide,
.exo .verdict {
  text-align: center;
}

.zone-reponse {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
}

.reponse {
  width: 8rem;
  padding: 0.6rem 0.9rem;
  font-size: 1.2rem;
  border-radius: 0.6rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
}

.reponse:focus {
  outline: 2px solid var(--lavande);
  outline-offset: 1px;
  border-color: transparent;
}

.valider {
  padding: 0.75rem 1.5rem;
  border: none;
  border-radius: 0.7rem;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
  color: var(--fond);
  background: var(--lavande);
}

.enonce sup {
  font-size: 0.6em;
}

/* Tableau de proportionnalité (automatisme « proportionnalite »), rendu dans
   l'énoncé. La consigne est discrète au-dessus ; le tableau est centré. */
.exo .enonce .consigne {
  display: block;
  margin-bottom: 0.75rem;
  font-size: 1rem;
  font-weight: 500;
  color: var(--texte-secondaire);
}

.tabprop {
  border-collapse: collapse;
  margin-inline: auto;
  font-variant-numeric: tabular-nums;
}

.tabprop td {
  border: 1px solid var(--surface-0);
  min-width: 3.4rem;
  padding: 0.55rem 0.9rem;
  text-align: center;
}

.tabprop .trou {
  color: var(--lavande);
  background: color-mix(in srgb, var(--lavande) 14%, transparent);
}

/* Tableau de valeurs (automatisme « fonctions ») : même esprit que .tabprop, avec
   une première colonne d'étiquettes (x / f(x)) distinguée des valeurs. */
.tabfonction {
  border-collapse: collapse;
  margin-inline: auto;
  font-variant-numeric: tabular-nums;
}

.tabfonction th,
.tabfonction td {
  border: 1px solid var(--surface-0);
  min-width: 3rem;
  padding: 0.55rem 0.9rem;
  text-align: center;
}

.tabfonction th {
  color: var(--texte-secondaire);
  font-weight: 600;
  background: color-mix(in srgb, var(--lavande) 10%, transparent);
}

.aide {
  margin-top: 0.5rem;
  font-size: 0.85rem;
  color: var(--texte-secondaire);
}

.verdict {
  min-height: 1.6rem;
  margin-top: 0.5rem;
  font-weight: 600;
}

.verdict.juste {
  color: var(--cyan);
}

.verdict.faux {
  color: var(--rouge);
}

/* --- Mode visuel (élèves en difficulté) ---------------------------------- */

/* L'en-tête ne place plus l'interrupteur dans le flux du titre : celui-ci est
   ancré au coin supérieur droit de la page de l'automatisme, plus bas. */
.exo-tete {
  display: block;
}

.exo-tete:has(> .bascule-visuel) h1 {
  padding-inline-end: 11rem;
}

.exo-tete > .bascule-visuel {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 0;
}

.bascule-visuel {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1rem;
  color: var(--texte-secondaire);
  cursor: pointer;
}

.bascule-visuel input {
  width: 1.2rem;
  height: 1.2rem;
  accent-color: var(--lavande);
  cursor: pointer;
}

.visuel {
  margin: 1rem 0;
}

/* Le mode visuel complète l'énoncé au lieu de prendre sa place. Son propre
   conteneur se déroule comme une feuille que l'on ajoute sous le calcul. */
.aide-visuelle {
  display: grid;
  grid-template-rows: 1fr;
  width: min(46rem, 100%);
  margin: 0.9rem auto 0;
  opacity: 1;
  transform-origin: top center;
}

/* Le tableau de numération a dix colonnes et deux commandes latérales. Il a
   besoin d'un peu plus d'espace que les autres aides, tout en restant borné par
   la largeur réellement disponible entre la navigation et le clavier. */
.aide-visuelle:has(.glisse-nombre) {
  width: min(58rem, 100%);
}

.aide-visuelle:has(.addition-decimaux-visuel) {
  width: min(42rem, 100%);
}

.aide-visuelle:has(.tri-statistique) {
  width: min(50rem, 100%);
}

.aide-visuelle > .visuel {
  min-height: 0;
  overflow: hidden;
}

.aide-visuelle.apparition-visuelle {
  animation: deployer-aide-visuelle 420ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.aide-visuelle.disparition-visuelle {
  animation: ranger-aide-visuelle 360ms ease-in both;
  pointer-events: none;
}

@keyframes deployer-aide-visuelle {
  from {
    grid-template-rows: 0fr;
    opacity: 0;
    translate: 0 -0.45rem;
  }
}

@keyframes ranger-aide-visuelle {
  to {
    grid-template-rows: 0fr;
    margin-top: 0;
    opacity: 0;
    translate: 0 -0.35rem;
  }
}

/* Figure d'un automatisme géométrique (ex. « Calculer une aire ») : SVG centré,
   redimensionné pour tenir sur petit écran sans déformer (viewBox conservé). */
.aire-figure,
.perimetre-figure,
.cercle-mesure-figure,
.angle-triangle-figure,
.aire-litterale-figure,
.perimetre-litteral-figure,
.longueur-litterale-figure {
  display: flex;
  justify-content: center;
}

.aire-figure svg,
.perimetre-figure svg,
.cercle-mesure-figure svg,
.angle-triangle-figure svg,
.aire-litterale-figure svg,
.perimetre-litteral-figure svg {
  width: auto;
  max-width: min(280px, 72vw);
  height: auto;
}

/* L'aide sur les aires vit dans le SVG de la question : la bascule ne crée
   qu'un marqueur invisible, afin que le quadrillage apparaisse dans la figure
   existante sans en ajouter une seconde sous l'énoncé. */
.aire-quadrillage,
.aire-rectangle-aide {
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms ease-out;
}

.aire-quadrillage .aire-aide-trait-main-levee {
  fill: none;
  stroke: color-mix(in srgb, var(--texte-secondaire) 58%, transparent);
  stroke-width: 1.15;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.aire-rectangle-aide .aire-aide-trait-main-levee {
  fill: none;
  stroke: var(--texte-secondaire);
  stroke-width: 1.7;
  stroke-dasharray: 6 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.enonce:has(
  .aide-visuelle:not(.disparition-visuelle) .aire-aide-visuelle
) :is(.aire-quadrillage, .aire-rectangle-aide) {
  opacity: 1;
}

/* Le texte décrit l'aide aux lecteurs d'écran ; son conteneur ne réserve pas
   de hauteur dans la page et ne déplace donc ni la consigne ni la réponse. */
.aide-visuelle:has(.aire-aide-visuelle) {
  display: contents;
}

.cercle-mesure-visuel {
  margin-block: -0.25rem 0.15rem;
}

.longueur-litterale-figure svg {
  width: auto;
  max-width: min(650px, 92vw);
  height: auto;
}

.longueur-litterale-accolade {
  vector-effect: non-scaling-stroke;
}

/* Repère d'un automatisme (ex. « Lire des coordonnées ») : un peu plus grand
   pour que les graduations chiffrées restent lisibles. */
.repere-figure {
  display: flex;
  justify-content: center;
}

.repere-figure svg {
  width: calc(var(--pas-quadrillage) * 10);
  height: calc(var(--pas-quadrillage) * 10);
  max-width: none;
  max-height: none;
}

.lecture-graphique-figure {
  display: flex;
  justify-content: center;
  margin-block: 0.25rem 0.5rem;
}

.lecture-graphique-figure svg {
  width: calc(var(--pas-quadrillage) * 11);
  height: auto;
  max-width: none;
  max-height: none;
  overflow: visible;
}

.lecture-graphique-etiquettes {
  fill: var(--texte-secondaire);
  font-family: var(--police-maths);
  font-size: 14px;
}

.lecture-graphique-trace :is(.droite-fonction, .courbe-fonction, .parabole-fonction) {
  fill: none;
  stroke: var(--cyan);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.lecture-graphique-reprise {
  fill: none;
  stroke: color-mix(in srgb, var(--cyan) 35%, transparent);
  stroke-width: 1.4;
  translate: 0.7px -0.45px;
}

.lecture-graphique-point {
  fill: var(--papier-note);
  stroke: var(--cyan);
  stroke-width: 2.4;
}

.pythagore-visuel {
  display: flex;
  justify-content: center;
  margin-block: 0.1rem 0.35rem;
}

.pythagore-visuel svg {
  width: auto;
  max-width: min(430px, 88vw);
  height: min(320px, 45vh);
  overflow: visible;
}

.pythagore-etiquette {
  fill: var(--texte);
  font-family: var(--police-maths);
  font-size: 18px;
}

.pythagore-etiquette.sommet {
  font-size: 20px;
  font-style: italic;
}

.agrandissement-reduction-visuel {
  display: flex;
  justify-content: center;
  margin-block: 0.1rem 0.35rem;
}

.agrandissement-reduction-figure {
  width: auto;
  max-width: min(820px, 94vw);
  height: min(310px, 43vh);
  overflow: visible;
}

.agrandissement-reduction-figure :is(
  .agrandissement-legende,
  .agrandissement-etiquette-mesure,
  .agrandissement-coefficient
) {
  fill: var(--texte);
  font-family: var(--police-maths);
}

.agrandissement-legende {
  fill: var(--texte-secondaire);
  font-size: 18px;
}

.agrandissement-etiquette-mesure,
.agrandissement-coefficient {
  font-size: 18px;
}

.agrandissement-reduction-figure .inconnue {
  fill: var(--lavande);
  font-size: 23px;
  font-weight: 700;
}

.probabilite-visuel {
  display: flex;
  justify-content: center;
  margin-block: 0.1rem 0.35rem;
}

.probabilite-figure {
  width: auto;
  max-width: min(620px, 92vw);
  height: min(300px, 42vh);
  overflow: visible;
}

.probabilite-numero-boule,
.probabilite-numero-secteur {
  fill: var(--texte);
  font-family: var(--police-maths);
  font-size: 22px;
  font-weight: 700;
  paint-order: stroke;
  stroke: color-mix(in srgb, var(--fond) 72%, transparent);
  stroke-width: 3px;
  stroke-linejoin: round;
}

.probabilite-numero-boule {
  font-size: 24px;
}

.probabilite-secteur {
  stroke: none;
}

.probabilite-coloriage {
  stroke: none;
}

.probabilite-coloriage-large {
  fill-opacity: 0.28;
}

.probabilite-coloriage-reprise {
  fill-opacity: 0.11;
}

.probabilite-pointeur-fond {
  fill: var(--fond);
  stroke: none;
}

/* Fréquences : tableaux et graphiques permanents de l'énoncé. Les SVG restent
   volontairement sobres afin que les effectifs dominent les aplats colorés. */
.frequence-visuel {
  display: flex;
  justify-content: center;
  margin-block: 0.1rem 0.4rem;
}

.frequence-figure {
  width: auto;
  max-width: min(660px, 94vw);
  height: min(330px, 43vh);
  overflow: visible;
}

/* Sur téléphone, une hauteur fixe rendait les SVG panoramiques presque carrés :
   preserveAspectRatio ajoutait alors une grande bande vide au-dessus et en
   dessous du graphique. La largeur pilote désormais leur hauteur naturelle. */
@media (max-width: 700px) {
  .agrandissement-reduction-figure,
  .probabilite-figure,
  .frequence-figure {
    width: 100%;
    height: auto;
  }

  /* Les deux formes se partagent un schéma très panoramique. Une légère mise à
     l'échelle exploite mieux chaque moitié sur téléphone sans rapprocher leurs
     mesures de la flèche centrale. */
  .agrandissement-reduction-figure .agrandissement-forme {
    transform: scale(1.12);
    transform-box: fill-box;
    transform-origin: center;
  }

  .agrandissement-reduction-figure :is(
    .agrandissement-legende,
    .agrandissement-etiquette-mesure,
    .agrandissement-coefficient
  ) {
    font-size: 28px;
  }

  .agrandissement-reduction-figure .inconnue {
    font-size: 34px;
  }
}

.frequence-figure text {
  fill: var(--texte);
  font-family: var(--police-maths);
}

.frequence-titre {
  font-size: 24px;
  font-weight: 700;
}

.frequence-valeur {
  font-size: 21px;
  font-weight: 700;
  paint-order: stroke;
  stroke: color-mix(in srgb, var(--fond) 74%, transparent);
  stroke-linejoin: round;
  stroke-width: 3px;
}

.frequence-legende-item text,
.frequence-categorie,
.frequence-axe-etiquette {
  font-size: 17px;
}

.frequence-coloriage,
.frequence-legende-trait {
  stroke-linecap: round;
  stroke-linejoin: round;
}

.frequence-coloriage {
  stroke: none;
}

.frequence-coloriage-large {
  fill-opacity: 0.28;
}

.frequence-coloriage-reprise {
  fill-opacity: 0.11;
}

.frequence-legende-trait {
  stroke-opacity: 0.42;
  vector-effect: non-scaling-stroke;
}

.frequence-grille {
  opacity: 0.5;
}

.frequence-tableau-visuel {
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  width: min(100%, 48rem);
  margin-inline: auto;
}

.frequence-contexte {
  max-width: 44rem;
  margin: 0;
  text-align: center;
}

.frequence-tableau {
  table-layout: fixed;
}

.frequence-tableau th {
  font-weight: 700 !important;
}

/* Horloge analogique : contour, graduations et aiguilles emploient les mêmes
   chemins irréguliers que les graphiques de fréquences. Le cadran reste carré
   et relativement bas, car la hauteur est l'axe rare sur une tablette paysage. */
.horloge-visuel {
  display: flex;
  justify-content: center;
  margin-block: 0.15rem 0.35rem;
}

.horloge-figure {
  width: auto;
  max-width: min(21rem, 82vw);
  height: clamp(14rem, 42vh, 21rem);
  overflow: visible;
}

.horloge-nombre {
  fill: var(--texte);
  font-family: var(--police-maths);
  font-size: 21px;
  font-weight: 600;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

.horloge-graduation {
  opacity: 0.42;
}

.horloge-graduation-heure {
  opacity: 0.82;
}

.horloge-aiguille,
.horloge-pivot {
  pointer-events: none;
}

.horloge-visuel-interactif,
.horloge-visuel-interactif .horloge-figure {
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.horloge-controle-aiguille {
  cursor: grab;
}

.horloge-controle-aiguille:focus {
  outline: none;
}

.horloge-controle-aiguille:active {
  cursor: grabbing;
}

.horloge-controle-heures {
  color: var(--lavande);
}

.horloge-controle-minutes {
  color: var(--rose);
}

.horloge-aiguille-cible {
  fill: none;
  stroke: transparent;
  stroke-width: 30;
  stroke-linecap: round;
  pointer-events: stroke;
}

.horloge-poignee {
  fill: color-mix(in srgb, currentColor 20%, var(--fond));
  stroke: currentColor;
  stroke-width: 2.2;
  opacity: 0.72;
  pointer-events: none;
}

.horloge-controle-aiguille:focus-visible .horloge-poignee {
  fill: color-mix(in srgb, currentColor 38%, var(--fond));
  stroke-width: 3.6;
  opacity: 1;
}

/* Une réponse manipulée dans la figure libère l'espace du clavier et remplace
   le cadre texte par le bouton de validation déjà utilisé par le moteur. */
.exo.reponse-interactive,
body.gaucher .exo.reponse-interactive {
  --espace-clavier: 0rem;
  padding-right: 0;
  padding-left: 0;
}

/* La classe clavier-visible reste présente sur tablette même quand l'horloge
   masque le clavier. Sa réserve ne doit décaler ni le score ni la validation. */
.exo.reponse-interactive.clavier-visible,
.exo.reponse-interactive.clavier-visible:has(.clavier[data-cols="4"]) {
  --espace-clavier: 0rem;
  padding-bottom: 0;
}

.exo.reponse-interactive :is(
  .cadre-reponse,
  .apercu-reponse,
  .clavier,
  .clavier-bascule
) {
  display: none;
}

.exo.reponse-interactive .zone-reponse {
  display: flex;
  justify-content: center;
}

.exo.reponse-interactive .valider {
  display: inline-flex;
}

/* Algorithmique : les blocs gardent les volumes, connecteurs et boucles en C
   de Scratch, recolorés avec la palette Catppuccin du cahier. Les blocs restent
   du vrai texte HTML : nets, légers et lisibles avec le zoom du navigateur. */
.algorithmique-visuel {
  --scratch-evenement: var(--jaune);
  --scratch-controle: var(--orange-note);
  --scratch-mouvement: var(--bleu-note);
  --scratch-apparence: var(--lavande);
  --scratch-variable: var(--rose);
  --scratch-stylo: var(--cyan);
  --scratch-capteur: color-mix(in srgb, var(--cyan) 68%, var(--bleu-note));
  --scratch-operateur: var(--vert-note);
  --scratch-texte: var(--papier-note);

  width: min(56rem, 100%);
  margin: 0.35rem auto 0.75rem;
  color: var(--encre);
  font-family: var(--police-main);
  font-size: 1rem;
}

/* Shantell Sans a une espace naturellement très fine à ce corps. Chaque mot
   devient donc une unité de mise en page : l'écart reste visible et la phrase
   peut toujours se replier proprement sur smartphone. */
.algorithmique-consigne-visible {
  display: flex;
  max-width: 100%;
  flex-wrap: wrap;
  justify-content: center;
  column-gap: 0.28em;
}

.algorithmique-calcul {
  display: grid;
  width: min(30rem, 100%);
  justify-items: center;
}

.algorithmique-visuel-interactif {
  display: grid;
  grid-template-columns: minmax(14rem, 21rem) minmax(18rem, 1fr);
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 3vw, 2.4rem);
}

.scratch-programme {
  display: grid;
  width: 100%;
  min-width: 0;
  justify-items: center;
}

.scratch-pile {
  width: fit-content;
  max-width: 100%;
  padding: 0.55rem 0.45rem 0.65rem;
  filter: drop-shadow(0.11rem 0.14rem 0 color-mix(in srgb, var(--encre) 16%, transparent));
  line-height: 1.12;
  text-align: left;
}

.scratch-bloc,
.scratch-boucle-tete,
.scratch-boucle-fin {
  --scratch-couleur: var(--scratch-mouvement);

  position: relative;
  z-index: 1;
  box-sizing: border-box;
  width: fit-content;
  max-width: 100%;
  min-height: 2.05rem;
  padding: 0.4rem 0.72rem 0.44rem;
  isolation: isolate;
  border: 0;
  border-radius: 0.48rem 0.34rem 0.5rem 0.37rem;
  background: transparent;
  box-shadow: none;
  color: var(--scratch-texte);
  font-size: clamp(0.86rem, 1.4vw, 1rem);
  font-weight: 650;
  white-space: nowrap;
}

.scratch-bloc-contenu {
  position: relative;
  z-index: 2;
}

/* Chaque bloc est une petite forme SVG irrégulière : une première ligne
   construit le contour et une reprise plus claire lui donne le même geste de
   crayon que les figures géométriques. */
.scratch-bloc-trace {
  position: absolute;
  z-index: 0;
  inset: -0.07rem -0.13rem;
  display: block;
  width: calc(100% + 0.26rem);
  max-width: none;
  height: calc(100% + 0.14rem);
  overflow: visible;
  pointer-events: none;
}

.scratch-bloc-surface {
  fill: var(--scratch-couleur);
  stroke: none;
}

.scratch-bloc-contour,
.scratch-bloc-reprise {
  fill: none;
  stroke: color-mix(in srgb, var(--scratch-couleur) 63%, var(--encre));
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.scratch-bloc-contour { stroke-width: 1.8; }

.scratch-bloc-reprise {
  opacity: 0.42;
  stroke: color-mix(in srgb, var(--papier-note) 38%, var(--scratch-couleur));
  stroke-width: 1.15;
}

.scratch-bloc + .scratch-bloc,
.scratch-bloc + .scratch-boucle,
.scratch-boucle + .scratch-bloc,
.scratch-boucle + .scratch-boucle,
.scratch-boucle-corps > .scratch-bloc + .scratch-bloc {
  margin-top: -0.08rem;
}

/* Petit tenon sous chaque commande, repris par l'encoche du bloc suivant. */
.scratch-bloc:not(:last-child)::after,
.scratch-boucle-tete::after,
.scratch-boucle-fin::after {
  position: absolute;
  z-index: 3;
  bottom: -0.27rem;
  left: 1.18rem;
  width: 1.28rem;
  height: 0.34rem;
  border: 0;
  border-radius: 0 0 0.35rem 0.25rem;
  background: var(--scratch-couleur);
  box-shadow:
    -1px 0 color-mix(in srgb, var(--scratch-couleur) 63%, var(--encre)),
    1px 1px color-mix(in srgb, var(--scratch-couleur) 63%, var(--encre));
  clip-path: polygon(2% 0, 98% 5%, 92% 88%, 72% 100%, 8% 90%);
  content: "";
  rotate: -0.7deg;
}

.scratch-bloc-evenement {
  --scratch-couleur: var(--scratch-evenement);
}

.scratch-bloc-controle,
.scratch-boucle-tete,
.scratch-boucle-fin {
  --scratch-couleur: var(--scratch-controle);
}

.scratch-bloc-mouvement { --scratch-couleur: var(--scratch-mouvement); }
.scratch-bloc-apparence { --scratch-couleur: var(--scratch-apparence); }
.scratch-bloc-variable { --scratch-couleur: var(--scratch-variable); }
.scratch-bloc-stylo { --scratch-couleur: var(--scratch-stylo); }
.scratch-bloc-capteur { --scratch-couleur: var(--scratch-capteur); }

.scratch-bloc-chapeau {
  min-height: 2.2rem;
  padding-top: 0.53rem;
  border-radius: 2rem 0.4rem 0.48rem 0.38rem / 1.05rem 0.4rem 0.5rem 0.36rem;
}

.scratch-drapeau {
  display: inline-block;
  width: 1.35rem;
  height: 1.35rem;
  margin: -0.18rem 0.18rem -0.22rem -0.08rem;
  overflow: visible;
  vertical-align: middle;
}

.scratch-drapeau-mat {
  fill: none;
  stroke: color-mix(in srgb, var(--scratch-texte) 72%, var(--encre));
  stroke-linecap: round;
  stroke-width: 1.8;
}

.scratch-drapeau-toile {
  fill: var(--vert-note);
  stroke: color-mix(in srgb, var(--vert-note) 65%, var(--encre));
  stroke-linejoin: round;
  stroke-width: 1.25;
}

.scratch-fleche-tourner {
  display: inline-grid;
  width: 1.85em;
  height: 1.42em;
  margin: -0.2em 0.04em -0.31em;
  color: var(--scratch-texte);
  vertical-align: middle;
}

.scratch-fleche-tourner svg {
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  overflow: visible;
}

.scratch-fleche-tourner-gauche svg {
  scale: -1 1;
}

.scratch-fleche-tourner :is(
  .scratch-fleche-tourner-trait,
  .scratch-fleche-tourner-reprise
) {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.scratch-fleche-tourner-trait { stroke-width: 2.3; }

.scratch-fleche-tourner-reprise {
  opacity: 0.42;
  stroke: color-mix(in srgb, var(--papier-note) 62%, var(--scratch-texte));
  stroke-width: 1.05;
}

.scratch-entree {
  display: inline-flex;
  min-width: 1.55em;
  min-height: 1.34em;
  padding: 0.04em 0.43em;
  box-sizing: border-box;
  align-items: center;
  justify-content: center;
  border: 1px solid color-mix(in srgb, var(--encre) 40%, transparent);
  border-radius: 999px;
  background: var(--papier-note);
  box-shadow: inset 0 0.08em 0 color-mix(in srgb, var(--encre) 12%, transparent);
  color: var(--encre);
  font-family: var(--police-maths);
  font-weight: 500;
  line-height: 1.05;
  vertical-align: 0.02em;
}

.scratch-entree-variable {
  border-color: color-mix(in srgb, var(--orange-note) 76%, var(--encre));
  background: var(--orange-note);
  color: var(--scratch-texte);
  font-family: var(--police-main);
  font-size: 0.9em;
  font-weight: 650;
}

.scratch-entree-capteur {
  border-color: color-mix(in srgb, var(--scratch-capteur) 68%, var(--encre));
  background: var(--scratch-capteur);
  color: var(--scratch-texte);
  font-family: var(--police-main);
  font-size: 0.9em;
  font-weight: 650;
}

.scratch-expression {
  gap: 0.2em;
  border-color: color-mix(in srgb, var(--scratch-operateur) 70%, var(--encre));
  background: var(--scratch-operateur);
  color: var(--scratch-texte);
}

.scratch-expression > .scratch-entree {
  font-size: 0.9em;
}

/* Une boucle n'est pas un rectangle plein : tête et pied sont reliés par une
   branche orange, tandis que les instructions s'emboîtent dans son ouverture. */
.scratch-boucle {
  position: relative;
  z-index: 2;
  width: fit-content;
  max-width: 100%;
  color: var(--scratch-texte);
}

.scratch-boucle::before {
  position: absolute;
  top: 1.7rem;
  bottom: 0.38rem;
  left: 0;
  width: 1.25rem;
  border: 0;
  background: var(--scratch-controle);
  box-shadow:
    inset 1.2px 0 color-mix(in srgb, var(--papier-note) 24%, transparent),
    -1.2px 0 color-mix(in srgb, var(--scratch-controle) 64%, var(--encre));
  clip-path: polygon(2% 0, 93% 2%, 100% 24%, 91% 51%, 98% 76%, 88% 100%, 4% 96%);
  content: "";
}

.scratch-boucle-tete {
  width: 100%;
  min-width: 10.5rem;
  border-bottom-left-radius: 0.12rem;
}

.scratch-boucle-corps {
  position: relative;
  z-index: 2;
  min-height: 2rem;
  margin-left: 1.15rem;
  padding-block: 0.14rem 0.08rem;
}

.scratch-boucle-fin {
  width: 100%;
  min-width: 7rem;
  min-height: 1.1rem;
  padding: 0;
  border-top-left-radius: 0.12rem;
}

.algorithmique-reponses {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.algorithmique-reponses-figures {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.45rem, 1.4vw, 0.9rem);
  width: min(31rem, 100%);
}

.algorithmique-choix {
  position: relative;
  min-width: 0;
  min-height: 7.6rem;
  padding: 0.22rem;
  border: 0;
  border-radius: 0.72rem 0.5rem 0.8rem 0.56rem / 0.55rem 0.78rem 0.5rem 0.72rem;
  background: transparent;
  color: var(--encre-legere);
  cursor: pointer;
  touch-action: manipulation;
  transition: color 140ms ease, background-color 140ms ease, translate 140ms ease;
}

.algorithmique-choix::before {
  position: absolute;
  inset: 0.15rem 0.1rem 0.08rem 0.18rem;
  border: 1.8px dashed currentColor;
  border-radius: inherit;
  content: "";
  opacity: 0.68;
  pointer-events: none;
  rotate: -0.45deg;
}

.algorithmique-choix:nth-of-type(even)::before {
  rotate: 0.6deg;
}

.algorithmique-choix:is(:hover, :focus-visible) {
  background: color-mix(in srgb, var(--lavande) 8%, transparent);
  color: var(--lavande);
  outline: none;
  translate: 0 -0.12rem;
}

.algorithmique-choix[aria-pressed="true"] {
  background: color-mix(in srgb, var(--cyan) 13%, transparent);
  color: var(--cyan);
}

.algorithmique-choix[aria-pressed="true"]::before {
  border-style: solid;
  border-width: 2.4px;
  opacity: 1;
}

.algorithmique-choix-figure svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 9rem;
  pointer-events: none;
}

.exo.reponse-juste .algorithmique-choix[aria-pressed="true"],
.exo.reponse-juste .algorithmique-case[aria-pressed="true"] {
  background: color-mix(in srgb, var(--cyan) 18%, transparent);
  color: var(--cyan);
}

.exo.reponse-fausse .algorithmique-choix[aria-pressed="true"],
.exo.reponse-fausse .algorithmique-case[aria-pressed="true"] {
  background: color-mix(in srgb, var(--rouge) 15%, transparent);
  color: var(--rouge);
}

.algorithmique-grille {
  position: relative;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(6, minmax(0, 1fr));
  width: min(19rem, calc(100vw - 3rem));
  aspect-ratio: 1;
  overflow: visible;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  rotate: -0.18deg;
}

.algorithmique-grille-trace {
  position: absolute;
  z-index: 3;
  inset: 0;
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.algorithmique-grille-lignes,
.algorithmique-grille-reprise {
  fill: none;
  stroke: color-mix(in srgb, var(--encre-legere) 78%, transparent);
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.algorithmique-grille-lignes { stroke-width: 1.75; }

.algorithmique-grille-reprise {
  opacity: 0.3;
  stroke: var(--bleu-note);
  stroke-width: 0.8;
}

.algorithmique-case {
  position: relative;
  z-index: 1;
  display: grid;
  min-width: 0;
  min-height: 0;
  padding: 0;
  place-items: center;
  border: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--encre);
  cursor: pointer;
  touch-action: manipulation;
}

.algorithmique-case:is(:hover, :focus-visible) {
  z-index: 2;
  background: color-mix(in srgb, var(--lavande) 13%, transparent);
  outline: 2.5px solid var(--lavande);
  outline-offset: -3px;
}

.algorithmique-case[aria-pressed="true"] {
  z-index: 1;
  background: color-mix(in srgb, var(--cyan) 17%, transparent);
  outline: 2.5px solid var(--cyan);
  outline-offset: -3px;
}

.algorithmique-case-depart {
  background: color-mix(in srgb, var(--jaune) 10%, transparent);
}

.algorithmique-robot {
  display: block;
  width: 78%;
  max-width: none;
  height: auto;
  aspect-ratio: 1;
  overflow: visible;
  rotate: var(--rotation-robot);
  filter: drop-shadow(0.08rem 0.1rem 0 color-mix(in srgb, var(--encre) 18%, transparent));
  pointer-events: none;
}

.algorithmique-robot-direction {
  fill: var(--rose);
  stroke: color-mix(in srgb, var(--rose) 70%, var(--encre));
  stroke-width: 1.2;
}

.algorithmique-robot-antenne,
.algorithmique-robot-bouche {
  fill: none;
  stroke: var(--encre);
  stroke-linecap: round;
  stroke-width: 1.7;
}

.algorithmique-robot-corps {
  fill: color-mix(in srgb, var(--cyan) 28%, var(--papier-note));
  stroke: var(--cyan);
  stroke-width: 1.8;
}

.algorithmique-robot-oeil { fill: var(--encre); }

.exo .valider:disabled {
  opacity: 0.38;
  cursor: default;
  translate: none;
}

.historique-detail .r-question .algorithmique-visuel {
  width: min(44rem, 100%);
  font-size: 0.82rem;
}

.historique-detail .r-question .algorithmique-visuel-interactif {
  grid-template-columns: minmax(11rem, 16rem) minmax(15rem, 1fr);
  gap: 0.8rem;
}

.historique-detail .r-question :is(.algorithmique-choix, .algorithmique-case) {
  pointer-events: none;
}

@media (max-width: 700px) {
  .algorithmique-visuel-interactif {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 0.8rem;
  }

  .algorithmique-visuel {
    font-size: 0.88rem;
  }

  .scratch-programme {
    width: min(23rem, 100%);
  }

  .scratch-pile {
    padding-block: 0.2rem 0.35rem;
  }

  .scratch-bloc,
  .scratch-boucle-tete,
  .scratch-boucle-fin {
    font-size: 0.82rem;
  }

  .algorithmique-reponses-figures {
    width: min(27rem, 100%);
  }

  .algorithmique-choix {
    min-height: 5.8rem;
  }

  .algorithmique-grille {
    width: min(17.25rem, calc(100vw - 2rem));
  }
}

@media (max-height: 560px) and (min-width: 701px) {
  .algorithmique-visuel {
    margin-block: -0.15rem 0.2rem;
    font-size: 0.86rem;
  }

  .scratch-pile {
    scale: 0.9;
  }

  .algorithmique-grille {
    width: min(15.5rem, 40vh);
  }

  .algorithmique-choix {
    min-height: 6rem;
  }
}

.exo:is(.reponse-juste, .reponse-fausse)
  .horloge-visuel-interactif .horloge-aiguille {
  stroke: var(--couleur-retour);
}

.historique-detail .r-question .horloge-visuel {
  width: min(17rem, 100%);
}

.historique-detail .r-question .horloge-figure {
  width: 100%;
  max-width: 100%;
  height: auto;
}

/* Calcul d'horaires : une demi-droite compacte matérialise uniquement les
   étapes du calcul. Les points d'interrogation remplacent réellement les
   horaires inconnus ; aucune correction n'est inscrite dans le SVG. */
.horaire-visuel {
  display: grid;
  justify-items: center;
  width: min(42rem, 100%);
  margin: 0.2rem auto 0;
  color: var(--encre);
}

.horaire-figure {
  display: block;
  width: 100%;
  height: auto;
  max-height: min(25vh, 11rem);
  overflow: visible;
}

.horaire-axe,
.horaire-fleche,
.horaire-graduation,
.horaire-etape {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.horaire-axe,
.horaire-fleche {
  stroke-width: 2.5;
}

.horaire-graduation {
  stroke-width: 3.2;
}

.horaire-etape {
  stroke-width: 2.8;
  opacity: 0.78;
}

.horaire-etape-0 { color: var(--lavande); }
.horaire-etape-1 { color: var(--cyan); }
.horaire-etape-2 { color: var(--rose); }

.horaire-etiquette {
  fill: var(--texte);
  font-family: var(--police-maths);
  font-size: 20px;
  font-weight: 600;
  text-anchor: middle;
}

.horaire-repere-inconnu {
  color: var(--lavande);
}

.horaire-repere-inconnu .horaire-etiquette {
  fill: var(--lavande);
  font-size: 24px;
  font-weight: 700;
}

.horaire-conseil {
  margin: -0.1rem 0 0;
  color: var(--texte-secondaire);
  font-family: var(--police-main);
  font-size: clamp(0.88rem, 1.4vw, 1rem);
  font-weight: 500;
}

.historique-detail .r-question .horaire-visuel {
  width: min(31rem, 100%);
}

@media (max-width: 560px) {
  .horaire-figure {
    max-height: none;
  }

  .horaire-etiquette {
    font-size: 18px;
  }
}

/* Balance d'équation : les poids sont de vrais boutons afin que le glissement
   tactile possède aussi une alternative au clic et au clavier. Le dessin de la
   balance reste un SVG léger, sans filtre, dans le langage « cahier » de l'app. */
.aide-visuelle:has(.equation-balance) {
  width: min(52rem, 100%);
}

.equation-balance {
  --translation-plateau: 0px;
  width: 100%;
  margin-block: 0.15rem 0.25rem;
  color: var(--encre);
  font-family: var(--police-maths);
}

.equation-balance-scene {
  position: relative;
  width: 100%;
  height: clamp(14rem, 37vh, 18.5rem);
  min-height: 0;
}

.equation-balance-dessin {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.equation-balance-fleau {
  transform-box: view-box;
  transform-origin: 400px 106px;
  transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

.equation-balance-pivot {
  fill: color-mix(in srgb, var(--jaune) 30%, transparent);
  stroke: var(--encre);
  stroke-width: 2.4;
  stroke-linejoin: round;
}

.equation-balance-scene[data-penche="gauche"] .equation-balance-fleau {
  transform: rotate(3.2deg);
}

.equation-balance-scene[data-penche="droite"] .equation-balance-fleau {
  transform: rotate(-3.2deg);
}

.equation-plateau {
  position: absolute;
  top: 0;
  bottom: 22%;
  display: flex;
  width: 38%;
  flex-direction: column;
  justify-content: flex-end;
  transition: translate 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

.equation-plateau-gauche {
  left: 3.7%;
}

.equation-plateau-droite {
  right: 3.7%;
}

.equation-balance-scene[data-penche="gauche"] .equation-plateau-gauche,
.equation-balance-scene[data-penche="droite"] .equation-plateau-droite {
  translate: 0 -0.6rem;
}

.equation-balance-scene[data-penche="gauche"] .equation-plateau-droite,
.equation-balance-scene[data-penche="droite"] .equation-plateau-gauche {
  translate: 0 0.6rem;
}

.equation-expression {
  min-height: 1.5em;
  margin-bottom: 0.15rem;
  font-size: clamp(1.05rem, 2.2vw, 1.35rem);
  font-weight: 700;
  text-align: center;
}

.equation-expression math {
  font-family: var(--police-maths);
}

.equation-objets {
  display: flex;
  height: 64%;
  box-sizing: border-box;
  /* L'ultime rangée, moins remplie, se place au-dessus : les rangées pleines
     reposent ainsi sur le plateau comme la base d'un tas. */
  flex-wrap: wrap-reverse;
  align-content: flex-start;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(0.06rem, 0.35vw, 0.2rem);
  padding: 0 0.32rem 0.2rem;
  overflow: visible;
}

.equation-poids {
  position: relative;
  display: inline-grid;
  flex: 0 0 auto;
  width: clamp(1.55rem, 3.7vw, 2.15rem);
  height: clamp(1.55rem, 3.7vw, 2.15rem);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--cyan);
  cursor: grab;
  touch-action: none;
  transition: scale 140ms ease, opacity 140ms ease, filter 140ms ease;
}

.equation-poids-x {
  width: clamp(2.25rem, 5.1vw, 3.15rem);
  color: var(--lavande);
}

.equation-poids.negatif {
  color: var(--rose);
}

.equation-poids > svg {
  grid-area: 1 / 1;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0.08rem 0.1rem 0 color-mix(in srgb, var(--encre) 12%, transparent));
}

.equation-poids-lavis {
  fill: currentcolor;
  fill-opacity: 0.24;
  stroke: none;
}

.equation-poids-contour,
.equation-poids-reprise {
  fill: none;
  stroke: currentcolor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.equation-poids-contour {
  stroke-width: 2.2;
}

.equation-poids-reprise {
  opacity: 0.42;
  stroke-width: 1.1;
}

.equation-poids-marque {
  z-index: 1;
  grid-area: 1 / 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--encre);
  font-family: var(--police-maths);
  pointer-events: none;
}

.equation-poids-marque-x {
  gap: 0.02rem;
  font-size: 1.38rem;
  font-weight: 700;
}

.equation-poids-marque-unite {
  font-size: 1rem;
}

.equation-poids:disabled {
  cursor: default;
  opacity: 0.58;
}

.equation-poids.attendu {
  filter: drop-shadow(0 0 0.35rem color-mix(in srgb, var(--jaune) 74%, transparent));
  animation: equation-poids-attendu 900ms ease-in-out infinite alternate;
}

@keyframes equation-poids-attendu {
  to { scale: 1.1; }
}

.equation-poids.en-glissement {
  z-index: 20;
  cursor: grabbing;
  opacity: 0.88;
  translate: var(--glisse-x) var(--glisse-y);
  scale: 1.12;
  filter: drop-shadow(0.2rem 0.35rem 0.3rem color-mix(in srgb, var(--encre) 28%, transparent));
  transition: none;
}

.equation-plateau-vide {
  align-self: center;
  margin-bottom: 0.35rem;
  color: var(--texte-secondaire);
  font-size: 1.25rem;
}

.equation-balance-niveau {
  position: absolute;
  top: 20.5%;
  left: 50%;
  display: grid;
  width: 2.8rem;
  height: 1.08rem;
  place-items: center;
  border: 2px solid var(--encre);
  border-radius: 999px 860px 940px 880px;
  background: var(--papier-note);
  translate: -50% -50%;
}

.equation-balance-niveau span {
  display: block;
  width: 0.72rem;
  height: 0.72rem;
  border-radius: 50%;
  background: var(--cyan);
  transition: translate 260ms ease, background-color 180ms ease;
}

.equation-balance-scene[data-penche="gauche"] .equation-balance-niveau span {
  translate: 0.72rem 0;
  background: var(--rouge);
}

.equation-balance-scene[data-penche="droite"] .equation-balance-niveau span {
  translate: -0.72rem 0;
  background: var(--rouge);
}

.equation-balance-retrait {
  display: flex;
  width: fit-content;
  min-width: 6.2rem;
  min-height: 2.9rem;
  box-sizing: border-box;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0.25rem 0.75rem;
  border: 2px dashed color-mix(in srgb, var(--rouge) 64%, var(--encre-legere));
  border-radius: 0.8rem 0.55rem 0.92rem 0.62rem;
  color: var(--rouge);
  font-size: 0.9rem;
  margin: -0.2rem auto 0;
  transition: background-color 120ms ease, scale 120ms ease;
}

.equation-balance-retrait svg {
  width: 1.8rem;
  height: 1.5rem;
  overflow: visible;
}

.equation-balance-retrait path {
  fill: none;
  stroke: currentcolor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2;
}

.equation-balance-retrait.cible-active {
  scale: 1.06;
  background: color-mix(in srgb, var(--rouge) 14%, transparent);
}

.equation-balance-annonce {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .equation-balance-fleau,
  .equation-plateau,
  .equation-balance-niveau span,
  .equation-poids.attendu {
    animation: none;
    transition: none;
  }
}

@container (max-width: 720px) {
  .equation-balance-scene {
    height: clamp(13rem, 34vh, 16rem);
  }

  .equation-plateau {
    width: 40%;
  }

  .equation-plateau-gauche { left: 2.5%; }
  .equation-plateau-droite { right: 2.5%; }
}

.pythagore-angle-droit {
  stroke: var(--accent-page);
}

.angles-calcul-visuel {
  display: flex;
  justify-content: center;
  margin-block: 0.15rem 0.4rem;
}

.angles-calcul-figure svg {
  width: auto;
  max-width: min(500px, 90vw);
  height: min(280px, 40vh);
  overflow: visible;
}

.notation-angle {
  position: relative;
  display: inline-block;
  padding-inline: 0.04em;
  font-family: var(--police-maths);
  font-style: italic;
  line-height: 1;
  font-size: 1.08em;
  vertical-align: 0.04em;
}

/* Chapeau d'angle réutilisable : deux traits légèrement irréguliers forment une
   pointe douce, plus géométrique que le caractère ⌢ sans perdre l'effet dessiné. */
.notation-angle::before,
.notation-angle::after {
  content: "";
  position: absolute;
  z-index: 1;
  top: -0.16em;
  width: 46%;
  height: 0.07em;
  background: currentColor;
  border-radius: 999px;
  pointer-events: none;
}

.notation-angle::before {
  left: 5%;
  transform: rotate(-10deg);
  transform-origin: right center;
}

.notation-angle::after {
  right: 5%;
  transform: rotate(9deg);
  transform-origin: left center;
}

/* Le repère n'embarque plus de quadrillage : le papier visible à travers son
   fond transparent fournit les carreaux. Le moteur pose ces deux variables pour
   faire coïncider exactement l'origine avec une intersection du fond. */
.repere-figure[data-quadrillage-papier] {
  translate: var(--recalage-repere-x, 0) var(--recalage-repere-y, 0);
}

/* Droite graduée (lecture sur un axe) : large et basse. */
.droite-figure {
  display: flex;
  justify-content: center;
}

.droite-figure svg {
  width: auto;
  max-width: min(420px, 94vw);
  height: auto;
}

/* L'encadrement emploie la même silhouette basse qu'une droite graduée. */
.encadrement-figure {
  display: flex;
  justify-content: center;
}

.encadrement-figure svg {
  width: auto;
  max-width: min(440px, 94vw);
  height: auto;
}

/* Disques de fractions : les secteurs de droite sont de grandes cibles SVG
   directement manipulables au doigt. Aucun état ne suggère que le coloriage
   choisi est juste ou faux. */
.disques-fractions {
  display: flex;
  justify-content: center;
  margin-inline: auto;
}

.disques-fractions svg {
  width: min(504px, 92vw);
  height: auto;
  overflow: visible;
}

.disques-fractions-egal {
  fill: var(--encre);
  font-family: var(--police-maths);
  font-size: 34px;
  font-weight: 500;
  dominant-baseline: middle;
  pointer-events: none;
  text-anchor: middle;
}

/* Les expressions dessinées conservent une expression MathML accessible sous
   leur représentation au crayon. Ces briques sont réutilisables dans les
   leçons et automatismes. */
.expression-dessinee-accessible {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.symbole-mathematique-dessine {
  display: inline-block;
  width: 0.72em;
  height: 0.72em;
  overflow: visible;
  flex: none;
}

:is(
  .symbole-mathematique-trait,
  .barre-fraction-dessinee-trait,
  .glyphe-variable-trait
) {
  vector-effect: non-scaling-stroke;
}

.symbole-mathematique-variable-x {
  width: 0.68em;
  height: 0.72em;
  vertical-align: -0.12em;
}

.expression-mathematique-variable .symbole-mathematique-variable-x {
  margin-inline: 0;
}

.expression-mathematique-dessinee {
  position: relative;
  display: inline-grid;
}

.expression-mathematique-visible {
  display: inline-flex;
  align-items: center;
  gap: 0;
}

/* Une expression inline n'est pas un grand visuel autonome : neutraliser ici
   sa marge évite qu'un x isolé augmente artificiellement la hauteur de ligne. */
.expression-mathematique-visible.visuel-question {
  margin-top: 0;
}

.expression-mathematique-visible .symbole-mathematique-dessine {
  margin-inline: 0.08em;
}

/* L'espacement mathématique natif du MathML disparaît dans sa copie manuscrite.
   On le restitue uniquement autour des opérateurs binaires : un signe négatif
   reste ainsi attaché au nombre qu'il précède. */
.exo .expression-mathematique-visible .expression-mathematique-operateur {
  margin-inline: 0.16em;
}

/* Dans le contenu pédagogique, les opérateurs sont affichés nettement plus
   petits que dans les automatismes. Leur trait doit donc être affiné pour
   conserver le même poids visuel que les chiffres manuscrits voisins. */
.contenu .symbole-mathematique-trait {
  stroke-width: 1.8;
}

/* `visuel-question` apporte dans les automatismes une taille et une graisse
   propres. Une expression intégrée à une leçon doit au contraire hériter de
   l'échelle du bloc qui remplace son MathML. */
.contenu .expression-mathematique-visible {
  margin-top: 0;
  font-size: inherit;
  font-weight: 400;
}

/* Le MathML masqué portait auparavant seul la taille et les marges des formules
   en bloc. Sa représentation visible reprend ces mêmes proportions. */
.contenu .expression-mathematique-bloc {
  display: grid;
  width: fit-content;
  margin: 0.75rem 0;
  font-size: 1.3rem;
}

main[data-vue="lecons"] .contenu .expression-mathematique-dessinee {
  font-size: 1.02em;
}

main[data-vue="lecons"] .contenu .expression-mathematique-bloc {
  margin-block: 0.65rem;
  font-size: 1.1em;
}

.expression-mathematique-groupe {
  display: inline-flex;
  align-items: center;
}

.expression-mathematique-variable {
  margin: 0;
  font-size: 1em;
}

.expression-mathematique-fraction {
  display: inline-grid;
  grid-template-rows: auto 0.26em auto;
  min-width: 1.25em;
  margin-inline: 0.08em;
  line-height: 0.82;
  text-align: center;
}

.expression-mathematique-fraction .barre-fraction-dessinee {
  width: 100%;
  height: 0.26em;
  overflow: visible;
}

.contenu .barre-fraction-dessinee-trait {
  stroke-width: 2.2;
}

.expression-mathematique-racine {
  display: inline-grid;
  grid-template-columns: 0.72em auto;
  grid-template-rows: 0.2em auto;
  align-items: start;
  margin-inline: 0.06em;
  vertical-align: middle;
}

.racine-carree-dessinee {
  z-index: 1;
  grid-column: 1;
  grid-row: 1 / span 2;
  width: 0.82em;
  height: 0.9em;
  margin: 0;
  overflow: visible;
}

.expression-mathematique-radicande {
  grid-column: 2;
  grid-row: 2;
  display: inline-flex;
  align-items: center;
  min-width: 0.65em;
  padding: 0 0.08em 0 0.02em;
  line-height: 1.1;
}

.barre-racine-carree-dessinee {
  grid-column: 2;
  grid-row: 1;
  align-self: start;
  width: calc(100% + 0.06em);
  height: 0.18em;
  margin: 0.025em 0 0 -0.08em;
  overflow: visible;
}

:is(
  .racine-carree-dessinee-trait,
  .barre-racine-carree-dessinee-trait
) {
  stroke-width: 1.8;
  vector-effect: non-scaling-stroke;
}

.expression-mathematique-puissance {
  display: inline-flex;
  align-items: flex-start;
}

.expression-mathematique-puissance sup {
  margin-left: 0.02em;
  font-size: 0.58em;
  line-height: 1;
}

.expression-mathematique-puissance sup .symbole-mathematique-dessine {
  width: 0.62em;
  height: 0.62em;
}

.egalite-fractions-expression {
  position: relative;
  display: inline-grid;
}

.egalite-fractions-calcul-dessine {
  display: inline-flex;
  align-items: center;
  gap: 0.24em;
  font-family: var(--police-maths);
  font-size: 1.08em;
  font-weight: 500;
}

.egalite-fractions-fraction-dessinee {
  display: inline-grid;
  grid-template-rows: auto 0.22em auto;
  align-items: center;
  justify-items: stretch;
  min-width: 1.35em;
  line-height: 0.82;
}

.egalite-fractions-terme {
  padding-inline: 0.1em;
  text-align: center;
}

.egalite-fractions-barre-dessinee {
  width: 100%;
  height: 0.22em;
  overflow: visible;
}

.egalite-fractions-egal-police {
  margin-inline: 0.12em;
  line-height: 1;
}

.egalite-fractions-barre-trait {
  vector-effect: non-scaling-stroke;
}

.disques-fractions-svg {
  touch-action: none;
}

.disque-fraction-secteur {
  stroke: none;
}

.disque-fraction-secteur.est-interactive {
  cursor: pointer;
}

.disque-fraction-secteur.est-interactive:focus-visible {
  outline: none;
}

.disque-fraction-focus {
  fill: none;
  stroke: transparent;
  stroke-width: 2.2;
  pointer-events: none;
}

.disque-fraction-secteur.est-interactive:focus-visible .disque-fraction-focus {
  stroke: var(--lavande);
  stroke-dasharray: 5 4;
}

.disque-fraction-coloriage {
  opacity: 0;
  pointer-events: none;
  stroke: none;
  transition: opacity 170ms ease;
}

.disque-fraction-secteur.est-coloriee .disque-fraction-coloriage,
.simplification-coloriage-fixe .disque-fraction-coloriage {
  opacity: 1;
}

.disque-fraction-coloriage-large {
  fill-opacity: 0.28;
}

.disque-fraction-coloriage-reprise {
  fill-opacity: 0.11;
}

.simplification-fraction-visuel {
  display: grid;
  grid-template-columns: minmax(0, 264px) 5.5rem;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 3vw, 2rem);
  margin-inline: auto;
}

.simplification-fraction-disque {
  width: min(264px, 68vw);
  height: auto;
  overflow: visible;
}

.simplification-decoupage:not(.est-actif) {
  display: none;
}

.simplification-ascenseur {
  display: grid;
  grid-template-rows: 10rem;
  justify-items: center;
  gap: 0.18rem;
  color: var(--encre);
  font-family: var(--police-main);
}

.simplification-nombre-parts {
  color: var(--encre);
  font-family: var(--police-maths);
  font-size: 1.06rem;
  line-height: 1;
  text-align: center;
}

.simplification-rail-croquis {
  position: relative;
  width: 3rem;
  height: 10rem;
}

.simplification-rail-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.simplification-course {
  position: absolute;
  inset: 1rem 0;
  pointer-events: none;
}

.simplification-cabine {
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border: 2px solid var(--encre);
  border-radius: 42% 58% 47% 53% / 54% 43% 57% 46%;
  background: var(--fond);
  translate: -50% 50%;
  rotate: -1.5deg;
}

.simplification-curseur {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  width: 10rem;
  height: 3rem;
  margin: 0;
  opacity: 0.001;
  cursor: ns-resize;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  transform: translate(-50%, -50%) rotate(-90deg);
}

.simplification-rail-croquis:has(.simplification-curseur:focus-visible) {
  outline: 2px solid color-mix(in srgb, var(--lavande) 72%, transparent);
  outline-offset: 0.2rem;
  border-radius: 0.65rem 0.4rem 0.7rem 0.35rem;
}

.simplification-rail-croquis:has(.simplification-curseur:active) .simplification-cabine {
  background: color-mix(in srgb, var(--lavande) 11%, var(--fond));
  translate: -50% 50%;
  rotate: 1deg;
}

/* Addition et soustraction de fractions : chaque disque conserve son aplat,
   tandis que son ascenseur extérieur ne change que le nombre de parts. */
.addition-fractions-visuel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2.8rem minmax(0, 1fr);
  align-items: center;
  justify-content: center;
  gap: clamp(0.35rem, 1.2vw, 0.8rem);
  width: min(43rem, 100%);
  margin-inline: auto;
}

.addition-fractions-groupe {
  display: grid;
  min-width: 0;
  align-items: center;
  justify-content: center;
  gap: clamp(0.35rem, 1vw, 0.7rem);
}

.addition-fractions-gauche {
  grid-template-columns: 3rem minmax(0, 13.75rem);
}

.addition-fractions-droite {
  grid-template-columns: minmax(0, 13.75rem) 3rem;
}

.addition-fractions-disque {
  width: min(13.75rem, 100%);
  height: auto;
  overflow: visible;
}

.addition-fractions-operateur {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  overflow: visible;
  color: var(--encre);
  font-family: var(--police-maths);
  font-size: 2.6rem;
  line-height: 1;
  rotate: -2deg;
}

.addition-fractions-ascenseur {
  min-width: 3rem;
}

@media (max-width: 700px) {
  .addition-fractions-visuel {
    grid-template-columns: minmax(0, 1fr) 2rem minmax(0, 1fr);
    gap: 0.25rem;
  }

  .addition-fractions-gauche {
    grid-template-columns: 2.6rem minmax(0, 1fr);
  }

  .addition-fractions-droite {
    grid-template-columns: minmax(0, 1fr) 2.6rem;
  }

  .addition-fractions-operateur {
    width: 1.9rem;
    height: 1.9rem;
    font-size: 1.9rem;
  }
}

/* Séries manipulables de la moyenne et de la médiane : les jetons ressemblent à
   des nombres entourés au crayon. Le glissement ne porte aucun code couleur de
   validation. */
.tri-statistique {
  display: grid;
  justify-items: center;
  gap: 0.85rem;
  margin-inline: auto;
}

.tri-statistique .visuel-question {
  color: var(--texte-secondaire);
  font-size: clamp(1rem, 1.8vw, 1.25rem);
  font-weight: 400;
}

.tri-statistique-liste {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(0.35rem, 1.2vw, 0.75rem);
  margin: 0;
  padding: 0.35rem;
  list-style: none;
}

.tri-statistique-liste > li {
  position: relative;
  z-index: 0;
  will-change: transform;
}

.tri-statistique-liste > li:nth-child(3n + 1) { rotate: -1.1deg; }
.tri-statistique-liste > li:nth-child(3n + 2) { rotate: 0.7deg; }
.tri-statistique-liste > li:nth-child(3n) { rotate: -0.35deg; }

.tri-statistique-jeton {
  display: grid;
  min-width: clamp(3.3rem, 6vw, 4.3rem);
  min-height: clamp(3rem, 5.5vw, 3.9rem);
  padding: 0.35rem 0.65rem;
  place-items: center;
  border: 2px solid var(--encre);
  border-radius: 46% 54% 43% 57% / 55% 44% 56% 45%;
  background: color-mix(in srgb, var(--papier-note) 88%, transparent);
  box-shadow: 0.12rem 0.16rem 0 color-mix(in srgb, var(--encre) 16%, transparent);
  color: var(--texte);
  cursor: grab;
  font-family: var(--police-maths);
  font-size: clamp(1.45rem, 2.8vw, 2rem);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.tri-statistique-jeton:focus-visible {
  outline: 2px solid var(--lavande);
  outline-offset: 3px;
}

.tri-statistique-liste > li.est-glisse {
  z-index: 3;
  transform: translateX(var(--decalage-tri, 0));
  rotate: 1.5deg;
}

.tri-statistique-liste > li.est-glisse .tri-statistique-jeton {
  cursor: grabbing;
  box-shadow: 0.22rem 0.32rem 0 color-mix(in srgb, var(--encre) 18%, transparent);
}

.tri-statistique-annonce {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.serie-statistique {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  max-width: 100%;
  column-gap: 0.15em;
  font-variant-numeric: tabular-nums;
}

.grille-pastilles {
  display: inline-grid;
  gap: 0.5rem;
}

.pastille {
  position: relative;
  box-sizing: border-box;
  width: 2.2rem;
  height: 2.2rem;
  border: 1.2px solid color-mix(in srgb, var(--pastille-couleur) 82%, var(--encre));
  border-radius: 47% 53% 44% 56% / 56% 45% 55% 44%;
  background: color-mix(in srgb, var(--pastille-couleur) 88%, transparent);
  box-shadow: inset 0.08rem -0.06rem 0 color-mix(in srgb, var(--pastille-couleur) 42%, transparent);
  rotate: -2deg;
}

.pastille::after {
  position: absolute;
  inset: 0.08rem 0.04rem 0.03rem 0.09rem;
  border: 0.7px solid color-mix(in srgb, var(--pastille-couleur) 58%, transparent);
  border-radius: 54% 46% 57% 43% / 45% 56% 44% 55%;
  content: "";
  rotate: 4deg;
}

.pastille:nth-child(4n + 2) {
  border-radius: 54% 46% 51% 49% / 43% 57% 46% 54%;
  rotate: 2.5deg;
  scale: 0.96 1.04;
}

.pastille:nth-child(4n + 3) {
  border-radius: 43% 57% 48% 52% / 54% 45% 55% 46%;
  rotate: -3.5deg;
  scale: 1.03 0.97;
}

.pastille:nth-child(4n) {
  border-radius: 52% 48% 42% 58% / 47% 53% 58% 42%;
  rotate: 1.5deg;
}

.visuel-question {
  margin-top: 1.5rem;
  font-size: 1.1rem;
  font-weight: 600;
}

.modele-barre {
  width: 100%;
  max-width: 34rem;
  border-collapse: collapse;
  table-layout: fixed;
}

.modele-barre td {
  padding: 0.7rem 0.5rem;
  border: 1px solid var(--overlay-0);
  background: var(--fond-secondaire);
  text-align: center;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Modèle en barre des compléments : plus compact qu'un tableau pleine largeur,
   et centré dans la zone du visuel. */
.modele-complement {
  max-width: 20rem;
  margin-inline: auto;
}

/* Police au même corps que la question, et les deux cases du bas dimensionnées
   proportionnellement (via le <colgroup>), pas en 50/50. */
.modele-barre.modele-complement td,
.modele-barre.modele-complement .mb-inconnu {
  font-size: 1.1rem;
}

.modele-barre .mb-total {
  background: var(--surface-0);
}

.modele-barre .mb-inconnu {
  color: var(--lavande);
  font-size: 1.4rem;
}

/* Parts coloriées de « a/b d'une quantité » : le numérateur, en couleur du
   thème. Le « ? » (valeur à trouver) est porté par la cellule centrale. */
.modele-barre .mb-part {
  background: color-mix(in srgb, var(--part-couleur) 30%, var(--fond-secondaire));
  color: var(--part-couleur);
  font-size: 1.4rem;
}

.numeration {
  width: fit-content; /* se réduit à la largeur du tableau */
  margin-inline: auto; /* centré horizontalement */
}

.num-table {
  border-collapse: collapse;
  font-size: 1rem; /* neutralise le 2rem hérité de .exo .enonce */
}

.num-table th,
.num-table td {
  width: 4rem; /* colonnes égales */
  border: 1px solid var(--surface-0);
  text-align: center;
}

.num-table th {
  vertical-align: bottom; /* libellés ancrés vers leur chiffre */
  background: var(--fond-secondaire);
}

/* Libellé vertical (bottom-to-top) ; la cellule s'auto-dimensionne. */
.num-table th .v {
  display: inline-block;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  padding: 0.4rem 0;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--texte-secondaire);
}

.num-table td {
  padding: 0.7rem 0;
  font-size: 1.5rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.session-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
}

/* Le clavier réduit volontairement la largeur utile de la question, mais pas
   celle du bandeau de session : le score reste accroché au bord droit. */
.exo.session > .session-tete {
  width: calc(100% + var(--espace-clavier));
  max-width: none;
}

body.gaucher .exo.session > .session-tete {
  margin-left: calc(-1 * var(--espace-clavier));
}

.chrono {
  font-size: 1.6rem;
  color: var(--lavande);
  font-variant-numeric: tabular-nums;
}

.score-session {
  color: var(--texte-secondaire);
}

.bilan {
  font-size: 1.2rem;
}

.graine {
  color: var(--texte-secondaire);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

/* --- Quizz --------------------------------------------------------------- */

.panneau-info {
  margin-bottom: 2rem;
  padding: 1.5rem;
  border-radius: 1rem;
  border: 1px dashed var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte-secondaire);
  font-weight: 500;
  text-align: center;
}

.quizz-passe {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
  padding: 1rem 1.25rem;
  border-radius: 1rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
}

.quizz-date {
  font-weight: 600;
}

.quizz-resultat {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.quizz-resultat .rang {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.8rem;
  height: 1.8rem;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--surface-0);
  color: var(--texte-secondaire);
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1;
}

.quizz-resultat .score {
  font-weight: 600;
  color: var(--texte-secondaire);
  font-variant-numeric: tabular-nums;
}

.quizz-resultat .podium.rang-1 {
  background: var(--jaune);
  color: var(--fond);
}

.quizz-resultat .podium.rang-2 {
  background: var(--overlay-0);
  color: var(--fond);
}

.quizz-resultat .podium.rang-3 {
  background: var(--rose);
  color: var(--fond);
}

/* --- Mes sessions : liste façon anciens quizz + page de bilan ------------- */

.session-lien {
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    transform 0.15s ease;
}

.session-lien:hover {
  border-color: var(--lavande);
  transform: translateY(-1px);
}

.session-bilan-tete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  margin-bottom: 2.5rem;
}

.session-bilan-tete .theme {
  margin-top: 0;
}

.session-bilan-tete h1 {
  margin-bottom: 0;
}

.session-bilan-score {
  flex-shrink: 0;
  color: var(--lavande);
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
}

.session-questions {
  max-width: 54rem;
}

.session-question {
  align-items: center;
  min-height: 4.5rem;
  padding: 1.1rem 1.35rem;
}

.session-question.juste {
  border-left: 4px solid var(--cyan);
}

.session-question.faux {
  border-left: 4px solid var(--rouge);
}

.session-question-corps,
.session-question-resultat {
  display: flex;
  flex-direction: column;
}

.session-question-corps {
  gap: 0.2rem;
}

.session-question-resultat {
  align-items: flex-end;
  min-width: 8rem;
}

.session-question-titre {
  color: var(--texte-secondaire);
  font-size: 0.8rem;
  font-weight: 600;
}

.r-question {
  font-weight: 600;
  font-size: 1.1rem;
}
/* Dans le bilan, le dessin d'une question (aire, périmètre, coordonnées…) est
   réduit en vignette à côté du score, mais assez grand pour que les graduations
   chiffrées et les axes restent lisibles. */
.r-question .visuel {
  margin: 0.3rem 0 0;
}
.r-question .visuel svg {
  max-width: 230px;
}
.r-question .visuel-question {
  margin-top: 0.3rem;
  font-size: 0.9rem;
  font-weight: 600;
}
/* Réponse fausse de l'élève : barrée et en rouge. */
.r-eleve {
  font-size: 0.9rem;
  color: var(--rouge);
  text-decoration: line-through;
}
.r-eleve::before {
  content: "✗ ";
  text-decoration: none;
}
/* Bonne réponse : verte (✓). En cas de réussite, c'est la seule affichée. */
.r-bonne {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--cyan);
}
.r-bonne::before {
  content: "✓ ";
}

/* --- Jeux : éléments communs (en-tête, modes, verdict, actions) ---------- */

.jeu-desc {
  font-size: 0.85rem;
  color: var(--texte-secondaire);
}

.carte .jeu-icone {
  color: var(--lavande);
}

.jeu-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}

.jeu-modes {
  display: inline-flex;
  gap: 0.4rem;
}

.jeu-mode {
  padding: 0.65rem 1.4rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte-secondaire);
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
}

.jeu-mode.active {
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

.jeu-consigne {
  max-width: 42rem;
  color: var(--texte-secondaire);
}

.jeu-verdict {
  min-height: 1.6rem;
  font-weight: 600;
}

.jeu-verdict.juste {
  color: var(--cyan);
}

.jeu-verdict.faux {
  color: var(--rouge);
}

.jeu-actions {
  display: flex;
  gap: 0.6rem;
}

.jeu-rejouer {
  padding: 0.7rem 1.45rem;
  border-radius: 0.7rem;
  border: 1px solid transparent;
  background: var(--lavande);
  color: var(--fond);
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
}

/* --- Jeux de combinaison (Le compte est bon, 24) ------------------------- */

.combi-cible {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin: 1.25rem 0;
}

.combi-cible span {
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--texte-secondaire);
}

.combi-cible strong {
  font-size: 2.6rem;
  line-height: 1;
  color: var(--lavande);
  font-variant-numeric: tabular-nums;
}

.combi-tuiles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

.combi-tuile {
  min-width: 3.9rem;
  padding: 0.95rem 0.75rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.6rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition:
    transform 0.12s ease,
    border-color 0.12s ease;
}

.combi-tuile.calcul {
  border-style: dashed;
  color: var(--cyan);
}

.combi-tuile:hover:not(:disabled) {
  transform: translateY(-2px);
  border-color: var(--lavande);
}

.combi-tuile.active {
  border-color: var(--lavande);
  background: color-mix(in srgb, var(--lavande) 18%, var(--fond-secondaire));
}

.combi-tuile.pris {
  opacity: 0.35;
  text-decoration: line-through;
}

.combi-tuile:disabled {
  cursor: default;
}

.combi-ops {
  display: inline-flex;
  gap: 0.4rem;
  margin-bottom: 1.25rem;
}

.combi-op {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.6rem;
  font-weight: 700;
  cursor: pointer;
}

.combi-op.active {
  color: var(--fond);
  background: var(--rose);
  border-color: transparent;
}

.combi-historique {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  font-size: 1.05rem;
  font-variant-numeric: tabular-nums;
}

.combi-historique li {
  padding: 0.2rem 0;
  color: var(--texte-secondaire);
}

.combi-historique strong {
  color: var(--texte);
}

.combi-annuler {
  padding: 0.7rem 1.45rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
}

/* --- Jeux : Nerdle ------------------------------------------------------- */

/* Légende des couleurs dans la consigne. */
.leg-juste {
  color: var(--cyan);
}
.leg-present {
  color: var(--lavande);
}
.leg-absent {
  color: var(--overlay-0);
}

.nerdle-grille {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: fit-content;
  margin: 1.25rem 0;
  --nerdle-case: 2.6rem;
}

.nerdle-ligne {
  display: grid;
  gap: 0.4rem;
}

.nerdle-case {
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--nerdle-case);
  border-radius: 0.5rem;
  border: 2px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.3rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.nerdle-case.remplie {
  border-color: var(--overlay-0);
}

.nerdle-case.juste {
  color: var(--fond);
  background: var(--cyan);
  border-color: transparent;
}

.nerdle-case.present {
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

.nerdle-case.absent {
  color: var(--fond);
  background: var(--overlay-0);
  border-color: transparent;
}

.nerdle-clavier {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: fit-content;
  margin-bottom: 1.25rem;
}

.nerdle-clavier-ligne {
  display: flex;
  gap: 0.35rem;
}

.nerdle-touche {
  min-width: 2.9rem;
  height: 3.3rem;
  padding: 0 0.6rem;
  border-radius: 0.5rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.3rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.1s ease;
}

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

.nerdle-touche.large {
  min-width: 4.8rem;
  font-size: 1.1rem;
}

.nerdle-touche.juste {
  color: var(--fond);
  background: var(--cyan);
  border-color: transparent;
}

.nerdle-touche.present {
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

.nerdle-touche.absent {
  color: var(--fond);
  background: var(--overlay-0);
  border-color: transparent;
}

/* --- Jeux : Circuit (relatifs) ------------------------------------------- */

.circuit-barre {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 1.25rem 0;
  padding: 0.75rem 1.25rem;
  border: 1px solid var(--surface-0);
  border-radius: 1rem;
  background: var(--fond-secondaire);
}

.circuit-tete-bloc {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.circuit-tete-bloc.droite {
  align-items: flex-end;
}

.circuit-label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--texte-secondaire);
}

.circuit-actuelle,
.circuit-cible {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--jaune);
}

.circuit-cible {
  color: var(--cyan);
}

.circuit-actuelle.ok {
  color: var(--cyan);
}

.circuit-jauge {
  display: flex;
  flex: 1;
  gap: 0.3rem;
  justify-content: center;
}

.circuit-jauge i {
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 0.25rem;
  background: var(--surface-0);
  transition: background-color 0.2s ease;
}

.circuit-jauge i.plein {
  background: var(--jaune);
}

.circuit-jauge i.plein.ok {
  background: var(--cyan);
  box-shadow: 0 0 8px color-mix(in srgb, var(--cyan) 60%, transparent);
}

.circuit-plateau {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.2rem;
  margin: 1.5rem 0;
}

.circuit-trace {
  width: 1.4rem;
  height: 3px;
  border-radius: 2px;
  background: var(--overlay-0);
}

.circuit-noeud {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 0.8rem;
  border: 2px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.3rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.circuit-noeud.source {
  color: var(--cyan);
  border-color: var(--cyan);
  background: color-mix(in srgb, var(--cyan) 14%, var(--fond-secondaire));
}

.circuit-noeud.cible-noeud {
  color: var(--jaune);
  border-color: var(--jaune);
  background: color-mix(in srgb, var(--jaune) 14%, var(--fond-secondaire));
}

.circuit-badge {
  position: absolute;
  bottom: -0.6rem;
  padding: 0 0.35rem;
  border-radius: 0.4rem;
  background: var(--cyan);
  color: var(--fond);
  font-size: 0.8rem;
}

.circuit-noeud.slot {
  cursor: pointer;
}

.circuit-noeud.slot.jouable {
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.circuit-noeud.slot.jouable:not(.vide) {
  cursor: grab;
}

.circuit-noeud.slot.vide {
  border-style: dashed;
  border-color: var(--overlay-0);
}

.circuit-noeud.slot.jouable:not(:disabled):hover {
  border-color: var(--lavande);
}

.circuit-noeud.slot.fixe {
  cursor: default;
}

.circuit-noeud.positif {
  color: var(--cyan);
  border-color: var(--cyan);
}

.circuit-noeud.negatif {
  color: var(--rouge);
  border-color: var(--rouge);
}

.circuit-noeud.slot.fixe.positif {
  background: color-mix(in srgb, var(--cyan) 14%, var(--fond-secondaire));
}

.circuit-noeud.slot.fixe.negatif {
  background: color-mix(in srgb, var(--rouge) 14%, var(--fond-secondaire));
}

.circuit-inventaire-bloc {
  margin-bottom: 1.25rem;
}

.circuit-inventaire {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.5rem;
}

.circuit-module {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 1rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  transition:
    transform 0.1s ease,
    border-color 0.1s ease;
}

.circuit-module:not(:disabled):hover {
  transform: translateY(-2px);
}

.circuit-module.active {
  border-color: var(--lavande);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--lavande) 40%, transparent);
}

.circuit-module:disabled {
  opacity: 0.4;
  cursor: default;
}

.circuit-module-val {
  font-size: 1.5rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.circuit-module.positif .circuit-module-val {
  color: var(--cyan);
}

.circuit-module.negatif .circuit-module-val {
  color: var(--rouge);
}

.circuit-module-qte {
  min-width: 1.4rem;
  padding: 0.1rem 0.3rem;
  border-radius: 0.4rem;
  background: var(--surface-0);
  color: var(--texte-secondaire);
  font-size: 0.85rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* --- Options ------------------------------------------------------------- */

.options {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 36rem;
}

.option {
  background: var(--fond-secondaire);
  border: 1px solid var(--surface-0);
  border-radius: 0.9rem;
  padding: 1rem 1.25rem;
}

.option h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}

.option dl {
  margin: 0;
}

.option dl > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--surface-0);
}

.option dl > div:first-child {
  border-top: none;
}

.option dt {
  color: var(--texte-secondaire);
}

.option dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
}

/* Pastille d'état devant la valeur. */
.option dd[data-etat]::before {
  content: "";
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  margin-right: 0.45rem;
  border-radius: 50%;
  vertical-align: middle;
  background: var(--overlay-0);
}

.option dd[data-etat="ok"]::before {
  background: var(--cyan);
}

.option dd[data-etat="neutre"]::before {
  background: var(--jaune);
}

.option dd[data-etat="ko"]::before {
  background: var(--rouge);
}

.opt-eleve {
  font-variant-numeric: tabular-nums;
}

.option-note {
  margin: 0.6rem 0 0;
  font-size: 0.85rem;
  color: var(--texte-secondaire);
}

/* Groupe de choix (ex. position du clavier) dans une carte d'options. */
.opt-radios {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin-top: 0.6rem;
}

.opt-radios label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
}

.opt-radios input {
  accent-color: var(--lavande);
  cursor: pointer;
}

/* --- Enrôlement (mode public) -------------------------------------------- */

.enrolement {
  background: var(--fond-secondaire);
  border: 1px solid var(--surface-0);
  border-radius: 0.9rem;
  padding: 1.25rem 1.5rem;
  max-width: 36rem;
}

.pin-code {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  margin: 1.25rem 0;
}

.pin-chiffre {
  min-width: 3rem;
  padding: 0.6rem 0;
  text-align: center;
  font-size: 2.4rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--lavande);
  background: color-mix(in srgb, var(--lavande) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--lavande) 35%, transparent);
  border-radius: 0.7rem;
}

.pin-attente {
  color: var(--texte-secondaire);
  font-style: italic;
}

/* --- Notifications « toast » (réutilisable) ------------------------------ */

.notifs {
  position: fixed;
  top: max(1rem, env(safe-area-inset-top));
  right: max(1rem, env(safe-area-inset-right));
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.8rem;
  pointer-events: none; /* seuls les toasts captent le clic */
}

.notif {
  --couleur-notif: var(--lavande);
  pointer-events: auto;
  position: relative;
  display: grid;
  grid-template-columns: 1.8rem minmax(0, 1fr);
  align-items: center;
  gap: 0.65rem;
  width: fit-content;
  min-width: min(13rem, calc(100vw - 2rem));
  max-width: min(23rem, calc(100vw - 2rem));
  box-sizing: border-box;
  padding: 0.9rem 1.1rem 0.85rem 0.9rem;
  border: 1.8px solid color-mix(in srgb, var(--couleur-notif) 58%, var(--encre));
  border-radius: 0.35rem 0.85rem 0.45rem 0.7rem / 0.7rem 0.4rem 0.8rem 0.35rem;
  background: color-mix(in srgb, var(--couleur-notif) 7%, var(--papier-note));
  box-shadow: 0.22rem 0.3rem 0 color-mix(in srgb, var(--encre) 16%, transparent);
  color: var(--encre);
  appearance: none;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
  opacity: 1;
  translate: 0;
  rotate: -0.7deg;
  scale: 1;
  transition:
    opacity 180ms ease,
    translate 220ms ease,
    scale 220ms ease;

  @starting-style {
    opacity: 0;
    translate: 1rem -0.15rem;
    scale: 0.97;
  }
}
.notif::after {
  position: absolute;
  right: 0.3rem;
  bottom: -0.22rem;
  left: 0.45rem;
  height: 0.32rem;
  border-bottom: 1.2px solid color-mix(in srgb, var(--couleur-notif) 45%, transparent);
  border-radius: 50%;
  content: "";
  rotate: 0.8deg;
}
.notif.fermeture {
  opacity: 0;
  translate: 1rem -0.15rem;
  scale: 0.97;
}
.notif-action:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--couleur-notif) 72%, var(--encre));
  outline-offset: 3px;
}
.notif-action:active {
  scale: 0.98;
}
.notif-pictogramme {
  display: grid;
  width: 1.65rem;
  height: 1.65rem;
  place-items: center;
  border: 1.7px solid currentColor;
  border-radius: 48% 52% 46% 54% / 54% 45% 55% 46%;
  color: var(--couleur-notif);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1;
  rotate: -5deg;
}
.notif-message {
  min-width: 0;
}
.notif-succes {
  --couleur-notif: var(--vert-note);
}
.notif-erreur {
  --couleur-notif: var(--rouge);
}
.notif-info {
  --couleur-notif: var(--lavande);
}
/* Accueil — progression générale et suivi par automatisme. */
main[data-vue="accueil"] {
  --accent-page: var(--lavande);
}

.accueil {
  box-sizing: border-box;
  width: min(72rem, 100%);
  margin-inline: auto;
  padding: clamp(0.4rem, 1.5vw, 1rem) clamp(0.1rem, 1vw, 0.7rem) 4rem;
  color: var(--encre);
}

.accueil a {
  color: inherit;
}

.accueil-vide {
  margin: 0;
  color: var(--texte-secondaire);
}

.accueil-voir-tout .fleche-manuscrite {
  width: 1.65rem;
  flex: 0 0 auto;
  color: var(--case-couleur, var(--lavande));
  transition: translate 180ms ease;
}

.accueil-voir-tout:hover .fleche-manuscrite {
  translate: 0.28rem 0;
}

.accueil-progression-graphe {
  min-height: 13rem;
}

.accueil-progression-graphe {
  display: flex;
  align-items: center;
}

.accueil-courbe-svg {
  display: block;
  width: 100%;
  max-height: 14rem;
  overflow: visible;
}

.accueil-courbe-svg text {
  fill: var(--texte-secondaire);
  font-family: inherit;
}

.accueil-axe,
.accueil-fleche-axe,
.accueil-repere,
.accueil-graduation {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.accueil-axe,
.accueil-fleche-axe {
  stroke: var(--texte-secondaire);
  stroke-width: 2.2;
}

.accueil-repere {
  stroke: color-mix(in srgb, var(--encre-legere) 24%, transparent);
  stroke-width: 1.1;
  stroke-dasharray: 4 7;
}

.accueil-graduation {
  stroke: color-mix(in srgb, var(--encre) 75%, transparent);
  stroke-width: 1.7;
}

.accueil-point {
  opacity: 0;
  animation: accueil-apparaitre-point 230ms ease-out calc(430ms + var(--delai-point)) forwards;
}

.accueil-point-valeur {
  fill: var(--cyan) !important;
  stroke: var(--fond);
  stroke-width: 4px;
  paint-order: stroke fill;
  font-size: 16px;
  stroke-linejoin: round;
  text-anchor: middle;
}

.accueil-point-date {
  font-size: 13px;
  text-anchor: middle;
}

.accueil-axe-valeur {
  font-size: 13px;
  text-anchor: end;
}

.accueil-graphe-message {
  font-size: 16px;
  text-anchor: middle;
}

@keyframes accueil-tracer-courbe {
  to { stroke-dashoffset: 0; }
}

@keyframes accueil-apparaitre-point {
  to { opacity: 1; }
}

.accueil-voir-tout {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1.15rem;
  color: var(--lavande);
  font-size: 0.95rem;
  text-decoration: none;
}

.accueil-axe,
.accueil-repere,
.accueil-graduation,
.accueil-segment-score {
  vector-effect: non-scaling-stroke;
}

.accueil-repere {
  opacity: 0.42;
}

.accueil-courbe-trace .accueil-segment-score {
  stroke-dasharray: 800;
  stroke-dashoffset: 800;
  animation: accueil-tracer-courbe 650ms ease-out forwards;
}

.accueil-courbe-trace .accueil-segment-score:nth-child(2) { animation-delay: 90ms; }
.accueil-courbe-trace .accueil-segment-score:nth-child(3) { animation-delay: 180ms; }
.accueil-courbe-trace .accueil-segment-score:nth-child(4) { animation-delay: 270ms; }
.accueil-courbe-trace .accueil-segment-score:nth-child(5) { animation-delay: 360ms; }
.accueil-courbe-trace .accueil-segment-score:nth-child(6) { animation-delay: 450ms; }
.accueil-courbe-trace .accueil-segment-score:nth-child(7) { animation-delay: 540ms; }

@media (prefers-reduced-motion: reduce) {
  .notif {
    transition: none;
    translate: 0;
    scale: 1;
  }
}

/* === Listes de contenus — fiches compactes dessinées ====================
   Leçons, automatismes et jeux partagent un unique contour de crayon :
   le quadrillage reste visible. Une hauteur commune laisse respirer jusqu'à
   trois lignes de titre sans désaligner les cartes de contenu. */
main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .theme {
  margin: 1.55rem 0 0.65rem;
  font-size: 1.07rem;
}

/* La liste publique contient quatorze groupes et plus de cinquante fiches. Les
   groupes lointains ne sont mis en page et peints qu'à l'approche du viewport. */
main[data-vue="automatismes"] .groupe-theme {
  content-visibility: auto;
  contain-intrinsic-block-size: auto 18rem;
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille {
  grid-template-columns: repeat(auto-fill, minmax(175px, 1fr));
  align-items: start;
  gap: 0.72rem 0.82rem;
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille > .carte {
  --couleur-note: var(--couleur-theme, var(--accent-page));
  --cadre-croquis: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 40' preserveAspectRatio='none'%3E%3Cpath d='M3 4C24 2 76 5 97 3C99 13 96 28 98 36C74 39 23 36 3 38C1 28 4 13 3 4Z' fill='none' stroke='black' stroke-width='.82' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  position: relative;
  isolation: isolate;
  box-sizing: border-box;
  height: 6rem;
  min-height: 6rem;
  justify-content: center;
  gap: 0;
  padding: 0.82rem 1rem 0.88rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  rotate: -0.18deg;
  translate: 0;
  transition: color 160ms ease, translate 160ms ease, rotate 160ms ease;
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille > .carte::before {
  position: absolute;
  inset: -0.14rem -0.16rem -0.16rem -0.12rem;
  z-index: -1;
  display: block;
  width: auto;
  height: auto;
  background: color-mix(in srgb, var(--couleur-note) 58%, var(--encre-legere));
  content: "";
  pointer-events: none;
  translate: 0;
  -webkit-mask: var(--cadre-croquis) center / 100% 100% no-repeat;
  mask: var(--cadre-croquis) center / 100% 100% no-repeat;
  rotate: -0.25deg;
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille > .carte:nth-child(even) {
  border-radius: 0;
  rotate: 0.2deg;
  translate: 0;
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille > .carte:hover {
  border: 0;
  background: color-mix(in srgb, var(--couleur-note) 5%, transparent);
  box-shadow: none;
  translate: 0 -0.14rem;
  rotate: -0.65deg;
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille > .carte .titre {
  position: relative;
  isolation: isolate;
  z-index: 1;
  color: var(--encre);
  font-size: clamp(1.07rem, 1.4vw, 1.22rem);
  font-weight: 500;
  line-height: 1.22;
}

/* Les libellés de la liste d'automatismes restent légèrement plus discrets
   que ceux du rail de navigation, qui sert de repère principal. */
main[data-vue="automatismes"] .grille > .carte .titre {
  font-size: clamp(1rem, 1.25vw, 1.08rem);
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille > .carte .titre::before {
  position: absolute;
  z-index: -1;
  right: -0.22em;
  bottom: -0.02em;
  left: -0.18em;
  height: 0.58em;
  background: color-mix(in srgb, var(--couleur-note) 17%, transparent);
  clip-path: polygon(0 24%, 11% 10%, 35% 17%, 62% 7%, 84% 16%, 100% 8%, 97% 82%, 73% 91%, 45% 82%, 18% 94%, 2% 78%);
  content: "";
  rotate: -0.8deg;
}

main:is(
  [data-vue="lecons"],
  [data-vue="automatismes"],
  [data-vue="jeux"]
) .grille > .carte .titre::after {
  right: -0.08em;
  bottom: -0.24em;
  left: -0.08em;
  border-top: 1.7px solid var(--couleur-note);
  opacity: 0.42;
  scale: 1;
  rotate: -1.1deg;
}

@container (max-width: 48rem) {
  main:is(
    [data-vue="lecons"],
    [data-vue="automatismes"],
    [data-vue="jeux"]
  ) .grille {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.7rem;
  }

  main:is(
    [data-vue="lecons"],
    [data-vue="automatismes"],
    [data-vue="jeux"]
  ) .grille > .carte {
    height: 6rem;
    min-height: 6rem;
    padding: 0.78rem 0.72rem 0.84rem;
  }
}

/* --- Jeux : Picross ------------------------------------------------------ */

.picross-outils {
  display: inline-flex;
  gap: 0.4rem;
  margin: 1rem 0;
}

.picross-outil {
  padding: 0.55rem 1.1rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte-secondaire);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
}

.picross-outil.active {
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

/* Disposition 2×2 : [coin][indices colonnes] / [indices lignes][grille]. */
.picross-plateau {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  width: 100%;
  --picross-case: 2.4rem;
  user-select: none;
  -webkit-user-select: none;
}

.picross-coin {
  grid-column: 1;
  grid-row: 1;
}

.picross-colonnes {
  display: flex;
  grid-column: 2;
  grid-row: 1;
  align-items: flex-end;
}

.picross-cl-col {
  width: var(--picross-case);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding-bottom: 0.25rem;
}

.picross-lignes {
  display: flex;
  grid-column: 1;
  grid-row: 2;
  justify-self: end;
  flex-direction: column;
}

.picross-cl-lig {
  height: var(--picross-case);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.4em;
  padding-right: 0.5rem;
}

/* Les indices : chiffres discrets, alignés au plus près de la grille. */
.picross-cl-col span,
.picross-cl-lig span {
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--texte-secondaire);
  font-variant-numeric: tabular-nums;
}

.picross-grille {
  display: grid;
  grid-column: 2;
  grid-row: 2;
  touch-action: none; /* le glisser peint au lieu de faire défiler */
}

.picross-case {
  box-sizing: border-box;
  height: var(--picross-case);
  padding: 0;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--overlay-0);
  font-size: calc(var(--picross-case) * 0.6); /* taille du ✕, proportionnelle */
  line-height: 1;
  cursor: pointer;
}

.picross-case.pleine {
  background: var(--lavande);
  border-color: var(--lavande);
}

.picross-case.marquee {
  color: var(--overlay-0);
}

/* Séparateurs plus épais tous les 5 cases (lisibilité des grandes grilles). */
.picross-case.sep-g {
  border-left: 2px solid var(--overlay-0);
}

.picross-case.sep-h {
  border-top: 2px solid var(--overlay-0);
}

.picross-case:disabled {
  cursor: default;
}

/* --- Jeux : Sudoku ------------------------------------------------------- */

.sudoku-plateau {
  margin: 1rem 0;
}

.sudoku-grille {
  --sudoku-case: clamp(2.4rem, 11.4vw, 3.24rem);
  display: grid;
  grid-template-columns: repeat(9, var(--sudoku-case));
  width: max-content;
  border: 2px solid var(--overlay-0);
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

.sudoku-case {
  box-sizing: border-box;
  width: var(--sudoku-case);
  height: var(--sudoku-case);
  padding: 0;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--lavande); /* chiffres saisis par l'élève */
  font-size: calc(var(--sudoku-case) * 0.55);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
}

/* Chiffres fournis (l'énoncé) : plus appuyés, non modifiables. */
.sudoku-case.donnee {
  color: var(--texte);
  font-weight: 700;
  cursor: default;
}

/* Séparateurs épais entre les blocs 3×3. */
.sudoku-case.sep-c {
  border-right: 2px solid var(--overlay-0);
}

.sudoku-case.sep-r {
  border-bottom: 2px solid var(--overlay-0);
}

/* Toutes les cases portant le même chiffre que la case sélectionnée. */
.sudoku-case.pair {
  background: color-mix(in srgb, var(--lavande) 20%, var(--fond-secondaire));
}

.sudoku-case.correcte {
  color: var(--vert-note);
}

.sudoku-case.possible {
  color: var(--jaune);
}

.sudoku-case.conflit {
  color: var(--rouge);
}

.sudoku-case.selection {
  background: color-mix(in srgb, var(--lavande) 38%, var(--fond-secondaire));
  outline: 2px solid var(--lavande);
  outline-offset: -2px;
}

.sudoku-case:disabled {
  cursor: default;
}

/* Notes (petits candidats) : mini-grille 3×3 dans la case. */
.sudoku-notes-grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: 100%;
  height: 100%;
}

.sudoku-notes-grille span {
  display: grid;
  place-items: center;
  font-size: calc(var(--sudoku-case) * 0.26);
  font-weight: 500;
  line-height: 1;
  color: var(--texte-secondaire);
}

.sudoku-pave {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 1rem 0;
  max-width: 26rem;
}

.sudoku-num,
.sudoku-effacer,
.sudoku-notes {
  padding: 0.55rem 1rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.15rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.sudoku-num {
  min-width: 2.7rem;
}

.sudoku-effacer,
.sudoku-notes {
  font-size: 1rem;
  color: var(--texte-secondaire);
}

.sudoku-num:disabled {
  opacity: 0.35;
  cursor: default;
}

.sudoku-notes.active {
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

/* --- Jeux : Mathdoku ----------------------------------------------------- */

.mathdoku-plateau {
  margin: 1rem 0;
}

.mathdoku-grille {
  --mathdoku-case: clamp(2.52rem, 11.4vw, 3.36rem);
  display: grid;
  grid-template-columns: repeat(9, var(--mathdoku-case));
  width: max-content;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

/* Les bordures (cadre, zones, blocs) sont posées en ligne par le rendu. */
.mathdoku-case {
  position: relative;
  box-sizing: border-box;
  width: var(--mathdoku-case);
  height: var(--mathdoku-case);
  padding: 0;
  background: var(--fond-secondaire);
  color: var(--lavande); /* chiffres saisis par l'élève */
  font-variant-numeric: tabular-nums;
  display: grid;
  place-items: center;
  cursor: pointer;
}

.mathdoku-val {
  font-size: calc(var(--mathdoku-case) * 0.5);
  font-weight: 600;
  line-height: 1;
}

.mathdoku-case.donnee {
  color: var(--texte);
}

.mathdoku-case.donnee .mathdoku-val {
  font-weight: 700;
}

.mathdoku-case.pair {
  background: color-mix(in srgb, var(--lavande) 20%, var(--fond-secondaire));
}

.mathdoku-case.conflit .mathdoku-val {
  color: var(--rouge);
}

.mathdoku-case.selection {
  background: color-mix(in srgb, var(--lavande) 38%, var(--fond-secondaire));
}

.mathdoku-case:disabled {
  cursor: default;
}

/* Étiquette de zone : résultat + opération, en haut à gauche. */
.mathdoku-label {
  position: absolute;
  top: 1px;
  left: 2px;
  font-size: calc(var(--mathdoku-case) * 0.28);
  font-weight: 700;
  line-height: 1;
  color: var(--texte-secondaire);
  pointer-events: none;
}

.mathdoku-label.bad {
  color: var(--rouge);
}

/* Notes (petits candidats) : mini-grille 3×3, décalée sous l'étiquette. */
.mathdoku-notes-grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: 100%;
  height: 100%;
}

.mathdoku-notes-grille span {
  display: grid;
  place-items: center;
  font-size: calc(var(--mathdoku-case) * 0.24);
  line-height: 1;
  color: var(--texte-secondaire);
}

.mathdoku-pave {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 1rem 0;
  max-width: 26rem;
}

.mathdoku-num,
.mathdoku-effacer,
.mathdoku-notes {
  padding: 0.55rem 1rem;
  border-radius: 0.7rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.15rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.mathdoku-num {
  min-width: 2.7rem;
}

.mathdoku-effacer,
.mathdoku-notes {
  font-size: 1rem;
  color: var(--texte-secondaire);
}

.mathdoku-num:disabled {
  opacity: 0.35;
  cursor: default;
}

.mathdoku-notes.active {
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

/* --- Page étroite : la navbar latérale devient une barre d'onglets en bas ---
   Container query sur la largeur de la page (html), comme l'appli prof. Le
   contenu (main) prend le haut et défile ; la nav passe en bas, horizontale et
   compacte. Les libellés restent (icône au-dessus) façon barre d'onglets mobile. */
@container (max-width: 48rem) {
  body {
    flex-direction: column;
    gap: 0;
  }
  main {
    order: 0; /* contenu en haut */
    padding: 1.25rem 1rem 1.5rem;
  }
  nav {
    order: 1; /* barre en bas */
    width: 100%;
    flex-direction: row;
    gap: 0;
    padding: 0.2rem 0.4rem;
    border-right: none;
    border-left: none;
    border-top: 1px solid var(--surface-0);
  }
  nav ul {
    flex: 1;
    flex-direction: row;
    justify-content: space-around;
    gap: 0.15rem;
  }
  nav li {
    flex: 1;
    min-width: 0;
  }
  /* « Options »/« Enrôler » redevient un onglet ordinaire (plus poussé en bas). */
  .nav-bas {
    margin-top: 0;
  }
  nav li > a {
    padding: 0.4rem 0.15rem;
    gap: 0.2rem;
    font-size: 0.62rem;
    border-radius: 0.6rem;
  }
  nav li > a svg {
    width: 22px;
    height: 22px;
  }
  .session-bilan-tete {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.75rem;
  }
  .session-question {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.75rem;
  }
  .session-question-resultat {
    align-items: flex-start;
    min-width: 0;
  }
}

/* --- Clavier virtuel (saisie tactile des automatismes) ------------------- */

/* Bascule en bas (à droite par défaut ; à gauche pour les gauchers, côté clavier).
   Allumée (lavande) quand le clavier est affiché. Au-dessus du contenu, sous les
   toasts (z-index 1000). Masquée par défaut : sur tactile, le clavier virtuel est
   obligatoire et ne se désactive pas (cf. clavier.js). Rétablie ci-dessous sur les
   interfaces à pointeur fin (souris/trackpad), où saisir au clavier physique a du
   sens. */
.clavier-bascule {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 30;
  width: 3.4rem;
  height: 3.4rem;
  display: none;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 2.4rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--crust, #000) 35%, transparent);
  transition: transform 0.1s ease;
}

/* Interface non tactile (souris/trackpad) : on rétablit la bascule. */
@media (hover: hover) and (pointer: fine) {
  .clavier-bascule {
    display: grid;
  }
}

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

.clavier-bascule[aria-pressed="true"] {
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

/* Gaucher : la bascule passe en bas à gauche, du côté du clavier. */
body.gaucher .clavier-bascule {
  right: auto;
  left: 1.25rem;
}

/* En mode public, Options occupe ce coin chez un droitier et le retour à la
   liste l'occupe chez un gaucher. La bascule reste du côté du clavier, juste
   au-dessus de cette action, au lieu de se dissimuler derrière elle. */
body.mode-public .clavier-bascule {
  bottom: calc(max(1.25rem, env(safe-area-inset-bottom)) + 5rem);
}

/* Touches posées directement sur le fond de la page (pas de panneau ni de bord),
   en retrait du bord et centrées verticalement. Le côté suit la latéralité (cf.
   lateralite.js) : droite par défaut, gauche pour un gaucher. */
.clavier {
  --decalage-apparition: 0.7rem;
  position: fixed;
  z-index: 29;
  top: 50%;
  right: 1.25rem;
  /* Safari peut rogner les quelques pixels qu'une touche tournée dépasse de la
     boîte flex. Cette réserve interne garde tous les traits manuscrits visibles. */
  padding-inline: 0.3rem;
  overflow: visible;
  /* La boîte fixe garde la largeur du pavé complet pendant que Firefox anime
     l'échelle de chaque touche. clavier.js fige ensuite cette largeur calculée. */
  width: max-content;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

body.gaucher .clavier {
  --decalage-apparition: -0.7rem;
  right: auto;
  left: 1.25rem;
}

.clavier[hidden] {
  display: none;
}

.clavier-ligne {
  display: flex;
  flex: 0 0 auto;
  width: max-content;
  gap: 0.35rem;
  justify-content: center;
}

.clavier-touche {
  width: 3.4rem; /* largeur FIXE : toutes les colonnes s'alignent (même ×10ⁿ) */
  height: 3.4rem;
  padding: 0;
  border-radius: 0.6rem;
  border: 1px solid var(--surface-0);
  background: var(--fond-secondaire);
  color: var(--texte);
  font-size: 1.4rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: transform 0.1s ease;
}

/* À l'ouverture par la bascule, les touches arrivent successivement depuis le
   bord où se trouve le clavier. À la fermeture, elles repartent dans l'ordre
   inverse. Les délais sont posés par clavier.js dans l'ordre de lecture. */
.clavier.clavier-apparition .clavier-touche {
  animation: apparition-touche-clavier 210ms cubic-bezier(0.2, 0.8, 0.35, 1.15)
    calc(var(--ordre-touche, 0) * 32ms) backwards;
}

.clavier.clavier-disparition {
  pointer-events: none;
}

.clavier.clavier-disparition .clavier-touche {
  animation: disparition-touche-clavier 210ms cubic-bezier(0.65, -0.15, 0.8, 0.2)
    calc((var(--nombre-touches, 1) - var(--ordre-touche, 0) - 1) * 32ms) forwards;
}

/* À l'arrivée dans un exercice, toutes les touches gonflent en cascade. Entre
   deux questions d'une session, clavier.js ne repose cette classe que sur les
   touches absentes du profil précédent : le pavé stable ne clignote pas. */
.clavier-touche.clavier-touche-en-attente {
  opacity: 0;
}

.clavier-touche.clavier-touche-nouvelle {
  transform-origin: center;
  animation: apparition-bulle-touche-clavier 360ms
    cubic-bezier(0.16, 0.84, 0.3, 1.28)
    calc(var(--ordre-animation, 0) * 38ms) backwards;
  /* Firefox compose différemment les propriétés indépendantes `scale` et
     `translate` dans un flex à largeur intrinsèque. La propriété historique
     `transform` conserve ici une géométrie stable dans tous les moteurs. */
  will-change: opacity, transform;
}

@keyframes apparition-bulle-touche-clavier {
  0% {
    opacity: 0;
    transform: translate(var(--decalage-apparition), 0.45rem) scale(0.22);
  }
  68% {
    opacity: 1;
    transform: translateY(-0.08rem) scale(1.12);
  }
  84% {
    transform: translateY(0.03rem) scale(0.96);
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

@keyframes apparition-touche-clavier {
  from {
    opacity: 0;
    scale: 0.68;
    translate: var(--decalage-apparition) 0.2rem;
  }
}

@keyframes disparition-touche-clavier {
  to {
    opacity: 0;
    scale: 0.68;
    translate: var(--decalage-apparition) 0.2rem;
  }
}

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

.clavier-touche:active {
  background: color-mix(in srgb, var(--lavande) 22%, var(--fond-secondaire));
}

.clavier-touche:disabled {
  cursor: default;
  opacity: 0.58;
}

/* Touches d'action (Valider / ⌫) : plus larges et accentuées. */
.clavier-touche.large {
  width: 5rem;
  font-size: 1.05rem;
  color: var(--fond);
  background: var(--lavande);
  border-color: transparent;
}

/* Le glyphe ⌫ a besoin d'être plus grand que le texte « Valider ». */
.clavier-touche[data-action="effacer"] {
  font-size: 1.7rem;
}

/* « ×10ⁿ » : police réduite pour tenir dans la largeur fixe d'une touche. */
.clavier-touche[data-touche="×10^"] {
  font-size: 1.1rem;
}

/* Disposition 4 colonnes (beaucoup de touches) : on aligne la rangée du bas sur
   les colonnes — ⌫ sur 1 colonne, Valider sur 2 (largeur = 2 touches + 1 gap) —
   pour que sa largeur totale égale celle des rangées de chiffres. Le « 2 colonnes »
   ne vaut que dans la rangée alignée 0 + ⌫ + Valider (3 touches) ; quand un surplus
   d'adaptatives (≥ 4) renvoie ⌫ + Valider sur leur propre rangée centrée, Valider
   garde sa largeur d'action normale. */
.clavier[data-cols="4"] .clavier-touche[data-action="effacer"] {
  width: 3.4rem;
}
.clavier[data-cols="4"] .clavier-ligne:has(.clavier-touche:nth-child(3)) .clavier-touche[data-action="valider"] {
  width: 7.15rem;
}

/* Les variables reprennent exactement la police italique des lettres placées
   sur les figures, sans passer par la variante <mi> imposée par Safari. */
.clavier-touche-variable {
  font-family: var(--police-maths);
  font-style: italic;
  font-weight: 400;
}

.clavier-touche-variable .symbole-mathematique-variable-x {
  width: 0.76em;
  height: 1em;
  vertical-align: -0.13em;
}

/* La touche spécialisée saisit ² d'un geste et montre le même petit 2
   attendu pour « au carré ». On le place explicitement afin de garder la même
   ligne visuelle dans les polices manuscrite et classique. */
.clavier-touche-carre {
  font-family: var(--police-maths);
  font-weight: 400;
}

.clavier-carre-exposant {
  display: inline-block;
  font-size: 0.68em;
  line-height: 1;
  translate: 0 -0.38em;
}

.clavier-touche.contient-symbole-mathematique .symbole-mathematique-dessine {
  vertical-align: -0.08em;
}

/* Écrans étroits (tablette portrait / mobile) : touches resserrées pour que le
   clavier n'empiète pas trop sur la saisie. */
@media (max-width: 720px) {
  .clavier-touche {
    width: 2.9rem;
    height: 3rem;
    font-size: 1.2rem;
  }
  .clavier-touche.large {
    width: 4.2rem;
  }
  .clavier-touche[data-touche="×10^"] {
    font-size: 0.95rem;
  }
  /* Rangée du bas alignée sur 4 colonnes (touches resserrées : 2,9rem + gap). */
  .clavier[data-cols="4"] .clavier-touche[data-action="effacer"] {
    width: 2.9rem;
  }
  .clavier[data-cols="4"] .clavier-ligne:has(.clavier-touche:nth-child(3)) .clavier-touche[data-action="valider"] {
    width: 6.15rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .clavier:is(.clavier-apparition, .clavier-disparition) .clavier-touche {
    animation: none;
  }
}

/* === Géométrie dynamique (route /geometrie) ============================== */
/* Outil plein écran : on retire la marge/le défilement de <main> pour que la
   zone de construction occupe toute la surface disponible (à côté de la nav). */
body.geo-actif main {
  padding: 0;
  overflow: hidden;
}

.geo-construction {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

/* Les règles `display` ci-dessous surchargeraient l'attribut [hidden] (dont le
   display:none est de faible spécificité) : on le rétablit explicitement. */
.geo-barre-props[hidden],
.geo-barre-actions[hidden],
.geo-contenu-historique[hidden],
.geo-effacer-traces[hidden] {
  display: none;
}

.geo-canvas {
  position: absolute;
  inset: 0;
  cursor: crosshair;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.geo-canvas text {
  user-select: none;
  -webkit-user-select: none;
}

.geo-canvas.geo-curseur-default {
  cursor: default;
}
.geo-canvas.geo-curseur-pointer {
  cursor: pointer;
}
.geo-canvas.geo-curseur-gomme {
  cursor: cell;
}

.geo-plan-wrapper {
  position: absolute;
  inset: 0;
}
.geo-plan-wrapper svg {
  display: block;
}

.geo-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.geo-overlay .geo-halo {
  stroke: light-dark(#c6a0f6, #b4befe);
  stroke-width: 8;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.35;
}

/* Surface commune aux panneaux flottants (menu, propriétés, historique…). */
.geo-menu,
.geo-barre-props,
.geo-historique,
.geo-effacer-traces,
.geo-barre-icones {
  background-color: var(--fond-secondaire);
  color: var(--texte);
  box-shadow:
    0 4px 16px light-dark(rgba(76, 79, 105, 0.1), rgba(0, 0, 0, 0.35)),
    0 1px 3px light-dark(rgba(76, 79, 105, 0.06), rgba(0, 0, 0, 0.2));
}

/* --- Menu d'outils (rail vertical à gauche) --- */
.geo-menu {
  position: absolute;
  top: 50%;
  left: 0.75rem;
  transform: translateY(-50%);
  z-index: 10;
  width: 64px;
  border-radius: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem;
  box-sizing: border-box;
}

.geo-menu button {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  background-color: transparent;
  color: inherit;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition:
    background-color 0.12s ease,
    color 0.12s ease;
}

.geo-menu button:hover {
  background: var(--surface-0);
}

.geo-menu button.actif {
  background: var(--lavande);
  color: var(--fond);
}

.geo-separateur-menu {
  width: 60%;
  height: 1px;
  background: var(--surface-0);
  opacity: 0.7;
  margin: 0.1rem 0;
}

/* --- Barre de propriétés (haut, centrée) --- */
.geo-barre-props {
  position: absolute;
  top: 0.75rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  border-radius: 14px;
  padding: 0.55rem 0.85rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  font-size: 1rem;
  width: max-content;
  max-width: calc(100% - 2rem);
}

.geo-groupe-haut,
.geo-groupe-style {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.9rem;
  row-gap: 0.5rem;
}

.geo-section {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.geo-libelle {
  font-size: 0.9rem;
  color: var(--texte-secondaire);
}

.geo-principale .geo-libelle {
  font-weight: 700;
  color: inherit;
  font-size: 1rem;
}

.geo-notation {
  font-style: italic;
  white-space: nowrap;
}

.geo-appartenance {
  font-size: 0.85rem;
  color: var(--texte-secondaire);
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  white-space: nowrap;
}

.geo-chapeau {
  position: relative;
  display: inline-block;
}

.geo-chapeau-arc {
  position: absolute;
  top: -0.35em;
  left: 10%;
  width: 80%;
  overflow: visible;
}

.geo-separateur-deux-points {
  font-weight: 700;
}

.geo-separateur {
  width: 1px;
  align-self: stretch;
  background: var(--surface-0);
  opacity: 0.7;
}

.geo-nom-input {
  background: var(--fond);
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 0.3rem 0.5rem;
  color: inherit;
  font: inherit;
  text-align: center;
  transition:
    border-color 0.12s ease,
    background-color 0.12s ease;
}

.geo-nom-input:focus {
  outline: none;
  border-color: var(--lavande);
}

.geo-palette-h {
  display: flex;
  gap: 0.3rem;
}

.geo-swatch {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  border: 1px solid light-dark(rgba(76, 79, 105, 0.15), rgba(0, 0, 0, 0.25));
  cursor: pointer;
  padding: 0;
  transition: transform 0.12s ease;
}

.geo-swatch:hover {
  transform: scale(1.15);
}

.geo-swatch.actif {
  outline: 2px solid var(--lavande);
  outline-offset: 2px;
}

.geo-epaisseur-input {
  width: 2.2rem;
  background: var(--fond);
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 0.25rem 0.4rem;
  color: inherit;
  font: inherit;
}

.geo-epaisseur-input:focus {
  outline: none;
  border-color: var(--lavande);
}

.geo-opacite-input {
  width: 8rem;
  accent-color: var(--lavande);
}

.geo-checkbox-option {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  user-select: none;
}

.geo-checkbox-option input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--lavande);
  margin: 0;
}

.geo-supprimer {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.4rem;
  color: var(--rouge);
  display: flex;
  align-items: center;
}

.geo-supprimer:hover {
  opacity: 0.7;
}

/* --- Panneau historique (bas droite) --- */
.geo-historique {
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  z-index: 30;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  overflow: hidden;
  transition:
    width 0.32s cubic-bezier(0.2, 0.8, 0.2, 1),
    height 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.geo-historique.ouvert {
  width: 320px;
  height: min(440px, calc(100% - 1.5rem));
}

.geo-declencheur-historique {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 40px;
  height: 40px;
  background: transparent;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  color: var(--texte);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  z-index: 1;
  transition: background-color 0.12s ease;
}

.geo-declencheur-historique:hover {
  background: var(--surface-0);
}

.geo-titre-historique {
  position: absolute;
  top: 0;
  left: 0.9rem;
  height: 52px;
  display: flex;
  align-items: center;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--texte);
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  transition: opacity 0.18s ease;
}

.geo-historique.ouvert .geo-titre-historique {
  opacity: 1;
  transition-delay: 0.14s;
}

.geo-contenu-historique {
  position: absolute;
  inset: 52px 0.5rem 0.5rem 0.5rem;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.geo-historique-vide {
  font-size: 0.85rem;
  color: var(--texte-secondaire);
  padding: 0.3rem 0.5rem;
  margin: 0;
}

.geo-liste-historique {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}

.geo-liste-historique li + li {
  border-top: 1px solid
    light-dark(rgba(108, 111, 133, 0.18), rgba(165, 173, 203, 0.12));
}

.geo-item-historique {
  width: 100%;
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 0.65rem 0.55rem 0.5rem;
  color: inherit;
  font: inherit;
  line-height: 1.4;
  cursor: pointer;
  text-align: left;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  transition: background-color 0.12s ease;
}

.geo-item-historique:hover {
  background: var(--surface-0);
}

.geo-item-historique.actif {
  background: var(--surface-0);
}

.geo-item-historique.cachee .geo-item-libelle,
.geo-item-historique.cachee .geo-item-notation {
  opacity: 0.55;
}

.geo-icone-cache {
  flex-shrink: 0;
  vertical-align: -2px;
  margin-right: 0.25rem;
  color: var(--texte-secondaire);
}

.geo-item-libelle {
  font-size: 0.8rem;
  color: var(--texte-secondaire);
  min-width: 4.5rem;
  display: inline-flex;
  align-items: center;
}

.geo-item-notation {
  font-style: italic;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  padding-top: 0.45em;
}

/* --- Bouton « effacer les traces » --- */
.geo-effacer-traces {
  position: absolute;
  right: calc(1.15rem + 52px);
  bottom: 0.75rem;
  z-index: 30;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.geo-bouton-effacer-traces {
  width: 40px;
  height: 40px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  color: var(--texte);
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.12s ease,
    color 0.12s ease;
}

.geo-bouton-effacer-traces:hover {
  background: var(--surface-0);
  color: var(--rouge);
}

/* --- Barre d'actions (haut droite) --- */
.geo-barre-icones {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  border-radius: 14px;
  padding: 0.4rem;
}

.geo-barre-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}

.geo-icone-bouton {
  box-sizing: border-box;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 10px;
  width: 40px;
  height: 40px;
  font-family: inherit;
  cursor: pointer;
  color: var(--texte);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.12s ease;
}

.geo-icone-bouton:hover {
  background: var(--surface-0);
}

.geo-groupe-charger {
  position: relative;
}

.geo-menu-charger {
  position: absolute;
  top: 0;
  right: calc(100% + 0.35rem);
  background-color: var(--fond-secondaire);
  border-radius: 10px;
  padding: 0.3rem;
  box-shadow:
    0 4px 16px light-dark(rgba(76, 79, 105, 0.18), rgba(0, 0, 0, 0.45)),
    0 1px 3px light-dark(rgba(76, 79, 105, 0.1), rgba(0, 0, 0, 0.25));
  display: flex;
  flex-direction: column;
  min-width: 12rem;
}

.geo-menu-charger button {
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
  font: inherit;
  color: var(--texte);
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
  transition: background-color 0.12s ease;
}

.geo-menu-charger button:hover {
  background: var(--surface-0);
}

/* Sur écran peu haut, le rail d'outils passe en grille deux colonnes collée au
   bord (comme dans l'appli d'origine). */
@media (max-height: 700px) {
  .geo-menu {
    left: 0;
    top: 50%;
    display: grid;
    grid-template-columns: repeat(2, 48px);
    grid-auto-rows: 48px;
    width: auto;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }
  .geo-separateur-menu {
    grid-column: 1 / -1;
    width: 80%;
    justify-self: center;
  }
}

/* === Cahier quadrillé — identité visuelle élève ==========================
   Cette couche reprend le langage du prototype (papier, notes adhésives,
   typographie manuscrite et déploiement depuis le point touché) tout en gardant
   les couleurs Catppuccin et les contraintes propres à l'application. */

:root {
  --papier: light-dark(#fbfaf6, #1e1e2e);
  --papier-note: light-dark(#fffdf8, #242438);
  --bureau: light-dark(#e6e9ef, #11111b);
  --encre: light-dark(#4c4f69, #cdd6f4);
  --encre-legere: light-dark(#6c6f85, #a6adc8);
  --quadrillage: light-dark(rgba(30, 102, 245, 0.085), rgba(137, 180, 250, 0.07));
  --marge-cahier: light-dark(rgba(210, 15, 57, 0.18), rgba(243, 139, 168, 0.13));
  --adhesif: light-dark(rgba(230, 214, 170, 0.72), rgba(108, 112, 134, 0.62));
  --ombre-papier: light-dark(rgba(76, 79, 105, 0.14), rgba(0, 0, 0, 0.34));
  --vert-note: light-dark(#40a02b, #a6e3a1);
  --orange-note: light-dark(#fe640b, #fab387);
  --violet-note: light-dark(#8839ef, #cba6f7);
  --bleu-note: light-dark(#1e66f5, #89b4fa);
  --turquoise-entrainement: light-dark(#08979d, #5eead4);
  --pas-quadrillage: 32px;
  --decalage-quadrillage-x: 0px;
  --decalage-quadrillage-y: -9px;
  --police-manuscrite: "Symbole Pi mathsmaths", "Shantell Sans", cursive;
  --police-reguliere: "STIX Two Math", "STIX Math", "Cambria Math", Cambria, "Times New Roman", serif;
  /* Par défaut, même les jetons MathML utilisent l'écriture manuscrite. STIX
     n'est rétablie partout que par l'option « Police classique ». */
  --police-main: var(--police-manuscrite);
  --police-maths: var(--police-manuscrite);
  --accent-page: var(--lavande);

  /* Les composants historiques continuent d'utiliser ces variables. */
  --fond: var(--papier);
  --fond-secondaire: var(--papier-note);
  --texte: var(--encre);
  --texte-secondaire: var(--encre-legere);
}

/* Préférences globales posées par preferences-affichage.js. La palette adaptée
   reprend des teintes séparables sans dépendre du seul axe rouge/vert. */
body.police-classique {
  --police-main: var(--police-reguliere);
  --police-maths: var(--police-reguliere);
  font-family: var(--police-reguliere);
}

body.police-classique :is(main, nav, button, input, select, textarea) {
  font-family: var(--police-reguliere);
}

body.couleurs-accessibles {
  --cyan: light-dark(#0072b2, #73bfe2);
  --lavande: light-dark(#9c4f96, #dd9bd5);
  --rose: light-dark(#cc79a7, #efb0d2);
  --jaune: light-dark(#b66d00, #f0c05a);
  --rouge: light-dark(#d55e00, #ff9b65);
  --vert-note: light-dark(#0072b2, #73bfe2);
  --orange-note: light-dark(#d55e00, #ff9b65);
  --violet-note: light-dark(#9c4f96, #dd9bd5);
  --bleu-note: light-dark(#0072b2, #73bfe2);
}

body {
  gap: 0;
  background-color: var(--papier);
  background-image:
    repeating-linear-gradient(
      transparent 0 calc(var(--pas-quadrillage) - 1px),
      var(--quadrillage) var(--pas-quadrillage)
    ),
    repeating-linear-gradient(
      90deg,
      transparent 0 calc(var(--pas-quadrillage) - 1px),
      var(--quadrillage) var(--pas-quadrillage)
    );
  background-position:
    var(--decalage-quadrillage-x) var(--decalage-quadrillage-y),
    var(--decalage-quadrillage-x) 0;
  font-family: var(--police-main);
  -webkit-font-smoothing: antialiased;
}

/* Les libellés créés dans les SVG (géométrie, graphiques et icônes) ne suivent
   pas toujours l'héritage HTML dans Safari. On leur applique donc explicitement
   la même préférence globale. */
svg text {
  font-family: var(--police-main);
}

nav {
  position: relative;
  z-index: 20;
  display: flex;
  flex-shrink: 0;
  flex-direction: column;
  width: 10rem;
  box-sizing: border-box;
  gap: 0.4rem;
  padding: 0.8rem 1rem 0.7rem 0.7rem;
  overflow: visible;
  border: 0;
  background: transparent;
  box-shadow: none;
  view-transition-name: main-nav;
}

/* La navigation EST la marge : cette ligne sépare la zone des annotations de
   la zone de travail, sans panneau, ombre ni changement de papier. */
nav::after {
  position: absolute;
  z-index: -1;
  top: 0;
  right: 0;
  bottom: 0;
  width: 2px;
  background: var(--marge-cahier);
  content: "";
  pointer-events: none;
}

body.gaucher nav {
  order: 1;
  padding-right: 0.7rem;
  padding-left: 1rem;
  border: 0;
  box-shadow: none;
}

body.gaucher nav::after {
  right: auto;
  left: 0;
}

nav ul {
  display: flex;
  flex: 1;
  flex-direction: column;
  width: 100%;
  margin: 0;
  padding: 0;
  justify-content: stretch;
  gap: 0;
  list-style: none;
}

/* Chaque raccourci reçoit la même tranche du rail, quelle que soit sa hauteur.
   Options reste un raccourci ordinaire au sein de cette répartition. */
.nav-bas {
  margin-top: 0;
}

nav li {
  flex: 1 1 0;
  min-height: 0;
}

nav li > a {
  --nav-couleur: var(--lavande);
  position: relative;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  min-height: 0;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  gap: 0.1rem;
  padding: 0.35rem 0.25rem 0.45rem;
  border: 0;
  border-radius: 0;
  color: var(--encre-legere);
  background: transparent;
  font-family: var(--police-main);
  font-size: 1.09rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.025em;
  text-align: center;
  transition:
    color 180ms ease,
    translate 180ms ease,
    rotate 180ms ease;
}

nav li:nth-child(1) > a { --nav-couleur: var(--vert-note); }
nav li:nth-child(2) > a { --nav-couleur: var(--orange-note); }
nav li:nth-child(3) > a { --nav-couleur: var(--jaune); }
nav li:nth-child(4) > a { --nav-couleur: var(--bleu-note); }
nav li:nth-child(5) > a { --nav-couleur: var(--violet-note); }
nav li:nth-child(6) > a { --nav-couleur: var(--cyan); }
nav li.nav-bas > a { --nav-couleur: var(--rose); }

nav a[href="/"] { --nav-couleur: var(--cyan); }
nav a[href="/automatismes"] { --nav-couleur: var(--orange-note); }
nav a[href="/quizz"] { --nav-couleur: var(--violet-note); }
nav a[href="/jeux"] { --nav-couleur: var(--bleu-note); }
nav a[href="/serieux"] { --nav-couleur: var(--vert-note); }

/* Le solde est un indicateur indépendant, placé en tête du rail plutôt qu'un
   onglet supplémentaire. Le libellé reste accessible via aria-label. */
nav > a.nav-serieux {
  display: grid;
  flex: 0 0 auto;
  width: 100%;
  min-height: 3.3rem;
  padding: 0.35rem;
  color: var(--vert-note);
  place-items: center;
}

nav > a.nav-serieux[hidden] {
  display: none;
}

nav > a.nav-serieux:is(:hover, :focus-visible) .nav-points-serieux,
nav > a.nav-serieux[aria-current="page"] .nav-points-serieux {
  scale: 1.08;
}

nav > a.nav-serieux:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 0.1rem;
}

nav > a.nav-serieux .nav-points-serieux {
  transition: scale 180ms ease;
}

nav li:nth-child(even) > a {
  rotate: 0.65deg;
}

nav li > a::before {
  position: absolute;
  inset: 0.12rem 0.18rem 0.08rem;
  border: 1.5px solid currentColor;
  border-radius: 48% 52% 46% 54% / 52% 45% 55% 48%;
  content: "";
  opacity: 0;
  rotate: -1.8deg;
  scale: 0.9;
  transition: opacity 180ms ease, scale 180ms ease;
  pointer-events: none;
}

nav li > a::after {
  position: absolute;
  right: 23%;
  bottom: 0.2rem;
  left: 20%;
  height: 0.25rem;
  border-top: 1.5px solid currentColor;
  border-radius: 50%;
  content: "";
  opacity: 0.75;
  rotate: -1.5deg;
  scale: 0 1;
  transform-origin: left;
  transition: scale 180ms ease;
}

nav li > a:hover {
  color: var(--nav-couleur);
  background: transparent;
  translate: 0.18rem 0;
  rotate: 0deg;
}

nav li > a:hover::after { scale: 1; }

nav li > a:focus-visible {
  color: var(--nav-couleur);
  outline: none;
}

nav li > a:focus-visible::before {
  opacity: 0.62;
  scale: 1;
}

nav li > a:focus-visible::after { scale: 1; }

nav li > a[aria-current="page"] {
  color: var(--nav-couleur);
  background: transparent;
  box-shadow: none;
}

nav li > a[aria-current="page"]::after { scale: 1; }

nav .icone-croquis {
  width: 33px;
  height: 33px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.65;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: rotate 180ms ease, scale 180ms ease;
}

nav .icone-croquis .detail-croquis {
  stroke-width: 1.25;
}

nav .icone-croquis .trace-reprise {
  opacity: 0.32;
  stroke-width: 1.1;
  translate: 0.35px 0.45px;
}

nav li:nth-child(odd) .icone-croquis { rotate: -1.8deg; }
nav li:nth-child(even) .icone-croquis { rotate: 1.5deg; }
nav li > a:hover .icone-croquis {
  rotate: -3deg;
  scale: 1.08;
}

main {
  position: relative;
  isolation: isolate;
  padding: clamp(1.8rem, 4vw, 3.5rem) clamp(2rem, 5vw, 5rem) 3rem;
  background: transparent;
  view-transition-name: page-content;
}

main[data-vue="lecons"] { --accent-page: var(--vert-note); }
main[data-vue="automatismes"] { --accent-page: var(--jaune); }
main[data-vue="quizz"] { --accent-page: var(--violet-note); }
main[data-vue="jeux"] { --accent-page: var(--bleu-note); }
main[data-vue="serieux"] { --accent-page: var(--vert-note); }
main[data-vue="options"],
main[data-vue="enroler"] { --accent-page: var(--cyan); }

main h1 {
  position: relative;
  width: fit-content;
  margin: 0 0 1.5rem;
  color: var(--accent-page);
  font-family: var(--police-main);
  font-size: clamp(2.2rem, 4.5vw, 3.6rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.045em;
  text-wrap: balance;
  rotate: -0.5deg;
}

/* Sur la fiche d'un automatisme, le titre laisse davantage de place à la
   question tout en conservant sa hiérarchie par rapport à la navbar. */
main[data-vue="automatismes"] .exo-tete h1 {
  font-size: clamp(2.05rem, 4vw, 3.2rem);
}

main h1::after {
  position: absolute;
  right: 0;
  bottom: -0.35rem;
  left: 0;
  height: 0.4rem;
  border-top: 2px solid currentColor;
  border-radius: 50%;
  content: "";
  opacity: 0.65;
  rotate: -0.7deg;
}

main[data-vue="quizz"] .theme {
  margin: 2.2rem 0 1rem;
  color: var(--accent-page);
  font-family: var(--police-main);
  font-size: 1.1rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
  rotate: -0.4deg;
}

.option::before {
  position: absolute;
  top: -11px;
  left: 50%;
  width: 54px;
  height: 22px;
  background: var(--adhesif);
  content: "";
  translate: -50% 0;
  rotate: -3deg;
}

.retour {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 1.25rem;
  color: var(--encre-legere);
  font-family: var(--police-main);
  font-size: 1rem;
  transition: color 160ms ease, translate 160ms ease;
}

.fleche-manuscrite {
  flex: 0 0 auto;
  width: 2.15rem;
  height: 1.55rem;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
  rotate: 0deg;
  transition: translate 160ms ease, rotate 160ms ease;
}

.fleche-manuscrite.droite {
  scale: -1 1;
  rotate: 0deg;
}

.retour:hover {
  color: var(--accent-page);
  translate: -0.2rem 0;
}

.contenu {
  max-width: 66rem;
  padding-bottom: 2rem;
  font-family: var(--police-maths);
  font-size: 1.06rem;
}

.contenu > h1 { color: var(--accent-page); }
.contenu h2 { color: var(--accent-page); }

/* === Leçons — notes manuscrites, surligneurs et traits de marge ========== */

main[data-vue="lecons"] .contenu {
  width: min(70rem, 100%);
  max-width: none;
  padding-bottom: 3rem;
  font-family: var(--police-main);
  font-size: clamp(1.28rem, 1.75vw, 1.5rem);
  line-height: 1.72;
}

main[data-vue="lecons"] .contenu > h1 {
  margin-bottom: clamp(2.4rem, 5vh, 3.5rem);
}

main[data-vue="lecons"] .bloc {
  --bloc-couleur: var(--lavande);
  position: relative;
  margin: clamp(2.2rem, 5vh, 3.4rem) 0;
  padding: 0.2rem 0.8rem 0.55rem 1.8rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

main[data-vue="lecons"] .bloc.definition { --bloc-couleur: var(--lavande); }
main[data-vue="lecons"] .bloc.exemple { --bloc-couleur: var(--cyan); }
main[data-vue="lecons"] .bloc.regle { --bloc-couleur: var(--rose); }

/* Trait repassé à gauche : sa largeur varie légèrement le long du passage, ce
   qui évite l'aspect parfaitement rectiligne d'une bordure CSS classique. */
main[data-vue="lecons"] .bloc::before {
  position: absolute;
  top: 0.2rem;
  bottom: 0.2rem;
  left: 0.42rem;
  width: 0.34rem;
  background: color-mix(in srgb, var(--bloc-couleur) 76%, transparent);
  clip-path: polygon(
    39% 0, 79% 3%, 56% 17%, 84% 31%, 53% 47%,
    76% 63%, 46% 79%, 67% 94%, 31% 100%, 13% 84%,
    35% 65%, 10% 48%, 37% 29%, 17% 13%
  );
  content: "";
  filter: drop-shadow(1px 0 color-mix(in srgb, var(--bloc-couleur) 28%, transparent));
  rotate: -0.35deg;
}

main[data-vue="lecons"] .bloc > h2 {
  position: relative;
  isolation: isolate;
  width: fit-content;
  margin: 0 0 0.9rem;
  color: color-mix(in srgb, var(--bloc-couleur) 78%, var(--encre));
  font-family: var(--police-main);
  font-size: clamp(1.45rem, 2.15vw, 1.8rem);
  font-weight: 600;
  line-height: 1.2;
  rotate: -0.55deg;
}

/* Bande de feutre uniquement derrière le mot-titre. Les bords non parallèles
   imitent le passage rapide d'un surligneur sur le papier. */
main[data-vue="lecons"] .bloc > h2::before {
  position: absolute;
  z-index: -1;
  right: -0.38em;
  bottom: -0.02em;
  left: -0.24em;
  height: 0.72em;
  background: color-mix(in srgb, var(--bloc-couleur) 31%, transparent);
  clip-path: polygon(0 25%, 8% 10%, 34% 17%, 58% 7%, 83% 16%, 100% 5%, 97% 83%, 72% 92%, 43% 82%, 17% 94%, 2% 79%);
  content: "";
  rotate: -1.2deg;
}

main[data-vue="lecons"] .bloc p {
  margin: 0.65rem 0;
}

main[data-vue="lecons"] .bloc strong {
  color: color-mix(in srgb, var(--bloc-couleur) 66%, var(--encre));
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--bloc-couleur) 52%, transparent);
  text-decoration-thickness: 1.4px;
  text-underline-offset: 0.16em;
}

main[data-vue="lecons"] .contenu math {
  font-size: 1.06em;
}

main[data-vue="lecons"] .contenu math[display="block"] {
  margin-block: 0.65rem;
  font-size: 1.28em;
}

/* Les tableaux sont tracés comme des grilles repassées. Chaque jonction ne
   possède toutefois qu'un seul trait : les ombres internes créaient auparavant
   une double bordure et des raccords décalés d'un pixel. */
main[data-vue="lecons"] .contenu table {
  border: 2px solid color-mix(in srgb, var(--bloc-couleur, var(--cyan)) 72%, var(--encre-legere));
  border-collapse: collapse;
  border-spacing: 0;
  border-radius: 0.28rem 0.08rem 0.34rem 0.12rem / 0.1rem 0.3rem 0.08rem 0.25rem;
  background: transparent;
  box-shadow: 0.11rem 0.1rem 0 color-mix(in srgb, var(--bloc-couleur, var(--cyan)) 17%, transparent);
  font-size: clamp(0.9rem, 1.3vw, 1.1rem);
  rotate: 0deg;
}

main[data-vue="lecons"] .contenu :is(th, td) {
  padding: 0.62rem 0.48rem;
  border: 2px solid color-mix(in srgb, var(--bloc-couleur, var(--cyan)) 58%, var(--encre-legere));
  background: transparent;
  box-shadow: none;
  font-family: var(--police-main);
  font-size: inherit;
  font-weight: 500;
}

main[data-vue="lecons"] .contenu th.vertical {
  padding: 0.62rem 0.24rem;
  color: color-mix(in srgb, var(--bloc-couleur, var(--cyan)) 58%, var(--encre));
  font-size: 0.9em;
}

/* MathML réduit naturellement numérateur et dénominateur. Dans cet
   automatisme, on les agrandit pour que la fraction garde le même poids visuel
   que la quantité placée à côté. */
.exo :is(
  .fraction-quantite-calcul,
  .egalite-fractions-calcul,
  .addition-fractions-calcul,
  .simplification-fraction-calcul
) mfrac {
  font-size: 1.38em;
}

.exo :is(
  .fraction-quantite-calcul,
  .egalite-fractions-calcul,
  .addition-fractions-calcul,
  .simplification-fraction-calcul
) {
  column-gap: 0.08em;
}

.modele-barre.modele-fraction {
  margin-inline: auto;
}

.exo :is(.enonce, .zone-reponse, .aide, .verdict),
.visuel-question,
.visuel :is(table, .consigne) {
  font-family: var(--police-maths);
}

.exo {
  --taille-question: clamp(1.9rem, 3.2vw, 2.35rem);
  --espace-clavier: 0rem;
  position: relative;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  padding-right: var(--espace-clavier);
  padding-left: 0;
  transition:
    padding-right 320ms cubic-bezier(0.22, 1, 0.36, 1),
    padding-left 320ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Le centre utile n'est pas celui de <main> quand le clavier flotte sur un
   côté : on retranche sa largeur réelle (3 ou 4 colonnes) et un peu d'air. Le
   contenu se centre alors entre le rail et le clavier au lieu de passer dessous.
   Sur tablette, clavier-visible reste toujours posé par clavier.js. */
.exo.clavier-visible {
  --espace-clavier: 11.65rem;
}

.exo.clavier-visible:has(.clavier[data-cols="4"]) {
  --espace-clavier: 15.4rem;
}

body.gaucher .exo {
  padding-right: 0;
  padding-left: var(--espace-clavier);
}

.exo > :not(.clavier, .clavier-bascule) {
  min-width: 0;
  max-width: 100%;
}

.exo .question-texte {
  overflow-wrap: anywhere;
}

.exo .enonce-rang-consigne,
.exo .enonce-rang-nombre {
  display: block;
}

.exo .enonce-rang-consigne {
  white-space: normal;
}

.exo .enonce-rang-nombre {
  margin-top: 0.12em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Lignes sémantiques d'un énoncé : elles imposent le retour demandé et donnent
   au moteur deux surfaces indépendantes pour son écriture successive. */
.exo .enonce-ligne {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}

.exo .enonce-ligne + .enonce-ligne {
  margin-top: 0.16em;
}

@media (max-width: 720px) {
  .exo.clavier-visible {
    --espace-clavier: 10.15rem;
  }

  .exo.clavier-visible:has(.clavier[data-cols="4"]) {
    --espace-clavier: 13.4rem;
  }
}

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

.exo .enonce {
  font-size: var(--taille-question);
  font-weight: 400;
  line-height: 1.28;
}

/* La figure est indépendante du texte de la question. Le même corps est donc
   appliqué à tous les automatismes, qu'ils soient purement calculatoires ou
   accompagnés d'un dessin. */
.exo .question-texte {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  font-family: var(--police-maths);
  font-size: inherit;
  font-weight: 400;
}

/* Les phrases se dévoilent par petits pas, comme une écriture qui avance. */
.exo .ecriture-en-cours {
  animation: ecriture-question var(--duree-ecriture, 700ms)
    steps(var(--etapes-ecriture, 20), end) var(--delai-ecriture, 0ms) both;
  will-change: clip-path;
}

@keyframes ecriture-question {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0); }
}

/* Un calcul isolé suit un geste continu : les glyphes se chevauchent dans le
   temps et se posent avec une imperceptible variation de hauteur et d'angle.
   La largeur finale est réservée dès le départ, donc rien ne se décale. */
.exo .glyphe-calcul-caractere {
  display: inline-block;
}

.exo .expression-mathematique-variable.glyphe-calcul-anime {
  display: inline-block;
}

.exo .ecriture-calcul-en-cours .glyphe-calcul-anime {
  transform-origin: 50% 82%;
  animation: ecriture-glyphe-calcul var(--duree-glyphe, 255ms)
    cubic-bezier(0.2, 0.72, 0.25, 1)
    calc(var(--delai-ecriture, 0ms) + var(--retard-glyphe, 0ms)) both;
  will-change: clip-path, filter, opacity, transform;
}

@keyframes ecriture-glyphe-calcul {
  0% {
    clip-path: inset(-0.18em 100% -0.18em -0.08em);
    filter: blur(0.018em);
    opacity: 0.12;
    transform:
      translate(-0.045em, var(--levee-glyphe, 0.05em))
      rotate(var(--inclinaison-glyphe, -0.7deg))
      scale(0.975, 0.99);
  }
  38% {
    filter: blur(0.008em);
    opacity: 0.9;
  }
  74% {
    clip-path: inset(-0.18em -0.08em -0.18em -0.08em);
    filter: blur(0);
    opacity: 1;
    transform:
      translate(0.012em, -0.014em)
      rotate(0.18deg)
      scale(1.012, 0.992);
  }
  100% {
    clip-path: inset(-0.18em -0.08em -0.18em -0.08em);
    filter: blur(0);
    opacity: 1;
    transform: none;
  }
}

.exo .enonce {
  position: relative;
}

.exo .enonce.enonce-effacement .partie-en-effacement {
  animation: effacement-gomme 650ms linear forwards;
}

.exo .partie-variable {
  display: inline-block;
  width: fit-content;
  margin-inline: auto;
}

@keyframes effacement-gomme {
  from {
    clip-path: inset(0);
    opacity: 1;
  }
  to {
    clip-path: inset(0 100% 0 0);
    opacity: 0.12;
  }
}

.gomme-transition {
  position: absolute;
  top: var(--gomme-y, 48%);
  left: var(--gomme-depart-x, 50%);
  z-index: 8;
  display: block;
  width: 4.4rem;
  height: 2.9rem;
  pointer-events: none;
  visibility: hidden;
  transform: translateX(0);
  rotate: 9deg;
  will-change: transform, rotate;
  filter: drop-shadow(0.13rem 0.16rem 0 color-mix(in srgb, var(--encre) 18%, transparent));
}

.gomme-transition.gomme-en-mouvement {
  visibility: visible;
  animation: passage-gomme 650ms cubic-bezier(0.46, 0.02, 0.58, 1) forwards;
}

.gomme-transition svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.gomme-transition :is(.gomme-corps, .gomme-bout, .gomme-joint, .gomme-miette) {
  stroke: var(--encre-legere);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.gomme-transition .gomme-corps {
  fill: color-mix(in srgb, var(--rose) 52%, var(--papier));
  stroke-width: 2.1;
}

.gomme-transition .gomme-bout {
  fill: color-mix(in srgb, var(--lavande) 36%, var(--papier));
  stroke-width: 1.8;
}

.gomme-transition .gomme-joint {
  fill: none;
  stroke-width: 1.5;
}

.gomme-transition .gomme-miette {
  fill: none;
  stroke-width: 1.7;
}

@keyframes passage-gomme {
  0% {
    transform: translate(0, 0);
    rotate: 9deg;
  }
  45% { rotate: -5deg; }
  100% {
    transform: translate(
      var(--gomme-course-x, -10rem),
      var(--gomme-course-y, 0)
    );
    rotate: 4deg;
  }
}

/* Les figures utilisent leurs vrais chemins irréguliers. Le tireté ne sert ici
   qu'à révéler chacun d'eux, puis la classe est retirée pour rendre son éventuel
   style pointillé d'origine (hauteur, construction auxiliaire, etc.). */
.exo svg.trace-main-levee .trait-main-levee.construction-trait {
  /* Le vide est volontairement plus long que le chemin normalisé. Avec le
     raccourci `1` (donc `1 1`), le motif suivant recommençait exactement à
     l'extrémité du trait et certains moteurs en peignaient un petit fragment
     avant que le tracé ne parte du centre. */
  stroke-dasharray: 1 2;
  stroke-dashoffset: 1;
  animation: construire-trait 267ms ease-out var(--delai-construction, 0ms) both;
  will-change: stroke-dashoffset;
}

@keyframes construire-trait {
  to { stroke-dashoffset: 0; }
}

.exo svg.trace-main-levee .construction-detail {
  opacity: 0;
  animation: poser-details-figure 217ms ease-out var(--delai-construction, 0ms) both;
}

@keyframes poser-details-figure {
  to { opacity: 1; }
}

/* Un aplat est posé seulement après la construction de sa figure. Sur une
   roue, le moteur décale cette animation d'un secteur au suivant. */
.exo svg.trace-main-levee .construction-coloriage {
  opacity: 0;
  animation: colorier-figure 280ms ease-out var(--delai-construction, 0ms) both;
}

@keyframes colorier-figure {
  to { opacity: 1; }
}

/* Les rectangles des diagrammes en barres poussent depuis l'axe horizontal,
   dans l'ordre des catégories. */
.exo svg.trace-main-levee .frequence-barre.construction-barre {
  opacity: 0;
  transform: scaleY(0);
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: construire-barre 430ms cubic-bezier(0.22, 1, 0.36, 1)
    var(--delai-construction, 0ms) both;
  will-change: opacity, transform;
}

@keyframes construire-barre {
  to {
    opacity: 1;
    transform: scaleY(1);
  }
}

/* Le masque des pointillés reproduit strictement la montée de la barre. Il est
   invisible tant que le coloriage n'a pas commencé, puis efface la grille
   uniquement derrière la surface déjà coloriée. */
.exo svg.trace-main-levee .frequence-masque-barre.construction-masque-barre {
  opacity: 0;
  transform: scaleY(0);
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: construire-masque-barre 430ms cubic-bezier(0.22, 1, 0.36, 1)
    var(--delai-construction, 0ms) both;
  will-change: opacity, transform;
}

@keyframes construire-masque-barre {
  to {
    opacity: 1;
    transform: scaleY(1);
  }
}

/* L'opacité conserve d'emblée la largeur du tableau : aucune case ne décale la
   mise en page en apparaissant. */
.exo table :is(th, td).construction-case {
  opacity: 0;
  transform: scale(0.86) rotate(-0.7deg);
  animation: construire-case 240ms ease-out var(--delai-construction, 0ms) both;
  transform-origin: center;
}

@keyframes construire-case {
  to {
    opacity: 1;
    transform: scale(1) rotate(0deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .exo .ecriture-en-cours,
  .exo .ecriture-calcul-en-cours .glyphe-calcul-anime,
  .exo .enonce.enonce-effacement .partie-en-effacement,
  .exo .construction-trait,
  .exo .construction-detail,
  .exo .construction-barre,
  .exo .construction-case,
  .exo.reponse-juste .reponse,
  .exo.reponse-fausse .reponse,
  .exo.reponse-juste .verdict,
  .exo.reponse-fausse .verdict {
    animation: none;
  }

  .aide-visuelle:is(.apparition-visuelle, .disparition-visuelle) {
    animation: none;
  }

  .aire-quadrillage,
  .aire-rectangle-aide,
  .exo .proportionnalite-aide,
  .exo .proportionnalite-aide-trait,
  .exo .proportionnalite-aide-operation,
  .exo .tableau-croquis.tableau-croquis {
    transition: none;
  }

  .gomme-transition { display: none; }
}

.exo .question-texte:empty {
  display: none;
}

/* Les consignes des questions avec tableau ont le même corps que les autres
   énoncés ; seul le contenu du tableau reste volontairement plus compact. */
.exo .enonce .question-texte > .consigne {
  font-size: 1em;
  font-weight: 400;
  color: var(--texte);
}

.exo .enonce :is(.tabprop, .tabfonction) {
  font-size: 1.15rem;
}

/* Le champ texte suit la préférence globale. La forme mathématique d'une
   variable reste portée par sa valeur, pas par une police imposée ici. */
.exo .reponse {
  font-family: var(--police-maths);
  width: clamp(10rem, 20vw, 14rem);
  font-size: var(--taille-question);
  font-style: normal;
  font-weight: 400;
  line-height: 1.1;
  font-variant-numeric: lining-nums tabular-nums;
}

.exo .reponse:is(
  [data-type="litteral"],
  [data-type="polynome"],
  [data-type="factorisation"]
) {
  font-style: normal;
}

/* L'égalité de Pythagore est nettement plus longue qu'une réponse numérique.
   Le champ suit son contenu sur les navigateurs modernes ; le repli conserve
   une largeur confortable sans dépasser l'espace disponible sur tablette. */
.exo .reponse[data-type="egalite-pythagore"] {
  field-sizing: content;
  width: auto;
  min-width: min(18rem, 64vw);
  max-width: min(34rem, 72vw);
}

@supports not (field-sizing: content) {
  .exo .reponse[data-type="egalite-pythagore"] {
    width: min(30rem, 72vw);
  }
}

/* Repli pour une ancienne question figurative encore servie depuis un cache. */
.exo .visuel-question {
  font-size: 1em;
  font-weight: 400;
}

.contenu math,
.exo math,
.visuel math {
  font-family: var(--police-maths);
}

/* === Automatismes — contrôles dessinés sur la feuille =================== */

.bascule-visuel {
  position: relative;
  gap: 0.68rem;
  color: var(--encre-legere);
  font-family: var(--police-main);
  font-size: clamp(1.15rem, 1.45vw, 1.32rem);
  rotate: -0.6deg;
}

.bascule-visuel input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

.bascule-visuel-case {
  display: grid;
  width: 1.55rem;
  height: 1.45rem;
  place-items: center;
  border: 1.8px solid currentColor;
  border-radius: 24% 18% 28% 15% / 20% 30% 17% 27%;
  background: transparent;
  box-shadow: 0.09rem 0.11rem 0 color-mix(in srgb, currentColor 18%, transparent);
  rotate: -2deg;
}

.bascule-visuel-case svg {
  width: 1.3rem;
  height: 1.3rem;
  overflow: visible;
}

.bascule-visuel-case path {
  fill: none;
  stroke: var(--cyan);
  stroke-dasharray: 28;
  stroke-dashoffset: 28;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.5;
  transition: stroke-dashoffset 170ms ease;
}

.bascule-visuel input:checked + .bascule-visuel-case {
  border-color: var(--cyan);
  color: var(--cyan);
  rotate: 1.5deg;
}

.bascule-visuel input:checked + .bascule-visuel-case path {
  stroke-dashoffset: 0;
}

.bascule-visuel input:focus-visible + .bascule-visuel-case {
  outline: 1.5px solid var(--lavande);
  outline-offset: 0.22rem;
}

.exo .reponse {
  width: clamp(10.5rem, 19vw, 14.5rem);
  padding: 0.42rem 0.75rem 0.34rem;
  border: 0;
  border-radius: 1.1rem 1.35rem 1rem 1.28rem / 0.78rem 1rem 0.72rem 0.94rem;
  background: transparent;
  box-shadow: none;
  outline: none;
  text-align: center;
  rotate: -0.65deg;
  transition:
    background-color 130ms ease,
    color 130ms ease,
    rotate 130ms ease;
}

.exo .reponse:focus {
  box-shadow: none;
  rotate: 0.25deg;
}

/* Les colonnes latérales restent toujours symétriques : l'aperçu occupe celle
   de droite sans jamais décaler le champ situé exactement au centre. */
.exo .zone-reponse {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  column-gap: 0.75rem;
}

/* Le champ natif ne permet pas de déformer ses pointillés. Son unique contour
   est donc un chemin irrégulier, avec des tirets de longueurs volontairement
   inégales. Le surligneur vit derrière ce cadre pour pouvoir en dépasser. */
.exo .cadre-reponse {
  position: relative;
  grid-column: 2;
  display: inline-grid;
  place-items: center;
  isolation: isolate;
  color: var(--encre);
}

.exo .apercu-reponse {
  grid-column: 3;
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: 0.14em;
  width: fit-content;
  color: var(--cyan);
  font-family: var(--police-maths);
  font-size: var(--taille-question);
  font-weight: 400;
  line-height: 1.1;
  text-align: left;
  white-space: nowrap;
  rotate: -0.45deg;
}

.exo .apercu-reponse .symbole-mathematique-environ {
  width: 0.78em;
  height: 0.78em;
}

.exo .apercu-reponse[hidden] {
  display: none;
}

.exo .cadre-reponse .reponse {
  position: relative;
  z-index: 1;
  caret-color: transparent;
}

/* Sur tablette, la saisie passe par le clavier virtuel : le caret natif ne doit
   pas apparaître au milieu de la réponse dessinée. On le conserve uniquement
   sur les interfaces qui disposent d'une souris ou d'un trackpad. */
@media (hover: hover) and (pointer: fine) {
  .exo .cadre-reponse .reponse {
    caret-color: var(--encre);
  }
}

.exo .saisie-mathematique-dessinee {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--couleur-retour, var(--encre));
  font-family: var(--police-maths);
  font-size: var(--taille-question);
  font-style: normal;
  font-weight: 400;
  font-variant-numeric: lining-nums tabular-nums;
  line-height: 1.1;
  white-space: pre;
  pointer-events: none;
  rotate: -0.65deg;
}

.exo .saisie-mathematique-dessinee .symbole-mathematique-dessine {
  position: absolute;
  left: 50%;
  top: 50%;
  margin: 0;
  translate: -50% -50%;
}

/* Le centre optique du x cursif est légèrement sous le centre de sa boîte SVG.
   On le recale uniquement dans le miroir de l'input, sans toucher au texte. */
.exo .saisie-mathematique-dessinee .symbole-mathematique-variable-x {
  translate: -50% calc(-50% + 0.08em);
}

.exo .saisie-mathematique-symbole {
  position: relative;
  display: inline-block;
}

.exo .saisie-mathematique-chasse {
  visibility: hidden;
}

/* Les glyphes Unicode d'exposant n'ont pas tous la même ligne de base dans la
   police manuscrite (notamment ⁻ et les chiffres). Le miroir garde leur chasse
   invisible pour le caret, mais dessine une seule ligne d'exposant homogène. */
.exo .saisie-mathematique-exposant {
  position: relative;
  display: inline-block;
}

.exo .saisie-mathematique-exposant-visible {
  position: absolute;
  left: 50%;
  bottom: 0.82em;
  display: inline-flex;
  align-items: center;
  font-size: 0.62em;
  line-height: 1;
  translate: -50% 0;
}

.exo .saisie-mathematique-exposant-negatif
  .saisie-mathematique-exposant-visible {
  translate: calc(-50% - 0.16em) 0;
}

.exo .saisie-mathematique-exposant-visible .symbole-mathematique-dessine {
  position: static;
  margin-inline: 0.04em;
  translate: none;
}

.exo .cadre-reponse.a-saisie-mathematique-dessinee .reponse {
  color: transparent !important;
  -webkit-text-fill-color: transparent !important;
}

.exo.reponse-juste .cadre-reponse.a-saisie-mathematique-dessinee .reponse,
.exo.reponse-fausse .cadre-reponse.a-saisie-mathematique-dessinee .reponse {
  animation: none;
}

.exo.reponse-juste .cadre-reponse.a-saisie-mathematique-dessinee
  .saisie-mathematique-dessinee {
  /* Le surligneur et la couleur donnent déjà le retour positif. Le miroir reste
     immobile pour que la réponse ne saute pas verticalement à la validation. */
  animation: none;
}

.exo.reponse-fausse .cadre-reponse.a-saisie-mathematique-dessinee
  .saisie-mathematique-dessinee {
  animation: refus-reponse 480ms ease-in-out both;
}

.exo.retour-disparition .cadre-reponse.a-saisie-mathematique-dessinee
  .saisie-mathematique-dessinee {
  animation: estomper-couleur-reponse var(--duree-disparition-retour) ease-in forwards;
}

.exo .cadre-reponse-trace {
  position: absolute;
  z-index: 2;
  inset: -0.16rem -0.22rem -0.18rem -0.2rem;
  width: calc(100% + 0.42rem);
  height: calc(100% + 0.34rem);
  overflow: visible;
  pointer-events: none;
}

.exo .cadre-reponse-trace path {
  fill: none;
  stroke: currentColor;
  stroke-dasharray: 14 7 8 9 17 6;
  stroke-dashoffset: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.2;
  vector-effect: non-scaling-stroke;
}

.exo .cadre-reponse::before {
  position: absolute;
  z-index: -1;
  inset: -0.22rem -0.62rem -0.18rem -0.55rem;
  border-radius: 1.15rem 1.48rem 1.06rem 1.35rem / 0.74rem 1.08rem 0.7rem 0.96rem;
  clip-path: polygon(
    1% 17%, 7% 8%, 22% 11%, 39% 5%, 58% 9%, 76% 4%, 94% 11%,
    100% 25%, 97% 44%, 100% 64%, 95% 87%, 83% 95%, 65% 91%,
    47% 97%, 29% 92%, 12% 96%, 2% 82%, 5% 61%, 0 39%
  );
  content: "";
  opacity: 0;
  pointer-events: none;
  transform: scaleX(0) rotate(-0.6deg);
  transform-origin: left center;
}

/* Correction immédiate : la couleur reste jusqu'à la question suivante et le
   contour reproduit un petit geste de crayon. La réussite rebondit doucement ;
   l'erreur tremble latéralement, donc les deux retours ne reposent pas seulement
   sur le rouge et le vert. */
.exo.reponse-juste .reponse {
  background-color: transparent;
  background-image: none;
  box-shadow: none;
  color: var(--cyan);
  -webkit-text-fill-color: var(--cyan);
  animation: confirmation-reponse 560ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.exo.reponse-fausse .reponse {
  background-color: transparent;
  background-image: none;
  box-shadow: none;
  color: var(--rouge);
  -webkit-text-fill-color: var(--rouge);
  animation: refus-reponse 480ms ease-in-out both;
}

.exo.reponse-juste .cadre-reponse::before {
  background: color-mix(in srgb, var(--cyan) 16%, transparent);
  animation: surligner-reponse 430ms cubic-bezier(0.24, 0.7, 0.36, 1) both;
}

.exo.reponse-fausse .cadre-reponse::before {
  background: color-mix(in srgb, var(--rouge) 14%, transparent);
  animation: surligner-reponse 430ms cubic-bezier(0.24, 0.7, 0.36, 1) both;
}

.exo.reponse-juste .verdict,
.exo.reponse-fausse .verdict {
  animation: apparition-verdict 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.exo .verdict-texte {
  display: inline-block;
  width: fit-content;
  max-width: 100%;
}

/* Le verdict se révèle lettre après lettre tout en conservant le léger rebond
   qui signale immédiatement qu'une réponse vient d'être évaluée. */
.exo:is(.reponse-juste, .reponse-fausse) .verdict-texte.ecriture-en-cours {
  animation:
    ecriture-question var(--duree-ecriture, 700ms)
      steps(var(--etapes-ecriture, 20), end) both,
    apparition-verdict 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
  will-change: clip-path, opacity, translate;
}

.exo.reponse-fausse .verdict {
  min-height: 2.5rem;
  font-family: var(--police-main);
  font-size: clamp(1.3rem, 2.2vw, 1.7rem);
  font-weight: 600;
  line-height: 1.2;
}

@keyframes confirmation-reponse {
  0%, 100% {
    scale: 1;
    rotate: -0.65deg;
  }
  32% {
    scale: 1.055;
    rotate: 1.1deg;
  }
  62% {
    scale: 0.985;
    rotate: -1deg;
  }
}

@keyframes refus-reponse {
  0%, 100% {
    translate: 0;
    rotate: -0.65deg;
  }
  18% { translate: -0.48rem; rotate: -1.4deg; }
  36% { translate: 0.42rem; rotate: 1.2deg; }
  54% { translate: -0.28rem; rotate: -1deg; }
  72% { translate: 0.18rem; rotate: 0.7deg; }
}

@keyframes surligner-reponse {
  from {
    opacity: 0.45;
    transform: scaleX(0.015) rotate(-0.6deg);
  }
  to {
    opacity: 1;
    transform: scaleX(1) rotate(-0.6deg);
  }
}

@keyframes apparition-verdict {
  from {
    opacity: 0;
    translate: 0 0.45rem;
    scale: 0.92;
  }
  to {
    opacity: 1;
    translate: 0;
    scale: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .exo.reponse-juste .reponse,
  .exo.reponse-fausse .reponse,
  .exo:is(.reponse-juste, .reponse-fausse) .saisie-mathematique-dessinee,
  .exo:is(.reponse-juste, .reponse-fausse) .cadre-reponse::before,
  .exo:is(.reponse-juste, .reponse-fausse) .verdict-texte.ecriture-en-cours {
    animation: none;
  }
}

.exo .verdict.juste {
  min-height: 2.5rem;
  font-family: var(--police-main);
  font-size: clamp(1.55rem, 2.6vw, 2rem);
  font-weight: 600;
  line-height: 1.2;
}

.exo .valider {
  --couleur-validation: color-mix(in srgb, var(--lavande) 78%, var(--encre));
  /* Le bouton reste prêt à être réactivé pour les réponses manipulées dans une
     figure. Les automatismes à saisie utilisent le clavier ou la touche Entrée. */
  position: relative;
  isolation: isolate;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 7.4rem;
  padding: 0.62rem 1rem 0.68rem;
  border: 0;
  border-radius: 0.34rem 0.2rem 0.4rem 0.24rem / 0.22rem 0.38rem 0.2rem 0.34rem;
  background: transparent;
  box-shadow: none;
  color: var(--couleur-validation);
  font-family: var(--police-main);
  font-size: 1.13rem;
  font-weight: 600;
  line-height: 1.15;
  rotate: -0.45deg;
  transition: color 150ms ease, translate 150ms ease, rotate 150ms ease;
}

/* Deux contours presque superposés remplacent le cadre SVG dynamique de la
   page Base de données, avec le même effet de trait repassé à la main. */
.exo .valider::before,
.exo .valider::after {
  position: absolute;
  z-index: -1;
  content: "";
  pointer-events: none;
}

.exo .valider::before {
  inset: 0.08rem 0.06rem 0.04rem;
  border: 1.8px solid currentColor;
  border-radius: 0.44rem 0.25rem 0.48rem 0.3rem / 0.3rem 0.46rem 0.26rem 0.42rem;
  background: color-mix(in srgb, var(--lavande) 9%, var(--fond-secondaire));
  opacity: 0.88;
  rotate: 0.35deg;
}

.exo .valider::after {
  inset: 0.15rem 0.11rem 0.1rem 0.14rem;
  border: 0.75px solid color-mix(in srgb, currentColor 52%, transparent);
  border-radius: 0.3rem 0.46rem 0.27rem 0.42rem / 0.44rem 0.27rem 0.4rem 0.25rem;
  rotate: -0.55deg;
}

.exo .valider:is(:hover, :focus-visible) {
  background: transparent;
  color: var(--lavande);
  translate: 0 -0.1rem;
  rotate: -0.9deg;
}

.exo .valider:focus-visible {
  outline: 2px dashed var(--lavande);
  outline-offset: 3px;
}

.exo .valider:active {
  translate: 0.05rem 0.04rem;
  rotate: -0.15deg;
}

.exo.reponse-juste { --couleur-retour: var(--cyan); }
.exo.reponse-fausse { --couleur-retour: var(--rouge); }
.exo.reponse-juste .valider { --couleur-envoi: var(--cyan); }
.exo.reponse-fausse .valider { --couleur-envoi: var(--rouge); }

/* Même teinte, même durée d'installation et même persistance que l'input : le
   bouton garde la couleur du verdict jusqu'au changement de question. */
.exo.reponse-juste .valider.valider-envoi {
  animation: colorer-validation-juste 560ms cubic-bezier(0.22, 1, 0.36, 1) both;
  will-change: color;
}

.exo.reponse-fausse .valider.valider-envoi {
  animation: colorer-validation-fausse 480ms ease-in-out both;
  will-change: color;
}

@keyframes colorer-validation-juste {
  from { color: var(--couleur-validation); }
  to { color: var(--cyan); }
}

@keyframes colorer-validation-fausse {
  from { color: var(--couleur-validation); }
  to { color: var(--rouge); }
}

@media (prefers-reduced-motion: reduce) {
  .exo .valider.valider-envoi {
    animation: none;
    color: var(--couleur-envoi, var(--couleur-validation));
  }
}

/* La gomme déclenche un fondu commun à tous les retours de correction. Les
   quatre transitions ont exactement la même durée pour disparaître comme un
   seul geste, sans rupture juste avant l'affichage de la question suivante. */
.exo.retour-disparition {
  --duree-disparition-retour: 420ms;
}

.exo.retour-disparition .reponse {
  animation: estomper-couleur-reponse var(--duree-disparition-retour) ease-in forwards;
}

.exo.retour-disparition .cadre-reponse::before {
  animation: estomper-surlignage-reponse var(--duree-disparition-retour) ease-in forwards;
}

.exo.retour-disparition .verdict {
  animation: estomper-verdict var(--duree-disparition-retour) ease-in forwards;
}

.exo.retour-disparition .valider.valider-envoi {
  animation: estomper-couleur-validation var(--duree-disparition-retour) ease-in forwards;
}

@keyframes estomper-couleur-reponse {
  from {
    color: var(--couleur-retour);
    -webkit-text-fill-color: var(--couleur-retour);
  }
  to {
    color: var(--encre);
    -webkit-text-fill-color: var(--encre);
  }
}

@keyframes estomper-surlignage-reponse {
  from {
    opacity: 1;
    transform: scaleX(1) rotate(-0.6deg);
  }
  to {
    opacity: 0;
    transform: scaleX(1) rotate(-0.6deg);
  }
}

@keyframes estomper-verdict {
  from {
    opacity: 1;
    translate: 0;
    scale: 1;
  }
  to {
    opacity: 0;
    translate: 0 0.18rem;
    scale: 0.985;
  }
}

@keyframes estomper-couleur-validation {
  from { color: var(--couleur-envoi); }
  to { color: var(--couleur-validation); }
}

.clavier-touche {
  position: relative;
  border: 1.7px solid color-mix(in srgb, var(--encre-legere) 72%, var(--lavande));
  border-radius: 45% 55% 42% 58% / 56% 43% 57% 44%;
  background: transparent;
  box-shadow:
    0.1rem 0.13rem 0 color-mix(in srgb, var(--encre-legere) 18%, transparent),
    inset 0.04rem -0.05rem 0 color-mix(in srgb, var(--encre-legere) 10%, transparent);
  color: var(--encre);
  font-family: var(--police-main);
  font-weight: 500;
  rotate: -0.8deg;
  transform: none;
  transition: translate 90ms ease, rotate 90ms ease, background-color 90ms ease;
  /* Safari interprète sinon deux frappes rapides comme un double-tap de zoom.
     `manipulation` retire ce geste sans interdire le zoom volontaire à deux
     doigts ni le défilement de la page. */
  touch-action: manipulation;
}

.clavier-ligne:nth-child(even) .clavier-touche {
  rotate: 0.65deg;
}

.clavier-touche:nth-child(even) {
  border-radius: 54% 46% 57% 43% / 44% 56% 42% 58%;
  rotate: 0.4deg;
}

.clavier-touche:hover {
  transform: none;
  translate: 0 -0.1rem;
  rotate: -1.8deg;
}

.clavier-touche:active {
  background: color-mix(in srgb, var(--lavande) 13%, transparent);
  box-shadow: 0.04rem 0.06rem 0 color-mix(in srgb, var(--encre-legere) 18%, transparent);
  translate: 0.05rem 0.07rem;
  rotate: 1deg;
}

.clavier-touche.large {
  border-color: var(--lavande);
  border-radius: 2.2rem 1.45rem 2rem 1.3rem / 1.25rem 2rem 1.35rem 1.9rem;
  background: color-mix(in srgb, var(--lavande) 8%, transparent);
  color: var(--lavande);
  font-family: var(--police-main);
  font-size: 1.12rem;
  font-weight: 600;
}

/* Les autres aides visuelles gardent leur géométrie pédagogique, mais perdent
   l'aspect de composant informatique : papier visible et tracés légèrement
   inclinés comme sur un schéma fait à la main. */
.exo .visuel :is(.modele-barre, .num-table) {
  rotate: -0.25deg;
}

.exo .visuel :is(.modele-barre, .num-table) :is(td, th) {
  border-color: color-mix(in srgb, var(--encre-legere) 64%, transparent);
}

.exo .visuel :is(.modele-barre td, .num-table th) {
  background: transparent;
}

.exo .visuel .modele-barre .mb-part {
  --couleur-remplissage-case: var(--part-couleur);

  background: transparent;
}

/* Tableaux pédagogiques : grands chiffres et lignes repassées au crayon. */
.exo .enonce :is(.tabprop, .tabfonction) {
  border: 2.1px solid color-mix(in srgb, var(--encre) 88%, transparent);
  border-collapse: separate;
  border-spacing: 0;
  border-radius: 0.3rem 0.12rem 0.26rem 0.08rem / 0.12rem 0.28rem 0.1rem 0.25rem;
  box-shadow:
    0.12rem 0.1rem 0 color-mix(in srgb, var(--encre-legere) 20%, transparent),
    inset 0.08rem -0.06rem 0 color-mix(in srgb, var(--encre-legere) 17%, transparent);
  font-size: clamp(1.5rem, 2.5vw, 1.85rem);
  rotate: -0.2deg;
}

.exo .enonce :is(.tabprop, .tabfonction) :is(td, th) {
  min-width: clamp(4.3rem, 8vw, 6.6rem);
  padding: 0.72rem 1.1rem;
  border: 0;
  border-right: 2px solid color-mix(in srgb, var(--encre) 84%, transparent);
  border-bottom: 2px solid color-mix(in srgb, var(--encre) 84%, transparent);
  box-shadow: inset -0.07rem -0.05rem 0 color-mix(in srgb, var(--encre-legere) 15%, transparent);
  font-size: inherit;
  font-weight: 500;
}

.exo .enonce :is(.tabprop, .tabfonction) tr > :last-child {
  border-right: 0;
}

.exo .enonce :is(.tabprop, .tabfonction) tr:last-child > * {
  border-bottom: 0;
}

/* Les tableaux d'énoncé partagent désormais le même calque de traits courbes
   que les modèles visuels. Le HTML garde les dimensions et le sens du tableau ;
   le SVG superposé se charge uniquement de son contour manuscrit. */
.tableau-croquis.tableau-croquis {
  position: relative;
  width: fit-content;
  margin-inline: auto;
  rotate: -0.16deg;
}

/* Safari change sinon brièvement le mode de rastérisation des chiffres au
   début et à la fin du glissement. Ce seul tableau garde donc son calque 3D
   avant, pendant et après l'animation. */
.tableau-croquis.tableau-croquis:has(.proportionnalite-aide) {
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  will-change: transform;
}

.tableau-croquis.tableau-croquis :is(.tabprop, .tabfonction, .num-table) {
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  rotate: 0deg;
}

.tableau-croquis.tableau-croquis :is(.tabprop, .tabfonction, .num-table) :is(td, th) {
  position: relative;
  border: 0;
  box-shadow: none;
}

.tableau-croquis.tableau-croquis .traces-modele-barre {
  z-index: 2;
}

/* Aide du tableau de proportionnalité : une flèche manuscrite désigne le
   passage le plus simple sans révéler son coefficient. Le calque est déjà lié
   aux bonnes lignes ou colonnes ; le mode visuel ne fait que le dévoiler. */
.exo:has(.proportionnalite-aide-horizontale) {
  --espace-aide-proportionnalite: 6rem;
  --depart-aide-proportionnalite: -6rem;
}

.exo:has(.proportionnalite-aide-horizontale.distance-2) {
  --espace-aide-proportionnalite: 7rem;
  --depart-aide-proportionnalite: -7rem;
}

.exo:has(.proportionnalite-aide-horizontale.distance-3) {
  --espace-aide-proportionnalite: 8rem;
  --depart-aide-proportionnalite: -8rem;
}

.proportionnalite-aide {
  position: absolute;
  z-index: 3;
  display: grid;
  opacity: 0;
  color: var(--lavande);
  pointer-events: none;
  place-items: center;
  transition: opacity 120ms ease-out 260ms;
}

.proportionnalite-aide > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.proportionnalite-aide-trait {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.15;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Le léger dépassement garantit que Safari peint aussi l'extrémité de la
     dernière branche, sans dévoiler le trait avant le début de l'animation. */
  stroke-dasharray: 1.01;
  stroke-dashoffset: 1.01;
  vector-effect: non-scaling-stroke;
  transition: stroke-dashoffset 470ms linear;
}

.proportionnalite-aide-operation {
  position: absolute;
  z-index: 1;
  display: inline-flex;
  align-items: baseline;
  gap: 0.2em;
  padding-inline: 0.15em;
  border-radius: 0.3rem;
  background: var(--fond);
  font-family: var(--police-main);
  font-size: 1.15rem;
  font-weight: 650;
  line-height: 1.25;
  white-space: nowrap;
  text-align: center;
  opacity: 0;
  transition: opacity 160ms ease-out;
}

.proportionnalite-aide-operation.operation-multiplier::before {
  content: "×";
}

.proportionnalite-aide-operation.operation-diviser::before {
  content: "÷";
}

.proportionnalite-aide-horizontale {
  left: var(--aide-gauche);
  width: var(--aide-largeur);
  height: 4rem;
}

/* Le chemin horizontal repasse par la pointe avant d'en tracer la seconde
   branche. Une réserve large garantit que sa normalisation reste suffisante
   après l'étirement produit par preserveAspectRatio="none". */
.proportionnalite-aide-horizontale .proportionnalite-aide-trait {
  stroke-dasharray: 2;
  stroke-dashoffset: 2;
}

.proportionnalite-aide-horizontale.distance-2 {
  height: 5rem;
}

.proportionnalite-aide-horizontale.distance-3 {
  height: 6rem;
}

.proportionnalite-aide-horizontale.sur-haut {
  bottom: calc(100% + 0.25rem);
}

.proportionnalite-aide-horizontale.sur-bas {
  top: calc(100% + 0.18rem);
}

.proportionnalite-aide-horizontale.sur-bas > svg {
  transform: scaleY(-1);
}

.proportionnalite-aide-horizontale.sur-haut
  .proportionnalite-aide-operation {
  right: 50%;
  bottom: calc(100% + 0.08rem);
  translate: 50% 0;
}

.proportionnalite-aide-horizontale.sur-bas
  .proportionnalite-aide-operation {
  top: calc(100% + 0.08rem);
  left: 50%;
  translate: -50% 0;
}

.proportionnalite-aide-verticale {
  top: 20%;
  left: calc(100% + 0.2rem);
  width: 3.25rem;
  height: 60%;
}

.proportionnalite-aide-verticale .proportionnalite-aide-operation {
  top: 50%;
  left: calc(100% + 0.08rem);
  translate: 0 -50%;
}

.enonce:has(
  .aide-visuelle:not(.disparition-visuelle)
  .proportionnalite-aide-marqueur
) .proportionnalite-aide {
  opacity: 1;
  transition-delay: 0ms;
}

.enonce:has(
  .aide-visuelle:not(.disparition-visuelle)
  .proportionnalite-aide-marqueur
) .proportionnalite-aide-trait {
  stroke-dashoffset: 0;
}

.enonce:has(
  .aide-visuelle:not(.disparition-visuelle)
  .proportionnalite-aide-marqueur
) .proportionnalite-aide-operation {
  opacity: 1;
  transition-delay: 500ms;
}

.enonce:has(
  .aide-visuelle:not(.disparition-visuelle)
  .proportionnalite-aide-marqueur
) .tableau-croquis:has(.proportionnalite-aide-horizontale.sur-haut) {
  margin-block-start: var(--espace-aide-proportionnalite);
  animation: glisser-aide-proportionnalite 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.enonce:has(
  .aide-visuelle:not(.disparition-visuelle)
  .proportionnalite-aide-marqueur
) .tableau-croquis:has(.proportionnalite-aide-horizontale.sur-bas) {
  margin-block-end: var(--espace-aide-proportionnalite);
}

/* La place de la flèche est réservée immédiatement, puis le tableau et la zone
   de réponse glissent sur leur propre calque. Les chiffres ne sont ainsi plus
   recalculés à chaque valeur fractionnaire d'une marge animée. */
.enonce:has(
  .aide-visuelle:not(.disparition-visuelle)
  .proportionnalite-aide-marqueur
):has(.proportionnalite-aide-horizontale) + .zone-reponse {
  animation: glisser-aide-proportionnalite 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.enonce:has(
  .aide-visuelle.disparition-visuelle
  .proportionnalite-aide-marqueur
) .tableau-croquis:has(.proportionnalite-aide-horizontale.sur-haut) {
  margin-block-start: var(--espace-aide-proportionnalite);
  animation: ranger-aide-proportionnalite 360ms ease-in both;
}

.enonce:has(
  .aide-visuelle.disparition-visuelle
  .proportionnalite-aide-marqueur
) .tableau-croquis:has(.proportionnalite-aide-horizontale.sur-bas) {
  margin-block-end: var(--espace-aide-proportionnalite);
}

.enonce:has(
  .aide-visuelle.disparition-visuelle
  .proportionnalite-aide-marqueur
):has(.proportionnalite-aide-horizontale) + .zone-reponse {
  animation: ranger-aide-proportionnalite 360ms ease-in both;
}

@keyframes glisser-aide-proportionnalite {
  from { transform: translate3d(0, var(--depart-aide-proportionnalite), 0); }
  to { transform: translate3d(0, 0, 0); }
}

@keyframes ranger-aide-proportionnalite {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(0, var(--depart-aide-proportionnalite), 0); }
}

@media (prefers-reduced-motion: reduce) {
  .exo .enonce:has(.proportionnalite-aide-horizontale)
    :is(.tableau-croquis),
  .exo .enonce:has(.proportionnalite-aide-horizontale) + .zone-reponse {
    animation: none;
  }
}

.aide-visuelle:has(.proportionnalite-aide-marqueur) {
  display: contents;
}

@media (max-width: 600px) {
  .exo .enonce .tableau-croquis .tabprop td {
    min-width: clamp(2.6rem, 14vw, 3.4rem);
    padding-inline: clamp(0.45rem, 2vw, 0.75rem);
  }

  .proportionnalite-aide-verticale {
    left: calc(100% + 0.08rem);
    width: 2.75rem;
  }

  .enonce:has(
    .aide-visuelle:not(.disparition-visuelle)
    .proportionnalite-aide-marqueur
  ) .tableau-croquis:has(.proportionnalite-aide-verticale) {
    translate: -2rem 0;
  }
}

/* Tableaux des leçons : les cellules HTML assurent toujours la
   mise en page et l'accessibilité, mais leurs bordures sont remplacées par un
   calque SVG ajusté à leur géométrie réelle (colspan et rowspan compris). */
.tableau-contenu-croquis.tableau-contenu-croquis {
  width: 100%;
  max-width: 100%;
  margin: 1rem 0;
  color: color-mix(in srgb, var(--encre) 90%, transparent);
}

.tableau-contenu-croquis.tableau-contenu-croquis > table {
  width: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  color: var(--texte);
  box-shadow: none;
}

.tableau-contenu-croquis.tableau-contenu-croquis > table :is(th, td) {
  border: 0;
}

/* Les règles historiques des pages de leçon ont une spécificité supérieure
   aux styles génériques du composant. On neutralise explicitement leur ancien
   contour coloré et leurs bordures de cellules sous le calque manuscrit. */
main[data-vue="lecons"] .contenu
  .tableau-contenu-croquis.tableau-contenu-croquis > table {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

main[data-vue="lecons"] .contenu
  .tableau-contenu-croquis.tableau-contenu-croquis > table :is(th, td) {
  border: 0;
}

main[data-vue="lecons"] .contenu
  .tableau-contenu-croquis.tableau-contenu-croquis > table th.vertical {
  color: var(--encre);
}

.traces-tableau-contenu {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.traces-tableau-contenu .tableau-contenu-trait {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.35;
}

/* Tableau de numération : même calque de traits courbes que les tableaux de
   proportionnalité, avec une première rangée plus haute pour les noms de rangs. */
.glisse-nombre {
  display: grid;
  grid-template-columns: 3.4rem minmax(0, 1fr) 3.4rem;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  margin-inline: auto;
}

.glisse-commande {
  display: grid;
  width: 3.4rem;
  height: 3.4rem;
  padding: 0;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--lavande);
  cursor: pointer;
  transition: opacity 140ms ease, translate 140ms ease;
}

.glisse-commande .glisse-fleche {
  width: 3.1rem;
  height: 1.8rem;
  overflow: visible;
  rotate: -2deg;
}

.glisse-commande .glisse-fleche path {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.glisse-commande .glisse-fleche .trait-main-levee {
  stroke-width: 2.3;
}

.glisse-commande .glisse-fleche .trace-reprise {
  stroke-width: 0.9;
  opacity: 0.28;
}

.glisse-commande:is(:hover, :focus-visible):not(:disabled) {
  color: var(--cyan);
  translate: 0 -0.1rem;
}

.glisse-commande:focus-visible {
  outline: 2px solid var(--lavande);
  outline-offset: 2px;
  border-radius: 48% 52% 43% 57% / 54% 45% 55% 46%;
}

.glisse-commande:disabled {
  opacity: 0.25;
  cursor: default;
}

.tableau-numeration-croquis.tableau-numeration-croquis .num-table {
  width: 100%;
  table-layout: fixed;
}

.tableau-numeration-croquis.tableau-numeration-croquis {
  width: 100%;
}

.tableau-numeration-croquis.tableau-numeration-croquis .num-table :is(th, td) {
  width: 10%;
  min-width: 0;
  padding-inline: 0.25rem;
  box-sizing: border-box;
  background: transparent;
  font-family: var(--police-main);
}

.tableau-numeration-croquis.tableau-numeration-croquis .num-table th {
  height: 7.1rem;
  padding-block: 0.4rem;
  vertical-align: middle;
}

.tableau-numeration-croquis.tableau-numeration-croquis .num-table th .v {
  height: 6.25rem;
  padding: 0.3rem 0;
  box-sizing: border-box;
  color: var(--texte-secondaire);
  font-size: clamp(1rem, 1.55vw, 1.16rem);
  font-weight: 500;
  line-height: 1.05;
}

.tableau-numeration-croquis.tableau-numeration-croquis .num-table td {
  height: 4rem;
  padding-block: 0.35rem;
  color: var(--texte);
  font-size: clamp(1.9rem, 3vw, 2.25rem);
  font-weight: 600;
}

.tableau-numeration-croquis .glisse-jeton {
  display: flex;
  align-items: baseline;
  justify-content: center;
  width: 100%;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  will-change: transform;
}

.tableau-numeration-croquis .glisse-jeton.est-glisse {
  z-index: 3;
  color: var(--lavande);
  cursor: grabbing;
  scale: 1.08;
}

.glisse-nombre.glisse-en-cours .tableau-numeration-croquis {
  cursor: grabbing;
}

.tableau-numeration-croquis .glisse-jeton > span {
  display: inline-block;
  width: 1ch;
  text-align: center;
}

/* Addition posée de décimaux : les deux nombres partagent le tableau, mais
   chaque rangée possède ses propres commandes et sa propre prise tactile. */
.addition-decimaux-glisse {
  display: grid;
  grid-template-columns: 3.4rem minmax(0, 1fr) 3.4rem;
  grid-template-rows: 7.1rem repeat(2, 4rem);
  gap: 0 0.7rem;
  align-items: center;
  width: min(34rem, 100%);
  margin-inline: auto;
}

.addition-decimaux-tableau-croquis.tableau-croquis {
  grid-column: 2;
  grid-row: 1 / -1;
  align-self: stretch;
}

.addition-decimaux-tableau-croquis.tableau-numeration-croquis
  .num-table :is(th, td) {
  width: 20%;
}

.addition-decimaux-tableau-croquis.tableau-numeration-croquis
  .num-table th {
  height: 7.1rem;
}

.addition-decimaux-tableau-croquis.tableau-numeration-croquis
  .num-table th .v {
  height: 6.25rem;
}

.addition-decimaux-glisse
  .glisse-commande[data-glisse-cible="terme-0"] {
  grid-row: 2;
}

.addition-decimaux-glisse
  .glisse-commande[data-glisse-cible="terme-1"] {
  grid-row: 3;
}

.addition-decimaux-glisse .glisse-gauche {
  grid-column: 1;
}

.addition-decimaux-glisse .glisse-droite {
  grid-column: 3;
}

.addition-decimaux-ligne.glisse-en-cours {
  cursor: grabbing;
}

.addition-decimaux-signe {
  position: absolute;
  z-index: 3;
  top: calc(5.7rem + 6rem);
  left: -1.05rem;
  color: var(--encre);
  font-family: var(--police-main);
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1;
  translate: 0 -50%;
  rotate: -2deg;
}

/* Conversion de longueurs : même glisse-nombre, ramené aux sept colonnes du
   système métrique. Les zéros ajoutés par l'élève gardent une couleur propre
   pour ne jamais être confondus avec les chiffres de la donnée. */
.tableau-conversion-longueur-croquis.tableau-conversion-longueur-croquis .num-table :is(th, td),
.tableau-conversion-aire-croquis.tableau-conversion-aire-croquis .num-table th {
  width: calc(100% / 7);
}

.tableau-conversion-aire-croquis.tableau-conversion-aire-croquis .num-table td {
  width: calc(100% / 14);
  padding-inline: 0.1rem;
  font-size: clamp(1.55rem, 2.4vw, 2rem);
}

.tableau-conversion-croquis.tableau-conversion-croquis .num-table th {
  height: 4.5rem;
}

.tableau-conversion-croquis.tableau-conversion-croquis .num-table th span {
  color: var(--texte-secondaire);
  font-size: clamp(1.25rem, 2vw, 1.55rem);
  font-weight: 600;
}

.tableau-conversion-croquis .num-table .conversion-source {
  background: color-mix(in srgb, var(--cyan) 8%, transparent);
}

.tableau-conversion-croquis .num-table .conversion-cible {
  background: color-mix(in srgb, var(--lavande) 10%, transparent);
}

.tableau-conversion-croquis .num-table th.conversion-source span {
  color: var(--cyan);
}

.tableau-conversion-croquis .num-table th.conversion-cible span {
  color: var(--lavande);
}

.conversion-metrique-aide {
  margin: 0 0 0.65rem;
  color: var(--texte-secondaire);
  font-size: 0.82em;
}

[data-glisse-zero-case][aria-disabled="false"] {
  cursor: pointer;
  touch-action: manipulation;
}

[data-glisse-zero-case]:focus-visible {
  outline: 2px solid var(--lavande);
  outline-offset: -0.35rem;
}

.glisse-zero-aide {
  display: inline-block;
  width: 1ch;
  color: var(--rose);
  font-family: var(--police-main);
  font-weight: 600;
  text-align: center;
  rotate: -3deg;
  animation: apparition-zero-aide 180ms ease-out both;
}

@keyframes apparition-zero-aide {
  from {
    opacity: 0;
    scale: 0.72;
  }
}

.exo .visuel .modele-barre {
  border: 2.25px solid color-mix(in srgb, var(--encre) 92%, transparent);
  border-collapse: separate;
  border-spacing: 0;
  border-radius: 0.32rem 0.08rem 0.38rem 0.12rem / 0.12rem 0.34rem 0.09rem 0.3rem;
  box-shadow: none;
  transform: skewX(-0.22deg);
}

.exo .visuel .modele-complement {
  width: min(26rem, 88vw);
  max-width: none;
}

.exo .visuel .modele-barre td {
  position: relative;
  padding: 0.82rem 0.72rem;
  border: 0;
  border-right: 2.15px solid color-mix(in srgb, var(--encre) 88%, transparent);
  border-bottom: 2.15px solid color-mix(in srgb, var(--encre) 88%, transparent);
  box-shadow: none;
  font-size: clamp(1.35rem, 2.2vw, 1.65rem);
  font-weight: 500;
}

/* De très petits écarts suffisent à casser la régularité informatique, sans
   nuire à la lecture des parts ni créer un coûteux filtre SVG. */
.exo .visuel .modele-barre tr:first-child td {
  border-bottom-width: 2.45px;
  border-radius: 0.18rem 0.04rem 0.14rem 0.03rem / 0.04rem 0.16rem 0.03rem 0.12rem;
  transform: rotate(0.18deg) translateY(0.02rem);
}

.exo .visuel .modele-barre tr:last-child td:nth-child(3n + 1) {
  transform: rotate(-0.38deg) translateY(-0.025rem);
}

.exo .visuel .modele-barre tr:last-child td:nth-child(3n + 2) {
  transform: rotate(0.3deg) translateY(0.025rem);
}

.exo .visuel .modele-barre tr:last-child td:nth-child(3n) {
  transform: rotate(-0.14deg) translateY(-0.01rem);
}

/* Les modèles en barre utilisent leurs cellules pour la mise en page et un
   calque de vrais chemins pour le tracé. Les lignes peuvent ainsi onduler sans
   doubler les bordures ni déformer le contenu. */
.exo .visuel .modele-barre-croquis {
  position: relative;
  width: 100%;
  max-width: 34rem;
  margin-inline: auto;
  rotate: -0.18deg;
}

.exo .visuel .modele-complement-croquis {
  width: min(26rem, 88vw);
}

.exo .visuel .modele-barre-croquis .modele-barre {
  width: 100%;
  max-width: none;
  margin: 0;
  border: 0;
  border-radius: 0;
  transform: none;
}

.exo .visuel .modele-barre-croquis .modele-barre td {
  border: 0;
  transform: none;
}

.exo .visuel .modele-barre-croquis .mb-part {
  clip-path: none;
}

/* Coloration légère au crayon : la teinte ne touche volontairement pas tous les
   bords et sa silhouette change d'une case à l'autre. Il n'y a plus de hachures. */
:is(.modele-barre .mb-part, .tabprop .trou, .num-table .colonne-unites) {
  position: relative;
  overflow: hidden;
  background: transparent;
}

.modele-barre .espace-case {
  display: inline-block;
  width: 0;
  visibility: hidden;
}

.tabprop .trou {
  --couleur-remplissage-case: var(--lavande);
}

.num-table .colonne-unites {
  --couleur-remplissage-case: var(--cyan);
  overflow: visible;
}

.num-table .colonne-unites::before,
.num-table .colonne-unites::after {
  z-index: 0;
}

.num-table .colonne-unites > :is(.v, .glisse-jeton) {
  position: relative;
  z-index: 1;
}

:is(.modele-barre .mb-part, .tabprop .trou, .num-table .colonne-unites)::before {
  position: absolute;
  inset: 0.07rem 0.05rem 0.09rem 0.08rem;
  background: color-mix(in srgb, var(--couleur-remplissage-case) 19%, transparent);
  clip-path: polygon(
    1% 13%, 7% 5%, 21% 7%, 39% 2%, 58% 6%, 76% 3%, 94% 8%,
    98% 21%, 95% 39%, 99% 58%, 96% 79%, 91% 94%, 73% 97%,
    54% 94%, 35% 98%, 16% 94%, 4% 88%, 7% 68%, 2% 49%, 5% 29%
  );
  content: "";
  pointer-events: none;
  rotate: -0.45deg;
}

:is(.modele-barre .mb-part, .tabprop .trou, .num-table .colonne-unites)::after {
  position: absolute;
  inset: 0.15rem 0.12rem 0.13rem 0.16rem;
  border-radius: 9% 4% 8% 5% / 13% 8% 15% 10%;
  background: color-mix(in srgb, var(--couleur-remplissage-case) 8%, transparent);
  clip-path: polygon(
    3% 9%, 18% 3%, 37% 6%, 55% 2%, 78% 5%, 97% 14%,
    94% 38%, 98% 61%, 92% 91%, 69% 96%, 48% 92%, 25% 97%,
    5% 87%, 8% 63%, 2% 39%
  );
  content: "";
  pointer-events: none;
  rotate: 0.7deg;
}

:is(.modele-barre .mb-part, .tabprop .trou, .num-table .colonne-unites):nth-child(even)::before {
  inset: 0.11rem 0.08rem 0.06rem 0.04rem;
  clip-path: polygon(
    2% 8%, 13% 3%, 31% 7%, 49% 2%, 68% 6%, 89% 3%, 98% 14%,
    94% 34%, 99% 52%, 95% 72%, 98% 89%, 82% 96%, 61% 93%,
    43% 98%, 24% 94%, 7% 98%, 3% 81%, 6% 61%, 1% 42%, 5% 22%
  );
  rotate: 0.55deg;
}

:is(.modele-barre .mb-part, .tabprop .trou, .num-table .colonne-unites):nth-child(even)::after {
  inset: 0.09rem 0.16rem 0.17rem 0.1rem;
  rotate: -0.5deg;
}

.exo .coloriage-apres-trace:is(.mb-part, .trou, .colonne-unites)::before,
.exo .coloriage-apres-trace:is(.mb-part, .trou, .colonne-unites)::after {
  animation: colorier-case 360ms ease-out var(--delai-coloriage, 0ms) both;
  transform-origin: left center;
}

@keyframes colorier-case {
  from {
    opacity: 0;
    scale: 0.12 0.88;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .exo .coloriage-apres-trace:is(.mb-part, .trou, .colonne-unites)::before,
  .exo .coloriage-apres-trace:is(.mb-part, .trou, .colonne-unites)::after {
    animation: none;
  }
}

.traces-modele-barre {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.traces-modele-barre .trait-main-levee {
  fill: none;
  stroke: color-mix(in srgb, var(--encre) 94%, transparent);
  stroke-width: 2.35;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.exo .visuel .modele-barre tr > td:last-child {
  border-right: 0;
}

.exo .visuel .modele-barre tr:last-child > td {
  border-bottom: 0;
}

.clavier-bascule {
  border: 1.8px solid var(--lavande);
  border-radius: 43% 57% 47% 53% / 55% 44% 56% 45%;
  background: transparent;
  box-shadow: 0.13rem 0.18rem 0 color-mix(in srgb, var(--lavande) 24%, transparent);
  color: var(--lavande);
  rotate: -2deg;
  transform: none;
}

.clavier-bascule:hover {
  transform: none;
  translate: 0 -0.12rem;
  rotate: 1deg;
}

.clavier-bascule[aria-pressed="true"] {
  border-color: var(--cyan);
  background: color-mix(in srgb, var(--cyan) 9%, transparent);
  color: var(--cyan);
}

.icone-clavier-croquis {
  width: 2.15rem;
  height: 1.9rem;
  overflow: visible;
}

.icone-clavier-croquis path {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

.icone-clavier-croquis path:not(.clavier-contour) {
  stroke-width: 2.5;
}

.icone-gomme-croquis {
  width: 2.45rem;
  height: 1.85rem;
  overflow: visible;
  pointer-events: none;
}

.icone-gomme-croquis path {
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icone-gomme-croquis .gomme-corps {
  fill: color-mix(in srgb, currentColor 9%, transparent);
  stroke-width: 1.65;
}

.icone-gomme-croquis .gomme-bande {
  fill: none;
  stroke-width: 1.25;
}

.icone-gomme-croquis .gomme-miettes {
  fill: none;
  stroke-width: 1.55;
}

.panneau-info,
.quizz-passe,
.option,
.enrolement {
  border-color: color-mix(in srgb, var(--accent-page) 22%, var(--surface-0));
  border-radius: 2px 6px 3px 5px;
  background: color-mix(in srgb, var(--accent-page) 7%, var(--papier-note));
  box-shadow: 3px 6px 13px var(--ombre-papier);
}

.options {
  max-width: 42rem;
  gap: 1.5rem;
}

.option {
  position: relative;
  padding: 1.35rem 1.5rem;
  rotate: -0.35deg;
}

.option:nth-child(even) { rotate: 0.35deg; }
.option h2 { color: var(--accent-page); font-family: var(--police-main); font-size: 1.2rem; }

/* Options : une page de cahier, sans cartes ni post-it. Les sections restent
   volontairement aérées et centrées ; les contrôles gardent les petites
   irrégularités d'un trait dessiné à la main. */
main[data-vue="options"] > h1 {
  margin-inline: auto;
  text-align: center;
}

main[data-vue="options"] .options {
  width: min(48rem, 100%);
  max-width: none;
  margin-inline: auto;
  gap: clamp(3rem, 7vh, 5rem);
  font-family: var(--police-main);
  font-size: 1.13rem;
}

main[data-vue="options"] .option {
  position: relative;
  width: 100%;
  box-sizing: border-box;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  rotate: 0deg;
}

main[data-vue="options"] .option::before {
  display: none;
}

main[data-vue="options"] .option:not(:last-child)::after {
  position: absolute;
  right: 12%;
  bottom: calc(clamp(3rem, 7vh, 5rem) / -2);
  left: 12%;
  height: 7px;
  border-top: 2px solid color-mix(in srgb, var(--lavande) 38%, transparent);
  border-radius: 48% 52% 45% 55%;
  content: "";
  rotate: -0.35deg;
}

main[data-vue="options"] .option h2 {
  margin: 0 0 1.35rem;
  color: var(--accent-page);
  font-family: var(--police-main);
  font-size: clamp(1.55rem, 3vw, 1.9rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: center;
  rotate: -0.45deg;
}

main[data-vue="options"] .option:nth-child(even) h2 {
  rotate: 0.35deg;
}

main[data-vue="options"] .option dl {
  width: min(42rem, 100%);
  margin-inline: auto;
}

main[data-vue="options"] .option dl > div {
  min-height: 2.75rem;
  box-sizing: border-box;
  gap: 2rem;
  padding: 0.6rem 0.85rem;
  border-top: 0;
}

main[data-vue="options"] .option dl > div:first-child {
  border-top: 0;
}

main[data-vue="options"] .option dt {
  color: var(--texte-secondaire);
  font-size: 1.08em;
}

main[data-vue="options"] .option dd {
  font-weight: 600;
}

/* Voyant cerclé, comme tracé puis rempli au feutre. */
main[data-vue="options"] .option dd[data-etat]::before {
  width: 0.88rem;
  height: 0.82rem;
  margin-right: 0.55rem;
  box-sizing: border-box;
  border: 1.7px solid currentColor;
  border-radius: 46% 54% 42% 58% / 55% 45% 57% 43%;
  background: radial-gradient(circle at 52% 47%, currentColor 0 34%, transparent 40%);
  box-shadow: 0.06rem 0.04rem 0 color-mix(in srgb, currentColor 46%, transparent);
  color: var(--overlay-0);
  rotate: -7deg;
}

main[data-vue="options"] .option dd[data-etat="ok"]::before {
  color: var(--cyan);
}

main[data-vue="options"] .option dd[data-etat="neutre"]::before {
  color: var(--jaune);
}

main[data-vue="options"] .option dd[data-etat="ko"]::before {
  color: var(--rouge);
}

main[data-vue="options"] .option-note {
  max-width: 40rem;
  margin: 1.15rem auto 0;
  color: var(--texte-secondaire);
  font-size: 1.04em;
  text-align: center;
}

main[data-vue="options"] .opt-radios {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 15rem));
  justify-content: center;
  gap: 1.4rem 3.25rem;
  margin-top: 2rem;
}

main[data-vue="options"] .opt-sous-titre {
  width: min(42rem, 100%);
  margin: 1.8rem auto 0;
  color: var(--accent-page);
  font-family: var(--police-main);
  font-size: 1.2em;
  font-weight: 500;
  text-align: center;
}

main[data-vue="options"] .opt-bascules {
  display: grid;
  grid-template-columns: minmax(0, 32rem);
  justify-content: center;
  gap: 1.15rem;
  margin-top: 1.35rem;
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) label {
  position: relative;
  display: grid;
  grid-template-columns: 2rem 1fr;
  align-items: center;
  gap: 0.85rem;
  min-height: 3.6rem;
  color: var(--texte);
  cursor: pointer;
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

main[data-vue="options"] .opt-case {
  display: grid;
  width: 1.55rem;
  height: 1.48rem;
  place-items: center;
  border: 2px solid var(--texte-secondaire);
  border-radius: 18% 8% 16% 6% / 9% 18% 7% 15%;
  box-shadow: 0.1rem 0.08rem 0 color-mix(in srgb, var(--texte-secondaire) 32%, transparent);
  rotate: -3deg;
  transition: color 150ms ease, border-color 150ms ease, rotate 150ms ease;
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) label:nth-child(even) .opt-case {
  border-radius: 7% 19% 6% 17% / 16% 6% 18% 8%;
  rotate: 2deg;
}

main[data-vue="options"] .opt-case svg {
  width: 1.65rem;
  height: 1.65rem;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2.5;
  opacity: 0;
  scale: 0.72;
  rotate: -8deg;
  transition: opacity 140ms ease, scale 180ms cubic-bezier(0.22, 1, 0.36, 1);
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) input:checked + .opt-case {
  border-color: var(--lavande);
  color: var(--lavande);
  rotate: -1deg;
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) input:checked + .opt-case svg {
  opacity: 1;
  scale: 1;
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) input:focus-visible + .opt-case {
  outline: 2px solid var(--lavande);
  outline-offset: 4px;
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) strong,
main[data-vue="options"] :is(.opt-radios, .opt-bascules) small {
  display: block;
  font-family: var(--police-main);
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) strong {
  font-size: 1.2em;
  font-weight: 600;
}

main[data-vue="options"] :is(.opt-radios, .opt-bascules) small {
  margin-top: 0.12rem;
  color: var(--texte-secondaire);
  font-size: 0.88em;
  line-height: 1.25;
}

main[data-vue="options"] .option dl > .opt-cache-ligne {
  position: relative;
  padding-right: 4rem;
  border-radius: 9% 3% 8% 4% / 12% 8% 11% 7%;
  cursor: pointer;
  transition: background-color 160ms ease;
}

main[data-vue="options"] .opt-cache-ligne:hover {
  background-color: color-mix(in srgb, var(--lavande) 8%, transparent);
}

main[data-vue="options"] .opt-cache-ligne:has(.opt-cache-ouvrir:focus-visible) {
  outline: 2px solid var(--lavande);
  outline-offset: 2px;
}

main[data-vue="options"] .opt-cache-ouvrir {
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

main[data-vue="options"] .opt-cache-fleche {
  position: absolute;
  top: 50%;
  right: 1.1rem;
  width: 2.35rem;
  height: 1.45rem;
  overflow: visible;
  color: var(--lavande);
  rotate: -2deg;
  translate: 0 -52%;
  transition: translate 160ms ease;
}

main[data-vue="options"] .opt-cache-fleche path {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

main[data-vue="options"] .opt-cache-fleche .trait-main-levee {
  stroke-width: 2.25;
}

main[data-vue="options"] .opt-cache-fleche .trace-reprise {
  stroke-width: 0.9;
  opacity: 0.28;
}

main[data-vue="options"] .opt-cache-ligne:hover .opt-cache-fleche {
  translate: 0.18rem -52%;
}

main[data-vue="options"] .opt-cache-panneau {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(36rem, 100vw);
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  overflow: hidden;
  border: 0;
  border-left: 2px solid color-mix(in srgb, var(--lavande) 48%, transparent);
  background-color: var(--papier);
  background-image:
    repeating-linear-gradient(
      transparent 0 calc(var(--pas-quadrillage) - 1px),
      var(--quadrillage) var(--pas-quadrillage)
    ),
    repeating-linear-gradient(
      90deg,
      transparent 0 calc(var(--pas-quadrillage) - 1px),
      var(--quadrillage) var(--pas-quadrillage)
    );
  color: var(--texte);
  box-shadow: -0.8rem 0 2.2rem color-mix(in srgb, var(--ombre-papier) 72%, transparent);
  font-family: var(--police-main);
}

main[data-vue="options"] .opt-cache-panneau[open] {
  animation: opt-cache-panneau-entree 240ms cubic-bezier(0.22, 1, 0.36, 1);
}

main[data-vue="options"] .opt-cache-panneau::backdrop {
  background: color-mix(in srgb, var(--bureau) 58%, transparent);
}

@keyframes opt-cache-panneau-entree {
  from { opacity: 0.75; translate: 100% 0; }
  to { opacity: 1; translate: 0; }
}

main[data-vue="options"] .opt-cache-panneau-contenu {
  height: 100%;
  padding: clamp(1.25rem, 4vw, 2.25rem);
  box-sizing: border-box;
  overflow-y: auto;
}

main[data-vue="options"] .opt-cache-panneau header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2rem;
}

main[data-vue="options"] .opt-cache-panneau header h2 {
  margin: 0;
  color: var(--accent-page);
  font-family: var(--police-main);
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  font-weight: 600;
  rotate: -0.45deg;
}

main[data-vue="options"] .opt-cache-fermer {
  display: grid;
  flex: 0 0 2.75rem;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0 0 0.15rem;
  place-items: center;
  border: 2px solid color-mix(in srgb, var(--texte-secondaire) 72%, transparent);
  border-radius: 48% 52% 44% 56% / 53% 45% 55% 47%;
  background: color-mix(in srgb, var(--papier) 86%, transparent);
  color: var(--texte-secondaire);
  font-family: var(--police-main);
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
  rotate: 2deg;
}

main[data-vue="options"] .opt-cache-fermer:is(:hover, :focus-visible) {
  border-color: var(--lavande);
  color: var(--lavande);
}

main[data-vue="options"] .opt-cache-fermer:focus-visible {
  outline: 2px solid var(--lavande);
  outline-offset: 3px;
}

main[data-vue="options"] .opt-cache-listes {
  margin-top: 0;
}

main[data-vue="options"] :is(.opt-cache-attente, .opt-cache-erreur) {
  margin: 0 0 1.4rem;
  color: var(--texte-secondaire);
  font-size: 1.02em;
  text-align: center;
}

main[data-vue="options"] .opt-cache-erreur {
  color: var(--rouge);
}

main[data-vue="options"] .opt-cache-groupes {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.4rem;
}

main[data-vue="options"] .opt-cache-groupes h3 {
  margin: 0 0 0.8rem;
  color: var(--lavande);
  font-size: 1.2em;
  font-weight: 600;
  rotate: -0.35deg;
}

main[data-vue="options"] .opt-cache-groupes ul {
  display: grid;
  gap: 0.55rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

main[data-vue="options"] .opt-cache-groupes li {
  display: grid;
  grid-template-columns: 1rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.55rem;
  line-height: 1.25;
}

main[data-vue="options"] .opt-cache-groupes li small {
  color: var(--texte-secondaire);
  font-family: var(--police-main);
  font-size: 0.75em;
  white-space: nowrap;
}

main[data-vue="options"] .opt-cache-voyant {
  align-self: center;
  width: 0.7rem;
  height: 0.66rem;
  box-sizing: border-box;
  border: 1.4px solid currentColor;
  border-radius: 45% 55% 42% 58% / 56% 44% 58% 42%;
  background: radial-gradient(circle, currentColor 0 33%, transparent 41%);
  color: var(--overlay-0);
  rotate: -6deg;
}

main[data-vue="options"] [data-cache="oui"] .opt-cache-voyant {
  color: var(--cyan);
}

main[data-vue="options"] [data-cache="non"] .opt-cache-voyant {
  color: var(--jaune);
}

/* Accueil : tableau de bord tracé directement sur le cahier. Il conserve une
   structure très lisible mais remplace les cartes/post-it par des cadres au
   feutre, légèrement irréguliers{
  width: min(64rem, 100%);
  margin-inline: auto;
  gap: clamp(1.5rem, 3.2vw, 2.4rem);
  font-family: var(--police-main);
  font-size: 1.08rem;
}

main[data-vue="accueil"] .quizz-resultat .rang {
  border: 1.7px solid currentColor;
  border-radius: 46% 54% 43% 57% / 55% 44% 56% 45%;
  background: transparent;
  box-shadow: 1px 1px 0 color-mix(in srgb, currentColor 30%, transparent);
  color: var(--violet-note);
  font-family: var(--police-main);
  rotate: -4deg;
}

main[data-vue="accueil"] .quizz-resultat .score {
  font-family: var(--police-main);
  font-size: 1.05rem;
}

main[data-vue="accueil"] .vide {
  color: var(--texte-secondaire);
  font-family: var(--police-main);
  font-size: 1.05rem;
}

/* Historique des sessions : même composition ouverte que l'accueil, sans
   cartes. Les traits et les voyants colorés suffisent à rythmer la feuille. */
.historique-sessions,
.historique-detail {
  width: min(58rem, 100%);
  margin-inline: auto;
  font-family: var(--police-main);
  font-size: 1.1rem;
}

.historique-sessions > h1 {
  margin: 1rem auto 1.2rem;
  text-align: center;
}

.historique-sessions > .aide {
  margin: 0;
  color: var(--texte-secondaire);
  font-family: var(--police-main);
  font-size: 1.08rem;
  text-align: center;
}

.historique-sessions .liste-sessions {
  display: grid;
  width: min(50rem, 100%);
  margin: 2.5rem auto 0;
}

.historique-sessions .liste-sessions > .vide {
  color: var(--texte-secondaire);
  font-family: var(--police-main);
  text-align: center;
}

.historique-sessions .session-lien {
  --session-couleur: var(--cyan);
  position: relative;
  min-height: 3.5rem;
  margin: 0;
  padding: 1rem 0.8rem 1rem 2.15rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--texte);
  font-family: var(--police-main);
  font-size: 1.08rem;
  rotate: 0deg;
  transition: color 160ms ease, translate 160ms ease;
}

.historique-sessions .session-lien:nth-child(3n + 2) {
  --session-couleur: var(--violet-note);
}

.historique-sessions .session-lien:nth-child(3n) {
  --session-couleur: var(--orange-note);
}

.historique-sessions .session-lien::before {
  position: absolute;
  top: 50%;
  left: 0.65rem;
  width: 0.72rem;
  height: 0.68rem;
  box-sizing: border-box;
  border: 1.5px solid currentColor;
  border-radius: 45% 55% 42% 58% / 56% 44% 58% 42%;
  background: radial-gradient(circle, currentColor 0 32%, transparent 40%);
  color: var(--session-couleur);
  content: "";
  translate: 0 -50%;
  rotate: -6deg;
}

.historique-sessions .session-lien::after {
  position: absolute;
  right: 1%;
  bottom: 0;
  left: 1%;
  border-top: 1.3px solid color-mix(in srgb, var(--session-couleur) 28%, transparent);
  border-radius: 50%;
  content: "";
  rotate: -0.2deg;
}

.historique-sessions .session-lien:last-child::after {
  display: none;
}

.historique-sessions .session-lien:hover {
  border: 0;
  color: var(--session-couleur);
  transform: none;
  translate: 0.25rem 0;
}

.historique-sessions .session-lien:focus-visible {
  outline: 2px solid var(--session-couleur);
  outline-offset: 3px;
}

.historique-sessions .quizz-date {
  font-weight: 500;
}

.historique-sessions .quizz-resultat .score {
  color: var(--session-couleur);
  font-family: var(--police-main);
  font-size: 1.12rem;
  font-weight: 600;
}

.historique-detail .session-bilan-tete {
  align-items: baseline;
  margin: 1.15rem 0 clamp(1.8rem, 4.5vh, 2.8rem);
}

.historique-detail .session-bilan-tete h1 {
  margin: 0;
  font-size: clamp(1.45rem, 3vw, 2rem);
  line-height: 1.1;
  rotate: -0.25deg;
}

.historique-detail .session-bilan-score {
  position: relative;
  color: var(--cyan);
  font-family: var(--police-main);
  font-size: clamp(1.15rem, 2.2vw, 1.55rem);
  font-weight: 600;
}

.historique-detail .session-bilan-score::after {
  position: absolute;
  right: -0.25rem;
  bottom: -0.2rem;
  left: -0.1rem;
  border-top: 2px solid currentColor;
  border-radius: 50%;
  content: "";
  opacity: 0.45;
  rotate: -1.5deg;
}

.historique-detail .session-questions {
  display: grid;
  width: min(54rem, 100%);
  max-width: none;
  margin-inline: auto;
}

.historique-detail .session-question {
  --question-couleur: var(--overlay-0);
  position: relative;
  min-height: 4.5rem;
  margin: 0;
  padding: 1.2rem 0.5rem 1.3rem 2.1rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  rotate: 0deg;
}

.historique-detail .session-question.juste {
  --question-couleur: var(--cyan);
  border-left: 0;
}

.historique-detail .session-question.faux {
  --question-couleur: var(--rouge);
  border-left: 0;
}

.historique-detail .session-question::before {
  position: absolute;
  top: 1.65rem;
  left: 0.45rem;
  width: 0.76rem;
  height: 0.72rem;
  box-sizing: border-box;
  border: 1.5px solid currentColor;
  border-radius: 46% 54% 43% 57% / 56% 44% 57% 43%;
  background: radial-gradient(circle, currentColor 0 32%, transparent 40%);
  color: var(--question-couleur);
  content: "";
  rotate: -7deg;
}

.historique-detail .session-question::after {
  position: absolute;
  right: 1%;
  bottom: 0;
  left: 1%;
  border-top: 1.2px solid color-mix(in srgb, var(--question-couleur) 25%, transparent);
  border-radius: 50%;
  content: "";
  rotate: 0.15deg;
}

.historique-detail .session-question:last-child::after {
  display: none;
}

.historique-detail .session-question-titre {
  color: var(--question-couleur);
  font-family: var(--police-main);
  font-size: 1.12rem;
  font-weight: 600;
}

.historique-detail .session-question-resultat {
  min-width: 10rem;
}

.historique-detail .r-question {
  font-family: var(--police-maths);
  font-size: clamp(1.2rem, 1.8vw, 1.4rem);
  font-weight: 400;
  line-height: 1.35;
}

.historique-detail .r-question .question-texte {
  font-family: var(--police-maths);
  font-size: inherit;
  font-weight: 400;
  line-height: inherit;
}

.historique-detail .r-question .question-texte:empty {
  display: none;
}

.historique-detail .r-question .visuel + .question-texte {
  margin-top: 0.35rem;
}

/* Le plan de calcul d'angle est recadré en JS autour de ses traits. Ses
   dimensions intrinsèques serrées évitent les bandes vides sans grossir
   sensiblement le dessin dans le bilan élève. */
.historique-detail .r-question .angles-calcul-visuel {
  margin-block: 0.2rem 0;
}

.historique-detail .r-question .angles-calcul-figure svg {
  display: block;
  width: auto;
  max-width: min(230px, 100%);
  height: auto;
}

.historique-detail .r-question .visuel-question {
  font-family: var(--police-maths);
  font-size: inherit;
  font-weight: 400;
  line-height: inherit;
}

.historique-detail .r-question .consigne {
  font-family: var(--police-maths);
  font-size: inherit;
  font-weight: 400;
  line-height: inherit;
  color: var(--texte);
}

.historique-detail .r-question :is(.tabprop, .tabfonction, .num-table) {
  font-size: 0.98rem;
}

.historique-detail .r-question .expression-mathematique-operateur {
  margin-inline: 0.16em;
}

.historique-detail :is(.r-eleve, .r-bonne) {
  font-family: var(--police-main);
  font-size: 1.15rem;
  line-height: 1.4;
}

.historique-detail :is(.r-eleve, .r-bonne) math {
  font-family: var(--police-maths);
}

/* La roue et le sac portent les données de probabilité : une vignette de
   230 px les rendait illisibles dans le bilan. Les figures géométriques gardent
   volontairement leur taille actuelle. */
.historique-detail .r-question .probabilite-visuel {
  width: min(25rem, 100%);
}

.historique-detail .r-question .probabilite-figure {
  width: 100%;
  max-width: 100%;
  height: auto;
}

/* Les diagrammes de fréquences portent autant d'informations que ceux de
   probabilités : le bilan leur réserve donc une vraie largeur de lecture. */
.historique-detail .r-question .frequence-visuel {
  width: min(31rem, 100%);
}

.historique-detail .r-question .frequence-tableau-visuel {
  flex-direction: column;
  align-items: stretch;
  gap: 0.55rem;
  width: min(42rem, 100%);
}

.historique-detail .r-question .frequence-tableau-visuel .frequence-contexte {
  overflow-wrap: normal;
}

.historique-detail .r-question .frequence-tableau-visuel .tableau-croquis,
.historique-detail .r-question .frequence-tableau-visuel .frequence-tableau {
  width: 100%;
}

.historique-detail .r-question .frequence-figure {
  width: 100%;
  max-width: 100%;
  height: auto;
}

/* Le schéma de segments fait partie de l'énoncé, pas d'une aide facultative.
   Cette règle explicite l'empêche de retomber à la vignette générique. */
.historique-detail .r-question .longueur-litterale-visuel {
  width: min(32rem, 100%);
}

.historique-detail .r-question .longueur-litterale-figure svg {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
}

/* Les jetons sont dimensionnés pour être manipulés pendant l'exercice. Dans
   une archive ils sont seulement lus et doivent rester compacts. */
.historique-detail .r-question .tri-statistique {
  gap: 0.35rem;
}

.historique-detail .r-question .tri-statistique-liste {
  gap: 0.32rem;
  padding: 0.15rem;
}

.historique-detail .r-question .tri-statistique-jeton {
  min-width: 2.45rem;
  min-height: 2.2rem;
  padding: 0.12rem 0.38rem;
  border-width: 1.5px;
  box-shadow: 0.06rem 0.08rem 0 color-mix(in srgb, var(--encre) 12%, transparent);
  cursor: default;
  font-size: 1.05rem;
  touch-action: auto;
}

/* Quizz : page ouverte sur le cahier. L'état courant et les anciens résultats
   sont structurés par la couleur et de fins traits manuscrits, sans panneau. */
.page-quizz {
  width: min(58rem, 100%);
  margin-inline: auto;
  font-family: var(--police-main);
  font-size: 1.1rem;
}

.page-quizz > h1 {
  margin: 0 auto 1.6rem;
  text-align: center;
}

.page-quizz .quizz-etat {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  margin: 0 auto clamp(3rem, 8vh, 5rem);
  color: var(--texte-secondaire);
  font-size: 1.08rem;
  text-align: center;
}

.page-quizz .quizz-etat::before {
  width: 0.78rem;
  height: 0.72rem;
  box-sizing: border-box;
  border: 1.6px solid currentColor;
  border-radius: 46% 54% 42% 58% / 56% 44% 58% 42%;
  background: radial-gradient(circle, currentColor 0 31%, transparent 40%);
  color: var(--violet-note);
  content: "";
  rotate: -7deg;
}

.page-quizz .quizz-archives {
  width: min(50rem, 100%);
  margin-inline: auto;
}

.page-quizz .quizz-archives > h2 {
  width: fit-content;
  margin: 0 auto 1.7rem;
  color: var(--violet-note);
  font-family: var(--police-main);
  font-size: clamp(1.5rem, 3vw, 1.85rem);
  text-align: center;
}

.page-quizz .quizz-liste {
  display: grid;
}

.page-quizz .quizz-passe {
  --quizz-couleur: var(--violet-note);
  position: relative;
  min-height: 4rem;
  margin: 0;
  padding: 1rem 0.8rem 1rem 2.2rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  rotate: 0deg;
}

.page-quizz .quizz-passe:nth-child(3n + 2) {
  --quizz-couleur: var(--cyan);
}

.page-quizz .quizz-passe:nth-child(3n) {
  --quizz-couleur: var(--orange-note);
}

.page-quizz .quizz-passe::before {
  position: absolute;
  top: 50%;
  left: 0.65rem;
  width: 0.72rem;
  height: 0.68rem;
  box-sizing: border-box;
  border: 1.5px solid currentColor;
  border-radius: 45% 55% 42% 58% / 56% 44% 58% 42%;
  background: radial-gradient(circle, currentColor 0 32%, transparent 40%);
  color: var(--quizz-couleur);
  content: "";
  translate: 0 -50%;
  rotate: -6deg;
}

.page-quizz .quizz-passe::after {
  position: absolute;
  right: 1%;
  bottom: 0;
  left: 1%;
  border-top: 1.3px solid color-mix(in srgb, var(--quizz-couleur) 28%, transparent);
  border-radius: 50%;
  content: "";
  rotate: -0.2deg;
}

.page-quizz .quizz-passe:last-child::after {
  display: none;
}

.page-quizz .quizz-identite {
  display: flex;
  flex-direction: column;
  gap: 0.08rem;
}

.page-quizz .quizz-titre {
  color: var(--quizz-couleur);
  font-family: var(--police-main);
  font-size: 1.24rem;
  font-weight: 600;
}

.page-quizz .quizz-date {
  color: var(--texte-secondaire);
  font-family: var(--police-main);
  font-size: 0.98rem;
  font-weight: 500;
}

.page-quizz .quizz-resultat {
  gap: 0.9rem;
}

.page-quizz .quizz-resultat .rang {
  width: 2.05rem;
  height: 1.95rem;
  border: 1.7px solid currentColor;
  border-radius: 46% 54% 43% 57% / 55% 44% 56% 45%;
  background: transparent;
  box-shadow: 1px 1px 0 color-mix(in srgb, currentColor 24%, transparent);
  color: var(--quizz-couleur);
  font-family: var(--police-main);
  font-size: 1rem;
  rotate: -4deg;
}

.page-quizz .quizz-resultat .podium.rang-1 { color: var(--jaune); }
.page-quizz .quizz-resultat .podium.rang-2 { color: var(--lavande); }
.page-quizz .quizz-resultat .podium.rang-3 { color: var(--rose); }

.page-quizz .quizz-resultat .score {
  color: var(--quizz-couleur);
  font-family: var(--police-main);
  font-size: 1.18rem;
  font-weight: 600;
}

.enrolement {
  padding: 1.5rem;
  rotate: -0.25deg;
}

/* === Jeux — commandes et schémas tracés sur la feuille ================= */

main[data-vue="jeux"] :is(.combi, .nerdle, .circuit, .picross, .sudoku, .mathdoku) {
  width: min(68rem, 100%);
  margin-inline: auto;
  font-family: var(--police-main);
  font-size: clamp(1.06rem, 1.4vw, 1.22rem);
  text-align: center;
}

/* Le contenu de chaque jeu reste centré, y compris les plateaux dont la
   largeur dépend de la difficulté. Les historiques gardent leur lecture
   alignée à gauche à l'intérieur de leur bloc centré. */
main[data-vue="jeux"] .jeu-tete,
main[data-vue="jeux"] :is(
  .jeu-modes,
  .jeu-actions,
  .combi-cible,
  .combi-tuiles,
  .combi-ops,
  .nerdle-clavier-ligne,
  .circuit-plateau,
  .circuit-inventaire,
  .sudoku-pave,
  .mathdoku-pave
) {
  justify-content: center;
}

main[data-vue="jeux"] :is(
  .jeu-consigne,
  .jeu-verdict,
  .nerdle-grille,
  .nerdle-clavier,
  .sudoku-plateau,
  .mathdoku-plateau,
  .sudoku-grille,
  .mathdoku-grille,
  .sudoku-pave,
  .mathdoku-pave
) {
  margin-inline: auto;
}

main[data-vue="jeux"] .picross-plateau {
  /* La grille occupe seule la colonne centrale. La largeur variable des
     indices à gauche ne peut donc plus modifier sa position horizontale. */
  justify-content: stretch;
}

main[data-vue="jeux"] .combi-historique {
  width: fit-content;
  margin-inline: auto;
  text-align: left;
}

main[data-vue="jeux"] .icone-jeu-dessinee {
  overflow: visible;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.65;
  rotate: -1.8deg;
  filter: drop-shadow(0.7px 0.8px color-mix(in srgb, currentColor 18%, transparent));
}

main[data-vue="jeux"] .grille > .carte:nth-child(even) .icone-jeu-dessinee {
  rotate: 2deg;
}

/* La liste reprend les fiches légères des automatismes, avec davantage de
   largeur pour conserver l'icône et la description. Chaque élément se lit
   comme une petite note illustrée, tracée directement sur le cahier. */
main[data-vue="jeux"] .grille-jeux {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 265px), 1fr));
  gap: 1rem 1.15rem;
  max-width: 72rem;
  margin-inline: auto;
}

main[data-vue="jeux"] .grille-jeux > .carte-jeu {
  --cadre-croquis: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 52' preserveAspectRatio='none'%3E%3Cpath d='M2.5 4.2C24 1.8 75 4.9 97.4 2.8C99 15.5 96.4 38 98 48.3C73 51.2 23.5 48 2.6 49.6C.8 37.5 3.9 16 2.5 4.2Z' fill='none' stroke='black' stroke-width='.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  display: grid;
  grid-template-columns: 4.25rem minmax(0, 1fr);
  grid-template-rows: auto auto;
  align-content: center;
  align-items: center;
  height: 8.4rem;
  min-height: 8.4rem;
  column-gap: 0.95rem;
  row-gap: 0.28rem;
  padding: 1.05rem 1.25rem 1.08rem;
}

main[data-vue="jeux"] .grille-jeux > .carte-jeu:nth-child(1) { --couleur-note: var(--bleu-note); }
main[data-vue="jeux"] .grille-jeux > .carte-jeu:nth-child(2) { --couleur-note: var(--cyan); }
main[data-vue="jeux"] .grille-jeux > .carte-jeu:nth-child(3) { --couleur-note: var(--violet-note); }
main[data-vue="jeux"] .grille-jeux > .carte-jeu:nth-child(4) { --couleur-note: var(--rose); }
main[data-vue="jeux"] .grille-jeux > .carte-jeu:nth-child(5) { --couleur-note: var(--orange-note); }
main[data-vue="jeux"] .grille-jeux > .carte-jeu:nth-child(6) { --couleur-note: var(--vert-note); }

main[data-vue="jeux"] .carte-jeu .jeu-icone {
  grid-row: 1 / span 2;
  grid-column: 1;
  box-sizing: border-box;
  width: 3.75rem;
  height: 3.75rem;
  padding: 0.48rem;
  border: 1.6px solid color-mix(in srgb, var(--couleur-note) 68%, var(--encre-legere));
  border-radius: 48% 52% 46% 54% / 53% 44% 56% 47%;
  background: color-mix(in srgb, var(--couleur-note) 7%, transparent);
}

main[data-vue="jeux"] .carte-jeu:nth-child(even) .jeu-icone {
  border-radius: 54% 46% 52% 48% / 45% 55% 47% 53%;
}

main[data-vue="jeux"] .carte-jeu .titre {
  grid-row: 1;
  grid-column: 2;
  align-self: end;
  font-size: clamp(1.08rem, 1.5vw, 1.27rem);
}

main[data-vue="jeux"] .carte-jeu .jeu-desc {
  grid-row: 2;
  grid-column: 2;
  align-self: start;
  color: var(--encre-legere);
  font-size: clamp(0.82rem, 1.05vw, 0.94rem);
  line-height: 1.35;
}

main[data-vue="jeux"] .grille-jeux > .carte-jeu:focus-visible {
  outline: 2px solid var(--couleur-note);
  outline-offset: 0.35rem;
}

@container (max-width: 48rem) {
  main[data-vue="jeux"] .grille-jeux > .carte-jeu {
    height: 8rem;
    min-height: 8rem;
    padding: 0.95rem 1rem;
  }
}

@container (max-width: 34rem) {
  main[data-vue="jeux"] .grille-jeux {
    grid-template-columns: minmax(0, 1fr);
  }
}

main[data-vue="jeux"] .icone-jeu-dessinee .aplat {
  fill: color-mix(in srgb, currentColor 48%, transparent);
  stroke: none;
}

main[data-vue="jeux"] .jeu-tete {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  width: 100%;
  gap: 1.4rem;
}

main[data-vue="jeux"] .jeu-tete h1 {
  grid-column: 2;
  justify-self: center;
}

main[data-vue="jeux"] .jeu-tete .jeu-explications {
  grid-column: 1;
  justify-self: start;
}

main[data-vue="jeux"] .jeu-tete .jeu-modes {
  grid-column: 3;
  justify-self: end;
  flex-wrap: nowrap;
  gap: 0.35rem;
}

main[data-vue="jeux"] .jeu-tete .jeu-mode {
  padding-inline: 0.55rem;
  font-size: 0.92rem;
  white-space: nowrap;
}

main[data-vue="jeux"] .jeu-consigne {
  --jeu-explications-hauteur: 14rem;
  max-width: 53rem;
  overflow: hidden;
  color: var(--encre);
  font-size: 1.08em;
  line-height: 1.58;
}

main[data-vue="jeux"] .jeu-consigne-ouverture {
  animation: jeu-explications-apparition 240ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

main[data-vue="jeux"] .jeu-consigne-fermeture {
  animation: jeu-explications-disparition 190ms ease-in both;
}

@keyframes jeu-explications-apparition {
  from {
    max-height: 0;
    margin-block: 0;
    opacity: 0;
    translate: 0 -0.25rem;
  }
  to {
    max-height: var(--jeu-explications-hauteur);
    opacity: 1;
    translate: 0;
  }
}

@keyframes jeu-explications-disparition {
  from {
    max-height: var(--jeu-explications-hauteur);
    opacity: 1;
    translate: 0;
  }
  to {
    max-height: 0;
    margin-block: 0;
    opacity: 0;
    translate: 0 -0.25rem;
  }
}

main[data-vue="jeux"] :is(button, .jeu-mode) {
  font-family: var(--police-main);
}

/* Les commandes reprennent exactement le langage des touches du clavier des
   automatismes : contour irrégulier, quadrillage visible et trait repassé. */
main[data-vue="jeux"] :is(
  .jeu-mode,
  .jeu-rejouer,
  .combi-tuile,
  .combi-op,
  .combi-annuler,
  .nerdle-touche,
  .circuit-module,
  .picross-outil,
  .sudoku-num,
  .sudoku-effacer,
  .sudoku-notes,
  .mathdoku-num,
  .mathdoku-effacer,
  .mathdoku-notes
) {
  position: relative;
  border: 1.7px solid color-mix(in srgb, var(--encre-legere) 72%, var(--lavande));
  border-radius: 45% 55% 42% 58% / 56% 43% 57% 44%;
  background: transparent;
  box-shadow:
    0.1rem 0.13rem 0 color-mix(in srgb, var(--encre-legere) 18%, transparent),
    inset 0.04rem -0.05rem 0 color-mix(in srgb, var(--encre-legere) 10%, transparent);
  color: var(--encre);
  font-weight: 500;
  rotate: -0.8deg;
  transform: none;
  transition: translate 90ms ease, rotate 90ms ease, background-color 90ms ease;
}

main[data-vue="jeux"] :is(
  .jeu-mode,
  .jeu-rejouer,
  .combi-tuile,
  .combi-op,
  .combi-annuler,
  .nerdle-touche,
  .circuit-module,
  .picross-outil,
  .sudoku-num,
  .sudoku-effacer,
  .sudoku-notes,
  .mathdoku-num,
  .mathdoku-effacer,
  .mathdoku-notes
):nth-child(even) {
  border-radius: 54% 46% 57% 43% / 44% 56% 42% 58%;
  rotate: 0.4deg;
}

main[data-vue="jeux"] :is(
  .jeu-mode,
  .jeu-rejouer,
  .combi-tuile,
  .combi-op,
  .combi-annuler,
  .nerdle-touche,
  .circuit-module,
  .picross-outil,
  .sudoku-num,
  .sudoku-effacer,
  .sudoku-notes,
  .mathdoku-num,
  .mathdoku-effacer,
  .mathdoku-notes
)::after {
  position: absolute;
  inset: 0.08rem 0.04rem 0.02rem 0.09rem;
  border: 0.65px solid color-mix(in srgb, currentColor 28%, transparent);
  border-radius: 53% 47% 44% 56% / 46% 55% 45% 54%;
  content: "";
  pointer-events: none;
  rotate: 2deg;
}

main[data-vue="jeux"] :is(
  .jeu-mode,
  .jeu-rejouer,
  .combi-tuile,
  .combi-op,
  .combi-annuler,
  .nerdle-touche,
  .circuit-module,
  .picross-outil,
  .sudoku-num,
  .sudoku-effacer,
  .sudoku-notes,
  .mathdoku-num,
  .mathdoku-effacer,
  .mathdoku-notes
):hover:not(:disabled) {
  transform: none;
  translate: 0 -0.1rem;
  rotate: -1.8deg;
}

main[data-vue="jeux"] :is(
  .jeu-mode,
  .jeu-rejouer,
  .combi-tuile,
  .combi-op,
  .combi-annuler,
  .nerdle-touche,
  .circuit-module,
  .picross-outil,
  .sudoku-num,
  .sudoku-effacer,
  .sudoku-notes,
  .mathdoku-num,
  .mathdoku-effacer,
  .mathdoku-notes
):active:not(:disabled) {
  background: color-mix(in srgb, var(--lavande) 13%, transparent);
  box-shadow: 0.04rem 0.06rem 0 color-mix(in srgb, var(--encre-legere) 18%, transparent);
  translate: 0.05rem 0.07rem;
  rotate: 1deg;
}

main[data-vue="jeux"] :is(.jeu-mode.active, .circuit-module.active, .picross-outil.active, .sudoku-notes.active, .mathdoku-notes.active) {
  border-color: var(--lavande);
  background: color-mix(in srgb, var(--lavande) 18%, transparent);
  box-shadow:
    0.1rem 0.13rem 0 color-mix(in srgb, var(--lavande) 22%, transparent),
    inset 0 -0.48em 0 color-mix(in srgb, var(--lavande) 9%, transparent);
  color: var(--lavande);
}

main[data-vue="jeux"] .jeu-modes {
  flex-wrap: wrap;
  gap: 0.65rem;
}

main[data-vue="jeux"] .jeu-mode {
  padding: 0.62rem 1.2rem;
  font-size: 1.08rem;
}

main[data-vue="jeux"] .jeu-rejouer,
main[data-vue="jeux"] .combi-annuler {
  padding: 0.72rem 1.42rem;
  color: var(--accent-page);
  font-size: 1.1rem;
}

main[data-vue="jeux"] .jeu-actions {
  gap: 0.85rem;
  margin-top: 0.8rem;
}

main[data-vue="jeux"] .jeu-verdict {
  min-height: 2rem;
  font-size: clamp(1.2rem, 1.8vw, 1.5rem);
  font-weight: 500;
  rotate: -0.35deg;
}

/* Jeux de combinaison : nombres entourés au crayon, cible soulignée au
   feutre et historique posé directement sur le papier. */
main[data-vue="jeux"] .combi-cible {
  gap: 1rem;
  margin: 1.7rem 0;
}

main[data-vue="jeux"] .combi-cible span,
main[data-vue="jeux"] .circuit-label {
  color: var(--encre-legere);
  font-size: 0.92rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: none;
}

main[data-vue="jeux"] .combi-cible strong {
  position: relative;
  color: var(--accent-page);
  font-family: var(--police-main);
  font-size: clamp(3rem, 6vw, 4.3rem);
  font-weight: 500;
  rotate: -1.5deg;
}

main[data-vue="jeux"] .combi-cible strong::after {
  position: absolute;
  right: -0.2em;
  bottom: -0.12em;
  left: -0.16em;
  border-top: 2px solid currentColor;
  border-radius: 50%;
  content: "";
  opacity: 0.55;
  rotate: -2deg;
}

main[data-vue="jeux"] .combi-tuile,
main[data-vue="jeux"] .combi-op {
  min-width: 3.8rem;
  min-height: 3.6rem;
  padding: 0.7rem;
  font-size: 1.8rem;
}

main[data-vue="jeux"] .combi-tuile.calcul {
  border-style: dashed;
  color: var(--cyan);
}

main[data-vue="jeux"] .combi-tuile.active,
main[data-vue="jeux"] .combi-op.active {
  border-color: var(--rose);
  background: color-mix(in srgb, var(--rose) 15%, transparent);
  color: var(--rose);
}

main[data-vue="jeux"] .combi-historique li {
  width: fit-content;
  padding: 0.32rem 0.2rem;
  border-bottom: 1.2px solid color-mix(in srgb, var(--accent-page) 24%, transparent);
  color: var(--encre-legere);
  rotate: -0.2deg;
}

/* Calculo : les cases restent rigoureusement alignées, mais leurs angles et
   leurs remplissages ont l'aspect d'un feutre posé à la main. */
main[data-vue="jeux"] .nerdle-grille {
  gap: 0.5rem;
  --nerdle-case: 2.85rem;
}

main[data-vue="jeux"] .nerdle-ligne {
  gap: 0.48rem;
}

main[data-vue="jeux"] .nerdle-case {
  border: 1.8px solid color-mix(in srgb, var(--accent-page) 52%, var(--encre-legere));
  border-radius: 0.48rem 0.72rem 0.42rem 0.68rem / 0.7rem 0.44rem 0.66rem 0.46rem;
  background: transparent;
  box-shadow: 0.07rem 0.08rem 0 color-mix(in srgb, var(--accent-page) 13%, transparent);
  font-family: var(--police-main);
  font-weight: 500;
}

main[data-vue="jeux"] .nerdle-ligne:nth-child(even) .nerdle-case:nth-child(odd) {
  border-radius: 0.7rem 0.42rem 0.68rem 0.45rem / 0.44rem 0.7rem 0.46rem 0.66rem;
}

main[data-vue="jeux"] .nerdle-case.juste,
main[data-vue="jeux"] .nerdle-touche.juste {
  border-color: var(--cyan);
  background: color-mix(in srgb, var(--cyan) 26%, transparent);
  color: color-mix(in srgb, var(--cyan) 76%, var(--encre));
}

main[data-vue="jeux"] .nerdle-case.present,
main[data-vue="jeux"] .nerdle-touche.present {
  border-color: var(--lavande);
  background: color-mix(in srgb, var(--lavande) 25%, transparent);
  color: color-mix(in srgb, var(--lavande) 76%, var(--encre));
}

main[data-vue="jeux"] .nerdle-case.absent,
main[data-vue="jeux"] .nerdle-touche.absent {
  border-color: var(--overlay-0);
  background: color-mix(in srgb, var(--overlay-0) 18%, transparent);
  color: var(--encre-legere);
}

main[data-vue="jeux"] .nerdle-clavier {
  gap: 0.55rem;
}

main[data-vue="jeux"] .nerdle-clavier-ligne {
  gap: 0.48rem;
}

main[data-vue="jeux"] .nerdle-touche {
  min-width: 3rem;
  height: 3.25rem;
  padding-inline: 0.65rem;
  font-size: 1.28rem;
}

main[data-vue="jeux"] .nerdle-touche.large {
  min-width: 5.4rem;
  font-size: 1.02rem;
}

/* Circuit : pistes au stylo, composants non rectilignes et jauge composée de
   petites marques plutôt que de voyants industriels. */
main[data-vue="jeux"] .circuit-barre {
  position: relative;
  gap: 1.4rem;
  padding: 0.8rem 0.3rem 1.15rem;
  border: 0;
  border-radius: 0;
  background: transparent;
}

main[data-vue="jeux"] .circuit-barre::after {
  position: absolute;
  right: 1%;
  bottom: 0;
  left: 1%;
  border-top: 1.8px solid color-mix(in srgb, var(--accent-page) 44%, transparent);
  border-radius: 50%;
  content: "";
  rotate: -0.25deg;
}

main[data-vue="jeux"] .circuit-jauge {
  gap: 0.48rem;
}

main[data-vue="jeux"] .circuit-jauge i {
  width: 1.35rem;
  height: 1.22rem;
  border: 1.5px solid var(--encre-legere);
  border-radius: 47% 53% 42% 58% / 55% 43% 57% 45%;
  background: transparent;
  rotate: -4deg;
}

main[data-vue="jeux"] .circuit-jauge i:nth-child(even) {
  border-radius: 56% 44% 55% 45% / 43% 58% 42% 57%;
  rotate: 5deg;
}

main[data-vue="jeux"] .circuit-jauge i.plein {
  border-color: var(--jaune);
  background: color-mix(in srgb, var(--jaune) 54%, transparent);
}

main[data-vue="jeux"] .circuit-jauge i.plein.ok {
  border-color: var(--cyan);
  background: color-mix(in srgb, var(--cyan) 54%, transparent);
  box-shadow: none;
}

main[data-vue="jeux"] .circuit-plateau {
  gap: 0.1rem;
  margin-block: 2rem;
}

main[data-vue="jeux"] .circuit-trace {
  width: 1.7rem;
  height: 0.45rem;
  border-top: 2px solid var(--encre-legere);
  border-radius: 50%;
  background: transparent;
  rotate: -2deg;
}

main[data-vue="jeux"] .circuit-trace:nth-child(4n) { rotate: 2.5deg; }

main[data-vue="jeux"] .circuit-noeud {
  width: 3.7rem;
  height: 3.55rem;
  border: 2px solid var(--encre-legere);
  border-radius: 44% 56% 48% 52% / 55% 43% 57% 45%;
  background: transparent;
  box-shadow: 0.1rem 0.09rem 0 color-mix(in srgb, var(--encre-legere) 18%, transparent);
  font-family: var(--police-main);
  font-weight: 500;
  rotate: -1.8deg;
}

main[data-vue="jeux"] .circuit-noeud:nth-of-type(even) {
  border-radius: 56% 44% 53% 47% / 43% 57% 45% 55%;
  rotate: 1.5deg;
}

main[data-vue="jeux"] .circuit-noeud.source,
main[data-vue="jeux"] .circuit-noeud.cible-noeud,
main[data-vue="jeux"] .circuit-noeud.slot.fixe {
  background: transparent;
}

main[data-vue="jeux"] .circuit-noeud.slot.vide {
  border-width: 2px;
}

main[data-vue="jeux"] .circuit-badge,
main[data-vue="jeux"] .circuit-module-qte {
  border: 1.2px solid currentColor;
  border-radius: 48% 52% 45% 55% / 55% 44% 56% 45%;
  background: var(--fond);
  font-family: var(--police-main);
}

main[data-vue="jeux"] .circuit-badge {
  color: var(--cyan);
}

main[data-vue="jeux"] .circuit-module-qte {
  color: var(--violet-note);
}

main[data-vue="jeux"] .circuit-module-val {
  font-weight: 500;
}

main[data-vue="jeux"] .circuit-module.en-glissement {
  opacity: 0.3;
}

main[data-vue="jeux"] .circuit-noeud.slot.en-glissement {
  opacity: 0.3;
}

main[data-vue="jeux"] .circuit-element-fantome {
  position: fixed;
  z-index: 70;
  margin: 0;
  pointer-events: none;
  cursor: grabbing;
  opacity: 0.96;
  translate: -50% -72%;
  rotate: -3deg;
  scale: 1.08;
  box-shadow: 0.2rem 0.28rem 0 color-mix(in srgb, var(--encre-legere) 24%, transparent);
}

main[data-vue="jeux"] .circuit-inventaire.depot-retour-cible {
  border-radius: 1rem;
  background: color-mix(in srgb, var(--violet-note) 13%, transparent);
  outline: 2px solid color-mix(in srgb, var(--violet-note) 50%, transparent);
  outline-offset: 0.35rem;
}

main[data-vue="jeux"] .circuit-noeud.slot.depot-cible {
  border-color: var(--lavande);
  background: color-mix(in srgb, var(--lavande) 18%, transparent);
  outline: 2px solid color-mix(in srgb, var(--lavande) 42%, transparent);
  outline-offset: 0.18rem;
  scale: 1.06;
}

main[data-vue="jeux"] .circuit-icone-dessinee {
  overflow: visible;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
  rotate: -3deg;
}

main[data-vue="jeux"] .circuit-icone-dessinee .reprise {
  opacity: 0.24;
  stroke-width: 1.05;
}

/* Picross, Sudoku et Mathdoku reprennent le montage des tableaux des
   automatismes : les boutons portent le contenu, un SVG superposé porte tous
   les traits. Aucune jonction n'est donc doublée. */
main[data-vue="jeux"] :is(.picross-grille, .sudoku-grille, .mathdoku-grille) {
  position: relative;
  isolation: isolate;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

main[data-vue="jeux"] .grille-jeu-traces {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  overflow: visible;
  color: color-mix(in srgb, var(--encre) 94%, transparent);
  pointer-events: none;
}

main[data-vue="jeux"] .grille-jeu-trait {
  vector-effect: non-scaling-stroke;
  stroke-width: 1.15px;
}

main[data-vue="jeux"] .grille-jeu-trait.majeur {
  stroke-width: 2.35px;
}

main[data-vue="jeux"] .grille-jeu-en-construction .grille-jeu-trait {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: dessiner-grille-jeu 320ms ease-out var(--delai-trait) both;
  will-change: stroke-dashoffset;
}

main[data-vue="jeux"] .grille-jeu-en-construction {
  pointer-events: none;
}

@keyframes dessiner-grille-jeu {
  to { stroke-dashoffset: 0; }
}

main[data-vue="jeux"] .picross-outils {
  gap: 0.7rem;
}

main[data-vue="jeux"] .picross-outil {
  padding: 0.6rem 1.15rem;
  font-size: 1.08rem;
}

/* Sur le Picross, les outils restent immobiles au survol : cela évite de
   provoquer une nouvelle composition du plateau juste en dessous sur Safari. */
main[data-vue="jeux"] .picross-outil:is(:hover, :active):not(:disabled) {
  translate: none;
  rotate: -0.8deg;
}

main[data-vue="jeux"] .picross-grille {
  /* Une rotation appliquée au plateau entier faisait varier l'anticrénelage de
     Safari à chaque repeinture (survol d'un outil ou coloriage d'une case), ce
     qui donnait l'impression que la grille sautait. Les traits SVG sont déjà
     irréguliers : aucune rotation globale n'est nécessaire. */
  rotate: none;
}

/* Les traits restent dans leur propre calque de composition. Sans cela,
   Safari pouvait ré-échantillonner le SVG placé sur une coordonnée
   sous-pixel lors du coloriage ou du survol des outils, malgré une géométrie
   strictement inchangée. */
main[data-vue="jeux"] .picross-grille .grille-jeu-traces {
  transform: translateZ(0);
  backface-visibility: hidden;
  will-change: transform;
}

main[data-vue="jeux"] .picross-case {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-width: 0;
  min-height: 0;
  border: 0;
  border-radius: 0;
  outline: 0;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  background: transparent;
  box-shadow: none;
  color: var(--encre-legere);
  font-family: var(--police-main);
  transform: none;
  translate: none;
  rotate: none;
  scale: none;
  transition: none;
}

main[data-vue="jeux"] .picross-case:is(:hover, :focus, :active) {
  outline: 0;
  background: transparent;
  box-shadow: none;
  transform: none;
  translate: none;
  rotate: none;
  scale: none;
}

main[data-vue="jeux"] .picross-case:focus-visible {
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent-page) 55%, transparent);
}

main[data-vue="jeux"] .picross-case.pleine {
  background: transparent;
}

main[data-vue="jeux"] .picross-case.pleine::before,
main[data-vue="jeux"] .picross-case.pleine::after {
  position: absolute;
  inset: 0.07rem 0.05rem 0.09rem 0.08rem;
  z-index: -1;
  background: color-mix(in srgb, var(--accent-page) 19%, transparent);
  clip-path: polygon(
    1% 13%, 7% 5%, 21% 7%, 39% 2%, 58% 6%, 76% 3%, 94% 8%,
    98% 21%, 95% 39%, 99% 58%, 96% 79%, 91% 94%, 73% 97%,
    54% 94%, 35% 98%, 16% 94%, 4% 88%, 7% 68%, 2% 49%, 5% 29%
  );
  content: "";
  pointer-events: none;
  rotate: -0.45deg;
  animation: colorier-case 280ms ease-out both;
  transform-origin: left center;
}

main[data-vue="jeux"] .picross-case.pleine::after {
  inset: 0.15rem 0.12rem 0.13rem 0.16rem;
  border-radius: 9% 4% 8% 5% / 13% 8% 15% 10%;
  background: color-mix(in srgb, var(--accent-page) 8%, transparent);
  clip-path: polygon(
    3% 9%, 18% 3%, 37% 6%, 55% 2%, 78% 5%, 97% 14%,
    94% 38%, 98% 61%, 92% 91%, 69% 96%, 48% 92%, 25% 97%,
    5% 87%, 8% 63%, 2% 39%
  );
  rotate: 0.7deg;
}

main[data-vue="jeux"] .picross-case.pleine:nth-child(3n + 2)::before {
  rotate: 2.2deg;
  scale: 0.97 1.03;
}

main[data-vue="jeux"] .picross-case.pleine:nth-child(3n)::after {
  rotate: -3deg;
  scale: 1.04 0.96;
}

main[data-vue="jeux"] .picross-case.sep-g {
  border-left: 0;
}

main[data-vue="jeux"] .picross-case.sep-h {
  border-top: 0;
}

main[data-vue="jeux"] .picross-case.marquee {
  display: grid;
  place-items: center;
}

main[data-vue="jeux"] .croix-picross {
  overflow: visible;
  fill: none;
  stroke: color-mix(in srgb, var(--encre-legere) 88%, var(--accent-page));
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.65;
  pointer-events: none;
  rotate: -1.5deg;
}

main[data-vue="jeux"] .picross-case .croix-picross {
  width: 68%;
  height: 68%;
}

main[data-vue="jeux"] .picross-outil:has(.croix-picross) {
  display: inline-flex;
  align-items: center;
  gap: 0.38rem;
}

main[data-vue="jeux"] .picross-outil .croix-picross {
  width: 1.12rem;
  height: 1.12rem;
}

main[data-vue="jeux"] .picross-case:nth-child(3n + 2) .croix-picross {
  rotate: 2deg;
  scale: 0.97 1.03;
}

main[data-vue="jeux"] .picross-case:nth-child(3n) .croix-picross {
  rotate: -3deg;
  scale: 1.03 0.96;
}

main[data-vue="jeux"] .croix-picross .reprise {
  opacity: 0.2;
  stroke-width: 0.9;
  translate: 0.35px -0.2px;
}

main[data-vue="jeux"] .picross-cl-col span,
main[data-vue="jeux"] .picross-cl-lig span {
  color: var(--encre);
  font-family: var(--police-main);
  font-size: 0.82rem;
  font-weight: 500;
}

main[data-vue="jeux"] .sudoku-grille {
  border: 0;
  rotate: 0.12deg;
}

main[data-vue="jeux"] .sudoku-case,
main[data-vue="jeux"] .mathdoku-case {
  background: transparent;
  font-family: var(--police-main);
  font-weight: 500;
}

main[data-vue="jeux"] .sudoku-case {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border: 0;
  box-shadow: none;
}

main[data-vue="jeux"] .mathdoku-case:is(.pair, .selection) {
  background: color-mix(in srgb, var(--accent-page) 17%, transparent);
}

main[data-vue="jeux"] .sudoku-case:is(.pair, .selection) {
  outline: 0;
  background: transparent;
}

/* La sélection et les chiffres identiques du Sudoku sont passés au crayon,
   comme une case coloriée du Picross et les zones pastel du Mathdoku. */
main[data-vue="jeux"] .sudoku-case:is(.pair, .selection)::before,
main[data-vue="jeux"] .sudoku-case:is(.pair, .selection)::after {
  position: absolute;
  inset: 0.07rem 0.05rem 0.09rem 0.08rem;
  z-index: -1;
  background: color-mix(in srgb, var(--accent-page) 12%, transparent);
  clip-path: polygon(
    1% 13%, 7% 5%, 21% 7%, 39% 2%, 58% 6%, 76% 3%, 94% 8%,
    98% 21%, 95% 39%, 99% 58%, 96% 79%, 91% 94%, 73% 97%,
    54% 94%, 35% 98%, 16% 94%, 4% 88%, 7% 68%, 2% 49%, 5% 29%
  );
  content: "";
  pointer-events: none;
  rotate: -0.45deg;
  animation: colorier-case 280ms ease-out both;
  transform-origin: left center;
}

main[data-vue="jeux"] .sudoku-case:is(.pair, .selection)::after {
  inset: 0.15rem 0.12rem 0.13rem 0.16rem;
  border-radius: 9% 4% 8% 5% / 13% 8% 15% 10%;
  background: color-mix(in srgb, var(--accent-page) 5%, transparent);
  clip-path: polygon(
    3% 9%, 18% 3%, 37% 6%, 55% 2%, 78% 5%, 97% 14%,
    94% 38%, 98% 61%, 92% 91%, 69% 96%, 48% 92%, 25% 97%,
    5% 87%, 8% 63%, 2% 39%
  );
  rotate: 0.7deg;
}

main[data-vue="jeux"] .sudoku-case.selection::before {
  background: color-mix(in srgb, var(--accent-page) 19%, transparent);
}

main[data-vue="jeux"] .sudoku-case.selection::after {
  background: color-mix(in srgb, var(--accent-page) 8%, transparent);
}

main[data-vue="jeux"] .sudoku-aide-paires {
  display: inline-flex;
  align-items: center;
  gap: 0.62rem;
  margin: 0.15rem auto 0.55rem;
  color: var(--encre-legere);
  font-family: var(--police-main);
  font-size: 1.02rem;
  cursor: pointer;
  rotate: -0.35deg;
}

main[data-vue="jeux"] .sudoku-aide-paires input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

main[data-vue="jeux"] .sudoku-aide-paires input:checked + .bascule-visuel-case {
  border-color: var(--cyan);
  color: var(--cyan);
  rotate: 1.5deg;
}

main[data-vue="jeux"] .sudoku-aide-paires input:checked + .bascule-visuel-case path {
  stroke-dashoffset: 0;
}

main[data-vue="jeux"] .sudoku-aide-paires input:focus-visible + .bascule-visuel-case {
  outline: 1.5px solid var(--lavande);
  outline-offset: 0.22rem;
}

main[data-vue="jeux"] .sudoku-case.sep-c {
  border-right: 0;
}

main[data-vue="jeux"] .sudoku-case.sep-r {
  border-bottom: 0;
}

main[data-vue="jeux"] :is(.sudoku-pave, .mathdoku-pave) {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.55rem;
  width: 11rem;
  max-width: none;
  margin: 0;
  justify-content: stretch;
}

main[data-vue="jeux"] :is(.sudoku-zone-jeu, .mathdoku-zone-jeu) {
  display: grid;
  place-items: center;
  width: 100%;
  max-width: 100%;
  margin: 0.8rem auto 0;
}

main[data-vue="jeux"] :is(.sudoku-plateau, .mathdoku-plateau) {
  margin: 0;
}

main[data-vue="jeux"] :is(.sudoku-commandes, .mathdoku-commandes) {
  position: fixed;
  z-index: 29;
  top: 50%;
  right: 1.25rem;
  display: grid;
  justify-items: center;
  gap: 0.65rem;
  translate: 0 -50%;
}

main[data-vue="jeux"] :is(
  .sudoku-effacer,
  .sudoku-notes,
  .mathdoku-effacer,
  .mathdoku-notes
) {
  grid-column: 1 / -1;
  width: 100%;
}

main[data-vue="jeux"] :is(.sudoku-zone-jeu, .mathdoku-zone-jeu) {
  box-sizing: border-box;
  padding-right: 13.25rem;
}

body.gaucher main[data-vue="jeux"] :is(.sudoku-zone-jeu, .mathdoku-zone-jeu) {
  padding-right: 0;
  padding-left: 13.25rem;
}

body.gaucher main[data-vue="jeux"] :is(.sudoku-commandes, .mathdoku-commandes) {
  right: auto;
  left: 1.25rem;
}

main[data-vue="jeux"] :is(.sudoku-num, .mathdoku-num) {
  min-width: 0;
  padding-inline: 0.45rem;
  font-size: 1.25rem;
}

main[data-vue="jeux"] .sudoku-aide-paires {
  width: 11rem;
  box-sizing: border-box;
  justify-content: center;
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.2;
  text-align: left;
}

main[data-vue="jeux"] :is(.sudoku-commandes, .mathdoku-commandes) .jeu-verdict {
  width: 11rem;
  min-height: 1.65rem;
  margin: 0;
  font-size: 1.08rem;
  line-height: 1.2;
}

main[data-vue="jeux"] :is(.sudoku-commandes, .mathdoku-commandes) .jeu-actions {
  margin-top: 0;
}

/* Sur un écran peu haut, le pavé latéral remonte près de l'en-tête. Le cadre
   d'explication des deux grilles reste dans la colonne libre et défile en interne. */
@media (max-height: 800px) and (min-width: 701px) {
  main[data-vue="jeux"] :is(
    #sudoku-explications,
    #mathdoku-explications
  ) {
    --jeu-explications-hauteur: 6.4rem;
    box-sizing: border-box;
    width: min(42rem, calc(100% - 13.25rem));
    max-height: var(--jeu-explications-hauteur);
    margin-right: 13.25rem;
    margin-left: auto;
    padding-inline: 0.45rem;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
  }

  body.gaucher main[data-vue="jeux"] :is(
    #sudoku-explications,
    #mathdoku-explications
  ) {
    margin-right: auto;
    margin-left: 13.25rem;
  }
}

@media (max-width: 700px) {
  main[data-vue="jeux"] :is(.sudoku-zone-jeu, .mathdoku-zone-jeu),
  body.gaucher main[data-vue="jeux"] :is(.sudoku-zone-jeu, .mathdoku-zone-jeu) {
    padding-inline: 0;
  }

  main[data-vue="jeux"] :is(.sudoku-zone-jeu, .mathdoku-zone-jeu) {
    grid-template-columns: minmax(0, 1fr);
  }

  main[data-vue="jeux"] :is(.sudoku-commandes, .mathdoku-commandes),
  body.gaucher main[data-vue="jeux"] :is(.sudoku-commandes, .mathdoku-commandes) {
    position: static;
    margin-top: 1rem;
    translate: none;
  }
}

main[data-vue="jeux"] :is(.sudoku-effacer, .mathdoku-effacer, .sudoku-notes, .mathdoku-notes) {
  font-size: 1.05rem;
}

main[data-vue="jeux"] .mathdoku-grille {
  rotate: -0.12deg;
  filter: none;
}

/* Les zones du Mathdoku sont distinguées par les mêmes aplats de crayon que
   « fraction d'une quantité ». Les traits de la grille restent tous neutres. */
main[data-vue="jeux"] .mathdoku-case {
  isolation: isolate;
  overflow: hidden;
  border: 0;
  box-shadow: none;
}

main[data-vue="jeux"] .mathdoku-case::before,
main[data-vue="jeux"] .mathdoku-case::after {
  position: absolute;
  inset: 0.07rem 0.05rem 0.09rem 0.08rem;
  z-index: -1;
  background: color-mix(in srgb, var(--zone-couleur) 16%, transparent);
  clip-path: polygon(
    1% 13%, 7% 5%, 21% 7%, 39% 2%, 58% 6%, 76% 3%, 94% 8%,
    98% 21%, 95% 39%, 99% 58%, 96% 79%, 91% 94%, 73% 97%,
    54% 94%, 35% 98%, 16% 94%, 4% 88%, 7% 68%, 2% 49%, 5% 29%
  );
  content: "";
  pointer-events: none;
  rotate: -0.45deg;
}

main[data-vue="jeux"] .mathdoku-case::after {
  inset: 0.15rem 0.12rem 0.13rem 0.16rem;
  border-radius: 9% 4% 8% 5% / 13% 8% 15% 10%;
  background: color-mix(in srgb, var(--zone-couleur) 7%, transparent);
  clip-path: polygon(
    3% 9%, 18% 3%, 37% 6%, 55% 2%, 78% 5%, 97% 14%,
    94% 38%, 98% 61%, 92% 91%, 69% 96%, 48% 92%, 25% 97%,
    5% 87%, 8% 63%, 2% 39%
  );
  rotate: 0.7deg;
}

main[data-vue="jeux"] .grille-jeu-en-construction .mathdoku-case::before,
main[data-vue="jeux"] .grille-jeu-en-construction .mathdoku-case::after {
  animation: colorier-case 360ms ease-out calc(1200ms + var(--delai-zone)) both;
  transform-origin: left center;
}

main[data-vue="jeux"] .mathdoku-case > * {
  position: relative;
  z-index: 1;
}

main[data-vue="jeux"] .mathdoku-val,
main[data-vue="jeux"] .mathdoku-label {
  font-family: var(--police-main);
  font-weight: 600;
}

main[data-vue="jeux"] .mathdoku-label {
  color: color-mix(in srgb, var(--zone-couleur) 42%, var(--encre));
}

main[data-vue="jeux"] .mathdoku-label.bad {
  color: var(--rouge);
}

main[data-vue="jeux"] :is(.sudoku-case.conflit, .mathdoku-case.conflit) {
  background: color-mix(in srgb, var(--rouge) 12%, transparent);
}

/* Tracé irrégulier direct, sans filtre SVG ni seconde reprise : net et léger. */
.exo svg.trace-main-levee .trait-main-levee {
  vector-effect: non-scaling-stroke;
}

body.geo-actif main {
  background: var(--fond);
}

/* Le rail ne bouge pas : seule la feuille de travail se replie puis se déploie. */
::view-transition-old(root),
::view-transition-new(root),
::view-transition-new(main-nav) {
  animation: none;
  mix-blend-mode: normal;
}

/* Le nouveau rail transparent ne doit pas laisser voir son ancien instantané :
   sinon un lien encore survolé apparaît deux fois pendant le déploiement. */
::view-transition-old(main-nav) {
  animation: none;
  opacity: 0;
}

/* Ces actions fixes vivent hors de `main`. Sans instantané nommé, elles sont
   dessinées à la fois dans l'ancienne et la nouvelle racine et semblent glisser
   ou se dédoubler pendant une transition de page. */
::view-transition-group(bouton-options-public),
::view-transition-group(bouton-liste-automatismes),
::view-transition-new(bouton-options-public),
::view-transition-new(bouton-liste-automatismes) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-group(bouton-options-public),
::view-transition-group(bouton-liste-automatismes) {
  z-index: 40;
}

::view-transition-old(bouton-options-public),
::view-transition-old(bouton-liste-automatismes) {
  animation: none;
  opacity: 0;
}

/* Dans Options, le changement de main fait réellement glisser le rail vers
   l'autre bord. La feuille accompagne le rééquilibrage de la mise en page, mais
   sans rejouer son animation habituelle d'ouverture de page. */
html.transition-lateralite::view-transition-group(main-nav),
html.transition-lateralite::view-transition-group(page-content) {
  z-index: 40;
  animation-duration: 850ms;
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

html.transition-lateralite::view-transition-old(page-content),
html.transition-lateralite::view-transition-new(page-content) {
  animation: none;
  mix-blend-mode: normal;
}

html.transition-lateralite::view-transition-old(page-content) {
  opacity: 0;
}

::view-transition-group(page-content) {
  z-index: 30;
  animation-duration: 400ms;
}

::view-transition-old(page-content) {
  animation: cahier-sortie 400ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

::view-transition-new(page-content) {
  transform-origin: var(--transition-x, 50%) var(--transition-y, 50%);
  animation: cahier-entree 400ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes cahier-sortie {
  from { opacity: 1; transform: scale(1); }
  to { opacity: 0; transform: scale(0.985); }
}

@keyframes cahier-entree {
  from { opacity: 0; transform: translateY(12px) scale(0.88); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@container (max-width: 48rem) {
  main {
    padding: 1.5rem 1.15rem 2.25rem;
    background: transparent;
  }

  nav,
  body.gaucher nav {
    order: 1;
    width: 100%;
    flex-direction: row;
    gap: 0;
    min-height: 5.2rem;
    padding: 0.55rem 0.35rem 0.15rem;
    border: 0;
    background: transparent;
    box-shadow: none;
  }

  nav::after,
  body.gaucher nav::after {
    top: 0;
    right: 0;
    bottom: auto;
    left: 0;
    width: auto;
    height: 2px;
    box-shadow: none;
  }

  nav ul {
    flex-direction: row;
    justify-content: space-around;
    gap: 0;
  }

  nav li > a {
    min-height: 4.4rem;
    gap: 0;
    padding: 0.35rem 0.08rem 0.3rem;
    font-size: clamp(0.72rem, 2.35vw, 0.92rem);
  }

  nav .icone-croquis {
    width: 30px;
    height: 30px;
  }

  nav li:nth-child(even) > a,
  nav li > a[aria-current="page"] { rotate: 0deg; }

  nav li > a:hover { translate: 0 -0.12rem; }

  nav li > a::before { inset: 0.14rem 0.04rem 0.05rem; }

  nav li > a::after {
    right: 18%;
    bottom: 0.08rem;
    left: 18%;
  }

  /* Sur une page trop étroite pour les trois colonnes, les difficultés passent
     sous le titre au lieu de le recouvrir. */
  main[data-vue="jeux"] .jeu-tete {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
  }

  main[data-vue="jeux"] .jeu-tete :is(h1, .jeu-modes, .jeu-explications) {
    grid-column: 1;
    justify-self: center;
  }

  main[data-vue="jeux"] .jeu-tete .jeu-modes {
    flex-wrap: wrap;
    justify-content: center;
  }
}

@media (max-width: 620px) {
  :root { --pas-quadrillage: 28px; }

  main h1 { font-size: clamp(2.15rem, 11vw, 3rem); }

  .historique-sessions,
  .historique-detail {
    font-size: 1.03rem;
  }

  .historique-sessions .session-lien {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    padding-block: 0.9rem;
  }

  .historique-sessions .session-lien .quizz-resultat {
    align-self: flex-end;
  }

  .historique-detail .session-bilan-tete {
    margin-bottom: 2rem;
  }

  .historique-detail .session-question {
    padding-right: 0;
  }

  .page-quizz {
    font-size: 1.03rem;
  }

  .page-quizz .quizz-etat {
    margin-bottom: 3rem;
  }

  .page-quizz .quizz-passe {
    gap: 0.8rem;
    padding-right: 0.2rem;
  }

  main[data-vue="options"] .options {
    gap: 3rem;
    font-size: 1.06rem;
  }

  main[data-vue="options"] .option dl > div {
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    padding-block: 0.8rem;
    text-align: center;
  }

  main[data-vue="options"] .option dd {
    text-align: center;
  }

  main[data-vue="options"] .opt-radios,
  main[data-vue="options"] .opt-cache-groupes {
    grid-template-columns: minmax(0, 1fr);
  }

  main[data-vue="options"] .opt-radios {
    width: min(17rem, 100%);
    margin-inline: auto;
  }

  main[data-vue="options"] .opt-cache-groupes {
    gap: 1.8rem;
  }

  main[data-vue="options"] .opt-cache-groupes li {
    grid-template-columns: 1rem minmax(0, 1fr);
  }

  main[data-vue="options"] .opt-cache-groupes li small {
    grid-column: 2;
  }
}

/* Le signal de session remplace toute l'interface par un écran de préparation.
   Le fond de l'application reste visible ; seuls le rail et la feuille changent. */
body.session-verrouillee main {
  width: 100%;
  height: 100dvh;
}

body.session-verrouillee main:has(.session-attente) {
  display: grid;
  max-width: none;
  padding: clamp(1.5rem, 5vw, 4rem);
  overflow: hidden;
  place-items: center;
}

.session-attente {
  display: grid;
  width: min(52rem, 100%);
  justify-items: center;
  gap: clamp(1.4rem, 4vh, 2.8rem);
  text-align: center;
}

.session-attente h1 {
  width: auto;
  max-width: 48rem;
  margin: 0;
  color: var(--lavande);
  font-size: clamp(2.1rem, 5vw, 4.6rem);
  line-height: 1.15;
  rotate: 0deg;
}

.session-attente-ligne {
  display: block;
}

.session-decompte-bloc {
  display: grid;
  width: min(36rem, 92vw);
  justify-items: center;
  gap: clamp(1rem, 2.5vh, 1.6rem);
}

.session-decompte-bloc.est-en-attente {
  visibility: hidden;
}

.session-decompte {
  margin: 0;
  color: var(--cyan);
  font-family: var(--police-main);
  font-size: clamp(4.6rem, 10vw, 7.4rem);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.session-decompte-chiffre {
  display: block;
}

.session-progression {
  display: grid;
  width: 100%;
  height: clamp(1.35rem, 3vw, 1.8rem);
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(0.25rem, 1vw, 0.55rem);
}

.session-progression-etape {
  position: relative;
  overflow: hidden;
  border: 1.6px solid color-mix(in srgb, var(--encre-legere) 76%, var(--cyan));
  border-radius: 12% 5% 10% 4% / 18% 9% 16% 7%;
  rotate: -0.45deg;
}

.session-progression-etape:nth-child(even) {
  border-radius: 5% 13% 4% 11% / 8% 17% 7% 15%;
  rotate: 0.5deg;
}

.session-progression-etape::before,
.session-progression-etape::after {
  position: absolute;
  content: "";
  opacity: 0;
  pointer-events: none;
  scale: 0.12 0.88;
  transform-origin: left center;
}

.session-progression-etape::before {
  inset: 0.08rem 0.06rem 0.09rem 0.08rem;
  background: color-mix(in srgb, var(--cyan) 23%, transparent);
  clip-path: polygon(
    1% 13%, 7% 5%, 21% 7%, 39% 2%, 58% 6%, 76% 3%, 94% 8%,
    98% 21%, 95% 42%, 99% 64%, 94% 91%, 73% 97%, 54% 94%,
    35% 98%, 16% 94%, 4% 88%, 7% 66%, 2% 44%, 5% 27%
  );
  rotate: -0.45deg;
}

.session-progression-etape::after {
  inset: 0.14rem 0.12rem 0.12rem 0.15rem;
  background: color-mix(in srgb, var(--lavande) 10%, transparent);
  clip-path: polygon(
    3% 9%, 18% 3%, 37% 6%, 55% 2%, 78% 5%, 97% 14%,
    94% 38%, 98% 61%, 92% 91%, 69% 96%, 48% 92%, 25% 97%,
    5% 87%, 8% 63%, 2% 39%
  );
  rotate: 0.7deg;
}

.session-progression-etape.est-coloriee::before,
.session-progression-etape.est-coloriee::after {
  animation: colorier-case 360ms ease-out both;
}

@media (prefers-reduced-motion: reduce) {
  .session-progression-etape.est-coloriee::before,
  .session-progression-etape.est-coloriee::after {
    animation: none;
    opacity: 1;
    scale: 1;
  }
}

html:is(.transition-session-entree, .transition-session-demarrage, .transition-session-sortie)::view-transition-old(page-content),
html:is(.transition-session-entree, .transition-session-demarrage, .transition-session-sortie)::view-transition-new(page-content),
html:is(.transition-session-entree, .transition-session-demarrage, .transition-session-sortie)::view-transition-old(main-nav),
html:is(.transition-session-entree, .transition-session-demarrage, .transition-session-sortie)::view-transition-new(main-nav) {
  mix-blend-mode: normal;
}

html.transition-session-entree::view-transition-old(page-content),
html.transition-session-entree::view-transition-old(main-nav) {
  animation: session-interface-effacer 520ms cubic-bezier(0.4, 0, 0.65, 1) both;
}

html.transition-session-entree::view-transition-new(page-content) {
  animation: session-attente-apparaitre 460ms cubic-bezier(0.2, 0.8, 0.25, 1) 390ms both;
}

html.transition-session-demarrage::view-transition-old(page-content),
html.transition-session-sortie::view-transition-old(page-content) {
  animation: session-interface-effacer 420ms cubic-bezier(0.4, 0, 0.65, 1) both;
}

html.transition-session-demarrage::view-transition-new(page-content) {
  animation: session-attente-apparaitre 420ms cubic-bezier(0.2, 0.8, 0.25, 1) 260ms both;
}

html.transition-session-sortie::view-transition-new(page-content),
html.transition-session-sortie::view-transition-new(main-nav) {
  animation: session-interface-redessiner 620ms cubic-bezier(0.2, 0.75, 0.25, 1) 300ms both;
}

@keyframes session-interface-effacer {
  from { opacity: 1; filter: blur(0); scale: 1; }
  to { opacity: 0; filter: blur(0.2rem); scale: 0.975; }
}

@keyframes session-attente-apparaitre {
  from { opacity: 0; translate: 0 0.75rem; }
  to { opacity: 1; translate: 0 0; }
}

@keyframes session-interface-redessiner {
  from {
    opacity: 0;
    clip-path: inset(0 100% 0 0);
    translate: 0.5rem 0;
  }
  to {
    opacity: 1;
    clip-path: inset(0);
    translate: 0 0;
  }
}

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

  ::view-transition-old(page-content),
  ::view-transition-new(page-content) {
    animation-duration: 0.01ms !important;
  }
}

/* === iPad en portrait ====================================================
   L'orientation est le bon signal ici : les iPad récents dépassent 48rem en
   portrait et échappaient donc à la seule règle de « page étroite ». La hauteur
   redevient abondante, tandis que toute la largeur sert au clavier rapide. */
@media (orientation: portrait) {
  body {
    flex-direction: column;
    gap: 0;
  }

  main {
    order: 0;
    padding: 1.5rem 1.15rem 2.25rem;
  }

  nav,
  body.gaucher nav {
    order: 1;
    width: 100%;
    min-height: 5.75rem;
    flex-direction: row;
    gap: 0;
    padding: 0.55rem 0.35rem 0.15rem;
    border: 0;
    background: transparent;
    box-shadow: none;
  }

  nav::after,
  body.gaucher nav::after {
    top: 0;
    right: 0;
    bottom: auto;
    left: 0;
    width: auto;
    height: 2px;
    box-shadow: none;
  }

  nav ul {
    flex: 1;
    flex-direction: row;
    justify-content: space-around;
    gap: 0;
  }

  nav li {
    flex: 1;
    min-width: 0;
  }

  .nav-bas {
    margin-top: 0;
  }

  nav li > a {
    min-height: 4.4rem;
    gap: 0;
    padding: 0.35rem 0.08rem 0.3rem;
    font-size: clamp(0.72rem, 2.35vw, 0.92rem);
    rotate: 0deg;
  }

  nav > a.nav-serieux {
    width: 3.9rem;
    min-height: 4.4rem;
    padding: 0.3rem 0.15rem;
  }

  nav .icone-croquis {
    width: 30px;
    height: 30px;
  }

  nav li > a:hover {
    translate: 0 -0.12rem;
  }

  nav li > a::before {
    inset: 0.14rem 0.04rem 0.05rem;
  }

  nav li > a::after {
    right: 18%;
    bottom: 0.08rem;
    left: 18%;
  }

  /* La latéralité n'a aucun effet dans cette disposition symétrique. La valeur
     reste mémorisée et redevient active dès le retour en paysage. */
  main[data-vue="options"] .opt-lateralite {
    display: none;
  }

  /* Les anciennes rangées deviennent transparentes pour le layout : toutes les
     touches participent au même flex et se répartissent sur une ou deux lignes. */
  .clavier,
  body.gaucher .clavier {
    --decalage-apparition: 0rem;
    top: auto;
    right: 0.75rem;
    bottom: 6.5rem;
    left: 0.75rem;
    box-sizing: border-box;
    width: auto;
    display: flex;
    flex-flow: row wrap;
    align-content: center;
    justify-content: center;
    gap: 0.35rem;
    transform: none;
  }

  .clavier[hidden] {
    display: none;
  }

  .clavier-ligne {
    display: contents;
  }

  /* Deux lignes de touches tiennent dans cette réserve. Le centrage latéral du
     paysage est neutralisé, y compris si la préférence mémorisée est gaucher. */
  .exo,
  body.gaucher .exo {
    padding-right: 0;
    padding-left: 0;
  }

  .exo.clavier-visible,
  .exo.clavier-visible:has(.clavier[data-cols="4"]) {
    --espace-clavier: 0rem;
    padding-bottom: 9rem;
  }

  .clavier-bascule,
  body.gaucher .clavier-bascule {
    right: 1rem;
    bottom: 15rem;
    left: auto;
  }

  /* Pendant une session la navbar est retirée : le clavier reprend sa place en
     bas de l'écran, sans laisser un vide de 5,75rem. */
  body.session-verrouillee .clavier {
    bottom: 0.75rem;
  }

  body.session-verrouillee .clavier-bascule {
    bottom: 9.25rem;
  }
}

/* Un onglet secondaire reste volontairement inerte : deux moteurs de session
   ne doivent jamais écrire dans la même progression ou la même outbox. */
body.onglet-secondaire {
  display: block;
}

body.onglet-secondaire > nav {
  display: none;
}

body.onglet-secondaire > main {
  display: grid;
  min-height: 100dvh;
  padding: 2rem;
  place-items: center;
}

.panneau-onglet-secondaire {
  display: grid;
  width: min(32rem, 100%);
  gap: 1.25rem;
  text-align: center;
}

.panneau-onglet-secondaire :is(h1, p) {
  margin: 0;
}

.session-version-erreur {
  display: grid;
  width: min(34rem, 100%);
  margin: auto;
  gap: 0.8rem;
  text-align: center;
}

.session-version-erreur :is(h1, p) {
  margin: 0;
}

/* === Quizz synchrone ===================================================== */
body.quizz-verrouille {
  gap: 0;
}

body.quizz-verrouille nav {
  display: none;
}

body.quizz-verrouille main {
  width: 100%;
  max-width: 72rem;
  height: 100dvh;
  margin-inline: auto;
  padding: clamp(1rem, 2.8vw, 2rem);
  overflow: auto;
}

body.quizz-verrouille .page-quizz {
  width: 100%;
}

body.quizz-verrouille .quizz-archives {
  display: none;
}

.quizz-direct:has(.quizz-etat) {
  min-height: 8rem;
}

.quizz-attente,
.quizz-fin {
  display: grid;
  min-height: min(72dvh, 40rem);
  place-content: center;
  justify-items: center;
  gap: 0.8rem;
  text-align: center;
}

.quizz-attente h2,
.quizz-fin h2 {
  margin: 0;
  color: var(--violet-note);
  font-size: clamp(2rem, 5vw, 4rem);
  text-wrap: balance;
}

.quizz-attente p,
.quizz-fin p {
  margin: 0;
  color: var(--texte-secondaire);
  font-size: clamp(1.2rem, 2.4vw, 1.7rem);
}

.quizz-attente-points {
  color: var(--violet-note);
  font-size: 2.5rem;
  letter-spacing: 0.3em;
  animation: quizz-points 1.2s ease-in-out infinite alternate;
}

@keyframes quizz-points {
  to { opacity: 0.35; translate: 0 0.2rem; }
}

.quizz-question {
  display: grid;
  width: min(66rem, 100%);
  margin-inline: auto;
  gap: clamp(0.7rem, 2vh, 1.25rem);
}

.quizz-question > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--violet-note);
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  font-weight: 650;
}

.quizz-chrono {
  min-width: 4.2rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.quizz-chrono.urgent {
  color: var(--rouge);
}

.quizz-question > h2 {
  max-width: 60rem;
  margin: 0 auto;
  color: var(--encre);
  font-size: clamp(1.45rem, 3.2vw, 2.25rem);
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-wrap: balance;
}

.quizz-figure {
  width: min(22rem, 48vh, 100%);
  height: auto;
  aspect-ratio: 1;
  max-height: 14rem;
  margin-inline: auto;
  overflow: visible;
  fill: none;
  stroke: var(--encre);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.quizz-figure-trace {
  stroke-width: 2.4;
}

.quizz-figure-hauteur {
  stroke: var(--violet-note);
  stroke-width: 1.7;
  stroke-dasharray: 7 6;
}

.quizz-figure text {
  fill: var(--encre);
  stroke: none;
  font-family: var(--police-main);
  font-size: 17px;
}

.quizz-figure.quizz-figure-babylonienne {
  width: auto;
  max-width: min(32rem, 92%);
  height: min(8.5rem, 23vh);
  aspect-ratio: auto;
  color: var(--encre);
  fill: currentColor;
  stroke: none;
}

.quizz-ecriture-babylonienne {
  display: block;
  width: auto;
  max-width: min(18rem, 100%);
  height: clamp(2.8rem, 7vh, 4.8rem);
  margin-inline: auto;
  overflow: visible;
  color: var(--encre);
}

.babylonien-reprise {
  opacity: 0.26;
}

.quizz-choix {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.65rem, 1.8vw, 1rem);
}

.quizz-question.phase-correction.correction-repliee .quizz-choix {
  grid-template-columns: minmax(0, 36rem);
  justify-content: center;
}

.quizz-question.phase-correction.correction-repliee .quizz-reponse.correcte {
  grid-column: 1;
  width: 100%;
  min-height: clamp(5.2rem, 12vh, 7rem);
  font-size: clamp(1.2rem, 2.5vw, 1.7rem);
  justify-self: center;
}

.quizz-reponse {
  --couleur-quizz: var(--lavande);
  --inclinaison-surligneur: -0.4deg;
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(4.4rem, 10vh, 6rem);
  padding: 0.8rem 1.2rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--encre);
  box-shadow: none;
  font: inherit;
  font-size: clamp(1.05rem, 2.1vw, 1.45rem);
  text-align: center;
  touch-action: manipulation;
}

.quizz-reponse-surlignage {
  position: absolute;
  z-index: 0;
  inset: 13% 0.25rem 11%;
  width: calc(100% - 0.5rem);
  height: 76%;
  overflow: visible;
  pointer-events: none;
  rotate: var(--inclinaison-surligneur);
  transition: scale 160ms ease;
}

.quizz-reponse-surlignage-trait {
  fill: none;
  stroke: var(--couleur-quizz);
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity 160ms ease, stroke 160ms ease;
}

.quizz-reponse-surlignage-large {
  stroke-width: 34;
  opacity: 0.28;
}

.quizz-reponse-surlignage-reprise {
  stroke-width: 21;
  opacity: 0.11;
}

.quizz-reponse > span {
  position: relative;
  z-index: 1;
}

.quizz-reponse > span:has(.quizz-ecriture-babylonienne) {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
}

.quizz-reponse[hidden] {
  display: none;
}

.quizz-reponse:nth-child(2) {
  --couleur-quizz: var(--rose);
  --inclinaison-surligneur: 0.35deg;
}
.quizz-reponse:nth-child(3) {
  --couleur-quizz: var(--cyan);
  --inclinaison-surligneur: 0.55deg;
}
.quizz-reponse:nth-child(4) {
  --couleur-quizz: var(--jaune);
  --inclinaison-surligneur: -0.3deg;
}

.quizz-reponse:not(:disabled):is(:hover, :focus-visible) .quizz-reponse-surlignage {
  scale: 1.01 1.08;
}

.quizz-reponse:not(:disabled):is(:hover, :focus-visible) .quizz-reponse-surlignage-large {
  opacity: 0.38;
}

.quizz-reponse:focus-visible {
  outline: 2px dashed color-mix(in srgb, var(--couleur-quizz) 76%, var(--encre));
  outline-offset: 0.2rem;
}

.quizz-reponse:not(:disabled):active {
  scale: 0.985;
}

.quizz-reponse.selectionnee .quizz-reponse-surlignage-large {
  opacity: 0.46;
}

.quizz-reponse.correcte .quizz-reponse-surlignage-trait {
  stroke: var(--vert-note);
}

.quizz-reponse.correcte .quizz-reponse-surlignage-large {
  opacity: 0.42;
}

.quizz-reponse.fausse .quizz-reponse-surlignage-trait {
  stroke: var(--rouge);
}

.quizz-reponse.fausse .quizz-reponse-surlignage-large {
  opacity: 0.34;
}

.quizz-reponse:disabled {
  opacity: 1;
  cursor: default;
}

.quizz-question-statut {
  min-height: 1.8rem;
  margin: 0;
  color: var(--texte-secondaire);
  font-size: 1.05rem;
  text-align: center;
}

.quizz-question-statut.juste { color: var(--vert-note); }
.quizz-question-statut.faux { color: var(--rouge); }

.quizz-fin-rang {
  color: var(--violet-note);
  font-size: clamp(3.5rem, 10vw, 7rem);
  line-height: 1;
}

.quizz-fin-rang.rang-1 { color: var(--jaune); }
.quizz-fin-rang.rang-2 { color: var(--lavande); }
.quizz-fin-rang.rang-3 { color: var(--rose); }

@container (max-width: 40rem) {
  .quizz-choix { grid-template-columns: 1fr; }
}

/* La bascule de session n’occupe aucune place sans aide pour cette question. */
.bascule-visuel[hidden] { display: none; }

.bascule-visuel-mobile {
  display: none;
}

/* === Accueil public =======================================================
   Avant l'enrôlement, les automatismes sont l'application entière : aucun rail
   ne concurrence la grille et l'action d'enrôlement reste accessible pendant
   tout le défilement. */
body.mode-public {
  display: block;
  min-height: 100dvh;
  height: auto;
  overflow: auto;
}

body.mode-public nav,
nav[hidden] {
  display: none;
}

body.mode-public main {
  width: min(78rem, 100%);
  min-height: 100dvh;
  margin-inline: auto;
  padding-bottom: calc(7rem + env(safe-area-inset-bottom));
  box-sizing: border-box;
  overflow: visible;
}

.bouton-options-public,
.bouton-liste-automatismes {
  position: fixed;
  z-index: 40;
  bottom: max(1.25rem, env(safe-area-inset-bottom));
  display: grid;
  width: 4.25rem;
  height: 4.25rem;
  padding: 0.9rem;
  box-sizing: border-box;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--orange-note) 14%, var(--papier-note));
  color: var(--orange-note);
  box-shadow: 3px 5px 11px var(--ombre-papier);
  rotate: -1deg;
  transition: translate 160ms ease, rotate 160ms ease, box-shadow 160ms ease;
}

.bouton-options-public {
  right: max(1.25rem, env(safe-area-inset-right));
  background: color-mix(in srgb, var(--cyan) 14%, var(--papier-note));
  color: var(--cyan);
  view-transition-name: bouton-options-public;
}

.bouton-liste-automatismes {
  left: max(1.25rem, env(safe-area-inset-left));
  background: color-mix(in srgb, var(--jaune) 14%, var(--papier-note));
  color: var(--jaune);
  rotate: 1deg;
  view-transition-name: bouton-liste-automatismes;
}

:is(.bouton-options-public, .bouton-liste-automatismes)::before,
:is(.bouton-options-public, .bouton-liste-automatismes)::after {
  position: absolute;
  border: 2px solid currentColor;
  border-radius: 48% 52% 46% 54% / 53% 47% 55% 45%;
  content: "";
  pointer-events: none;
}

:is(.bouton-options-public, .bouton-liste-automatismes)::before {
  inset: 0.08rem 0.04rem 0.02rem 0.1rem;
  rotate: -2.5deg;
}

:is(.bouton-options-public, .bouton-liste-automatismes)::after {
  inset: 0.2rem 0.14rem 0.13rem 0.22rem;
  border-width: 1px;
  opacity: 0.42;
  rotate: 3.5deg;
}

.bouton-options-public .icone-options-public,
.bouton-liste-automatismes .icone-liste-automatismes {
  position: relative;
  z-index: 1;
  width: 2.35rem;
  height: 2.35rem;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.bouton-options-public .icone-options-trait,
.bouton-liste-automatismes .icone-liste-trait {
  stroke-width: 1.75;
}

.bouton-options-public .icone-options-reprise,
.bouton-liste-automatismes .icone-liste-reprise {
  opacity: 0.34;
  stroke-width: 1.05;
  translate: 0.35px 0.45px;
}

:is(.bouton-options-public, .bouton-liste-automatismes)[hidden] {
  display: none;
}

:is(.bouton-options-public, .bouton-liste-automatismes):is(:hover, :focus-visible) {
  box-shadow: 5px 8px 16px var(--ombre-papier);
  outline: 2px dashed color-mix(in srgb, currentColor 68%, transparent);
  outline-offset: 0.25rem;
  translate: 0 -0.18rem;
  rotate: 0deg;
}

:is(.bouton-options-public, .bouton-liste-automatismes):is(:hover, :focus-visible)::before {
  rotate: 1deg;
}

:is(.bouton-options-public, .bouton-liste-automatismes):is(:hover, :focus-visible) > svg {
  scale: 1.06;
}

/* La route d'enrôlement ne devient plus une seconde page au style ancien : elle
   se résume au petit cadre qui porte le PIN, centré sur la feuille. */
body.mode-public main[data-vue="enroler"] {
  display: grid;
  width: 100%;
  min-height: 100dvh;
  padding: 1.5rem;
  place-items: center;
}

main[data-vue="enroler"] .enrolement {
  width: min(21rem, calc(100vw - 3rem));
  min-height: 7rem;
  padding: 1.2rem 1.4rem;
  box-sizing: border-box;
  border: 2px solid color-mix(in srgb, var(--orange-note) 62%, var(--encre));
  border-radius: 49% 51% 47% 53% / 54% 46% 52% 48%;
  background: color-mix(in srgb, var(--orange-note) 7%, var(--papier-note));
  box-shadow: 4px 7px 16px var(--ombre-papier);
  rotate: -0.45deg;
  animation: cadre-enrolement-apparition 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

main[data-vue="enroler"] .pin-code {
  min-height: 4.6rem;
  margin: 0;
  align-items: center;
  gap: clamp(0.38rem, 2vw, 0.7rem);
}

main[data-vue="enroler"] .pin-chiffre {
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--orange-note);
  font-family: var(--police-main);
  font-size: clamp(2.7rem, 11vw, 4rem);
  font-weight: 650;
  line-height: 1;
  text-shadow: 1px 2px 0 color-mix(in srgb, var(--orange-note) 15%, transparent);
}

main[data-vue="enroler"] .pin-chiffre:nth-child(even) {
  translate: 0 0.08rem;
  rotate: 1deg;
}

main[data-vue="enroler"] .pin-attente {
  color: var(--encre-legere);
  font-size: 1rem;
  text-align: center;
}

body.mode-public main[data-vue="options"] {
  display: grid;
  width: 100%;
  min-height: 100dvh;
  padding: clamp(1.5rem, 5vw, 3rem) 1.5rem 7rem;
  place-items: center;
}

main[data-vue="options"] .options-publiques {
  width: min(36rem, 100%);
  gap: clamp(2.5rem, 7vh, 4rem);
}

main[data-vue="options"] .options-publiques .option:not(:last-child)::after {
  bottom: calc(clamp(2.5rem, 7vh, 4rem) / -2);
}

main[data-vue="options"] .options-publiques .option h2 {
  margin-bottom: 1rem;
}

main[data-vue="options"] .options-publiques .opt-bascules {
  margin-top: 0;
}

main[data-vue="options"] .option-enrolement .option-note {
  margin-top: 0;
}

main[data-vue="options"] .option-enrolement .pin-code {
  min-height: 4.6rem;
  margin: 1rem 0 0;
  align-items: center;
}

main[data-vue="options"] .opt-diagnostic-local {
  width: min(30rem, 100%);
  margin: 0.5rem auto 0;
}

main[data-vue="options"] .opt-diagnostic-local summary {
  width: fit-content;
  margin-inline: auto;
  color: var(--texte-secondaire);
  cursor: pointer;
  font-size: 0.95em;
}

main[data-vue="options"] .opt-diagnostic-local summary:focus-visible {
  outline: 2px solid var(--lavande);
  outline-offset: 0.3rem;
}

main[data-vue="options"] .opt-diagnostic-local dl {
  margin-top: 1rem;
}

main[data-vue="options"] .opt-diagnostic-local .option-note {
  margin-top: 0.5rem;
  font-size: 0.88em;
}

main[data-vue="options"] .option-enrolement .pin-chiffre {
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--orange-note);
  font-family: var(--police-main);
  font-size: clamp(2.7rem, 11vw, 4rem);
  font-weight: 650;
  line-height: 1;
}

main[data-vue="options"] .option-enrolement .pin-chiffre:nth-child(even) {
  translate: 0 0.08rem;
  rotate: 1deg;
}

main[data-vue="options"] .option-enrolement .pin-attente {
  color: var(--encre-legere);
  font-size: 1rem;
  text-align: center;
}

@keyframes cadre-enrolement-apparition {
  from { opacity: 0; scale: 0.92; translate: 0 0.6rem; }
  to { opacity: 1; scale: 1; translate: 0; }
}

/* Sur un téléphone invité, l'espace vertical appartient à la question et au
   clavier. Le nom de l'automatisme disparaît et l'aide devient un simple œil,
   gris éteint puis cyan allumé. L'iPad conserve l'en-tête complet. */
@media (max-width: 700px), (max-width: 1000px) and (max-height: 520px) {
  body.mode-public main[data-vue="automatismes"]:has(.exo) {
    padding-top: max(0.8rem, env(safe-area-inset-top));
  }

  body.mode-public main[data-vue="automatismes"] .exo-tete h1,
  body.mode-public main[data-vue="automatismes"] .bascule-visuel-case {
    display: none;
  }

  body.mode-public main[data-vue="automatismes"] .exo-tete > .bascule-visuel {
    top: 0;
    right: 0;
    width: 2.75rem;
    height: 2.75rem;
    justify-content: center;
    gap: 0;
    color: var(--encre-legere);
    opacity: 0.48;
    rotate: -1deg;
    transition: color 160ms ease, opacity 160ms ease, rotate 160ms ease;
  }

  body.mode-public main[data-vue="automatismes"] .bascule-visuel-mobile {
    display: block;
    width: 2rem;
    height: 1.45rem;
    overflow: visible;
    fill: none;
    stroke: currentColor;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 1.8;
  }

  body.mode-public main[data-vue="automatismes"] .bascule-visuel-mobile .trace-reprise {
    opacity: 0.3;
    stroke-width: 0.9;
  }

  body.mode-public main[data-vue="automatismes"]
    .bascule-visuel:has(input:checked) {
    color: var(--cyan);
    opacity: 1;
    rotate: 1deg;
  }

  body.mode-public main[data-vue="automatismes"]
    .bascule-visuel input:focus-visible ~ .bascule-visuel-mobile {
    border-radius: 50%;
    outline: 1.5px solid var(--cyan);
    outline-offset: 0.3rem;
  }

  body.mode-public main[data-vue="automatismes"] .bascule-visuel-texte {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
