/*
 * Design system — étape 0.
 * Thème Kapibou (kit d'identité, cf. web/img/LISEZ-MOI.md), mobile-first.
 * Accessibilité dys native (claude.md règle d'or #15) : police adaptable, taille/interligne
 * réglables, fort contraste, grandes cibles tactiles. Les préférences d'un profil enfant
 * piloteront ces variables via les classes/attributs sur <html>.
 *
 * Contraintes non négociables du kit :
 *   - JAMAIS de blanc pur (le fond crème réduit l'éblouissement des lecteurs dys).
 *   - JAMAIS de rouge (« le rouge, c'est le stylo du prof ») — les erreurs se signalent en Miel.
 *   - Police de lecture = Atkinson Hyperlegible ; titres/logo = Baloo 2. Pas d'OpenDyslexic.
 */

/* Polices du kit (licence SIL OFL). Servies depuis le CDN fontsource (jsDelivr) :
   pas d'étape de build côté SWA. Repli système immédiat via font-display: swap.
   Pour un self-host sans réseau tiers, poser les .woff2 sous /img/fonts et remplacer les URL. */
@font-face {
  font-family: "Atkinson Hyperlegible"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("https://cdn.jsdelivr.net/fontsource/fonts/atkinson-hyperlegible@latest/latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Atkinson Hyperlegible"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("https://cdn.jsdelivr.net/fontsource/fonts/atkinson-hyperlegible@latest/latin-700-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Baloo 2"; font-style: normal; font-weight: 800; font-display: swap;
  src: url("https://cdn.jsdelivr.net/fontsource/fonts/baloo-2@latest/latin-800-normal.woff2") format("woff2");
}

/* Jetons de marque Kapibou (source unique : web/img/couleurs.css, dupliqués ici pour
   éviter une dépendance de chargement — garder synchronisés). */
:root {
  --kb-creme:        #FBF3E4;  /* fond principal — jamais de blanc pur */
  --kb-creme-fonce:  #F3E6CD;  /* cartes, blocs secondaires */
  --kb-brun:         #B5794E;  /* pelage de Kapi */
  --kb-brun-profond: #8A5733;  /* oreilles, ombres */
  --kb-brun-sombre:  #6B3F26;  /* intérieur d'oreille */
  --kb-museau:       #4A3428;  /* truffe, bouche */
  --kb-encre:        #2B2420;  /* texte, yeux */
  --kb-miel:         #E0913A;  /* accent : action, boutons, signalement */
  --kb-vert-eau:     #46907F;  /* accent : acquis, validation */
  --kb-brun-clair:   #C98A5C;  /* pelage sur fond sombre */
}

:root {
  /* Palette — le design system (--sc-*) est mappé sur les jetons de marque (--kb-*). */
  --sc-bg: var(--kb-creme);
  --sc-surface: var(--kb-creme-fonce);
  --sc-ink: var(--kb-encre);
  --sc-muted: var(--kb-brun-profond);
  --sc-primary: var(--kb-brun);
  --sc-primary-ink: var(--kb-creme);
  --sc-accent: var(--kb-miel);
  --sc-success: var(--kb-vert-eau);      /* acquis / validation */
  --sc-danger: var(--kb-miel);           /* pas de rouge : le signalement se fait en Miel */
  --sc-warning: var(--kb-miel);
  --sc-border: var(--kb-brun-clair);

  /* Typographie — pilotable par les préférences dys.
     Baloo 2 pour les titres, Atkinson Hyperlegible pour le corps (kit d'identité). */
  --sc-font: "Atkinson Hyperlegible", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --sc-font-title: "Baloo 2", "Atkinson Hyperlegible", system-ui, sans-serif;
  --sc-font-size: 17px;
  --sc-line-height: 1.7;
  --sc-letter-spacing: 0.01em;

  /* Rayons / espacements */
  --sc-radius: 16px;
  --sc-tap: 48px; /* cible tactile mini */
}

/* Préférence : police adaptée dys.
   Le kit prescrit Atkinson Hyperlegible (Braille Institute) et déconseille explicitement
   OpenDyslexic. On renforce donc espacement/interligne sur la même famille. */
html[data-font="dys"] {
  --sc-letter-spacing: 0.05em;
  --sc-line-height: 2;
  word-spacing: 0.12em;
}
/* Préférence : taille de texte confort. */
html[data-textsize="large"] { --sc-font-size: 20px; }
html[data-textsize="xlarge"] { --sc-font-size: 23px; }
/* Préférence : fort contraste — reste dans la palette du kit (pas de blanc/noir purs).
   Fond crème, encre poussée au museau le plus sombre, bordures encre. */
html[data-contrast="high"] {
  --sc-bg: var(--kb-creme);
  --sc-ink: var(--kb-encre);
  --sc-muted: var(--kb-museau);
  --sc-border: var(--kb-encre);
  --sc-surface: var(--kb-creme);
}
/* Préférence : réduire les animations. */
html[data-motion="reduced"] *,
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

* { box-sizing: border-box; }

/* Barre de défilement verticale aux couleurs du site (claude.md règle d'or #21).
   Piste crème foncé, curseur miel (brun au survol). Appliquée à TOUT le site :
   - Firefox / standard : scrollbar-color sur html (hérité par les enfants scrollables).
   - WebKit (Chrome/Edge/Safari) : ::-webkit-scrollbar sur tout élément scrollable.
   Ne jamais restyler une barre au cas par cas : cette règle est la source unique. */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--kb-miel) var(--kb-creme-fonce);
}
*::-webkit-scrollbar { width: 12px; height: 12px; }
*::-webkit-scrollbar-track { background: var(--kb-creme-fonce); border-radius: 8px; }
*::-webkit-scrollbar-thumb {
  background: var(--kb-miel);
  border-radius: 8px;
  border: 3px solid var(--kb-creme-fonce);
}
*::-webkit-scrollbar-thumb:hover { background: var(--kb-brun); }

/* La chaîne de hauteur html→body permet au sticky footer (badge de version) de
   se caler au bas de la fenêtre sur les pages courtes : body min-height:100vh
   n'a d'effet que si html occupe déjà toute la hauteur. */
html { height: 100%; }
/* Aucun défilement horizontal dans l'app : garde-fou contre tout débordement latéral
   (élément décoratif, largeur fixe…) qui provoquerait un scroll horizontal sur mobile. */
html, body { overflow-x: hidden; }
body { width: 100%; }

body {
  margin: 0;
  /* Sticky footer : le body remplit au moins la fenêtre et empile ses enfants
     en colonne, pour que le badge de version (#sc-version-badge, margin-top:auto)
     se cale tout en bas de la PAGE sans chevaucher le contenu (cf. version.js). */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: var(--sc-font);
  font-size: var(--sc-font-size);
  line-height: var(--sc-line-height);
  letter-spacing: var(--sc-letter-spacing);
  color: var(--sc-ink);
  background: var(--sc-bg);
}

/* Titres en Baloo 2 (kit d'identité : « logo et titres uniquement »). */
h1, h2, h3, .kb-title {
  font-family: var(--sc-font-title);
  letter-spacing: 0;
}

.sc-container { width: 100%; max-width: 900px; margin: 0 auto; padding: 1.25rem; box-sizing: border-box; }

/* Petite animation « pop » (coche de succès) — respecte le réglage « réduire les animations ». */
@keyframes kb-pop { 0% { transform: scale(0); } 60% { transform: scale(1.25); } 100% { transform: scale(1); } }
.kb-pop { display: inline-block; animation: kb-pop .35s ease-out; }
html[data-motion="reduced"] .kb-pop, html[data-motion="reduced"] .fa-spin { animation: none; }

/* Animation d'envoi d'e-mail : avion en papier qui flotte puis s'envole (fiche envoyée). */
.kb-plane-stage {
  position: relative; height: 72px; display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.kb-plane-stage .kb-plane { font-size: 2.6rem; color: var(--sc-accent); }
.kb-plane-stage .kb-plane-check { font-size: 3rem; color: var(--sc-success); }
/* En attente : l'avion « flotte » (léger tangage) en boucle. */
@keyframes kb-plane-bob {
  0%,100% { transform: translate(0,0) rotate(-4deg); }
  50%     { transform: translate(0,-6px) rotate(2deg); }
}
.kb-plane-stage.is-flying .kb-plane { animation: kb-plane-bob 1s ease-in-out infinite; }
/* Succès : l'avion décolle vers le haut-droite et disparaît. */
@keyframes kb-plane-away {
  0%   { transform: translate(0,0) rotate(0deg) scale(1); opacity: 1; }
  100% { transform: translate(160px,-120px) rotate(18deg) scale(.6); opacity: 0; }
}
.kb-plane-stage.is-sent .kb-plane { animation: kb-plane-away .6s ease-in forwards; }
/* Respect du réglage « réduire les animations » : avion fixe, pas de vol. */
html[data-motion="reduced"] .kb-plane-stage .kb-plane { animation: none !important; }

.sc-btn {
  display: inline-flex; align-items: center; justify-content: center;
  /* text-align:center + line-height confortable : un libellé qui passe sur 2 lignes
     (ex. « Espace parent » sur mobile) reste bien centré, chaque ligne comprise. */
  min-height: var(--sc-tap); padding: .35rem 1.25rem; line-height: 1.2; text-align: center;
  border: none; border-radius: var(--sc-radius);
  background: var(--sc-primary); color: var(--sc-primary-ink);
  font: inherit; font-weight: 700; cursor: pointer; text-decoration: none;
  transition: transform .08s ease, filter .15s ease;
}
/* Un lien stylé en bouton (.sc-btn sur un <a>) ne doit jamais être souligné. */
.sc-btn:hover, .sc-btn:focus { text-decoration: none; }
.sc-btn:hover { filter: brightness(1.05); }
.sc-btn:active { transform: translateY(1px); }
.sc-btn-accent { background: var(--sc-accent); }
.sc-btn-danger { background: var(--sc-danger); }
/* Bouton secondaire « fantôme » : contour, fond transparent, texte primaire. Sert aux actions de
   NAVIGATION discrètes (pas les actions principales, qui restent pleines/accent). */
.sc-btn-ghost {
  background: transparent; color: var(--sc-primary);
  border: 2px solid var(--sc-primary);
}
.sc-btn-ghost:hover { filter: none; background: var(--sc-primary); color: var(--sc-primary-ink); }

.sc-card {
  background: var(--sc-surface);
  border: 1px solid var(--sc-border);
  border-radius: var(--sc-radius);
  padding: 1.25rem;
}

/* État vide (claude.md règle d'or #14) — jamais de texte brut à la place. */
.sc-state { text-align: center; padding: 3rem 1rem; color: var(--sc-muted); }
.sc-state-icon { font-size: 2.5rem; margin-bottom: .5rem; }
.sc-state h3 { margin: .25rem 0; color: var(--sc-ink); }

/* Modale (claude.md règle d'or #13) — remplace tout alert/confirm/prompt natif. */
.sc-modal-backdrop {
  position: fixed; inset: 0; background: rgba(20, 24, 48, .45);
  display: none; align-items: center; justify-content: center; padding: 1rem; z-index: 1000;
}
.sc-modal-backdrop.open { display: flex; }
/* Empêche la page derrière la modale de défiler (scroll chaining). Posé sur <html> quand une
   modale est ouverte, par js/modal.js. Le contenu de la modale garde son propre scroll. */
html.kb-modal-lock, html.kb-modal-lock body { overflow: hidden; }
.sc-modal-backdrop { overscroll-behavior: contain; }
.sc-modal {
  background: var(--sc-surface); border-radius: var(--sc-radius);
  max-width: 480px; width: 100%; padding: 1.5rem;
  box-shadow: 0 20px 60px rgba(20, 24, 48, .25);
}
.sc-modal-head { font-size: 1.2rem; font-weight: 800; margin-bottom: .5rem; }
.sc-modal-head-danger { color: var(--sc-danger); }
.sc-modal-actions { display: flex; gap: .5rem; justify-content: flex-end; margin-top: 1.25rem; }

/* Variante large pour un contenu riche et long (ex. fiche découverte de Kapi).
   Le corps défile à l'intérieur de la modale ; l'en-tête (bouton fermer) reste visible. */
.sc-modal--wide {
  max-width: 780px; padding: 0;
  max-height: 92vh; display: flex; flex-direction: column; overflow: hidden;
}
.sc-modal--wide .kb-pdf-modal-head {
  padding: .85rem 1.1rem; border-bottom: 1px solid var(--sc-border);
  position: sticky; top: 0; background: var(--sc-surface); z-index: 2; flex: 0 0 auto;
  margin-bottom: 0;
}
.sc-modal--wide .sc-modal-body { overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }

/* Variante SCROLLABLE à largeur STANDARD : plafonne la hauteur sur petit écran et rend le CORPS
   défilable, en gardant l'en-tête (titre) et le pied (actions) toujours visibles. À utiliser pour
   toute modale standard dont le contenu peut dépasser l'écran (ex. réglages, formulaire court). */
.sc-modal--scroll {
  max-height: 90vh; max-height: 90dvh; display: flex; flex-direction: column; overflow: hidden;
}
.sc-modal--scroll .sc-modal-head,
.sc-modal--scroll .sc-modal-actions { flex: 0 0 auto; }
.sc-modal--scroll .sc-modal-body {
  flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  margin: 0 -.25rem; padding: 0 .25rem;   /* évite de rogner le halo de focus des champs au bord */
}

/* Bouton « Qui est Kapi ? » sous la mascotte du hero : discret, joueur, non concurrent des CTA. */
.kb-kapi-link {
  display: inline-flex; align-items: center; gap: .4rem;
  background: color-mix(in srgb, var(--kb-miel) 14%, transparent);
  color: var(--kb-brun-profond); font: inherit; font-weight: 700; font-size: .95rem;
  border: 2px dashed color-mix(in srgb, var(--kb-miel) 55%, transparent);
  border-radius: 999px; padding: .35rem .95rem; cursor: pointer;
  margin: 0 auto 1rem; transition: background-color .15s ease, transform .1s ease;
}
.kb-kapi-link:hover { background: color-mix(in srgb, var(--kb-miel) 24%, transparent); }
.kb-kapi-link:active { transform: translateY(1px); }
.kb-kapi-link:focus-visible { outline: 3px solid var(--sc-primary); outline-offset: 2px; }
.kb-kapi-link i { color: var(--kb-miel); }
html[data-motion="reduced"] .kb-kapi-link { transition: none; }

/* Toast — texte en crème sur encre (jamais de blanc pur). */
.sc-toast {
  position: fixed; left: 50%; bottom: 1.5rem; transform: translateX(-50%);
  background: var(--sc-ink); color: var(--kb-creme); padding: .75rem 1.25rem;
  border-radius: var(--sc-radius); z-index: 1100; opacity: 0; transition: opacity .2s ease;
  pointer-events: none;   /* invisible (opacity:0) mais présent : ne doit JAMAIS capter un tap */
}
.sc-toast.show { opacity: 1; }

/* Toast de RÉCOMPENSE : chaleureux (dégradé miel→brun, texte crème), pour célébrer un trophée. */
.kb-toast-reward {
  background: linear-gradient(135deg, var(--kb-miel, #E0913A), var(--kb-brun, #B5794E));
  color: var(--kb-creme, #FBF3E4); font-weight: 800;
  box-shadow: 0 6px 20px rgba(138, 87, 51, .35);
  border: 2px solid var(--kb-creme, #FBF3E4);
}
.kb-toast-reward i { color: var(--kb-creme, #FBF3E4); }

/* Champ PIN masqué SANS type="password" : le navigateur ne le voit pas comme un mot de passe
   (pas de popup « enregistrer/mettre à jour le mot de passe »), mais les caractères restent
   masqués visuellement. Combiner avec autocomplete="off" + inputmode="numeric" sur l'input. */
.kb-pin {
  -webkit-text-security: disc;   /* Chromium/Brave/Safari */
  text-security: disc;           /* futur standard */
}

/* Champ mot de passe avec œil d'affichage/masquage à droite.
   Envelopper l'<input type="password"> dans <span class="kb-pw"> + bouton .kb-pw-eye.
   L'input garde ses styles ; on lui réserve la place de l'œil à droite. */
.kb-pw { position: relative; display: block; }
.kb-pw > input { padding-right: 3rem !important; }
.kb-pw-eye {
  position: absolute; top: 0; right: 0; height: 100%; width: 3rem;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 0; padding: 0; cursor: pointer;
  color: var(--sc-muted); font-size: 1.15rem; line-height: 1;
  border-radius: 0 var(--sc-radius) var(--sc-radius) 0;
}
.kb-pw-eye:hover { color: var(--sc-primary); }
.kb-pw-eye:focus-visible { outline: 2px solid var(--sc-primary); outline-offset: -2px; }

/* Champ OTP à cases : gros chiffres VISIBLES, une case par chiffre. */
.kb-otp { display: flex; gap: .5rem; justify-content: center; margin: .25rem 0 .5rem; }
.kb-otp-cell {
  width: 2.8rem; height: 3.4rem; padding: 0; text-align: center;
  font-family: var(--sc-font-title, inherit); font-size: 1.8rem; font-weight: 800; color: var(--sc-ink);
  background: var(--sc-bg); border: 2px solid var(--sc-border); border-radius: var(--sc-radius);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.kb-otp-cell:focus {
  outline: none; border-color: var(--sc-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sc-primary) 22%, transparent);
}
@media (max-width: 380px) { .kb-otp-cell { width: 2.3rem; height: 3rem; font-size: 1.5rem; } .kb-otp { gap: .35rem; } }

/* Lien « Retour » (claude.md) : toujours précédé d'une flèche vers la gauche.
   Utiliser .kb-back sur tout lien de retour/navigation arrière ; ne jamais poser un « Retour »
   textuel sans cette flèche. La flèche est décorative (ajoutée en ::before). */
.kb-back {
  display: inline-flex; align-items: center; gap: .5rem;
  color: var(--sc-muted); text-decoration: none;
}
/* La flèche est une icône Font Awesome Pro injectée par version.js (compatible avec le mode
   SVG+JS du kit). Grosse et marquée : accent + taille renforcée. */
.kb-back .kb-back-icon { color: var(--sc-primary); font-size: 1.5em; line-height: 1; }
.kb-back:hover { color: var(--sc-ink); }
.kb-back:hover .kb-back-icon { color: var(--sc-ink); }

/* Lien texte soigné (ex. « Mot de passe oublié »). Cible tactile confortable, soulignement
   discret qui s'anime au survol, pictogramme optionnel injecté via .kb-textlink-icon. */
.kb-textlink {
  display: inline-flex; align-items: center; gap: .45rem;
  color: var(--sc-primary); font-size: .95rem; font-weight: 600;
  text-decoration: none; padding: .35rem .2rem; border-radius: var(--sc-radius);
  transition: color .15s ease;
}
.kb-textlink > span { position: relative; }
/* Soulignement animé : trait fin sous le libellé, déployé au survol/focus. */
.kb-textlink > span::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1.5px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform .18s ease;
}
.kb-textlink:hover, .kb-textlink:focus-visible { color: var(--sc-ink); }
.kb-textlink:hover > span::after, .kb-textlink:focus-visible > span::after { transform: scaleX(1); }
.kb-textlink .kb-textlink-icon { font-size: .9em; opacity: .85; }

/* Rendu de fiche aéré (lisibilité, accessibilité dys). L'espacement s'accentue en mode dys. */
#sheet h2.kb-sec-head { margin: 1.5rem 0 .6rem; display: flex; align-items: center; gap: .5rem; }
#sheet .kb-sec-emoji { font-size: 1.3em; flex: 0 0 auto; }
/* Le titre de section reste TOUJOURS dans le cadre : peut rétrécir (min-width:0) et couper un mot
   trop long (overflow-wrap) plutôt que déborder à droite. */
#sheet .kb-sec-title { min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
#sheet .kb-sec-list { margin: .4rem 0; padding-left: 1.4rem; }
#sheet .kb-sec-list li { margin: .5rem 0; line-height: inherit; }
#sheet .kb-sec-example {
  font-style: italic; color: var(--sc-muted);
  background: var(--sc-bg); border-radius: var(--sc-radius); padding: .6rem .9rem; margin: .6rem 0 0;
}
/* Liste de points-clés (préfixés ✅) : pas de puce native, l'emoji tient lieu de marqueur. */
#sheet .kb-check-list { list-style: none; margin: .4rem 0; padding-left: 0; }
#sheet .kb-check-list li { margin: .5rem 0; line-height: inherit; }
html[data-font="dys"] #sheet .kb-check-list li { margin: .8rem 0; }

/* En mode police adaptée (dys) : on aère davantage les listes de la fiche. */
html[data-font="dys"] #sheet .kb-sec-list li { margin: .8rem 0; }
html[data-font="dys"] #sheet .kb-sec-head { margin-top: 2rem; }

/* Modale d'attente de génération (non fermable) : Kapi de la matière + animation. */
.kb-wait-card { text-align: center; max-width: 360px; }
.kb-wait-stage {
  --kb-wait-color: var(--sc-primary);
  position: relative; width: 140px; height: 140px; margin: .5rem auto 1rem;
  display: flex; align-items: center; justify-content: center;
}
/* Anneau qui tourne autour de Kapi. */
.kb-wait-ring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 5px solid var(--sc-border);
  border-top-color: var(--kb-wait-color);
  animation: kb-spin 1s linear infinite;
}
.kb-wait-kapi { width: 96px; height: auto; animation: kb-bob 1.6s ease-in-out infinite; }
@keyframes kb-spin { to { transform: rotate(360deg); } }
@keyframes kb-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.kb-wait-title { font-family: var(--sc-font-title); font-weight: 800; font-size: 1.25rem; color: var(--sc-ink); }
.kb-wait-text { color: var(--sc-muted); margin: .4rem 0 1rem; }
/* Trois points animés. */
.kb-wait-dots { display: flex; gap: .4rem; justify-content: center; }
.kb-wait-dots span {
  width: 10px; height: 10px; border-radius: 50%; background: var(--sc-primary);
  animation: kb-dot 1.2s ease-in-out infinite;
}
.kb-wait-dots span:nth-child(2) { animation-delay: .2s; }
.kb-wait-dots span:nth-child(3) { animation-delay: .4s; }
@keyframes kb-dot { 0%,100% { opacity: .3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-5px); } }
/* Respect de la préférence « réduire les animations » (règle #15). */
html[data-motion="reduced"] .kb-wait-ring,
html[data-motion="reduced"] .kb-wait-kapi,
html[data-motion="reduced"] .kb-wait-dots span { animation: none; }

/* Modale de score du quiz : mascotte de la matière + score + message. */
.kb-score-card { text-align: center; max-width: 380px; }
.kb-score-kapi { width: 120px; height: auto; display: block; margin: 0 auto .5rem; }
.kb-score-value { font-family: var(--sc-font-title); font-weight: 800; font-size: 1.8rem; color: var(--sc-primary); }
.kb-score-msg { color: var(--sc-ink); font-size: 1.15rem; margin-top: .4rem; }

/* Champ de saisie en erreur (validation front) : bord rouge marqué + petit message d'aide.
   Rouge assumé ici (feedback de saisie), distinct du Miel de --sc-danger réservé aux actions. */
.kb-field-invalid { border-color: #D64545 !important; box-shadow: 0 0 0 3px rgba(214, 69, 69, .18); }
.kb-field-hint { color: #D64545; font-size: .9rem; margin: .35rem 0 0; }

/* Modale « plus de quota IA » (quota.js) : Kapi calme + message bienveillant + date de réinitialisation.
   Chiffres serveur (règle #16) ; fermeture explicite uniquement (règle #13). */
.kb-quota-card { text-align: center; max-width: 400px; }
.kb-quota-kapi { width: 120px; height: auto; display: block; margin: 0 auto .6rem; }
.kb-quota-title { font-family: var(--sc-font-title); font-weight: 800; font-size: 1.35rem; color: var(--sc-ink); margin: 0 0 .5rem; }
.kb-quota-text { color: var(--sc-ink); font-size: 1.05rem; line-height: 1.5; margin: 0 0 .6rem; }
.kb-quota-reset {
  color: var(--sc-primary); font-weight: 700; font-size: 1.05rem;
  background: var(--kb-creme-fonce); border-radius: var(--sc-radius);
  padding: .6rem .8rem; margin: 0 0 1rem;
}

/* Action IA verrouillée (quota atteint) : grisée + cadenas, cliquable pour réafficher l'explication.
   Vaut pour les cartes d'action (.kb-action) et les raccourcis de hub (.kb-tm-btn). Le cadenas est un
   <i class="fa-…"> injecté par quota.js (kit FA en mode SVG+JS, règle #18.1 : pas de ::before font FA). */
.is-locked {
  opacity: .55; filter: grayscale(.4); cursor: not-allowed;
  position: relative;
}
.is-locked:hover { transform: none; border-color: var(--sc-border); }
.kb-lock-badge {
  position: absolute; top: .4rem; right: .5rem;
  font-size: .85rem; color: var(--sc-muted);
}

/* Champ de formulaire (label + contrôle) : espacement vertical entre champs. */
.kb-field { display: block; margin-bottom: 1rem; }
.kb-field:last-child { margin-bottom: 0; }

/* Variante COMPACTE pour les formulaires denses (ex. modale de demande collège) : marge réduite,
   label resserré. Garde la taille de cible tactile de l'input (accessibilité #15). */
.kb-field-tight { margin-bottom: .6rem; }
.kb-field-tight > span { display: block; font-weight: 700; font-size: .9rem; margin-bottom: .2rem; }

/* Modale de demande collège : largeur mesurée + pied d'action fixe (bouton toujours visible, hors scroll). */
.kb-req-modal { max-width: 560px; }
.kb-req-foot {
  flex: 0 0 auto; padding: .85rem 1.25rem; border-top: 1px solid var(--sc-border);
  background: var(--sc-surface);
}

/* Séparateur horizontal entre blocs de formulaire. */
.kb-sep { height: 0; border: none; border-top: 1px solid var(--sc-border); margin: 1rem 0; }

/* CTA KapiQuiz « Jouer en famille » : mis en avant (pleine largeur, plus grand, ludique). */
.kb-kapiquiz-cta {
  display: flex; align-items: center; justify-content: center; gap: .6rem;
  width: 100%; margin: 1.5rem 0 0; text-decoration: none;
  font-size: 1.15rem; font-weight: 800; padding: .9rem 1.25rem;
  box-shadow: 0 6px 16px rgba(224, 145, 58, .35);
}
.kb-kapiquiz-cta .fa-wand-magic-sparkles { font-size: 1.3rem; }
.kb-kapiquiz-cta:hover { transform: translateY(-1px); box-shadow: 0 8px 20px rgba(224, 145, 58, .45); }

/* Bloc « Jouer en famille » : titre + deux CTA de jeux côte à côte sur une ligne. */
.kb-games-title { margin: 1.5rem 0 .6rem; font-size: 1.15rem; }
.kb-games-row { display: flex; gap: .75rem; }
.kb-games-row .kb-game-cta { flex: 1 1 0; width: auto; margin: 0; min-width: 0; }
/* Très petits écrans : on repasse en colonne pour garder le libellé lisible. */
@media (max-width: 360px) {
  .kb-games-row { flex-direction: column; }
}

/* Séparateur « OU » : un mot centré entre deux traits (choix alternatif entre deux blocs). */
.kb-or {
  display: flex; align-items: center; gap: .75rem;
  margin: 1rem 0; color: var(--sc-muted); font-weight: 800; text-transform: uppercase;
  font-size: .85rem; letter-spacing: .05em;
}
.kb-or::before, .kb-or::after {
  content: ""; flex: 1 1 auto; height: 0; border-top: 2px solid var(--sc-border);
}

/* Libellé de champ mis en avant (titre de section de formulaire). */
.kb-label {
  display: block; margin-bottom: .4rem;
  font-family: var(--sc-font-title, inherit); font-weight: 800; font-size: 1.05rem;
  color: var(--sc-ink);
}

/* Champ texte de base du design system. */
.kb-input {
  width: 100%; box-sizing: border-box; font: inherit; color: var(--sc-ink);
  padding: .65rem .85rem; border-radius: var(--sc-radius);
  border: 2px solid var(--sc-border); background: var(--sc-bg);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.kb-input::placeholder { color: var(--sc-muted); }
.kb-input:focus {
  outline: none; border-color: var(--sc-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sc-primary) 20%, transparent);
}

/* Champ de recherche avec loupe à gauche. */
.kb-search { position: relative; display: block; }
.kb-search .kb-search-ico {
  position: absolute; left: .85rem; top: 50%; transform: translateY(-50%);
  color: var(--sc-muted); pointer-events: none; font-size: .95rem;
}
.kb-search .kb-input { padding-left: 2.4rem; }
/* Retire la croix native du type=search (rendu incohérent selon navigateur). */
.kb-search .kb-input::-webkit-search-decoration,
.kb-search .kb-input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* <select> NATIF au style de l'app (jeton de marque, grande cible tactile dys — règle #15).
   À utiliser quand une simple liste suffit (pas d'icône par option) ; pour des options illustrées,
   préférer le composant custom .kb-select ci-dessous. Caret SVG couleur brun inline (aucune dépendance FA). */
.kb-select-native {
  width: 100%; box-sizing: border-box; font: inherit; font-weight: 700; color: var(--sc-ink);
  min-height: var(--sc-tap); padding: .55rem 2.6rem .55rem .85rem;
  border: 2px solid var(--sc-border); border-radius: var(--sc-radius); background-color: var(--sc-bg);
  -webkit-appearance: none; -moz-appearance: none; appearance: none; cursor: pointer;
  /* Chevron bas (brun profond #8A5733), posé à droite. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238A5733' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .9rem center;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.kb-select-native:hover { border-color: var(--sc-primary); }
.kb-select-native:focus-visible,
.kb-select-native:focus { outline: none; border-color: var(--sc-primary); box-shadow: 0 0 0 3px rgba(181, 121, 78, .22); }

/* Select personnalisé de matière (ask.html) : liste déroulante avec icône + couleur par option.
   Un <select> natif ne peut pas afficher d'icônes/SVG ; ce composant custom le remplace. */
.kb-select { position: relative; }
.kb-select-btn {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  padding: .6rem .8rem; border-radius: var(--sc-radius); cursor: pointer;
  border: 2px solid var(--sc-border); background: var(--sc-bg); color: var(--sc-ink);
  font: inherit; font-weight: 700; text-align: left;
  transition: border-color .12s ease;
}
.kb-select-btn:hover, .kb-select-btn[aria-expanded="true"] { border-color: var(--sc-primary); }
.kb-select-caret { color: var(--sc-muted); font-size: .8rem; transition: transform .12s ease; }
.kb-select-btn[aria-expanded="true"] .kb-select-caret { transform: rotate(180deg); }
.kb-select-current { display: inline-flex; align-items: center; gap: .5rem; min-width: 0; }
/* Liste déroulante : au-dessus du reste, scroll si longue. */
.kb-select-list {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + .3rem);
  margin: 0; padding: .3rem; list-style: none; max-height: 15rem; overflow-y: auto;
  background: var(--sc-bg); border: 2px solid var(--sc-border); border-radius: var(--sc-radius);
  box-shadow: 0 8px 24px rgba(0,0,0,.12);
}
.kb-select-opt {
  display: flex; align-items: center; gap: .5rem; padding: .5rem .6rem;
  border-radius: calc(var(--sc-radius) - 4px); cursor: pointer; font-weight: 700;
}
.kb-select-opt:hover { background: var(--sc-bg-soft, rgba(0,0,0,.04)); }
.kb-select-opt[aria-selected="true"] { background: var(--sc-bg-soft, rgba(0,0,0,.06)); }
/* Pastille colorée portant l'icône/le drapeau de la matière. */
.kb-opt-dot {
  --kb-opt-color: var(--sc-primary);
  flex: 0 0 auto; width: 1.7rem; height: 1.7rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--kb-opt-color) 18%, transparent);
}
.kb-opt-dot .kb-opt-ico { color: var(--kb-opt-color); font-size: .9rem; }
.kb-opt-dot .kb-opt-flag { width: 18px; height: auto; border-radius: 2px; display: block; }
.kb-opt-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Graphique SVG (réponse « graphique » d'une question). */
.kb-chart { background: var(--sc-bg); border-radius: var(--sc-radius); padding: .75rem; }
.kb-chart-title { font-weight: 800; text-align: center; margin-bottom: .5rem; color: var(--sc-ink); }

/* Historique « Mes questions » : ligne cliquable + bouton supprimer. */
.kb-qrow { display: flex; align-items: stretch; gap: .5rem; min-width: 0; }
.kb-qopen {
  flex: 1 1 auto; display: flex; align-items: center; gap: .6rem; min-width: 0;
  background: var(--sc-surface); border: 1px solid var(--sc-border); border-radius: var(--sc-radius);
  padding: .7rem .9rem; cursor: pointer; font: inherit; text-align: left; color: inherit;
}
.kb-qopen:hover { border-color: var(--sc-primary); }
.kb-qopen > .kb-qmode-dot { flex: 0 0 auto; }
.kb-qtext { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
.kb-qdate { flex: 0 0 auto; color: var(--sc-muted); font-size: .85rem; }
.kb-qdel { flex: 0 0 auto; align-self: center; background: var(--sc-bg); color: var(--sc-danger); }
.kb-qdel:hover { background: var(--sc-danger); color: #fff; }
/* Filtres « Mes questions » : boutons ronds à icône colorée, sans texte. */
.kb-qfilter {
  --kb-qfilter-color: var(--sc-primary);
  width: 2.6rem; height: 2.6rem; border-radius: 50%; flex: 0 0 auto; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: 2px solid var(--kb-qfilter-color); background: var(--sc-bg);
  color: var(--kb-qfilter-color); font-size: 1.05rem;
  transition: background .12s ease, color .12s ease, transform .1s ease;
}
.kb-qfilter:hover { transform: translateY(-1px); }
/* Filtre actif : rond plein à sa couleur, icône blanche. */
.kb-qfilter[aria-pressed="true"] { background: var(--kb-qfilter-color); color: #fff; }

/* En-tête de la modale de consultation : pastille colorée + icône de la rubrique. */
.kb-qmode-head {
  --kb-qmode-color: var(--sc-primary);
  display: inline-flex; align-items: center; gap: .5rem; color: var(--kb-qmode-color);
}
.kb-qmode-dot {
  width: 1.9rem; height: 1.9rem; border-radius: 50%; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--kb-qmode-color) 18%, transparent);
}
.kb-qmode-dot i { font-size: .95rem; }

/* ── Case à cocher tactile (STANDARD — claude.md règle #20) ──────────────────
   Toute case à cocher utilise .kb-check : grosse, bord épais, couleur de marque
   quand cochée. Facile à viser au doigt (accessibilité, grandes cibles). */
.kb-check {
  flex: 0 0 auto; width: 1.9rem; height: 1.9rem; margin: 0;
  accent-color: var(--sc-primary); cursor: pointer;
  transform: scale(1.15); transform-origin: center;
}

/* Ligne cliquable enveloppant une .kb-check + libellé (carte tactile).
   Utiliser .kb-check-row sur le <label> quand la case est présentée en « carte ». */
.kb-check-row {
  display: flex; align-items: center; gap: .8rem;
  min-height: 3.4rem; border: 3px solid var(--sc-border); border-radius: var(--sc-radius);
  padding: .7rem 1rem; cursor: pointer; font-weight: 700;
  transition: border-color .12s ease, background .12s ease;
}
.kb-check-row:hover { border-color: var(--sc-primary); }
/* Sélectionnée : bord + léger fond de la couleur primaire, bien visible. */
.kb-check-row.sel {
  border-color: var(--sc-primary);
  background: color-mix(in srgb, var(--sc-primary) 12%, transparent);
}

/* Alias historique : la sélection de fiche (quiz-setup) est une .kb-check-row. */
.kb-sheet-pick { }

/* Modale caméra (prise de photo du cours) : flux vidéo en direct. */
.kb-cam-card { max-width: 560px; width: 96%; }
.kb-cam-video {
  width: 100%; max-height: 60vh; background: #000;
  border-radius: var(--sc-radius); display: block; object-fit: contain;
}

/* Bouton « fermer » rond : croix Font Awesome centrée dans un cercle. */
.kb-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: 0 0 auto;
  border: none; border-radius: 50%; cursor: pointer;
  background: var(--sc-bg); color: var(--sc-muted);
  transition: background .12s ease, color .12s ease;
}
.kb-close i, .kb-close svg { font-size: 1rem; line-height: 1; }
.kb-close:hover { background: var(--sc-primary); color: #fff; }

/* Modale d'aperçu PDF : large, avec iframe occupant la hauteur disponible. */
.kb-pdf-modal { max-width: 900px; width: 96%; display: flex; flex-direction: column; }
.kb-pdf-modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
/* En-tête de modale avec pastille-icône colorée (reprend l'icône/couleur du bouton d'ouverture). */
.kb-modal-head-group { display: flex; align-items: center; gap: .7rem; min-width: 0; }
/* Dans le groupe, le titre ne porte pas sa marge basse (sinon décalé vers le haut face à l'icône centrée). */
.kb-modal-head-group .sc-modal-head { margin-bottom: 0; }
.kb-modal-head-ico {
  --kb-fc: var(--sc-primary);
  flex: 0 0 auto; width: 2.3rem; height: 2.3rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.05rem;
  color: #fff; background: var(--kb-fc);
}
/* Conteneur scrollable (le défilement tactile se fait ici, pas dans le viewer PDF interne). */
.kb-pdf-scroll {
  height: 75vh; overflow: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain; border: 1px solid var(--sc-border);
  border-radius: var(--sc-radius); background: var(--sc-bg);
}
.kb-pdf-frame { display: block; width: 100%; height: 75vh; border: 0; }
/* Sur écran tactile/mobile : on donne à l'iframe une grande hauteur et c'est le conteneur
   .kb-pdf-scroll qui gère le défilement tactile (le viewer PDF natif en iframe scrolle mal au doigt). */
@media (pointer: coarse), (max-width: 640px) {
  .kb-pdf-frame { height: 1400px; }
  /* L'iframe capterait le geste tactile (et scrolle mal) : on laisse le conteneur gérer le défilement. */
  .kb-pdf-scroll .kb-pdf-frame { pointer-events: none; }
  /* Sur mobile on n'affiche pas l'iframe mais l'écran « Ouvrir le PDF » : la zone épouse son contenu
     (pas de 75vh fixe qui créerait une grande zone vide). */
  .kb-pdf-scroll { height: auto; overflow: visible; }
}

/* Boutons avec icône + libellé (icône FA alignée au texte). */
.kb-iconbtn { gap: .5rem; }
.kb-iconbtn i { font-size: 1rem; }
/* Variante icône seule : carré à la hauteur de cible tactile. */
.kb-iconbtn--icononly { padding: 0; width: var(--sc-tap); flex: 0 0 auto; }
/* Bouton « Arrêter » injecté par speech.js à côté du bouton « Écouter » (pause/reprise).
   Petite marge de sécurité si le conteneur parent n'a pas de gap (ex. bulle du tuteur). */
.kb-speech-stop { margin-left: .4rem; }

/* En-tête de la page fiche : flèche retour à gauche, actions groupées à droite. */
.kb-sheet-head {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: .75rem; padding: 1rem 0;
}
.kb-sheet-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

/* Bibliothèque : accordéon par matière (library.html). En-tête coloré à la couleur de la matière. */
.kb-acc { border-radius: var(--sc-radius); overflow: hidden; box-shadow: 0 1px 4px rgba(43,36,32,.1); }
.kb-acc-head {
  --kb-acc-color: var(--sc-primary);
  width: 100%; display: flex; align-items: center; gap: .75rem;
  padding: .85rem 1rem; border: none; cursor: pointer;
  background: var(--kb-acc-color); color: #fff;
  font: inherit; font-weight: 800; text-align: left;
}
.kb-acc-icon { flex: 0 0 auto; display: inline-flex; }
.kb-acc-ico { font-size: 1.2rem; }
.kb-acc-icon img.kb-acc-ico { width: 26px; height: auto; border-radius: 3px; display: block; }
.kb-acc-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-acc-count {
  flex: 0 0 auto; background: rgba(255,255,255,.25); border-radius: 999px;
  min-width: 1.6em; height: 1.6em; padding: 0 .5em; display: inline-flex; align-items: center; justify-content: center;
  font-size: .85rem;
}
.kb-acc-chevron { flex: 0 0 auto; transition: transform .2s ease; }
.kb-acc-head[aria-expanded="true"] .kb-acc-chevron { transform: rotate(180deg); }

.kb-acc-body { background: var(--sc-surface); border: 1px solid var(--sc-border); border-top: none; }
.kb-acc-item {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: .8rem 1rem; text-decoration: none; color: inherit;
  border-top: 1px solid var(--sc-border);
}
.kb-acc-item:first-child { border-top: none; }
.kb-acc-item:hover { background: var(--sc-bg); }
.kb-acc-item-title { font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-acc-item-meta { flex: 0 0 auto; color: var(--sc-muted); font-size: .9rem; }

/* Jauge de consommation (modale « Ma consommation IA ») : piste claire avec cadre,
   remplissage de la couleur du cadre par défaut (les seuils 80 %/100 % sont posés en JS). */
.kb-gauge {
  position: relative; height: 26px; margin: .75rem 0;
  background: var(--sc-bg); border: 2px solid var(--sc-primary); border-radius: 999px;
  overflow: hidden;
}
.kb-gauge-fill { height: 100%; width: 0; background: var(--sc-primary); transition: width .3s ease; }
.kb-gauge-pct {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: .9rem; color: var(--sc-ink);
}

/* Phrase de motivation (space.html) : centrée, sans cadre, discrète mais soignée.
   L'icône (aléatoire) est calée sur la 1re ligne du texte, pas centrée verticalement. */
.kb-motivation {
  text-align: center; margin: .5rem auto 1.5rem; padding: 0 .5rem; max-width: 30rem;
  color: var(--sc-ink); font-family: var(--sc-font-title);
  font-size: 1.35rem; line-height: 1.4;
}
.kb-motivation-icon {
  color: var(--sc-accent); font-size: 1.15rem; margin-right: .5rem;
}
/* Le kit FA rend l'icône en <svg> : on le cale sur la ligne de texte. */
.kb-motivation-icon.fa-solid, .kb-motivation svg.kb-motivation-icon {
  vertical-align: -0.05em;
}
.kb-motivation-text { font-weight: 800; }

/* Grille des cartes d'action : 3 par ligne, repli à 2 puis 1 sur petits écrans.
   Prête à accueillir d'autres boutons sans changement. */
.kb-actions { display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); }
@media (max-width: 560px) { .kb-actions { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 360px) { .kb-actions { grid-template-columns: 1fr; } }

/* Cartes d'action de l'espace enfant (icône FA + libellé). */
.kb-action {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .6rem;
  text-decoration: none; color: inherit; text-align: center; min-height: 120px;
  padding: 1rem .5rem;
  transition: transform .08s ease, border-color .12s ease;
}
.kb-action:hover { transform: translateY(-2px); border-color: var(--sc-primary); }
.kb-action-icon { font-size: 2rem; color: var(--sc-primary); }
/* Icône-mascotte d'une carte d'action (plus fun qu'une icône FA) : Kapi déguisé,
   dimensionné pour s'aligner avec les icônes FA des autres tuiles. */
.kb-action-kapi { width: 3.2rem; height: 3.2rem; object-fit: contain; }
.kb-action:hover .kb-action-kapi { transform: scale(1.06); }
.kb-action > div { font-size: .95rem; line-height: 1.2; }
/* Tuile de JEU (ex. KapiGrille) : mascotte et libellé plus grands pour l'impact. */
.kb-action-game .kb-action-kapi { width: 4.6rem; height: 4.6rem; }
.kb-action-game > div { font-size: 1.2rem; }

/* Action PHARE « Aide-moi à apprendre » : pleine largeur, disposition horizontale, teinte miel.
   Placée en tête de la grille (grid-column: 1/-1) pour occuper toute la ligne. */
.kb-action-hero {
  grid-column: 1 / -1;
  flex-direction: row; gap: 1rem; min-height: 0; padding: 1.1rem 1.25rem;
  background: color-mix(in srgb, var(--sc-accent) 16%, var(--sc-surface));
  border-color: color-mix(in srgb, var(--sc-accent) 45%, var(--sc-border));
}
.kb-action-hero:hover { border-color: var(--sc-accent); }
.kb-action-hero .kb-action-icon { color: var(--sc-accent); flex: 0 0 auto; }
.kb-action-hero > div { font-size: 1.15rem; }

/* Code couleur par THÈME des actions de l'espace enfant : chaque tuile porte une classe kb-th-*
   qui fixe la teinte du thème (--kb-th) ; seuls l'ICÔNE et la BORDURE se colorent (fond crème
   conservé — anti-éblouissement dys, charte). Pour 4 thèmes NETTEMENT distincts, on réutilise les
   couleurs de MATIÈRES déjà employées dans l'app (web/js/subjects.js) : orangé/bleu/vert/violet.
   Définies comme jetons de thème dédiés (--kb-theme-*), jamais de couleur en dur sur la classe.
   Thèmes : comprendre (miel orangé) · fiches (bleu) · quiz (vert d'eau) · questions (violet). */
:root {
  --kb-theme-comprendre: var(--kb-miel);   /* orangé — cohérent avec les héros déjà miel */
  --kb-theme-fiches:      #3B6FB6;          /* bleu (maths) */
  --kb-theme-quiz:        var(--kb-vert-eau); /* vert d'eau */
  --kb-theme-questions:   #7A54B3;          /* violet (physique-chimie) */
  /* Thèmes par MATIÈRE pour les modules bonus — couleurs exactes de web/js/subjects.js. */
  --kb-theme-anglais:     #2E6DA4;          /* bleu drapeau (anglais) */
  --kb-theme-francais:    #B5495B;          /* framboise (français) */
  --kb-theme-maths:       #3B6FB6;          /* bleu (maths) */
  --kb-theme-histoire:    #C07A2C;          /* orangé (histoire-géo) */
  --kb-theme-espagnol:    #D9822B;          /* orangé drapeau (espagnol) */
  --kb-theme-allemand:    #4A4A4A;          /* gris foncé (allemand) */
  --kb-theme-italien:     #3E8E5A;          /* vert (italien) */
  --kb-theme-sciences:    #46907F;          /* vert d'eau (SVT/sciences) */
}
.kb-th-comprendre { --kb-th: var(--kb-theme-comprendre); }
.kb-th-fiches     { --kb-th: var(--kb-theme-fiches); }
.kb-th-quiz       { --kb-th: var(--kb-theme-quiz); }
.kb-th-questions  { --kb-th: var(--kb-theme-questions); }
.kb-th-anglais    { --kb-th: var(--kb-theme-anglais); }
.kb-th-francais   { --kb-th: var(--kb-theme-francais); }
.kb-th-maths      { --kb-th: var(--kb-theme-maths); }
.kb-th-histoire   { --kb-th: var(--kb-theme-histoire); }
.kb-th-espagnol   { --kb-th: var(--kb-theme-espagnol); }
.kb-th-allemand   { --kb-th: var(--kb-theme-allemand); }
.kb-th-italien    { --kb-th: var(--kb-theme-italien); }
.kb-th-sciences   { --kb-th: var(--kb-theme-sciences); }
/* Tuile normale : bordure teintée du thème + icône colorée (le survol renforce la bordure). */
.kb-action[class*="kb-th-"] { border-color: color-mix(in srgb, var(--kb-th) 42%, var(--sc-border)); }
.kb-action[class*="kb-th-"]:hover { border-color: var(--kb-th); }
.kb-action[class*="kb-th-"] .kb-action-icon { color: var(--kb-th); }
/* Héros : reprend la teinte du thème (fond légèrement teinté + bordure + icône), au lieu du miel fixe. */
.kb-action-hero[class*="kb-th-"] {
  background: color-mix(in srgb, var(--kb-th) 16%, var(--sc-surface));
  border-color: color-mix(in srgb, var(--kb-th) 45%, var(--sc-border));
}
.kb-action-hero[class*="kb-th-"]:hover { border-color: var(--kb-th); }
.kb-action-hero[class*="kb-th-"] .kb-action-icon { color: var(--kb-th); }

/* En-tête de l'espace enfant : carte propre avec avatar, salutation et bouton discret. */
.kb-home-head {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  background: var(--sc-surface); border: 1px solid var(--sc-border);
  border-radius: var(--sc-radius); padding: 1rem 1.25rem; margin: 1rem 0 1.5rem;
}
.kb-home-id { display: flex; align-items: center; gap: 1rem; text-decoration: none; color: inherit; flex: 1; min-width: 0; }
.kb-home-avatar {
  flex: 0 0 auto; width: 64px; height: 64px; border-radius: 50%;
  background: var(--sc-bg); display: flex; align-items: center; justify-content: center; overflow: hidden;
  box-shadow: inset 0 0 0 2px var(--sc-primary);
}
.kb-home-avatar img { width: 76%; height: auto; display: block; }
.kb-home-greet { display: flex; flex-direction: column; min-width: 0; }
.kb-home-hello {
  font-family: var(--sc-font-title); font-weight: 800; font-size: 1.5rem; line-height: 1.15;
  color: var(--sc-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;   /* évite le débordement sur 2 lignes */
}
.kb-home-sub { color: var(--sc-muted); font-size: .95rem; margin-top: .15rem; }
.kb-home-switch {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: .4rem;
  background: transparent; color: var(--sc-muted);
  border: 1px solid var(--sc-border); border-radius: 999px; padding: .5rem .9rem;
  font: inherit; font-size: .9rem; font-weight: 700; cursor: pointer;
  transition: border-color .12s ease, color .12s ease;
}
.kb-home-switch:hover { color: var(--sc-primary); border-color: var(--sc-primary); }
/* Variante icône seule (gagne de la place pour la salutation). Cible tactile ronde. */
.kb-home-switch--icon { padding: 0; width: var(--sc-tap); height: var(--sc-tap); justify-content: center; border-radius: 50%; }
.kb-home-switch--icon i { font-size: 1.1rem; }

/* Accessibilité : texte visible uniquement pour les lecteurs d'écran. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Grille de choix de matière : vrais boutons carrés colorés, 3 par ligne. */
.kb-subject-grid {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(3, 1fr);   /* exactement 3 par ligne */
}
.kb-subject {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .4rem;
  aspect-ratio: 1 / 1;                       /* carré */
  padding: .5rem .3rem;
  /* Couleur de fond propre à la matière, injectée en variable --kb-subj-color. */
  background: var(--kb-subj-color, var(--kb-brun));
  color: #fff;
  border: none; border-radius: var(--sc-radius);
  font: inherit; font-weight: 800; cursor: pointer; text-align: center;
  box-shadow: 0 2px 6px rgba(43,36,32,.15);
  transition: transform .08s ease, box-shadow .12s ease, filter .12s ease;
}
.kb-subject .kb-subject-icon { font-size: 2rem; line-height: 1; }
/* Drapeau SVG (langues) — vrai drapeau, lisible partout (Windows inclus), accessible dys. */
.kb-subject .kb-subject-flag {
  width: 46px; height: auto; display: block;
  border-radius: 4px; box-shadow: 0 1px 2px rgba(0,0,0,.35);
}
.kb-subject .kb-subject-label { font-size: .82rem; line-height: 1.1; }
.kb-subject:hover { filter: brightness(1.06); }
.kb-subject:active { transform: translateY(1px); }
/* Matière sélectionnée : anneau net + coche. */
.kb-subject[aria-pressed="true"] {
  outline: 4px solid var(--sc-ink);
  outline-offset: 1px;
  box-shadow: 0 4px 12px rgba(43,36,32,.3);
}
.kb-subject[aria-pressed="true"]::after {
  content: "\2713"; font-weight: 900;               /* ✓ coche unicode (indépendante de FA) */
  position: absolute; top: .3rem; right: .4rem; font-size: .9rem; color: var(--sc-ink);
  background: #fff; border-radius: 999px; width: 1.4em; height: 1.4em;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 1px 3px rgba(0,0,0,.3);
}
/* Titre de groupe (Sciences / Langues) : occupe toute la largeur. */
.kb-subject-group { grid-column: 1 / -1; font-weight: 800; color: var(--sc-muted); margin: .6rem 0 0; font-size: .95rem; }

/* Variante « Trouver une fiche » : boutons plus petits (pas carrés), icône plus grosse. */
.kb-subject-grid--find .kb-subject { aspect-ratio: auto; min-height: 7.5rem; padding: .9rem .4rem; gap: .5rem; }
.kb-subject-grid--find .kb-subject .kb-subject-icon { font-size: 2.9rem; }
.kb-subject-grid--find .kb-subject .kb-subject-flag { width: 58px; }

/* ─── Marque Kapibou ─────────────────────────────────────────────────────────
   Briques réutilisables pour poser logo, wordmark et mascotte de façon cohérente.
   Les SVG vivent sous /img (kit d'identité). Respecter la zone de respiration. */

/* Logo horizontal dans une barre de navigation (accueil, en-têtes). */
.kb-logo { display: inline-flex; align-items: center; text-decoration: none; }
.kb-logo img { height: 40px; width: auto; display: block; }         /* ≥ 120px de large */
.kb-logo--sm img { height: 32px; }

/* Wordmark seul, quand la place manque. */
.kb-wordmark img { height: 28px; width: auto; display: block; }

/* Mascotte Kapi — illustration décorative, ratio préservé, jamais déformée. */
.kb-mascotte { display: block; margin: 0 auto; max-width: 100%; height: auto; }
.kb-mascotte--hero { width: 180px; }
.kb-mascotte--card { width: 96px; }
.kb-mascotte--spot { width: 64px; }

/* Bandeau accent (CTA, section « dys ») : fond brun, illustration à côté du texte. */
.kb-band {
  background: var(--sc-primary); color: var(--sc-primary-ink);
  border-radius: var(--sc-radius);
}

/* Bannière d'installation PWA (bas d'écran, refermable). */
.kb-pwa-banner {
  position: fixed; left: .75rem; right: .75rem; bottom: .75rem; z-index: 200;
  display: flex; align-items: center; gap: .75rem;
  background: var(--sc-surface); border: 1px solid var(--sc-border); border-radius: var(--sc-radius);
  box-shadow: 0 8px 28px rgba(0,0,0,.18); padding: .75rem .9rem;
  max-width: 620px; margin: 0 auto;
}
.kb-pwa-banner-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.kb-pwa-banner-txt strong { font-family: var(--sc-font-title, inherit); }
.kb-pwa-banner-txt span { color: var(--sc-muted); font-size: .88rem; }
.kb-pwa-banner-act { flex: 0 0 auto; display: flex; align-items: center; gap: .4rem; }
.kb-pwa-close {
  flex: 0 0 auto; width: 2rem; height: 2rem; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: var(--sc-bg); color: var(--sc-muted);
}
.kb-pwa-close:hover { color: var(--sc-ink); }
/* Quand la bannière PWA (position:fixed, bas d'écran) est affichée, on réserve de l'espace sous le
   contenu pour qu'elle ne recouvre pas le dernier élément (ex. la section vidéo) — sinon en portrait
   mobile le tap est intercepté par la bannière. ~5.5rem (hauteur bannière) + safe-area iOS. */
body.kb-has-pwa-banner { padding-bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px)); }

/* Guide d'installation PWA : modale illustrée adaptée à l'appareil (iOS/Android/PC).
   Réutilise .sc-modal-backdrop/.sc-modal du design system ; styles propres aux étapes. */
.kb-ig-card { max-width: 440px; }
.kb-ig-lead { margin: .25rem 0 1rem; color: var(--sc-ink); line-height: 1.5; }
.kb-ig-steps { display: flex; flex-direction: column; gap: .7rem; margin: .25rem 0 .5rem; }
.kb-ig-step {
  display: flex; align-items: center; gap: .8rem;
  background: var(--sc-bg); border: 2px solid var(--sc-border);
  border-radius: var(--sc-radius); padding: .7rem .85rem;
}
.kb-ig-num {
  flex: 0 0 auto; width: 1.9rem; height: 1.9rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--kb-miel, #E0913A); color: #fff; font-weight: 800; font-size: 1rem;
}
.kb-ig-ic {
  flex: 0 0 auto; width: 2.4rem; height: 2.4rem; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--sc-surface); border: 2px solid var(--kb-brun-clair, #C98A5C);
  color: var(--kb-brun, #B5794E); font-size: 1.15rem;
}
.kb-ig-txt { flex: 1 1 auto; min-width: 0; line-height: 1.4; }
.kb-ig-txt strong { color: var(--kb-brun-profond, #8A5733); }
.kb-ig-actions { display: flex; flex-direction: column; gap: .5rem; }
.kb-ig-actions .sc-btn { width: 100%; }
html[data-font="dys"] .kb-ig-step { gap: 1rem; padding: .85rem 1rem; }
html[data-font="dys"] .kb-ig-steps { gap: .9rem; }

/* Bouton présenté comme un lien (ex. « Installer l'application » sur l'accueil) : discret mais tactile. */
.kb-link-btn {
  background: none; border: none; cursor: pointer; padding: .4rem .2rem;
  color: var(--kb-brun-profond, #8A5733); font: inherit; font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px;
}
.kb-link-btn:hover { color: var(--kb-brun, #B5794E); }

/* Barre de contrôle audio FLOTTANTE (fiche lue à voix haute) : suit le scroll (position:fixed) pour
   mettre en pause / reprendre sans remonter en haut (accessibilité #15). Visible pendant la lecture. */
.kb-audiobar {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); z-index: 210;
  display: flex; align-items: center; gap: .5rem;
  background: var(--sc-surface); border: 2px solid var(--kb-brun, #B5794E);
  border-radius: 999px; box-shadow: 0 8px 28px rgba(138, 87, 51, .35);
  padding: .5rem .6rem;
}
.kb-audiobar[hidden] { display: none; }
/* Quand la bannière PWA est aussi affichée, on remonte la barre audio pour ne pas la recouvrir. */
body.kb-has-pwa-banner .kb-audiobar { bottom: calc(6.5rem + env(safe-area-inset-bottom, 0px)); }
html[data-motion="reduced"] .kb-audiobar { transition: none; }

/* Bouton toggle « Surligner à la lecture » : atténué (grisé) quand le surlignage est désactivé. */
.kb-hl-btn.is-off { opacity: .5; }

/* Surlignage mot-à-mot pendant l'écoute (docs/CONCEPTION-SurlignageLecture.md). Chaque mot lu est
   enrobé dans .kb-w ; le mot en cours de lecture porte .is-reading. Doux et contrasté (dys, règle #15). */
.kb-w { border-radius: .2rem; transition: background-color .12s ease; }
.kb-w.is-reading {
  background: color-mix(in srgb, var(--kb-miel, #E0913A) 45%, transparent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--kb-miel, #E0913A) 45%, transparent);
}
html[data-motion="reduced"] .kb-w { transition: none; }

/* ── Page « Mes progrès » ──────────────────────────────────────────────────── */
/* Barre de progression réutilisable. */
.kb-progbar { background: var(--sc-border); border-radius: 999px; height: 14px; overflow: hidden; margin: .4rem 0; }
.kb-progbar-fill { height: 100%; border-radius: 999px; transition: width .5s ease; }

/* Bandeau de félicitations : mascotte + message personnalisé. */
.kb-prog-hero { display: flex; align-items: center; gap: 1rem; }
.kb-prog-hero-mascot { width: 72px; height: auto; flex: 0 0 auto; }
.kb-prog-hero-title { font-family: var(--sc-font-title, inherit); font-weight: 800; font-size: 1.2rem; color: var(--sc-ink); }
.kb-prog-hero-sub { color: var(--sc-muted); margin-top: .25rem; }

/* Tuiles de statistiques clés (2 par ligne mobile). */
.kb-prog-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; margin-top: .75rem; }
.kb-prog-stat {
  --kb-s: var(--sc-primary); min-width: 0;   /* autorise la tuile à rétrécir dans la grille */
  background: var(--sc-surface); border: 1px solid var(--sc-border); border-radius: var(--sc-radius);
  padding: .8rem; text-align: center;
}
.kb-prog-stat > i { color: var(--kb-s); font-size: 1.3rem; }
/* La valeur (ex. « matière préférée » au libellé long) doit passer à la ligne, jamais déborder. */
.kb-prog-stat-val { font-family: var(--sc-font-title, inherit); font-weight: 800; font-size: 1.3rem; color: var(--sc-ink); margin-top: .2rem; line-height: 1.2; overflow-wrap: anywhere; }
.kb-prog-stat-lbl { color: var(--sc-muted); font-size: .82rem; margin-top: .1rem; }

.kb-prog-h2 { font-family: var(--sc-font-title, inherit); font-weight: 800; font-size: 1.15rem; margin: 1.5rem 0 .6rem; }

/* ── Récompenses : série (streak) + grille de badges (salle des trophées) ────── */
/* Rappel de série sur l'espace enfant (lien discret vers la salle des trophées). */
.kb-streak-line {
  display: inline-flex; align-items: center; gap: .5rem; text-decoration: none;
  margin: .25rem 0 .75rem; padding: .4rem .8rem; border-radius: 999px;
  background: color-mix(in srgb, var(--kb-miel, #E0913A) 16%, transparent);
  color: var(--kb-brun-profond, #8A5733); font-weight: 800; font-size: .95rem;
}
.kb-streak-line i { color: var(--kb-miel, #E0913A); }

.kb-streak { display: flex; align-items: center; gap: 1rem; }
.kb-streak-flame {
  flex: 0 0 auto; width: 3.4rem; height: 3.4rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 1.6rem;
  color: #fff; background: linear-gradient(135deg, var(--kb-miel, #E0913A), var(--kb-brun, #B5794E));
}
.kb-streak-body { min-width: 0; }
.kb-streak-cur { font-weight: 800; font-size: 1.15rem; }
.kb-streak-best { color: var(--sc-muted); font-size: .95rem; }

.kb-badges-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; margin: 1.5rem 0 .6rem; }
.kb-badges-count { color: var(--sc-muted); font-weight: 700; font-size: .95rem; white-space: nowrap; }
.kb-badges-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: .75rem;
}
.kb-badge { margin: 0; text-align: center; display: flex; flex-direction: column; align-items: center; gap: .35rem; }
.kb-badge-img { width: 100%; max-width: 96px; aspect-ratio: 1; }
.kb-badge-name { font-size: .82rem; font-weight: 700; line-height: 1.2; }
.kb-badge.is-locked .kb-badge-name { color: var(--sc-muted); font-weight: 600; }
/* Un badge à débloquer reste discret (le verrou est déjà dessiné dans l'asset). */
.kb-badge.is-locked { opacity: .85; }

/* Bandeau de trophées côté rapport PARENT (activity.html). */
.kb-act-rewards { margin-bottom: 1rem; }
.kb-act-rewards-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; margin-bottom: .6rem; }
.kb-act-rewards-title { font-weight: 800; font-size: 1.05rem; }
.kb-act-rewards-streak { color: var(--sc-muted); font-weight: 700; font-size: .9rem; white-space: nowrap; }
.kb-act-badge-strip { display: flex; flex-wrap: wrap; gap: .75rem; }
.kb-act-badge-chip { margin: 0; width: 72px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: .25rem; }
.kb-act-badge-chip img { width: 56px; height: 56px; }
.kb-act-badge-chip figcaption { font-size: .72rem; font-weight: 700; line-height: 1.15; }

/* Carte de détail par matière. */
.kb-prog-subj { margin-top: .6rem; }
.kb-prog-subj-head { display: flex; align-items: center; gap: .5rem; margin-bottom: .2rem; }
.kb-prog-subj-name { font-weight: 800; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-prog-badge {
  --kb-b: var(--sc-primary); flex: 0 0 auto;
  font-size: .78rem; font-weight: 700; padding: .15rem .5rem; border-radius: 999px;
  color: var(--kb-b); background: color-mix(in srgb, var(--kb-b) 15%, transparent);
}
.kb-prog-subj-meta { display: flex; flex-wrap: wrap; gap: .3rem .9rem; color: var(--sc-muted); font-size: .88rem; }

/* Chronologie des derniers quiz. */
.kb-prog-recent { display: grid; grid-template-columns: minmax(0, 1fr); gap: .5rem; }
.kb-prog-rrow {
  display: flex; align-items: center; gap: .6rem;
  background: var(--sc-surface); border: 1px solid var(--sc-border); border-radius: var(--sc-radius); padding: .55rem .75rem;
}
.kb-prog-rmid { flex: 1 1 auto; min-width: 0; }
.kb-prog-rsubj { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-prog-rdate { color: var(--sc-muted); font-size: .82rem; }
.kb-prog-rscore { flex: 0 0 auto; font-family: var(--sc-font-title, inherit); font-weight: 800; font-size: 1.05rem; }

/* ══════════════════════════════════════════════════════════════════════════
   Page vitrine (index.html) — sections marketing soignées + animations.
   Réutilise les jetons de marque. Animations désactivées si data-motion=reduced.
   ══════════════════════════════════════════════════════════════════════════ */

/* Révélation au défilement (posée par le script inline de index.html). */
[data-reveal] { opacity: 0; transform: translateY(18px); transition: opacity .6s ease, transform .6s ease; }
[data-reveal].is-in { opacity: 1; transform: none; }
html[data-motion="reduced"] [data-reveal] { opacity: 1; transform: none; transition: none; }

/* Barre de navigation vitrine. */
.kb-nav { display: flex; justify-content: space-between; align-items: center; gap: .6rem 1rem; width: 100%; padding: 1rem 1.25rem; flex-wrap: wrap; }
.kb-nav .kb-logo { margin-right: auto; }   /* pousse le bouton à droite même si space-between est neutralisé */
.kb-nav .kb-logo img { height: 40px; width: auto; }

/* ── Hero ── */
.kb-hero {
  background:
    radial-gradient(1100px 380px at 50% -120px, var(--kb-creme-fonce), transparent 70%),
    var(--sc-bg);
  padding: 1rem 0 2.5rem;
}
.kb-hero-inner { text-align: center; max-width: 760px; }
.kb-hero-kapi {
  width: 150px; height: auto; display: block; margin: 0 auto .5rem;
  filter: drop-shadow(0 10px 18px rgba(107, 63, 38, .18));
  animation: kb-float 5s ease-in-out infinite;
}
@keyframes kb-float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
html[data-motion="reduced"] .kb-hero-kapi { animation: none; }
.kb-hero-title {
  font-size: clamp(1.9rem, 5vw, 2.9rem); line-height: 1.15; margin: .4rem 0 .6rem; color: var(--sc-ink);
}
.kb-hero-text { font-size: 1.12rem; color: var(--sc-muted); max-width: 640px; margin: 0 auto 1.4rem; }
.kb-hero-cta { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }

/* Pastille « essai gratuit ». */
.kb-pill {
  display: inline-flex; align-items: center; gap: .45rem;
  background: color-mix(in srgb, var(--kb-miel) 20%, transparent);
  color: var(--kb-brun-profond); font-weight: 700; font-size: .9rem;
  padding: .35rem .8rem; border-radius: 999px;
}
.kb-pill i { color: var(--kb-miel); }

/* Gros boutons d'appel à l'action. */
.kb-cta-lg { min-height: 54px; padding: 0 1.6rem; font-size: 1.05rem; text-decoration: none; }
.kb-cta-ghost { background: transparent; color: var(--sc-primary); border: 2px solid var(--sc-primary); }

/* Bandeau de réassurance sous le hero. */
.kb-trust {
  list-style: none; margin: 1.6rem 0 0; padding: 0;
  display: flex; gap: 1.2rem; flex-wrap: wrap; justify-content: center;
  color: var(--sc-muted); font-size: .95rem; font-weight: 600;
}
.kb-trust li { display: inline-flex; align-items: center; gap: .5rem; }
.kb-trust i { color: var(--sc-success); }

/* ── Sections génériques ── */
.kb-section { padding: 3rem 1.25rem; }
.kb-eyebrow {
  text-align: center; text-transform: uppercase; letter-spacing: .08em;
  font-weight: 800; font-size: .82rem; color: var(--sc-accent); margin: 0 0 .4rem;
}
.kb-eyebrow--onDark { color: var(--kb-creme); opacity: .9; text-align: left; }
.kb-section-title {
  text-align: center; font-size: clamp(1.5rem, 3.5vw, 2.1rem); margin: 0 auto .5rem; color: var(--sc-ink);
}
.kb-section-sub { text-align: center; color: var(--sc-muted); max-width: 640px; margin: 0 auto 2rem; font-size: 1.05rem; }

/* Grille de cartes-avantages. */
.kb-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.kb-feature {
  transition: transform .18s ease, box-shadow .18s ease;
}
.kb-feature:hover { transform: translateY(-4px); box-shadow: 0 14px 30px rgba(107, 63, 38, .12); }
.kb-feature h3 { margin: .1rem 0 .4rem; color: var(--sc-ink); }
.kb-feature p { color: var(--sc-muted); margin: 0; }
/* Tuile étirée sur toute la largeur de la grille (ex. 7ᵉ tuile seule sur sa ligne).
   Contenu en ligne (icône à gauche, texte à droite) pour ne pas laisser de vide. */
.kb-feature--wide { grid-column: 1 / -1; display: flex; align-items: center; gap: 1.25rem; }
.kb-feature--wide .kb-feature-body { flex: 1; }
@media (max-width: 620px) {
  .kb-feature--wide { flex-direction: column; align-items: flex-start; gap: .75rem; }
}
.kb-feature-ico {
  --kb-fc: var(--sc-primary);
  width: 3rem; height: 3rem; border-radius: 14px; margin-bottom: .8rem;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.35rem;
  color: var(--kb-fc); background: color-mix(in srgb, var(--kb-fc) 16%, transparent);
}
html[data-motion="reduced"] .kb-feature { transition: none; }

/* ── Liste explicative en LIGNES (alternative aux tuiles) ──────────────────
   Chaque entrée = icône ronde colorée à gauche + titre/texte à droite. Pensée
   pour un contenu long qui se lit verticalement (ex. guide PAP/PPS). La couleur
   de l'icône se pilote par --kb-fc sur chaque .kb-infolist-item (comme kb-feature). */
.kb-infolist { display: flex; flex-direction: column; gap: .35rem; margin: .4rem 0; }
.kb-infolist-item {
  display: flex; gap: 1rem; align-items: flex-start;
  padding: 1rem 0; border-bottom: 2px solid var(--kb-creme-fonce);
}
.kb-infolist-item:last-child { border-bottom: 0; }
.kb-infolist-ico {
  --kb-fc: var(--sc-primary);
  flex: 0 0 auto; width: 2.8rem; height: 2.8rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.2rem;
  color: var(--kb-fc); background: color-mix(in srgb, var(--kb-fc) 16%, transparent);
}
.kb-infolist-body { flex: 1; min-width: 0; }
.kb-infolist-body h4 { margin: .15rem 0 .3rem; color: var(--sc-ink); font-size: 1.08rem; }
.kb-infolist-body p { color: var(--sc-muted); margin: 0; }
@media (max-width: 520px) {
  .kb-infolist-ico { width: 2.4rem; height: 2.4rem; font-size: 1.05rem; }
}

/* ── En-tête de SOUS-SECTION mis en valeur (bandeau + pastille icône) ───────
   Alternative au discret .kb-eyebrow pour un vrai titre de bloc. Pastille ronde
   colorée à gauche (--kb-fc) + titre marqué, sur un bandeau crème foncé à filet
   d'accent. Utilisé pour les en-têtes du guide professeur. */
.kb-guide-head {
  --kb-fc: var(--sc-primary);
  display: flex; align-items: center; gap: .8rem;
  margin: 2rem 0 1rem; padding: .7rem .95rem;
  background: color-mix(in srgb, var(--kb-fc) 9%, var(--kb-creme-fonce));
  border-left: 5px solid var(--kb-fc); border-radius: 12px;
}
.kb-guide-head:first-child { margin-top: .4rem; }
.kb-guide-head-ico {
  flex: 0 0 auto; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.15rem;
  color: #fff; background: var(--kb-fc);
}
.kb-guide-head-txt {
  margin: 0; font-size: 1.2rem; font-weight: 800; line-height: 1.25;
  color: var(--sc-ink); text-transform: none; letter-spacing: 0;
}
/* Variante CLIQUABLE : l'en-tête ouvre une modale avec le contenu de la section. */
.kb-guide-head--btn {
  width: 100%; text-align: left; cursor: pointer; font: inherit;
  transition: transform .15s ease, box-shadow .15s ease;
}
.kb-guide-head--btn:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(107, 63, 38, .12); }
.kb-guide-head--btn:focus-visible { outline: 3px solid var(--kb-fc); outline-offset: 2px; }
.kb-guide-head-chevron { margin-left: auto; color: var(--kb-fc); font-size: 1.05rem; flex: 0 0 auto; }
html[data-motion="reduced"] .kb-guide-head--btn { transition: none; }
@media (max-width: 520px) {
  .kb-guide-head-ico { width: 2.2rem; height: 2.2rem; font-size: 1rem; }
  .kb-guide-head-txt { font-size: 1.06rem; }
}

/* ── Entrée EN CASCADE, prononcée, des cartes d'un conteneur [data-stagger] ──
   Chaque carte surgit du bas avec un léger zoom et un petit rebond (overshoot),
   décalée dans le temps par son index --kb-i (posé en JS). Plus marqué que le
   reveal générique. Vaut pour toute grille marquée (.kb-grid, .kb-steps…).
   Neutralisé si l'utilisateur réduit les animations (#15). */
[data-stagger] > [data-reveal] {
  --kb-i: 0;
  transition: none;   /* pilotage par keyframes, pas par la transition du reveal */
}
[data-stagger] > [data-reveal].is-in {
  animation: kb-tile-pop .62s cubic-bezier(.2, .8, .3, 1.28) both;
  animation-delay: calc(var(--kb-i) * 85ms);
}
@keyframes kb-tile-pop {
  0%   { opacity: 0; transform: translateY(40px) scale(.92); }
  60%  { opacity: 1; transform: translateY(-5px) scale(1.01); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
html[data-motion="reduced"] [data-stagger] > [data-reveal],
html[data-motion="reduced"] [data-stagger] > [data-reveal].is-in {
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  [data-stagger] > [data-reveal],
  [data-stagger] > [data-reveal].is-in { animation: none; }
}

/* Bande « pour les parents » : léger fond contrasté pour séparer les blocs. */
.kb-parent-band { background: var(--kb-creme-fonce); }

/* ── Comment ça marche ── */
.kb-steps { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.kb-step { position: relative; padding-top: 1.5rem; }
.kb-step-n {
  position: absolute; top: -14px; left: 1.25rem;
  width: 2rem; height: 2rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--sc-accent); color: #fff; font-weight: 800; font-family: var(--sc-font-title, inherit);
  box-shadow: 0 4px 10px rgba(107, 63, 38, .2);
}
.kb-step-ico {
  font-size: 1.8rem; color: var(--sc-primary); margin-bottom: .6rem;
  display: inline-block; transform-origin: center bottom;
  transition: transform .25s cubic-bezier(.2, .8, .3, 1.4);
}
.kb-step h3 { margin: .1rem 0 .4rem; }
.kb-step p { color: var(--sc-muted); margin: 0; }

/* Survol : la carte se soulève (ombre + léger scale), l'icône rebondit et le
   badge numéroté grossit. Transition posée pour un mouvement fluide. Le hover
   écrase l'animation d'entrée (kb-tile-pop) pour reprendre la main sur transform. */
.kb-step {
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.kb-step:hover {
  animation: none;                       /* rend la main au transform de survol */
  transform: translateY(-6px) scale(1.02);
  box-shadow: 0 16px 34px rgba(107, 63, 38, .15);
  border-color: var(--sc-accent);
}
.kb-step:hover .kb-step-ico {
  transform: translateY(-2px) scale(1.15) rotate(-6deg);
}
.kb-step:hover .kb-step-n {
  transform: scale(1.12);
}
.kb-step-n { transition: transform .2s cubic-bezier(.2, .8, .3, 1.4); }

html[data-motion="reduced"] .kb-step,
html[data-motion="reduced"] .kb-step-ico,
html[data-motion="reduced"] .kb-step-n { transition: none; }
html[data-motion="reduced"] .kb-step:hover { transform: none; }
html[data-motion="reduced"] .kb-step:hover .kb-step-ico,
html[data-motion="reduced"] .kb-step:hover .kb-step-n { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .kb-step, .kb-step-ico, .kb-step-n { transition: none; }
  .kb-step:hover { transform: none; }
  .kb-step:hover .kb-step-ico, .kb-step:hover .kb-step-n { transform: none; }
}

/* ── Frise « réviser au bon moment » (timeline horizontale) ──
   Alternative aux grilles de cartes : une progression rythmée par des pastilles
   reliées par un trait. Réutilise les jetons de marque --kb-* / --sc-*. */
/* Grille à nombre de colonnes FIXE (et non auto-fit) : indispensable pour couper
   proprement le trait connecteur en fin de rangée via :nth-child. --kb-tl-cols
   pilote le nombre de colonnes et le calcul du trait ; --kb-tl-gap = gouttière. */
.kb-timeline {
  --kb-tl-cols: 3;
  --kb-tl-gap: 1.25rem;
  display: grid; gap: 1.6rem var(--kb-tl-gap);
  grid-template-columns: repeat(var(--kb-tl-cols), 1fr);
}
.kb-tl-item { position: relative; padding-top: 3.6rem; text-align: center; }
.kb-tl-item h3 { margin: 0 0 .35rem; color: var(--sc-ink); font-size: 1.1rem; }
.kb-tl-item p { color: var(--sc-muted); margin: 0; }
/* Trait connecteur : centré verticalement sur la pastille (1.3rem = rayon), il
   part du centre de l'item (left:50%) et rejoint le centre de l'item SUIVANT.
   Distance centre→centre = une largeur d'item + une gouttière (width:100%+gap).
   DERRIÈRE la pastille (z-index) qui masque la jointure. */
.kb-tl-item::before {
  content: ""; position: absolute; z-index: 0;
  top: 1.3rem; height: 2px; transform: translateY(-50%);
  left: 50%; width: calc(100% + var(--kb-tl-gap));
  background: color-mix(in srgb, var(--sc-accent) 35%, transparent);
}
/* Pas de trait sur le dernier de chaque rangée (fin de rangée = multiple du
   nombre de colonnes) ni sur le tout dernier item. */
.kb-timeline .kb-tl-item:nth-child(3n)::before,
.kb-tl-item:last-child::before { display: none; }
.kb-tl-ico {
  --kb-fc: var(--sc-primary);
  position: absolute; z-index: 1; top: 0; left: 50%; transform: translateX(-50%);
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.2rem;
  color: #fff; background: var(--kb-fc);
  box-shadow: 0 4px 12px rgba(107, 63, 38, .22);
  border: 3px solid var(--sc-bg, var(--kb-creme));
}
/* ── Entrée dédiée de la frise « Réviser au bon moment » ──────────────────────
   Animation PLUS prononcée et DISTINCTE des autres reveals de la page : chaque
   item bascule en avant (rotation 3D depuis le haut) avec un ressort marqué, la
   pastille surgit ensuite avec un rebond, et le trait connecteur se dessine de
   gauche à droite. On surcharge le `kb-tile-pop` générique du [data-stagger]
   pour ces items uniquement ; le décalage en cascade réutilise --kb-i (posé JS).
   Neutralisé si l'utilisateur réduit les animations (règle #15). */
.kb-timeline[data-stagger] { perspective: 1100px; }
.kb-timeline[data-stagger] > [data-reveal] {
  transform-origin: 50% 0;
  transform: perspective(1100px) rotateX(-72deg) translateY(-14px) scale(.9);
  opacity: 0;
}
.kb-timeline[data-stagger] > [data-reveal].is-in {
  animation: kb-tl-flip .72s cubic-bezier(.16, 1.02, .3, 1.28) both;
  animation-delay: calc(var(--kb-i) * 130ms);
}
@keyframes kb-tl-flip {
  0%   { opacity: 0; transform: perspective(1100px) rotateX(-72deg) translateY(-14px) scale(.9); }
  55%  { opacity: 1; transform: perspective(1100px) rotateX(8deg)  translateY(3px)   scale(1.03); }
  75%  { transform: perspective(1100px) rotateX(-3deg) translateY(0) scale(.995); }
  100% { opacity: 1; transform: perspective(1100px) rotateX(0)     translateY(0)    scale(1); }
}
/* La pastille surgit après la bascule de sa carte, avec un rebond franc. */
.kb-timeline[data-stagger] > [data-reveal] .kb-tl-ico {
  transform: translateX(-50%) scale(0);
}
.kb-timeline[data-stagger] > [data-reveal].is-in .kb-tl-ico {
  animation: kb-tl-ico-pop .5s cubic-bezier(.2, .9, .28, 1.55) both;
  animation-delay: calc(var(--kb-i) * 130ms + .28s);
}
@keyframes kb-tl-ico-pop {
  0%   { transform: translateX(-50%) scale(0)   rotate(-25deg); }
  60%  { transform: translateX(-50%) scale(1.28) rotate(8deg); }
  100% { transform: translateX(-50%) scale(1)    rotate(0); }
}
/* Le trait connecteur se dessine de gauche à droite en suivant la cascade. */
.kb-timeline[data-stagger] > [data-reveal]::before { transform: translateY(-50%) scaleX(0); transform-origin: left center; }
.kb-timeline[data-stagger] > [data-reveal].is-in::before {
  animation: kb-tl-line .45s ease both;
  animation-delay: calc(var(--kb-i) * 130ms + .34s);
}
@keyframes kb-tl-line { from { transform: translateY(-50%) scaleX(0); } to { transform: translateY(-50%) scaleX(1); } }
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal],
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal].is-in,
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal] .kb-tl-ico,
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal].is-in .kb-tl-ico,
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal]::before,
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal].is-in::before {
  animation: none; opacity: 1; transform: none;
}
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal] .kb-tl-ico,
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal].is-in .kb-tl-ico { transform: translateX(-50%); }
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal]::before,
html[data-motion="reduced"] .kb-timeline[data-stagger] > [data-reveal].is-in::before { transform: translateY(-50%) scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .kb-timeline[data-stagger] > [data-reveal],
  .kb-timeline[data-stagger] > [data-reveal].is-in,
  .kb-timeline[data-stagger] > [data-reveal] .kb-tl-ico,
  .kb-timeline[data-stagger] > [data-reveal].is-in .kb-tl-ico,
  .kb-timeline[data-stagger] > [data-reveal]::before,
  .kb-timeline[data-stagger] > [data-reveal].is-in::before { animation: none; opacity: 1; }
  .kb-timeline[data-stagger] > [data-reveal],
  .kb-timeline[data-stagger] > [data-reveal].is-in { transform: none; }
}

/* Tablette : 2 colonnes → couper le trait tous les 2 items. */
@media (max-width: 900px) {
  .kb-timeline { --kb-tl-cols: 2; }
  .kb-timeline .kb-tl-item:nth-child(3n)::before { display: block; }
  .kb-timeline .kb-tl-item:nth-child(2n)::before { display: none; }
}
@media (max-width: 620px) {
  .kb-timeline { --kb-tl-cols: 1; }
  .kb-tl-item::before,
  .kb-timeline .kb-tl-item:nth-child(3n)::before { display: none; }
  .kb-tl-item { padding-top: 0; padding-left: 4rem; text-align: left; }
  .kb-tl-ico { left: .6rem; transform: none; top: .1rem; }
}

/* ── Liste d'atouts (2 colonnes) : alternative compacte aux cartes.
   Icône ronde à gauche + titre/texte. Utilisée par « Pour vous, parent ». */
.kb-perklist {
  display: grid; gap: 1.1rem 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  max-width: 900px; margin: 0 auto;
}
.kb-perk { display: flex; gap: .9rem; align-items: flex-start; }
.kb-perk-ico {
  --kb-fc: var(--sc-primary);
  flex: 0 0 auto; width: 2.6rem; height: 2.6rem; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.2rem;
  color: var(--kb-fc); background: color-mix(in srgb, var(--kb-fc) 16%, transparent);
}
.kb-perk h3 { margin: .15rem 0 .25rem; color: var(--sc-ink); font-size: 1.08rem; }
.kb-perk p { color: var(--sc-muted); margin: 0; }

/* ── Démo publique (CTA « essayer une fiche ») ── */
.kb-demo-cta { display: flex; justify-content: center; margin-top: 1.75rem; }

/* ── Preuve sociale (note + témoignages) ── */
.kb-rating {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center;
  gap: .5rem .7rem; margin: 0 auto 2rem;
}
.kb-rating-stars { color: var(--kb-miel); font-size: 1.15rem; letter-spacing: .1em; }
.kb-rating-num { font-size: 1.15rem; color: var(--sc-ink); }
.kb-rating-num strong { font-size: 1.4rem; }
.kb-rating-count { color: var(--sc-muted); }
.kb-reviews { align-items: stretch; }
.kb-review {
  display: flex; flex-direction: column; gap: .9rem; margin: 0;
  transition: transform .18s ease, box-shadow .18s ease;
}
.kb-review:hover { transform: translateY(-4px); box-shadow: 0 14px 30px rgba(107, 63, 38, .12); }
html[data-motion="reduced"] .kb-review { transition: none; }
.kb-review blockquote {
  margin: 0; color: var(--sc-ink); font-size: 1.02rem; line-height: 1.55; flex: 1;
}
.kb-review figcaption { display: flex; flex-direction: column; }
.kb-review-who { font-weight: 800; color: var(--sc-ink); }
.kb-review-role { color: var(--sc-muted); font-size: .92rem; }
.kb-reviews-note { text-align: center; color: var(--sc-muted); font-size: .9rem; margin: 1.5rem auto 0; max-width: 640px; }

/* ── Démo publique (page /demo.html) ── */
.kb-demo-msg { text-align: center; color: var(--sc-muted); margin: 1rem auto; }
.kb-demo-note { text-align: center; color: var(--sc-muted); font-size: .88rem; margin: .8rem auto 0; }
.kb-back--btn { background: none; border: none; cursor: pointer; font: inherit; color: var(--sc-primary); padding: 0; }

/* Sélecteur des 8 sujets : icône de matière (couleur dédiée) + 2 lignes (matière+niveau / sujet). */
.kb-demo-pick {
  display: flex; align-items: center; gap: .9rem;
  text-align: left; cursor: pointer; border: 2px solid var(--sc-border);
  border-left: 6px solid var(--kb-subj-color, var(--kb-brun));
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.kb-demo-pick:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(107, 63, 38, .12); border-color: var(--sc-accent); border-left-color: var(--kb-subj-color, var(--kb-brun)); }
html[data-motion="reduced"] .kb-demo-pick { transition: none; }
.kb-demo-pick-ico {
  flex: 0 0 auto; width: 2.8rem; height: 2.8rem; border-radius: 14px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.3rem;
  color: var(--kb-subj-color, var(--kb-brun));
  background: color-mix(in srgb, var(--kb-subj-color, var(--kb-brun)) 15%, transparent);
}
.kb-demo-pick-ico-i { width: 1.6rem; height: 1.6rem; }           /* drapeau SVG (langues) */
.kb-demo-pick-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.kb-demo-pick-l1 { font-weight: 800; color: var(--sc-ink); }
.kb-demo-pick-l2 { color: var(--sc-muted); font-size: .95rem; }
.kb-demo-pick-go {
  flex: 0 0 auto; width: 2.2rem; height: 2.2rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--kb-miel) 16%, transparent); color: var(--kb-miel);
}
/* Sélecteur groupé par thème : titre de groupe + grille du groupe. */
.kb-demo-group {
  margin: 1.6rem 0 .7rem; font-size: 1.05rem; color: var(--sc-muted);
  text-transform: uppercase; letter-spacing: .05em; font-weight: 800;
}
.kb-demo-group:first-child { margin-top: 0; }
.kb-demo-group-grid { margin-bottom: .4rem; }

/* Titre de la démo ouverte : petite icône de matière colorée. */
.kb-demo-label-ico {
  display: inline-flex; align-items: center; justify-content: center; margin-right: .5rem;
  color: var(--kb-subj-color, var(--kb-brun));
}
.kb-demo-label-ico-i { width: 1.4rem; height: 1.4rem; vertical-align: middle; }

/* Comparaison standard | dys (deux colonnes qui s'empilent sur mobile). */
.kb-demo-cols { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-items: start; }
.kb-demo-col { display: flex; flex-direction: column; }
.kb-demo-col--dys { border: 2px solid var(--sc-accent); }
.kb-demo-col-head { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin-bottom: .8rem; flex-wrap: wrap; }
.kb-demo-col-tag {
  font-weight: 800; font-size: .82rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--sc-muted); background: var(--kb-creme-fonce); border-radius: 999px; padding: .3rem .8rem;
}
.kb-demo-listen { flex: 0 0 auto; font-size: .9rem; padding: .35rem .7rem; transition: background .15s ease, color .15s ease, border-color .15s ease; }
.kb-demo-listen i { margin-right: .3rem; }
/* Mode écoute en cours : bouton plein (miel) pour un signal visuel net. */
.kb-demo-listen.is-playing {
  background: var(--kb-miel); color: #fff; border-color: var(--kb-miel);
}
.kb-demo-listen.is-playing i { color: #fff; }
html[data-motion="reduced"] .kb-demo-listen { transition: none; }
.kb-demo-col-tag--dys { color: #fff; background: var(--kb-miel); }
.kb-demo-col-tag--dys i { margin-right: .3rem; }
/* Titre de la fiche démo : doit DOMINER les titres de section (qui sont des h2). On fixe une taille
   explicite plus grande (l'h3 par défaut était plus petit que les h2 de section). */
.kb-demo-sheet-title { margin: 0 0 .5rem; color: var(--sc-ink); font-size: 1.6rem; line-height: 1.25; }
/* Titres de section des démos : même rendu que dans l'app (#sheet h2.kb-sec-head) — l'app étant scopée
   « #sheet », on reporte ici la même mise en forme (taille h2, emoji centré verticalement). */
.kb-demo-col .kb-sec-head { margin: 1.5rem 0 .6rem; display: flex; align-items: center; gap: .5rem; }
.kb-demo-col .kb-sec-head:first-child { margin-top: .4rem; }
.kb-demo-col .kb-sec-emoji { font-size: 1.3em; flex: 0 0 auto; }
/* Le titre reste TOUJOURS dans le cadre de la colonne : peut rétrécir (min-width:0) et couper un mot
   trop long plutôt que déborder (miroir de #sheet .kb-sec-title). */
.kb-demo-col .kb-sec-title { min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
.kb-demo-summary { background: var(--kb-creme-fonce); border-radius: var(--sc-radius); padding: .6rem .9rem; margin: 0 0 .8rem; }
.kb-demo-summary p { margin: .3rem 0 0; }

/* FAQ (page /faq.html) + FAQ courtes des pages SEO chapitre : accordéons details/summary natifs,
   accessibles, aux couleurs de marque. Grande cible tactile pour le summary (accessibilité dys, règle #15). */
.kb-faq { display: flex; flex-direction: column; gap: .8rem; }
.kb-faq-item { padding: 0; overflow: hidden; }
.kb-faq-item > summary {
  list-style: none; cursor: pointer; padding: 1rem 1.2rem; min-height: 3.2rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  font-weight: 700; color: var(--sc-ink);
}
.kb-faq-item > summary::-webkit-details-marker { display: none; }
/* Chevron unicode (pas de police FA en ::after : le kit est en mode SVG+JS, cf. règle #18). */
.kb-faq-item > summary::after {
  content: "\25BE"; /* ▾ */ font-size: 1.1em; line-height: 1;
  color: var(--kb-brun); transition: transform .2s ease; flex: 0 0 auto;
}
.kb-faq-item[open] > summary::after { transform: rotate(180deg); }
.kb-faq-item > p { margin: 0; padding: 0 1.2rem 1.1rem; color: var(--sc-muted); line-height: 1.6; }
html[data-motion="reduced"] .kb-faq-item > summary::after { transition: none; }

/* Pages SEO « fiche de révision [chapitre] [niveau] » (web/fiche/*.html, générées par gen-seo.ps1).
   Aperçu du socle : plan (titres de sections) + mots-clés en pastilles de marque. */
.kb-fiche-seo { line-height: 1.7; }
.kb-fiche-seo > p { color: var(--sc-ink); margin: 0 0 1rem; }
/* Le résumé garde le centrage du design system (max-width + margin auto) : la règle générique
   ci-dessus écrasait sinon `margin: 0 auto` et alignait le bloc à gauche. */
.kb-fiche-seo > p.kb-section-sub { margin: 0 auto 2rem; }
.kb-fiche-seo h2 { margin: 1.6rem 0 .6rem; color: var(--kb-brun); font-size: 1.25rem; }
.kb-fiche-plan { margin: 0 0 1rem; padding-left: 1.3rem; }
.kb-fiche-plan li { margin: 0 0 .4rem; color: var(--sc-ink); }
.kb-fiche-terms { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; }
.kb-fiche-term {
  display: inline-block; padding: .35rem .7rem; border-radius: 999px;
  background: var(--kb-creme-fonce); color: var(--kb-brun-profond, #8A5733);
  font-size: .95rem; font-weight: 600;
}
/* Maillage interne des fiches SEO : chapitres voisins (même matière × niveau). */
.kb-fiche-related { margin-top: 2rem; padding-top: 1.2rem; border-top: 2px solid var(--kb-creme-fonce); }
.kb-fiche-rellist { list-style: none; margin: 0 0 .8rem; padding: 0; display: grid; gap: .4rem; }
.kb-fiche-rellist li { margin: 0; }
.kb-fiche-rellist a {
  display: inline-block; padding: .3rem .1rem; color: var(--kb-brun); font-weight: 600;
  text-decoration: none; border-bottom: 1px solid transparent;
}
.kb-fiche-rellist a:hover { border-bottom-color: var(--kb-brun); }

/* Catalogue des fiches (web/fiches.html) : accordéon MATIÈRE → NIVEAU → badges de chapitres.
   <details>/<summary> natif (zéro JS) ; tous les liens restent dans le DOM (SEO : crawl intact même
   replié). La couleur de marque de la matière est passée en --kb-cat-color (style inline). */
.kb-catalogue { display: flex; flex-direction: column; gap: .8rem; }

/* Niveau 1 : matière (icône/drapeau + libellé + compteur + chevron). */
.kb-cat-subj {
  --kb-cat-color: var(--kb-miel);
  border: 2px solid var(--kb-brun-clair, #C98A5C); border-left: 6px solid var(--kb-cat-color);
  border-radius: var(--sc-radius); background: var(--kb-creme-fonce); overflow: hidden;
}
.kb-cat-subj-sum {
  display: flex; align-items: center; gap: .8rem; padding: .9rem 1.1rem; cursor: pointer;
  list-style: none; font-weight: 700; color: var(--kb-brun); font-size: 1.2rem;
  min-height: 3.4rem;   /* grande cible tactile (accessibilité dys, règle #15) */
}
.kb-cat-subj-sum::-webkit-details-marker { display: none; }   /* triangle natif masqué (on a le chevron) */
.kb-cat-subj-ic { display: inline-flex; align-items: center; justify-content: center; width: 2.2rem; }
.kb-cat-subj-ic .kb-cat-icon { font-size: 1.7rem; line-height: 1; color: var(--kb-cat-color); }
.kb-cat-subj-ic .kb-cat-flag { width: 1.9rem; height: auto; border-radius: 3px; display: block; }
.kb-cat-subj-name { flex: 1; }
.kb-cat-count {
  min-width: 1.6rem; padding: .1rem .5rem; border-radius: 999px; text-align: center;
  background: var(--kb-cat-color); color: #fff; font-size: .85rem; font-weight: 700;
}
.kb-cat-chevron { transition: transform .2s ease; color: var(--kb-brun-profond, #8A5733); font-size: .9rem; }
.kb-cat-subj[open] > .kb-cat-subj-sum .kb-cat-chevron { transform: rotate(180deg); }

/* Niveau 2 : niveau scolaire (imbriqué dans la matière). */
.kb-cat-grade { border-top: 1px solid var(--kb-brun-clair, #C98A5C); }
.kb-cat-grade-sum {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .6rem 1.1rem .6rem 3rem; cursor: pointer; list-style: none;
  color: var(--kb-brun-profond, #8A5733); font-weight: 600; font-size: 1.02rem; min-height: 2.8rem;
}
.kb-cat-grade-sum::-webkit-details-marker { display: none; }
.kb-cat-grade[open] > .kb-cat-grade-sum .kb-cat-chevron { transform: rotate(180deg); }

.kb-cat-list { list-style: none; margin: 0; padding: 0 1.1rem 1rem 3rem; display: flex; flex-wrap: wrap; gap: .5rem; }
.kb-cat-list li a {
  display: inline-block; padding: .45rem .8rem; border-radius: var(--sc-radius);
  background: var(--kb-creme, #FBF3E4); border: 1px solid var(--kb-brun-clair, #C98A5C);
  color: var(--sc-ink); text-decoration: none; font-weight: 600;
}
.kb-cat-list li a:hover { background: var(--kb-miel); color: #fff; border-color: var(--kb-miel); }

/* Réduire les animations (préférence système / dys, règle #15). */
@media (prefers-reduced-motion: reduce) { .kb-cat-chevron { transition: none; } }

/* ═══ Dossier « troubles dys » (pilier /troubles-dys.html + 5 pages filles) ═══
   Traitement visuel + actionnable, dans le design system. Couleur d'accent par page via --kb-ac
   (posée en style inline sur .kb-dys-page), défaut miel. */
.kb-dys-page { --kb-ac: var(--kb-miel); }

/* Hero coloré avec grande icône thématique. */
.kb-dys-hero {
  text-align: center; padding: 2rem 1.2rem 1.6rem; margin: .5rem 0 1.5rem;
  border-radius: var(--sc-radius);
  background: linear-gradient(160deg, var(--kb-creme-fonce), var(--kb-creme));
  border: 2px solid var(--kb-brun-clair);
}
.kb-dys-hero-ico {
  width: 4.2rem; height: 4.2rem; border-radius: 50%; margin: 0 auto .8rem;
  display: flex; align-items: center; justify-content: center;
  background: var(--kb-ac); color: #fff; font-size: 1.9rem;
}
.kb-dys-hero h1 { margin: 0 0 .5rem; }

/* Chiffres / faits clés en gros (bande de statistiques). */
.kb-dys-stats { display: flex; flex-wrap: wrap; gap: 1rem; margin: 0 0 1.5rem; }
.kb-dys-stat {
  flex: 1 1 8rem; text-align: center; padding: 1rem .8rem;
  background: var(--kb-creme-fonce); border-radius: var(--sc-radius);
  border-bottom: 4px solid var(--kb-ac);
}
.kb-dys-stat b { display: block; font-size: 1.8rem; color: var(--kb-ac); line-height: 1.1; }
.kb-dys-stat span { font-size: .9rem; color: var(--sc-muted); }

/* Encart « Bon à savoir » (accent, filet gauche). */
.kb-dys-note {
  display: flex; gap: .9rem; align-items: flex-start;
  background: var(--kb-creme); border-left: 5px solid var(--kb-ac);
  border-radius: 0 var(--sc-radius) var(--sc-radius) 0; padding: 1rem 1.2rem; margin: 1.2rem 0;
}
.kb-dys-note i { color: var(--kb-ac); font-size: 1.2rem; margin-top: .15rem; flex: 0 0 auto; }
.kb-dys-note p { margin: 0; }

/* Étapes « Que faire concrètement » (numérotées, visuelles). */
.kb-dys-steps { list-style: none; margin: 1rem 0; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.kb-dys-steps li { display: flex; gap: .9rem; align-items: flex-start; }
.kb-dys-steps .n {
  flex: 0 0 auto; width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--kb-ac); color: #fff; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.kb-dys-steps .t { margin: .2rem 0 0; }

/* Liste d'aménagements / points, avec pastille d'icône. */
.kb-dys-list { list-style: none; margin: 1rem 0; padding: 0; display: flex; flex-direction: column; gap: .7rem; }
.kb-dys-list li { display: flex; gap: .8rem; align-items: flex-start; }
.kb-dys-list li i { color: var(--kb-ac); margin-top: .2rem; flex: 0 0 auto; }

/* Mini-glossaire (terme + définition). */
.kb-dys-gloss { display: flex; flex-direction: column; gap: .7rem; margin: 1rem 0 0; }
.kb-dys-gloss div { padding-left: .9rem; border-left: 3px solid var(--kb-brun-clair); }
.kb-dys-gloss b { font-weight: 800; color: var(--kb-brun); }

/* Tuiles de troubles (grille du pilier) : lien « En savoir plus » poussé en bas et aligné à droite,
   quelle que soit la longueur du texte de la tuile. */
.kb-dys-card { display: flex; flex-direction: column; }
.kb-dys-more {
  margin: .8rem 0 0 auto;               /* margin-top:auto → bas de tuile ; margin-left:auto → à droite */
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--kb-brun); font-weight: 600;
}

/* Navigation inter-troubles (chips en bas des pages filles). */
.kb-dys-nav { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0; }
.kb-dys-nav a {
  padding: .45rem .8rem; border-radius: 999px; text-decoration: none; font-weight: 600;
  background: var(--kb-creme-fonce); color: var(--sc-ink);
}
.kb-dys-nav a:hover { background: var(--kb-ac); color: #fff; }

/* Aperçu « adapté dys » : mêmes aides de lecture que la préférence html[data-font="dys"] du portail
   (règle #15) — Atkinson Hyperlegible (le kit déconseille OpenDyslexic, cf. haut du fichier) avec
   interligne/espacement renforcés + texte agrandi. Portée LOCALE à la colonne (n'affecte pas la page). */
.kb-dys-preview {
  font-size: 1.1rem; line-height: 2; letter-spacing: .05em; word-spacing: .12em;
}
.kb-dys-preview li { margin-bottom: .55rem; }
.kb-quiz-card { margin-top: .9rem; text-align: left; }
.kb-quiz-prompt { font-weight: 800; margin: 0 0 .3rem; }

/* ── Bandeau accessibilité dys (fond brun) ── */
.kb-dys { display: flex; gap: 1.5rem; align-items: center; flex-wrap: wrap; padding: 1.75rem; }
.kb-dys-kapi { width: 120px; height: auto; flex: 0 0 auto; }
.kb-dys-txt { flex: 1; min-width: 240px; }
.kb-dys-txt h2 { color: var(--kb-creme); }
.kb-dys-txt p { color: var(--kb-creme); opacity: .92; margin: .5rem 0 0; }

/* ── Prix ── */
.kb-price-wrap { display: flex; justify-content: center; }
.kb-price {
  max-width: 420px; width: 100%; text-align: center;
  border: 2px solid var(--sc-accent);
  box-shadow: 0 16px 40px rgba(107, 63, 38, .12);
}
.kb-price-head { display: flex; align-items: baseline; justify-content: center; gap: .3rem; margin-bottom: .3rem; }
.kb-price-amount { font-family: var(--sc-font-title, inherit); font-size: 3rem; font-weight: 800; color: var(--sc-primary); }
.kb-price-period { color: var(--sc-muted); font-weight: 600; }
.kb-price-detail { color: var(--sc-muted); margin: 0 0 1rem; }
.kb-price-list { list-style: none; margin: 0 0 1.25rem; padding: 0; text-align: left; display: grid; gap: .55rem; }
.kb-price-list li { display: flex; align-items: center; gap: .6rem; color: var(--sc-ink); }
.kb-price-list i { color: var(--sc-success); flex: 0 0 auto; }

/* ── CTA final ── */
.kb-final {
  text-align: center; background: var(--kb-creme-fonce); border-radius: var(--sc-radius);
  padding: 2.5rem 1.5rem;
}
.kb-final-kapi { width: 100px; height: auto; margin: 0 auto .5rem; display: block; }
.kb-final h2 { margin: .2rem 0 .5rem; color: var(--sc-ink); }
.kb-final p { color: var(--sc-muted); margin: 0 auto 1.4rem; }

/* ── Footer riche (vitrine) : marque + colonnes + barre de bas ── */
.kb-footer {
  margin-top: 2rem;
  background: var(--kb-museau);          /* brun très sombre du kit — pas de noir pur */
  color: var(--kb-creme);
}
.kb-footer a { color: var(--kb-creme); text-decoration: none; opacity: .82; }
.kb-footer a:hover { opacity: 1; text-decoration: underline; }
.kb-footer-grid {
  display: grid; gap: 2rem;
  grid-template-columns: 1.4fr 1fr 1.3fr;
  grid-template-areas:
    "brand legal contact"
    "product product product";
  padding: 2.5rem 1.25rem 1.5rem;
}
.kb-footer-brand { grid-area: brand; }
/* Colonne « Produit » : placée en ligne, pleine largeur, sous les autres colonnes. */
.kb-footer-grid > nav[aria-label="Produit"] { grid-area: product; }
.kb-footer-grid > nav[aria-label="Produit"] { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: .55rem 1.4rem; border-top: 1px solid rgba(251, 243, 228, .18); padding-top: 1.5rem; }
.kb-footer-grid > nav[aria-label="Produit"] .kb-footer-h { flex-basis: 100%; margin-bottom: 0; }
.kb-footer-grid > nav[aria-label="Légal"] { grid-area: legal; }
.kb-footer-grid > div.kb-footer-col { grid-area: contact; }
.kb-footer-brand .kb-logo img { height: 34px; }
/* Logo horizontal « encre » sur fond sombre : on l'éclaircit pour le rendre lisible. */
.kb-footer-brand .kb-logo img { filter: brightness(0) invert(1); opacity: .95; }
.kb-footer-baseline { color: var(--kb-creme); opacity: .8; margin: .8rem 0 1rem; max-width: 34ch; }
.kb-footer-social { display: flex; gap: .6rem; }
.kb-footer-social a {
  width: 2.3rem; height: 2.3rem; border-radius: 10px; opacity: 1;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.05rem;
  background: rgba(251, 243, 228, .12); color: var(--kb-creme);
  transition: background .15s ease;
}
.kb-footer-social a:hover { background: var(--kb-miel); text-decoration: none; }
.kb-footer-col { display: flex; flex-direction: column; gap: .55rem; }
.kb-footer-h {
  font-family: var(--sc-font-title, inherit); font-size: .8rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--kb-miel); margin: 0 0 .3rem;
}
.kb-footer-contact { display: flex; align-items: flex-start; gap: .55rem; margin: 0; color: var(--kb-creme); opacity: .82; }
.kb-footer-contact i { color: var(--kb-miel); margin-top: .2rem; flex: 0 0 auto; }
a.kb-footer-contact:hover { opacity: 1; }
/* Espaces & accès : rangée horizontale de tuiles à icônes sous les 4 colonnes. */
.kb-footer-access {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem;
  padding: 1.5rem 1.25rem;
  border-top: 1px solid rgba(251, 243, 228, .18);
}
.kb-footer-access a.kb-access-tile {
  display: inline-flex; align-items: center; gap: .55rem; opacity: 1;
  padding: .7rem 1.15rem; border-radius: 999px;
  background: rgba(251, 243, 228, .1); border: 1px solid rgba(251, 243, 228, .18);
  color: var(--kb-creme); font-weight: 600; font-size: .92rem;
  transition: background .15s ease, border-color .15s ease, transform .15s ease;
}
.kb-footer-access a.kb-access-tile:hover {
  background: var(--kb-miel); border-color: var(--kb-miel);
  color: var(--kb-museau); text-decoration: none; transform: translateY(-2px);
}
.kb-footer-access .kb-access-tile i { color: var(--kb-miel); flex: 0 0 auto; }
.kb-footer-access a.kb-access-tile:hover i { color: var(--kb-museau); }
@media (max-width: 460px) {
  .kb-footer-access { flex-direction: column; align-items: stretch; }
  .kb-footer-access a.kb-access-tile { justify-content: center; }
}
/* Barre de bas : copyright + hébergement, séparée par un filet. */
.kb-footer-bottom {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: .5rem;
  padding: 1rem 1.25rem 1.5rem; font-size: .85rem;
  border-top: 1px solid rgba(251, 243, 228, .15);
  color: var(--kb-creme); opacity: .7;
}
.kb-footer-hosted { display: inline-flex; align-items: center; gap: .4rem; }
.kb-footer-hosted i { color: var(--kb-vert-eau); }
@media (max-width: 720px) {
  .kb-footer-grid {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "brand brand"
      "legal contact"
      "product product";
  }
}
@media (max-width: 460px) {
  .kb-footer-grid {
    grid-template-columns: 1fr;
    grid-template-areas:
      "brand"
      "legal"
      "contact"
      "product";
  }
}

/* Logo en tête des pages légales. */
.kb-legal-logo { display: inline-flex; margin: .5rem 0 1rem; }
.kb-legal-logo img { height: 44px; width: auto; }

/* ── Kapi décoratifs sur la vitrine (égaient la page, purement décoratifs) ── */
.kb-deco-section { position: relative; }
.kb-deco {
  position: absolute; width: 84px; height: auto; opacity: .9; z-index: 0;
  pointer-events: none; user-select: none;
  filter: drop-shadow(0 6px 12px rgba(107, 63, 38, .15));
  animation: kb-float 6s ease-in-out infinite;
}
.kb-deco--tr { top: .5rem; right: 1rem; }
.kb-deco--tl { top: .5rem; left: 1rem; }
html[data-motion="reduced"] .kb-deco { animation: none; }
/* Sur petit écran : on masque les Kapi de coin pour ne pas gêner la lecture (accessibilité dys). */
@media (max-width: 860px) { .kb-deco { display: none; } }
/* Le contenu de section passe au-dessus du décor. */
.kb-deco-section > :not(.kb-deco) { position: relative; z-index: 1; }

/* Kapi qui dépasse en haut de la carte prix. */
.kb-price { position: relative; overflow: visible; }
.kb-price-kapi {
  position: absolute; top: -46px; right: 0; width: 76px; height: auto;
  transform: rotate(8deg); pointer-events: none;
  filter: drop-shadow(0 6px 12px rgba(107, 63, 38, .18));
}

/* ── Animation d'ENTRÉE prononcée de la carte prix ──
   Plus marquée que le reveal générique : la carte surgit du bas avec un léger
   scale et rebondit (overshoot via cubic-bezier). Le montant « pulse » et Kapi
   fait un bond pour attirer l'œil. Déclenché par .is-in (posé par l'observer).
   Neutralisé si l'utilisateur réduit les animations (règle #15). */
.kb-price[data-reveal] {
  /* Écrase la transition douce du reveal générique : on pilote par keyframes. */
  transition: none;
}
.kb-price[data-reveal].is-in {
  animation: kb-price-pop .7s cubic-bezier(.18, .89, .32, 1.28) both;
}
.kb-price[data-reveal].is-in .kb-price-amount {
  display: inline-block;
  animation: kb-price-amount-pulse .9s ease .35s both;
}
.kb-price[data-reveal].is-in .kb-price-kapi {
  animation: kb-price-kapi-bounce .8s cubic-bezier(.28, .84, .42, 1.4) .2s both;
}

@keyframes kb-price-pop {
  0%   { opacity: 0; transform: translateY(48px) scale(.9); }
  60%  { opacity: 1; transform: translateY(-6px) scale(1.015); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes kb-price-amount-pulse {
  0%   { transform: scale(1); }
  30%  { transform: scale(1.18); color: var(--sc-accent); }
  60%  { transform: scale(.98); }
  100% { transform: scale(1); }
}
@keyframes kb-price-kapi-bounce {
  0%   { transform: rotate(8deg) translateY(0); }
  35%  { transform: rotate(-6deg) translateY(-14px); }
  70%  { transform: rotate(10deg) translateY(0); }
  100% { transform: rotate(8deg) translateY(0); }
}

/* Respect de « réduire les animations » : apparition instantanée, aucun mouvement. */
html[data-motion="reduced"] .kb-price[data-reveal],
html[data-motion="reduced"] .kb-price[data-reveal].is-in,
html[data-motion="reduced"] .kb-price[data-reveal].is-in .kb-price-amount,
html[data-motion="reduced"] .kb-price[data-reveal].is-in .kb-price-kapi {
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  .kb-price[data-reveal],
  .kb-price[data-reveal].is-in,
  .kb-price[data-reveal].is-in .kb-price-amount,
  .kb-price[data-reveal].is-in .kb-price-kapi { animation: none; }
}

/* ── Emploi du temps (timetable.html) : puces matières par jour ── */
.kb-tt-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.kb-tt-chip {
  --kb-chip-color: var(--sc-primary);
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .4rem .7rem; border-radius: 999px; cursor: pointer;
  border: 2px solid var(--sc-border); background: var(--sc-bg); color: var(--sc-ink);
  font: inherit; font-weight: 700; font-size: .85rem;
  transition: border-color .12s ease, background .12s ease;
}
.kb-tt-chip .kb-tt-ico { color: var(--kb-chip-color); }
.kb-tt-chip .kb-tt-flag { width: 18px; height: auto; border-radius: 2px; display: block; }
.kb-tt-chip:hover { border-color: var(--kb-chip-color); }
.kb-tt-chip.sel { background: var(--kb-chip-color); border-color: var(--kb-chip-color); color: #fff; }
.kb-tt-chip.sel .kb-tt-ico { color: #fff; }
/* Séparateur entre les matières du jour (sélectionnées) et celles à ajouter. */
.kb-tt-sep { flex: 0 0 auto; align-self: stretch; width: 2px; border-radius: 2px; background: var(--sc-border); margin: 0 .2rem; }

/* ── Hub « Prépare demain » (space.html) : matières du prochain jour + raccourcis d'action ── */
.kb-tomorrow { margin-bottom: 1rem; padding: 1rem 1.1rem; }
.kb-tomorrow-head {
  display: flex; align-items: center; gap: .5rem; margin-bottom: .75rem;
  font-family: var(--sc-font-title, inherit); font-weight: 800; font-size: 1.15rem; color: var(--sc-ink);
}
.kb-tomorrow-ico { color: var(--sc-accent); }

/* ── Hub fusionné « Mon plan » (Demain / À venir), repliable ───────────────── */
.kb-plan { padding: 0; overflow: hidden; }          /* l'en-tête et le corps gèrent leur propre padding */
.kb-plan-head {
  display: flex; align-items: center; gap: .55rem; cursor: pointer; padding: 1rem 1.1rem;
  font-family: var(--sc-font-title, inherit); font-weight: 800; font-size: 1.15rem; color: var(--sc-ink);
}
.kb-plan-head:hover { background: color-mix(in srgb, var(--sc-primary) 6%, transparent); }
.kb-plan-title { flex: 0 0 auto; }
.kb-plan-summary { flex: 1 1 auto; min-width: 0; font-weight: 600; font-size: .9rem; color: var(--sc-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-plan-caret { flex: 0 0 auto; opacity: .7; transition: transform .15s ease; }
.kb-plan.is-collapsed .kb-plan-caret { transform: rotate(-90deg); }   /* replié : chevron à droite */
html[data-motion="reduced"] .kb-plan-caret { transition: none; }
.kb-plan-body { padding: 0 1.1rem 1.1rem; }
.kb-plan.is-collapsed .kb-plan-body { display: none; }

/* Barre d'onglets Demain / À venir. */
.kb-plan-tabs { display: flex; gap: .4rem; margin-bottom: .9rem; }
.kb-plan-tab {
  flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  padding: .5rem .7rem; border-radius: var(--sc-radius); border: 1px solid var(--sc-border);
  background: var(--kb-creme-fonce); color: var(--sc-ink); font-weight: 700; font-size: .92rem; cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.kb-plan-tab i { font-size: .85rem; color: var(--sc-accent); }
.kb-plan-tab.is-active { background: var(--sc-primary); color: var(--sc-primary-ink); border-color: var(--sc-primary); }
.kb-plan-tab.is-active i { color: var(--sc-primary-ink); }
html[data-motion="reduced"] .kb-plan-tab { transition: none; }
.kb-plan-panel-title { font-weight: 800; color: var(--sc-ink); margin-bottom: .6rem; }

/* Message explicatif (étapes) sous le titre du hub. */
.kb-tomorrow-intro {
  background: var(--sc-bg); border-radius: var(--sc-radius);
  border-left: 4px solid var(--sc-accent); padding: .8rem 1rem; margin-bottom: 1rem;
}
/* Titre repliable du message (details/summary natif). */
.kb-tomorrow-intro-sum {
  display: flex; align-items: center; gap: .5rem; cursor: pointer; list-style: none;
  font-weight: 700; color: var(--sc-muted);
}
.kb-tomorrow-intro-sum::-webkit-details-marker { display: none; }   /* masque la flèche native */
.kb-tomorrow-intro-sum > i:first-child { color: var(--sc-accent); }
.kb-tomorrow-intro-caret { margin-left: auto; transition: transform .15s ease; }
.kb-tomorrow-intro[open] .kb-tomorrow-intro-caret { transform: rotate(180deg); }
.kb-tomorrow-intro[open] .kb-steps-mini { margin-top: .7rem; }
html[data-motion="reduced"] .kb-tomorrow-intro-caret { transition: none; }
.kb-steps-mini { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.kb-steps-mini li { display: flex; align-items: flex-start; gap: .6rem; color: var(--sc-ink); line-height: 1.35; }
.kb-step-badge {
  flex: 0 0 auto; width: 1.6rem; height: 1.6rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--sc-accent); color: #fff; font-weight: 800; font-size: .85rem;
  font-family: var(--sc-font-title, inherit);
}

.kb-tomorrow-list { display: grid; gap: .7rem; }
/* Tuile matière : en-tête (.kb-tm-top) puis actions puis récap, empilés en colonne. */
.kb-tm-row {
  display: flex; flex-direction: column; gap: .5rem;
  background: var(--sc-bg); border: 1px solid var(--sc-border); border-radius: var(--sc-radius); padding: .6rem .75rem;
}
.kb-tm-subj { display: flex; align-items: center; gap: .5rem; min-width: 0; flex: 1 1 auto; font-weight: 800; }
.kb-tm-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-tm-actions { display: flex; gap: .4rem; flex-wrap: wrap; }
.kb-tm-btn {
  display: inline-flex; align-items: center; gap: .35rem; text-decoration: none;
  padding: .4rem .7rem; border-radius: 999px; font-weight: 700; font-size: .82rem;
  color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 12%, transparent);
  transition: background .12s ease, color .12s ease;
}
.kb-tm-btn i { font-size: .85rem; }
.kb-tm-btn:hover { background: var(--sc-primary); color: var(--sc-primary-ink); text-decoration: none; }

/* « Prends de l'avance » : un bloc par jour à venir, en-tête cliquable (déplie/replie) + liste de tuiles. */
.kb-adv-day { margin-top: .6rem; }
.kb-adv-day-head {
  display: flex; align-items: center; gap: .5rem; cursor: pointer;
  font-weight: 800; padding: .5rem .25rem; border-radius: var(--sc-radius);
}
.kb-adv-day-head:hover { background: color-mix(in srgb, var(--sc-primary) 8%, transparent); }
.kb-adv-day-ico { color: var(--sc-primary); }
.kb-adv-day-name { flex: 1 1 auto; }
.kb-adv-day-caret { transition: transform .15s ease; opacity: .7; }
.kb-adv-day.is-collapsed .kb-adv-day-caret { transform: rotate(-90deg); }   /* replié : chevron à droite */
.kb-adv-day-body { margin-top: .4rem; }
.kb-adv-day.is-collapsed .kb-adv-day-body { display: none; }
html[data-motion="reduced"] .kb-adv-day-caret { transition: none; }

/* Mode révision d'été : petit texte d'intro sous le titre de la séance. */
.kb-summer-intro { margin: .2rem 0 .6rem; color: var(--sc-muted); }

/* Recherche de fiches (find.html) : lignes de chapitres du corpus, cliquables. */
.kb-find-row {
  display: flex; align-items: center; gap: .7rem; text-decoration: none;
  background: var(--sc-bg); border: 1px solid var(--sc-border); border-radius: var(--sc-radius);
  padding: .7rem .9rem; color: var(--sc-ink); font-weight: 700;
  transition: border-color .12s ease, background .12s ease;
}
.kb-find-row:hover { border-color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 6%, transparent); text-decoration: none; }
.kb-find-ico { color: var(--sc-primary); flex: 0 0 auto; }
.kb-find-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.kb-find-caret { color: var(--sc-muted); flex: 0 0 auto; }
.kb-find-badge {
  flex: 0 0 auto; font-size: .78rem; font-weight: 700; color: var(--sc-primary);
  background: color-mix(in srgb, var(--sc-primary) 14%, transparent);
  padding: .2rem .6rem; border-radius: 999px; white-space: nowrap;
}
.kb-find-lib {
  display: inline-flex; align-items: center; gap: .4rem; margin-top: .3rem;
  color: var(--sc-primary); font-weight: 700; text-decoration: none; justify-self: start;
}
.kb-find-lib:hover { text-decoration: underline; }

/* ── Profil enfant en LIGNE pleine largeur (profiles.html) : avatar+infos à gauche, actions à droite ── */
.kb-profile-row {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: 1rem 1.25rem;
}
/* Zone cliquable (sélection du profil) : avatar + prénom + classe. */
.kb-profile-id {
  display: flex; align-items: center; gap: 1rem; flex: 1 1 240px; min-width: 0;
  background: none; border: none; cursor: pointer; text-align: left; font: inherit; color: inherit;
  padding: .2rem; border-radius: var(--sc-radius);
}
.kb-profile-id:hover { background: color-mix(in srgb, var(--sc-primary) 8%, transparent); }
.kb-profile-avatar { width: 64px; height: auto; flex: 0 0 auto; }
.kb-profile-info { display: flex; flex-direction: column; min-width: 0; }
.kb-profile-name { font-weight: 800; font-size: 1.15rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-profile-grade { color: var(--sc-muted); }

/* Boutons d'action à droite (icône FA + libellé), soignés. */
.kb-profile-actions { display: flex; gap: .5rem; flex: 0 0 auto; flex-wrap: wrap; }
.kb-profile-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  padding: .55rem .9rem; border-radius: 999px; text-decoration: none;
  font-weight: 700; font-size: .9rem;
  color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 12%, transparent);
  border: 1.5px solid transparent;
  transition: background .12s ease, color .12s ease;
}
.kb-profile-btn i { font-size: .95rem; }
.kb-profile-btn:hover { background: var(--sc-primary); color: var(--sc-primary-ink); text-decoration: none; }
/* Sur petit écran : les actions passent sous l'identité, en pleine largeur. */
@media (max-width: 520px) {
  .kb-profile-actions { flex: 1 1 100%; }
  .kb-profile-btn { flex: 1 1 auto; }
}
/* Le bouton « Signaler » réutilise .kb-profile-btn (élément <button>) : neutraliser le style natif. */
button.kb-profile-btn { cursor: pointer; font-family: inherit; }

/* ── Signalement d'erreur IA (modale multi-étapes, page Profils) ── */
.kb-report-child { display: flex; align-items: center; gap: .6rem; font-weight: 700; }
.kb-report-avatar { width: 2.2rem; height: 2.2rem; border-radius: 50%; object-fit: cover; }
.kb-report-types { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: .5rem; }
.kb-report-type {
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  padding: .7rem .5rem; border-radius: var(--sc-radius); cursor: pointer; font: inherit;
  font-weight: 700; font-size: .9rem; text-align: center;
  color: var(--sc-ink); background: var(--sc-card); border: 2px solid var(--sc-border);
  transition: border-color .12s ease, background .12s ease;
}
.kb-report-type i { font-size: 1.3rem; color: var(--sc-primary); }
.kb-report-type:hover { border-color: var(--sc-primary); }
.kb-report-type.sel { border-color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 10%, transparent); }
.kb-report-prods { display: flex; flex-direction: column; gap: .4rem; }
.kb-report-prod {
  display: flex; flex-direction: column; gap: .15rem; text-align: left;
  padding: .6rem .8rem; border-radius: var(--sc-radius); cursor: pointer; font: inherit;
  color: var(--sc-ink); background: var(--sc-card); border: 2px solid var(--sc-border);
  transition: border-color .12s ease, background .12s ease;
}
.kb-report-prod:hover { border-color: var(--sc-primary); }
.kb-report-prod.sel { border-color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 10%, transparent); }
.kb-report-prod-label { font-weight: 700; }
.kb-report-prod-meta { font-size: .82rem; color: var(--sc-muted); }

/* ── Consommation IA dans la tuile d'un enfant (page Profils) ──
   Bloc pleine largeur sous l'identité + actions : ligne label + moyenne générations/jour, puis jauge
   de tokens + %, puis date de remise à zéro (chiffres serveur uniquement, règles #1/#16). */
.kb-profile-usage {
  flex: 1 1 100%; margin-top: .25rem; padding-top: .85rem;
  border-top: 1.5px dashed var(--sc-border);
}
.kb-profile-usage-top {
  display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
  margin-bottom: .35rem; font-size: .85rem;
}
.kb-profile-usage-label {
  display: inline-flex; align-items: center; gap: .4rem;
  font-weight: 700; color: var(--sc-muted);
}
.kb-profile-usage-avg { font-weight: 800; color: var(--sc-ink); white-space: nowrap; }
.kb-gauge--sm { height: 16px; margin: 0; }
.kb-gauge--sm .kb-gauge-pct { font-size: .72rem; }
.kb-profile-usage-reset { margin: .35rem 0 0; font-size: .78rem; color: var(--sc-muted); }
/* État de chargement discret (avant réponse serveur). */
.kb-profile-usage.is-loading .kb-gauge-fill { width: 30% !important; opacity: .35; }

/* ── Hub « Prépare demain » : en-tête de tuile (matière + bouton « J'ai fini ») ── */
.kb-tm-top { display: flex; align-items: center; gap: .6rem; margin-bottom: .5rem; }
.kb-tm-done {
  display: inline-flex; align-items: center; gap: .35rem; cursor: pointer;
  padding: .4rem .8rem; border-radius: 999px; font-weight: 700; font-size: .82rem;
  color: #fff; background: var(--sc-success); border: none;
  transition: filter .12s ease;
}
.kb-tm-done:hover { filter: brightness(1.06); }
.kb-tm-done:disabled { cursor: default; }
.kb-tm-row { transition: background .2s ease, border-color .2s ease; }

/* Groupe de boutons d'en-tête (« Rien à faire » + « C'est fini ! »). */
.kb-tm-cta { display: inline-flex; align-items: center; gap: .4rem; flex-wrap: wrap; justify-content: flex-end; }
/* Mobile : la matière prend toute la première ligne (nom entier, plus de « Mat… »),
   les boutons d'en-tête passent en dessous. */
@media (max-width: 560px) {
  .kb-tm-top { flex-wrap: wrap; }
  .kb-tm-subj { flex: 1 1 100%; }
  .kb-tm-cta { flex: 1 1 100%; justify-content: flex-start; }
  /* Tuile validée (« Fait ✓ » / « Rien à faire ») : un seul petit badge → tout sur UNE ligne
     (nom + badge + chevron). On annule le passage à la ligne réservé à l'état actif (3 boutons).
     nowrap + min-width:0 : un nom long (ex. « Histoire-Géo ») s'ellipse au lieu de faire passer
     le chevron à la ligne suivante (badge « Rien à faire », plus large que « Fait ✓ »). */
  .kb-tm-row.is-done .kb-tm-top { flex-wrap: nowrap; }
  .kb-tm-row.is-done .kb-tm-subj { flex: 1 1 auto; min-width: 0; }
  .kb-tm-row.is-done .kb-tm-cta { flex: 0 0 auto; justify-content: flex-end; }
  .kb-tm-row.is-done .kb-tm-caret { flex: 0 0 auto; }
}
/* « Rien à faire » : action secondaire NEUTRE (pas vert : rien n'a été fait), contour discret. */
.kb-tm-nothing {
  display: inline-flex; align-items: center; gap: .35rem; cursor: pointer;
  padding: .4rem .8rem; border-radius: 999px; font-weight: 700; font-size: .82rem;
  color: var(--sc-muted); background: transparent; border: 2px solid var(--sc-border);
  transition: background .12s ease, border-color .12s ease;
}
.kb-tm-nothing:hover { background: color-mix(in srgb, var(--sc-muted) 8%, transparent); border-color: var(--sc-muted); }
.kb-tm-nothing:disabled { cursor: default; }
/* Rangée « Rien à faire » : badge neutre (pas vert), tuile non valorisée comme un vrai travail. */
.kb-tm-nothing.is-done { background: var(--kb-creme-fonce); color: var(--sc-muted); border-color: var(--sc-border); opacity: 1; }
html[data-motion="reduced"] .kb-tm-nothing { transition: none; }

/* État « accompli » : on GARDE la tuile (valorise le travail fait), estompée et badgée en vert. */
.kb-tm-row.is-done {
  background: color-mix(in srgb, var(--sc-success) 8%, transparent);
  border-color: color-mix(in srgb, var(--sc-success) 45%, var(--sc-border));
}
.kb-tm-row.is-done .kb-tm-actions { opacity: .55; }   /* actions estompées mais toujours accessibles */
/* Bouton devenu badge « Fait ✓ » : vert plein, contour, non cliquable. */
.kb-tm-done.is-done { background: var(--sc-success); color: #fff; opacity: 1; }
html[data-motion="reduced"] .kb-tm-row { transition: none; }

/* Tuile « Fait ✓ » repliable : en-tête cliquable + chevron aligné à droite. */
.kb-tm-top--toggle { cursor: pointer; }
.kb-tm-caret {
  flex: 0 0 auto; color: var(--sc-muted); font-size: 1rem;
  padding: .35rem;                     /* zone de clic confortable au doigt */
  transition: transform .15s ease;
}
.kb-tm-row.is-collapsed .kb-tm-caret { transform: rotate(-90deg); }   /* replié : chevron vers la droite */
/* Repliée : on masque actions + récap, on garde la ligne matière + badge. */
.kb-tm-row.is-collapsed .kb-tm-actions,
.kb-tm-row.is-collapsed .kb-tm-recap { display: none; }
.kb-tm-row.is-collapsed .kb-tm-top { margin-bottom: 0; }
html[data-motion="reduced"] .kb-tm-caret { transition: none; }

/* Récapitulatif du travail accompli, sous la tuile validée. */
.kb-tm-recap {
  margin-top: .7rem; padding-top: .6rem; border-top: 1px dashed color-mix(in srgb, var(--sc-success) 45%, var(--sc-border));
}
.kb-tm-recap-title { font-weight: 700; font-size: .9rem; color: var(--sc-success); margin-bottom: .35rem; }
.kb-tm-recap-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.kb-tm-recap-list li { display: flex; align-items: baseline; gap: .5rem; font-size: .9rem; color: var(--sc-ink); }
.kb-tm-recap-list i { color: var(--sc-primary); flex: 0 0 auto; }
.kb-tm-recap-none { margin: 0; font-size: .9rem; color: var(--sc-muted); }

/* Félicitation quand toutes les matières du jour sont validées. */
.kb-celebrate {
  display: flex; align-items: center; gap: 1rem; margin-top: 1rem;
  background: color-mix(in srgb, var(--sc-success) 12%, transparent);
  border: 2px solid color-mix(in srgb, var(--sc-success) 45%, var(--sc-border));
  border-radius: var(--sc-radius); padding: 1rem 1.1rem;
}
.kb-celebrate-kapi { width: 64px; height: auto; flex: 0 0 auto; }
.kb-celebrate-msg {
  margin: 0; font-family: var(--sc-font-title, inherit); font-weight: 800;
  font-size: 1.1rem; color: var(--sc-ink);
}

/* ── Rapport d'activité parent (activity.html) ── */
/* En-tête de jour : titre + temps total à droite. */
.kb-act-dayhead { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; flex-wrap: wrap; margin: 1.5rem 0 .5rem; }
.kb-act-day { font-family: var(--sc-font-title, inherit); font-size: 1.05rem; margin: 0; text-transform: capitalize; color: var(--sc-ink); }
.kb-act-total { font-weight: 700; font-size: .9rem; color: var(--sc-primary); }
.kb-act-total i { margin-right: .25rem; }
.kb-act-card { margin-bottom: .7rem; }
/* Durée par matière (chip discret dans l'en-tête de la carte). */
.kb-act-time {
  flex: 0 0 auto; font-size: .78rem; font-weight: 700; padding: .15rem .5rem; border-radius: 999px;
  color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 12%, transparent);
}
.kb-act-time i { margin-right: .25rem; }
.kb-act-head { display: flex; align-items: center; gap: .55rem; margin-bottom: .5rem; }
.kb-act-subj { font-weight: 800; flex: 1 1 auto; min-width: 0; }
.kb-act-badge {
  flex: 0 0 auto; font-size: .78rem; font-weight: 700; padding: .15rem .5rem; border-radius: 999px;
  color: var(--sc-success); background: color-mix(in srgb, var(--sc-success) 15%, transparent);
}
.kb-act-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.kb-act-list li { display: flex; align-items: baseline; gap: .5rem; color: var(--sc-ink); }
.kb-act-list i { color: var(--sc-primary); flex: 0 0 auto; }
.kb-act-none { color: var(--sc-muted); font-style: italic; margin: 0; }

/* ── En-tête d'une question de quiz : énoncé + bouton « Écouter » sur une ligne ── */
.kb-q-head { display: flex; align-items: flex-start; gap: .75rem; }
.kb-q-head .kb-q-listen, .kb-corr-listen .kb-q-listen { flex: 0 0 auto; }

/* ── Réponses de quiz (quiz.html) : lisibilité dys — puce fixe, texte aéré ── */
.kb-quiz-choices { display: grid; gap: .9rem; margin-top: .75rem; }
.kb-quiz-choice {
  display: flex; align-items: flex-start; gap: .8rem; cursor: pointer;
  padding: .5rem; border-radius: var(--sc-radius); line-height: 1.5;
}
.kb-quiz-choice:hover { background: color-mix(in srgb, var(--sc-primary) 7%, transparent); }
/* La bulle radio ne rétrécit JAMAIS, même si le texte tient sur plusieurs lignes. */
.kb-quiz-radio {
  flex: 0 0 auto; width: 1.5rem; height: 1.5rem; margin-top: .1rem;
}
.kb-quiz-choice-text { flex: 1 1 auto; min-width: 0; }
/* Confort dys : réponses davantage espacées et interligne renforcé. */
html[data-font="dys"] .kb-quiz-choices { gap: 1.25rem; }
html[data-font="dys"] .kb-quiz-choice { line-height: 1.7; }

/* ══ Formats de quiz avancés ══════════════════════════════════════════════════ */

/* Choix des formats (quiz-setup) : tuiles cochables uniformes, grandes cibles tactiles (dys). */
.kb-fmt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .7rem; }
.kb-fmt {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .55rem; cursor: pointer; text-align: center; min-height: 6.2rem;
  padding: 1rem .7rem; border-radius: 1rem; font: inherit;
  border: 2px solid var(--sc-border); background: var(--sc-bg); color: var(--sc-ink);
  transition: border-color .14s ease, background .14s ease, box-shadow .14s ease, transform .08s ease;
}
/* Pastille d'icône ronde et lisible. Le kit FA rend l'icône en <svg> (mode SVG+JS) :
   on stylise l'enveloppe .kb-fmt-ico, pas l'icône elle-même. */
.kb-fmt .kb-fmt-ico {
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 12%, transparent);
  transition: color .14s ease, background .14s ease;
}
.kb-fmt .kb-fmt-ico i, .kb-fmt .kb-fmt-ico svg { font-size: 1.15rem; }
.kb-fmt span { font-weight: 700; line-height: 1.25; font-size: .98rem; }
.kb-fmt:hover { border-color: var(--sc-primary); box-shadow: 0 4px 14px rgba(0,0,0,.06); }
.kb-fmt:active { transform: translateY(1px); }
.kb-fmt.sel {
  border-color: var(--sc-primary);
  background: color-mix(in srgb, var(--sc-primary) 12%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sc-primary) 22%, transparent);
}
.kb-fmt.sel .kb-fmt-ico { color: #fff; background: var(--sc-primary); }
/* Coche d'état sélectionné, coin haut-droit. */
.kb-fmt::after {
  content: "\2713"; font-weight: 900;
  position: absolute; top: .5rem; right: .55rem; width: 1.35rem; height: 1.35rem;
  display: flex; align-items: center; justify-content: center; font-size: .8rem; line-height: 1;
  border-radius: 50%; background: var(--sc-primary); color: #fff;
  opacity: 0; transform: scale(.5); transition: opacity .12s ease, transform .12s ease;
}
.kb-fmt.sel::after { opacity: 1; transform: scale(1); }
.kb-fmt-challenge {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 3.2rem; border-radius: 1rem; font-weight: 800; font-size: 1.02rem;
  background: var(--sc-accent); color: #fff; border: none;
}
.kb-fmt-challenge:hover { filter: brightness(1.04); }

/* Vrai / Faux : deux gros boutons. */
.kb-tf { display: flex; gap: .6rem; margin-top: .75rem; }
.kb-tf-btn {
  flex: 1 1 0; min-height: 3rem; cursor: pointer; font: inherit; font-weight: 800; font-size: 1rem;
  border: 3px solid var(--sc-border); border-radius: var(--sc-radius); background: var(--sc-bg); color: var(--sc-ink);
  transition: border-color .12s ease, background .12s ease;
}
.kb-tf-btn:hover { border-color: var(--sc-primary); }
.kb-tf-btn.sel { border-color: var(--sc-primary); background: color-mix(in srgb, var(--sc-primary) 14%, transparent); }

/* Remise en ordre : liste avec boutons monter/descendre. */
.kb-order { list-style: none; margin: .75rem 0 0; padding: 0; display: grid; gap: .5rem; counter-reset: kbord; }
.kb-order-item {
  display: flex; align-items: center; gap: .6rem;
  border: 2px solid var(--sc-border); border-radius: var(--sc-radius); padding: .6rem .75rem; background: var(--sc-bg);
}
.kb-order-item::before { counter-increment: kbord; content: counter(kbord); font-weight: 800; color: var(--sc-primary); flex: 0 0 auto; width: 1.4rem; text-align: center; }
.kb-order-text { flex: 1 1 auto; min-width: 0; }
.kb-order-btns { flex: 0 0 auto; display: flex; gap: .3rem; }
.kb-order-btns button {
  width: 2.2rem; height: 2.2rem; border-radius: 10px; cursor: pointer; border: none;
  background: color-mix(in srgb, var(--sc-primary) 14%, transparent); color: var(--sc-primary);
}
.kb-order-btns button:hover { background: var(--sc-primary); color: #fff; }

/* Appariement : gauche fixe + menu de droite. */
.kb-match { display: grid; gap: .5rem; margin-top: .75rem; }
.kb-match-row { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.kb-match-left { flex: 1 1 40%; min-width: 0; font-weight: 700; }
.kb-match-sel { flex: 1 1 45%; min-width: 0; min-height: 2.6rem; }

/* Corrigé : la bonne réponse mise en avant. */
.kb-corr-sol { font-weight: 700; color: var(--sc-success); }

/* Vidéos pédagogiques validées (bas de la fiche). Embed responsive 16:9, charte de marque. */
.kb-vid-title { margin-top: 1.5rem; }
.kb-vid-note { color: var(--sc-muted); font-size: .9rem; margin: .1rem 0 .8rem; }
.kb-vid-list { display: grid; gap: 1rem; }
.kb-vid { margin: 0; }
/* Ratio 16:9 par `aspect-ratio` sur le cadre, l'iframe en flux normal (PAS position:absolute + padding
   %) : en device-mode Chromium/portrait, l'iframe absolue dans une boîte au padding-% a une zone
   tactile décalée (les contrôles YouTube ne répondent pas). Une hauteur réelle + iframe block règle ça. */
.kb-vid-frame {
  width: 100%; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--sc-radius);
  border: 2px solid var(--kb-brun-clair); background: var(--kb-creme-fonce);
}
.kb-vid-frame iframe {
  display: block; width: 100%; height: 100%; border: 0;
}
/* FAÇADE (lite embed) : un vrai <button> (zone tactile fiable en portrait ET paysage, contrairement
   à l'iframe YouTube dont le hit-testing est cassé en portrait sur iOS). Miniature en fond + gros
   bouton play centré. Au 1er tap, JS remplace ce bouton par l'iframe autoplay. */
.kb-vid-facade {
  position: relative; display: block; padding: 0; cursor: pointer;
  background-color: var(--kb-creme-fonce); background-size: cover; background-position: center;
  font: inherit; color: inherit;
}
.kb-vid-facade .kb-vid-play {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 4.2rem; height: 4.2rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(43, 36, 32, .72); color: #fff; font-size: 1.5rem;
  box-shadow: 0 4px 16px rgba(0,0,0,.35); transition: transform .12s ease, background .12s ease;
  pointer-events: none;   /* le tap est capté par le bouton lui-même, pas par la pastille */
}
.kb-vid-facade .kb-vid-play i { margin-left: .18rem; }   /* recentre le triangle play optiquement */
.kb-vid-facade:hover .kb-vid-play,
.kb-vid-facade:focus-visible .kb-vid-play { background: var(--sc-primary); transform: translate(-50%, -50%) scale(1.06); }
.kb-vid-cap { margin: .45rem .2rem 0; font-weight: 700; color: var(--sc-ink); line-height: 1.3; }
.kb-vid-chan { font-weight: 400; color: var(--sc-muted); }

/* ── Bascule Fiche / Carte mentale (segmented control) + carte mentale (résumé visuel arbre) ──
   docs/CONCEPTION-CarteMentale.md — Lot 1. Rendu ARBRE VERTICAL (pas radial : lecture linéaire,
   pas de zoom/pan, grandes cibles = accessibilité dys règle #15). Couleurs de marque uniquement. */
.kb-viewtoggle {
  display: inline-flex; gap: .25rem; margin: 0 auto 1rem; padding: .3rem;
  background: var(--kb-creme-fonce); border: 2px solid var(--sc-border); border-radius: 999px;
}
.kb-viewtoggle-btn {
  display: inline-flex; align-items: center; gap: .45rem; cursor: pointer;
  padding: .5rem 1rem; border: none; border-radius: 999px; font: inherit; font-weight: 700;
  color: var(--sc-muted); background: transparent; transition: background .15s ease, color .15s ease;
}
.kb-viewtoggle-btn.is-active { background: var(--sc-primary); color: var(--sc-primary-ink); }
.kb-viewtoggle-btn:not(.is-active):hover { color: var(--sc-ink); }
html[data-motion="reduced"] .kb-viewtoggle-btn { transition: none; }
/* Centrer la bascule au-dessus de la fiche. */
main > .kb-viewtoggle { display: flex; justify-content: center; }

.kb-map { display: flex; flex-direction: column; align-items: center; gap: 1rem; }
/* Sujet central : grande carte de marque, ancre visuelle en tête de l'arbre. */
.kb-map-central {
  text-align: center; font-weight: 800; font-size: 1.25rem; line-height: 1.3;
  color: var(--sc-primary-ink); background: var(--sc-primary);
  border-radius: var(--sc-radius); padding: .9rem 1.3rem; max-width: 100%;
}
.kb-map-branches { display: grid; gap: .9rem; width: 100%; }
/* Une branche = carte colorée (couleur par index via --kb-map-color) : repérage visuel. */
.kb-map-branch {
  border: 2px solid var(--kb-map-color, var(--sc-border));
  border-left-width: 8px; border-radius: var(--sc-radius);
  background: color-mix(in srgb, var(--kb-map-color, var(--sc-primary)) 8%, var(--sc-surface));
  padding: .8rem 1rem;
}
.kb-map-branch-head {
  display: flex; align-items: center; gap: .6rem;
  font-weight: 800; font-size: 1.05rem; color: var(--sc-ink);
}
.kb-map-branch-ico { color: var(--kb-map-color, var(--sc-primary)); font-size: 1.05rem; }
.kb-map-branch-dot {
  width: 1rem; height: 1rem; border-radius: 50%; flex: 0 0 auto;
  background: var(--kb-map-color, var(--sc-primary));
}
.kb-map-leaves { list-style: none; margin: .6rem 0 0; padding: 0; display: grid; gap: .45rem; }
.kb-map-leaves li {
  position: relative; padding: .35rem .6rem .35rem 1.4rem; line-height: 1.4;
  background: var(--sc-surface); border-radius: 10px; color: var(--sc-ink);
}
.kb-map-leaves li::before {
  content: ""; position: absolute; left: .6rem; top: 50%; transform: translateY(-50%);
  width: .45rem; height: .45rem; border-radius: 50%;
  background: var(--kb-map-color, var(--sc-primary));
}

/* Frise chronologique (fiches d'histoire) : liste verticale datée avec rail du temps à gauche.
   Rendue DANS la vue fiche (pas dans la bascule carte). Pastille de date de marque, aérée (dys #15). */
.kb-tl { margin-top: 1.4rem; }
/* Même taille/poids que les autres titres de section de la fiche (#sheet h2) : seul l'icône est ajoutée. */
.kb-tl-title { display: flex; align-items: center; gap: .5rem; margin: 1.5rem 0 .8rem; }
.kb-tl-title .fa-timeline { color: var(--sc-primary); }
.kb-tl-list {
  list-style: none; margin: 0; padding: 0 0 0 .3rem;
  border-left: 3px solid var(--sc-primary);
}
/* ⚠️ Règles SCOPÉES à `.kb-tl-list` : `.kb-tl-item` est AUSSI le nom des étapes
   de la timeline vitrine (`.kb-timeline .kb-tl-item`, cf. plus haut). Sans ce
   préfixe, ce bloc écrasait le `padding-top` des étapes → icône sur le titre. */
.kb-tl-list .kb-tl-item {
  position: relative; display: flex; align-items: flex-start; flex-wrap: wrap;
  gap: .6rem; padding: 0 0 1rem 1.1rem; line-height: 1.5;
}
.kb-tl-list .kb-tl-item:last-child { padding-bottom: 0; }
/* Point sur le rail, en face de chaque repère. */
.kb-tl-list .kb-tl-dot {
  position: absolute; left: -.72rem; top: .35rem;
  width: .85rem; height: .85rem; border-radius: 50%; flex: 0 0 auto;
  background: var(--sc-accent); border: 3px solid var(--sc-surface);
}
/* Date : pastille miel, bien repérable. */
.kb-tl-list .kb-tl-date {
  flex: 0 0 auto; font-weight: 800; color: var(--sc-primary-ink);
  background: var(--sc-accent); border-radius: 8px; padding: .2rem .6rem;
  white-space: nowrap;
}
.kb-tl-list .kb-tl-label { flex: 1 1 12rem; color: var(--sc-ink); min-width: 10rem; text-align: left; }
/* Repère « An 0 · J.-C. » intercalé (pas un fait du contenu) : pastille et libellé estompés pour se
   distinguer des vrais événements, mais bien lisibles (contraste conservé). */
.kb-tl-list .kb-tl-zero .kb-tl-date { background: var(--sc-primary); }
.kb-tl-list .kb-tl-zero .kb-tl-dot { background: var(--sc-primary); }
.kb-tl-list .kb-tl-zero .kb-tl-label { color: var(--sc-primary); font-style: italic; }

/* Illustrations (Wikimedia Commons) : image réelle encadrée, intercalée dans une section. Attribution CC
   obligatoire sous l'image. Grande, aérée, coins doux (charte) ; pas d'animation (accessibilité #15). */
.kb-ill {
  margin: .8rem 0 1.2rem; padding: .5rem; background: var(--sc-surface);
  border: 1px solid var(--sc-border); border-radius: var(--sc-radius);
  max-width: 420px;
}
.kb-ill-img {
  display: block; width: 100%; height: auto; border-radius: calc(var(--sc-radius) - 4px);
  background: var(--sc-bg);
}
.kb-ill-cap { margin: .5rem .2rem .2rem; font-weight: 700; color: var(--sc-ink); line-height: 1.35; }
/* Attribution CC repliée derrière un petit « © » cliquable (discret mais accessible = conforme CC). */
.kb-ill-credit { margin: .2rem .2rem 0; }
.kb-ill-copy {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; border-radius: 50%; cursor: pointer;
  background: var(--sc-bg); color: var(--sc-muted); font-weight: 800; font-size: .85rem;
  border: 1px solid var(--sc-border); list-style: none; user-select: none;
}
.kb-ill-copy::-webkit-details-marker { display: none; }   /* masque le chevron natif (WebKit) */
.kb-ill-copy::marker { content: ""; }                      /* idem (Firefox/standard) */
.kb-ill-copy:hover { background: var(--sc-primary); color: #fff; border-color: var(--sc-primary); }
.kb-ill-credit-text { margin: .35rem .1rem 0; font-size: .78rem; color: var(--sc-muted); line-height: 1.4; }
.kb-ill-credit-text a { color: var(--sc-muted); text-decoration: underline; }
/* Image cliquable (agrandissement) : bouton nu autour de l'image + loupe au survol. */
.kb-ill-btn {
  position: relative; display: block; width: 100%; padding: 0; border: 0; cursor: zoom-in;
  background: none; border-radius: calc(var(--sc-radius) - 4px); overflow: hidden;
}
.kb-ill-zoom {
  position: absolute; right: .5rem; bottom: .5rem;
  width: 2rem; height: 2rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--sc-ink) 60%, transparent); color: #fff; font-size: .9rem;
  opacity: 0; transition: opacity .12s ease;
}
.kb-ill-btn:hover .kb-ill-zoom, .kb-ill-btn:focus-visible .kb-ill-zoom { opacity: 1; }
html[data-motion="reduced"] .kb-ill-zoom { opacity: 1; }

/* Lightbox : image en grand, centrée, fermeture explicite (✕). */
.kb-lightbox .kb-lightbox-card {
  position: relative; background: var(--sc-surface); border-radius: var(--sc-radius);
  padding: .8rem; max-width: min(92vw, 1100px); max-height: 92vh;
  display: flex; flex-direction: column; box-shadow: var(--sc-shadow, 0 10px 40px rgba(0,0,0,.35));
}
.kb-lightbox-img {
  display: block; max-width: 100%; max-height: 78vh; width: auto; height: auto;
  margin: 0 auto; border-radius: calc(var(--sc-radius) - 4px); background: var(--sc-bg);
  object-fit: contain;
}
.kb-lightbox-close {
  position: absolute; top: .5rem; right: .5rem; z-index: 2;
  background: color-mix(in srgb, var(--sc-ink) 55%, transparent); color: #fff;
}
.kb-lightbox-cap { margin: .6rem .2rem .1rem; font-weight: 700; color: var(--sc-ink); text-align: center; }
.kb-lightbox-credit { margin: .1rem .2rem 0; font-size: .8rem; color: var(--sc-muted); text-align: center; }
.kb-lightbox-credit a { color: var(--sc-muted); text-decoration: underline; }
/* Galerie de bas de fiche (images sans section rattachée) : grille responsive. */
.kb-ill-gallery-title { margin-top: 1.5rem; }
.kb-ill-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; }
.kb-ill-gallery .kb-ill { margin: 0; max-width: none; }

/* Schéma mathématique généré (SVG serveur, exact) : encadré clair, centré, légende dessous. */
.kb-mathfig {
  margin: .8rem 0 1.2rem; padding: .6rem; max-width: 460px;
  background: var(--sc-surface); border: 1px solid var(--sc-border); border-radius: var(--sc-radius);
}
.kb-mathfig svg, .kb-mathfig-img { display: block; width: 100%; height: auto; }
.kb-mathfig-cap { margin: .5rem .2rem 0; font-weight: 700; color: var(--sc-ink); line-height: 1.35; text-align: center; }

/* Dictée vocale : bouton micro accolé à un champ (input/textarea). Grande cible tactile (dys #15). */
.kb-mic-wrap { position: relative; display: block; }
.kb-mic-wrap > input,
.kb-mic-wrap > textarea { width: 100%; padding-right: 3.2rem; }   /* place pour le micro */
.kb-mic {
  /* Champ mono-ligne (input) : micro CENTRÉ verticalement, quelle que soit la hauteur du champ. */
  position: absolute; top: 50%; transform: translateY(-50%); right: .45rem;
  width: 2.5rem; height: 2.5rem; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: var(--sc-primary); color: #fff; font-size: 1rem;
  transition: background .12s ease, transform .08s ease, box-shadow .12s ease;
}
.kb-mic:hover { filter: brightness(1.05); }
.kb-mic:active { transform: translateY(-50%) scale(.96); }
/* Champ multi-lignes (textarea) : micro calé en HAUT à droite (le champ peut grandir). */
.kb-mic-wrap > textarea + .kb-mic { top: .5rem; transform: none; }
.kb-mic-wrap > textarea + .kb-mic:active { transform: scale(.96); }
/* En écoute : pastille miel + halo pulsé (repère d'état clair). */
.kb-mic.is-listening { background: var(--sc-accent); box-shadow: 0 0 0 0 color-mix(in srgb, var(--sc-accent) 60%, transparent); animation: kb-mic-pulse 1.4s ease-out infinite; }
@keyframes kb-mic-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--sc-accent) 55%, transparent); }
  70%  { box-shadow: 0 0 0 12px color-mix(in srgb, var(--sc-accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--sc-accent) 0%, transparent); }
}
/* Non supporté : micro grisé (visible mais inactif). */
.kb-mic-disabled { background: var(--sc-border); color: var(--sc-muted); cursor: not-allowed; }
.kb-mic-disabled:hover { filter: none; }
/* Réduire les animations (accessibilité #15) : pas de pulsation. */
html[data-motion="reduced"] .kb-mic.is-listening { animation: none; }

/* ── Grosse empreinte biométrique avec halo animé (login mode biométrie) ─────── */
.kb-bioprint {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  /* Boîte élargie pour laisser respirer le halo (qui s'étend bien au-delà du disque). */
  width: 13rem; height: 13rem; margin: .25rem auto; padding: 0;
  border: none; background: transparent; cursor: pointer;
}
/* Disque central : dégradé miel→brun, empreinte blanche. Grande cible tactile (dys #15). */
.kb-bioprint-disc {
  position: relative; z-index: 2;
  width: 6.4rem; height: 6.4rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 35% 30%, var(--sc-accent), var(--kb-brun));
  color: #fff; font-size: 3rem;
  box-shadow: 0 8px 22px rgba(138,87,51,.35);
  transition: transform .15s ease, box-shadow .15s ease;
}
.kb-bioprint:hover .kb-bioprint-disc { transform: scale(1.04); box-shadow: 0 10px 26px rgba(138,87,51,.45); }
.kb-bioprint:active .kb-bioprint-disc { transform: scale(.97); }
.kb-bioprint:focus-visible { outline: none; }
.kb-bioprint:focus-visible .kb-bioprint-disc { box-shadow: 0 0 0 4px color-mix(in srgb, var(--sc-accent) 45%, transparent); }
/* Halos concentriques qui pulsent vers l'extérieur (deux ondes décalées). */
.kb-bioprint-halo {
  position: absolute; z-index: 1; inset: 0; margin: auto;
  width: 6.4rem; height: 6.4rem; border-radius: 50%;
  border: 3px solid var(--sc-accent);
  animation: kb-bioprint-pulse 2.4s ease-out infinite;
}
.kb-bioprint-halo--2 { animation-delay: 1.2s; }
@keyframes kb-bioprint-pulse {
  0%   { transform: scale(1);   opacity: .7; }
  70%  { opacity: .12; }
  100% { transform: scale(3.2); opacity: 0; }
}
.kb-bioprint-label { font-weight: 800; color: var(--kb-brun); margin: .25rem 0 0; }
/* Réduire les animations (accessibilité #15) : pas de pulsation. */
html[data-motion="reduced"] .kb-bioprint-halo { animation: none; opacity: 0; }

/* TRÈS gros check vert de succès d'installation PWA (remplace Kapi + anneau à la fin).
   Le kit FA (SVG+JS) convertit le <i> en <svg> : on force la taille sur les DEUX (i et svg généré),
   sinon le SVG garde sa taille intrinsèque (d'où l'effet « tout petit »). */
.kb-install-check,
i.kb-install-check, svg.kb-install-check {
  font-size: 8rem; line-height: 1;
  width: 8rem; height: 8rem;
  color: #2FA060 !important; fill: #2FA060 !important;   /* vert franc et vif */
  animation: kb-check-pop .4s ease-out;
}
@keyframes kb-check-pop {
  0% { transform: scale(.4); opacity: 0; }
  60% { transform: scale(1.14); opacity: 1; }
  100% { transform: scale(1); }
}
html[data-motion="reduced"] .kb-install-check { animation: none; }

/* Consommation IA : bloc DISCRET, sans cadre (règle #16). Texte atténué, fine jauge intégrée.
   Ligne 1 : icône + libellé + jauge + % ; ligne 2 : date de réinitialisation, centrée, sans puce. */
.kb-usage-line { margin: .6rem .25rem 2rem; font-size: .85rem; color: var(--sc-muted); }
/* Jauge « Prends de l'avance » : moins d'écart avant la liste des jours (pas le grand espace bas
   de la jauge de consommation IA). */
#advanceGauge.kb-usage-line { margin-bottom: .5rem; }
.kb-usage-line-top { display: flex; align-items: center; gap: .5rem; }
.kb-usage-line-ico { font-size: .9rem; opacity: .75; }
.kb-usage-line-label { font-weight: 600; }
.kb-usage-line-track {
  /* Piste VIDE bien distincte du remplissage : fond crème clair + bord sombre (sinon, brun clair
     sur brun, on ne voyait pas où s'arrêtait le remplissage → effet « barre pleine »). */
  flex: 1 1 auto; min-width: 3rem; height: 8px;
  background: var(--kb-creme); border: 1px solid var(--kb-brun-profond);
  border-radius: 999px; overflow: hidden;
}
.kb-usage-line-fill { display: block; height: 100%; width: 0; background: var(--sc-primary); border-radius: 999px; transition: width .5s ease; }
.kb-usage-line-pct { font-weight: 700; flex: 0 0 auto; }
/* Date rapprochée de la barre (marge négative) : rendu validé sur maquette. */
.kb-usage-line-reset { text-align: center; opacity: .8; margin-top: -0.5rem; }

/* ── Mode concentration (SPEC-ModeConcentration §5.2). ──
   L'app reste UTILISABLE en plein écran ; un bouton CADENAS flottant ouvre la modale de déverrouillage.
   Cette modale ne se ferme PAS par clic à côté / Échap (règle #13) : seulement « Annuler » (on reste
   concentré) ou le bon code (on sort). Recouvre TOUT (position fixed, z-index très haut). */
.kb-focus-lock {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 9999;
  display: none; align-items: center; justify-content: center;
  width: 3.6rem; height: 3.6rem; border-radius: 50%;
  background: var(--sc-primary); color: var(--kb-creme); border: none;
  font-size: 1.5rem; cursor: pointer; box-shadow: 0 4px 14px rgba(43, 36, 32, .28);
}
.kb-focus-lock.show { display: flex; }
.kb-focus-lock:focus-visible { outline: none; box-shadow: 0 0 0 4px color-mix(in srgb, var(--sc-primary) 35%, transparent); }
.kb-focus-overlay {
  position: fixed; inset: 0; z-index: 10000;
  display: none; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--kb-encre) 55%, transparent); padding: 1rem;
}
.kb-focus-overlay.open { display: flex; }
.kb-focus-card {
  text-align: center; width: 100%; max-width: 22rem;
  background: var(--kb-creme); border-radius: var(--sc-radius);
  padding: 1.5rem 1.25rem; box-shadow: 0 10px 30px rgba(43, 36, 32, .35);
}
.kb-focus-kapi { width: 88px; height: auto; margin-bottom: .25rem; }
.kb-focus-title { font-family: var(--sc-font-title); font-weight: 800; font-size: 1.4rem; color: var(--sc-ink); margin: .25rem 0; }
.kb-focus-hint { color: var(--sc-muted); margin: 0 0 1rem; }
.kb-focus-dots { display: flex; gap: .55rem; justify-content: center; margin: .25rem 0 .5rem; }
.kb-focus-dot {
  width: .9rem; height: .9rem; border-radius: 50%;
  background: var(--kb-creme-fonce); border: 2px solid var(--sc-border);
}
.kb-focus-dot.on { background: var(--sc-primary); border-color: var(--sc-primary); }
.kb-focus-err { color: var(--sc-danger); min-height: 1.2em; margin: .25rem 0 .5rem; font-weight: 700; }
.kb-focus-pad {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem;
  max-width: 18rem; margin: 0 auto;
}
.kb-focus-key {
  min-height: 4rem; font-family: var(--sc-font-title, inherit); font-size: 1.6rem; font-weight: 800;
  color: var(--sc-ink); background: var(--kb-creme-fonce); border: 2px solid var(--sc-border);
  border-radius: var(--sc-radius); cursor: pointer; transition: border-color .12s ease, background .12s ease;
}
.kb-focus-key:hover { border-color: var(--sc-primary); }
.kb-focus-key:active { background: color-mix(in srgb, var(--sc-primary) 14%, var(--kb-creme-fonce)); }
.kb-focus-key:focus-visible { outline: none; border-color: var(--sc-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--sc-primary) 22%, transparent); }
.kb-focus-key--back { color: var(--sc-primary); }
.kb-focus-key--cancel { font-size: 1rem; color: var(--sc-muted); }

/* ── Pavé numérique à l'écran (brique partagée kbKeypad, web/js/keypad.js) ─────────────────────
   Saisie de PIN SANS clavier natif du smartphone : le champ garde inputmode="none" et readonly,
   et la saisie passe EXCLUSIVEMENT par ce pavé (gros boutons tactiles, accessibilité dys règle #15).
   Rendu dans un conteneur par kbKeypad.mount(). Même grammaire visuelle que le pavé du mode focus. */
.kb-keypad {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem;
  max-width: 18rem; margin: .75rem auto 0;
}
.kb-keypad-key {
  min-height: 3.8rem; font-family: var(--sc-font-title, inherit); font-size: 1.6rem; font-weight: 800;
  color: var(--sc-ink); background: var(--kb-creme-fonce); border: 2px solid var(--sc-border);
  border-radius: var(--sc-radius); cursor: pointer; transition: border-color .12s ease, background .12s ease;
  touch-action: manipulation; -webkit-user-select: none; user-select: none;
}
.kb-keypad-key:hover { border-color: var(--sc-primary); }
.kb-keypad-key:active { background: color-mix(in srgb, var(--sc-primary) 14%, var(--kb-creme-fonce)); }
.kb-keypad-key:focus-visible { outline: none; border-color: var(--sc-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--sc-primary) 22%, transparent); }
.kb-keypad-key--back { color: var(--sc-primary); }
.kb-keypad-key--empty { background: transparent; border: 0; cursor: default; }
@media (max-width: 380px) { .kb-keypad-key { min-height: 3.3rem; font-size: 1.4rem; } .kb-keypad { gap: .45rem; } }

/* ── KapiQuiz (jeu famille : roue + question + score) — docs/SPEC-KapiQuiz.md ───────────────── */

/* Bandeau de score : série en cours + record famille. */
.kb-kq-score {
  display: flex; gap: .75rem; flex-wrap: wrap;
  margin-bottom: 1rem;
}
.kb-kq-score-item {
  flex: 1 1 0; min-width: 8rem;
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  background: var(--kb-creme-fonce);
  border: 2px solid var(--sc-border);
  border-radius: var(--sc-radius);
  padding: .6rem .85rem;
}
.kb-kq-score-item > i { font-size: 1.3rem; color: var(--sc-accent); }
.kb-kq-score-label { color: var(--sc-muted); font-size: .9rem; }
.kb-kq-score-val { font-weight: 800; font-size: 1.35rem; color: var(--sc-primary); margin-left: auto; }
.kb-kq-score-date { flex-basis: 100%; color: var(--sc-muted); font-size: .8rem; }

/* Scène de la roue : canvas carré + curseur bas + bouton central Kapi. */
.kb-kq-wheel-wrap {
  position: relative;
  width: min(90vw, 360px);
  aspect-ratio: 1 / 1;
  margin: .5rem auto 0;
}
.kb-kq-wheel { width: 100%; height: 100%; display: block; filter: drop-shadow(0 4px 10px rgba(107,63,38,.18)); }
/* Couche d'icônes de matière superposée au canvas : tourne avec la roue (transform posé par wheel.js).
   Chaque icône est centrée puis poussée sur le rayon de son segment. Ne capte pas les clics (le clic va au Kapi). */
.kb-kq-iconlayer {
  position: absolute; inset: 0; pointer-events: none; z-index: 1;
  transform-origin: 50% 50%; will-change: transform;
}
.kb-kq-icon {
  position: absolute; top: 50%; left: 50%;
  width: 2.1rem; height: 2.1rem;
  display: flex; align-items: center; justify-content: center;
}
.kb-kq-icon-g { font-size: 1.7rem; color: #FBF3E4; }                 /* icône FA : crème, lisible sur la couleur */
.kb-kq-icon-g.fa-flag, .kb-kq-icon img.kb-kq-icon-g,
.kb-kq-icon img { width: 1.9rem; height: 1.45rem; object-fit: contain;
  border-radius: 3px; box-shadow: 0 1px 3px rgba(43,36,32,.35); }     /* drapeau : léger relief */
/* Curseur : une flèche qui pointe vers le HAUT, posée en bas de la roue. */
.kb-kq-pointer {
  position: absolute; left: 50%; bottom: -6px; transform: translateX(-50%);
  color: var(--sc-accent); font-size: 2.4rem; line-height: 1; z-index: 2;
  filter: drop-shadow(0 2px 2px rgba(107,63,38,.3));
}
/* Bouton central Kapi : lance la roue. */
.kb-kq-kapi {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 34%; aspect-ratio: 1/1; border-radius: 50%;
  background: var(--kb-creme); border: 4px solid var(--sc-accent);
  box-shadow: 0 4px 12px rgba(107,63,38,.28);
  cursor: pointer; padding: .4rem; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  transition: transform .12s ease, box-shadow .12s ease;
}
.kb-kq-kapi img { width: 100%; height: 100%; object-fit: contain; }
.kb-kq-kapi:hover { transform: translate(-50%, -50%) scale(1.05); }
.kb-kq-kapi:active { transform: translate(-50%, -50%) scale(.96); }
.kb-kq-kapi:focus-visible { outline: none; box-shadow: 0 0 0 4px color-mix(in srgb, var(--sc-accent) 40%, transparent); }
.kb-kq-kapi.is-spinning { animation: kb-kq-wobble .5s ease-in-out infinite; }
@keyframes kb-kq-wobble { 0%,100% { transform: translate(-50%,-50%) rotate(-4deg); } 50% { transform: translate(-50%,-50%) rotate(4deg); } }

.kb-kq-hint { text-align: center; color: var(--sc-muted); margin: 1rem 0 0; }

/* Carte question. */
.kb-kq-question { margin-top: 1.5rem; }
.kb-kq-pop { animation: kb-kq-pop .35s ease; }
@keyframes kb-kq-pop { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }

.kb-kq-subject { display: flex; align-items: center; gap: .6rem; margin-bottom: .75rem; }
.kb-kq-subject-kapi { width: 2.6rem; height: 2.6rem; object-fit: contain; }
.kb-kq-subject-ic-i { font-size: 1.4rem; color: var(--sc-primary); }
.kb-kq-subject-ic img { width: 1.6rem; height: 1.2rem; object-fit: contain; vertical-align: middle; }
.kb-kq-subject-label { font-weight: 800; font-size: 1.15rem; color: var(--sc-primary); }

.kb-kq-prompt-row { display: flex; align-items: flex-start; gap: .6rem; }
.kb-kq-prompt { flex: 1 1 auto; font-size: 1.2rem; font-weight: 700; margin: 0 0 .5rem; }

.kb-kq-choices { display: flex; flex-direction: column; gap: .6rem; margin-top: .5rem; }
.kb-kq-choice {
  display: flex; align-items: center; gap: .75rem; width: 100%; text-align: left;
  min-height: var(--sc-tap);
  background: var(--kb-creme-fonce); border: 3px solid var(--sc-border);
  border-radius: var(--sc-radius); padding: .6rem .85rem; font: inherit; cursor: pointer;
  transition: border-color .12s ease, background .12s ease, transform .08s ease;
}
.kb-kq-choice:hover:not(:disabled) { border-color: var(--sc-primary); }
.kb-kq-choice:active:not(:disabled) { transform: scale(.99); }
.kb-kq-choice:disabled { cursor: default; }
.kb-kq-choice-letter {
  flex: 0 0 auto; width: 2rem; height: 2rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--sc-primary); color: var(--sc-primary-ink); font-weight: 800;
}
.kb-kq-choice-text { flex: 1 1 auto; }
.kb-kq-choice.is-chosen { border-color: var(--sc-primary); }
.kb-kq-choice.is-correct {
  border-color: var(--kb-vert-eau); background: color-mix(in srgb, var(--kb-vert-eau) 14%, var(--kb-creme-fonce));
}
.kb-kq-choice.is-correct .kb-kq-choice-letter { background: var(--kb-vert-eau); }
.kb-kq-choice.is-wrong {
  border-color: var(--sc-accent); background: color-mix(in srgb, var(--sc-accent) 14%, var(--kb-creme-fonce));
}
.kb-kq-choice.is-wrong .kb-kq-choice-letter { background: var(--sc-accent); }

.kb-kq-explain {
  margin-top: .85rem; padding: .7rem .85rem; border-radius: var(--sc-radius);
  background: var(--kb-creme); border: 2px solid var(--sc-border); color: var(--sc-ink);
}
.kb-kq-explain > i { color: var(--sc-primary); margin-right: .35rem; }
.kb-kq-ai { color: var(--sc-muted); font-size: .85rem; text-align: center; margin: 1rem 0 0; }

/* Intro. */
.kb-kq-intro-kapi { text-align: center; margin: 0 0 .75rem; }
.kb-kq-intro-kapi img { width: 6rem; height: 6rem; object-fit: contain; }
.kb-kq-intro-sound {
  background: color-mix(in srgb, var(--sc-accent) 14%, var(--kb-creme-fonce));
  border-radius: var(--sc-radius); padding: .6rem .85rem; font-weight: 700;
}
.kb-kq-intro-sound > i { color: var(--sc-accent); margin-right: .35rem; }
.kb-kq-intro-srctitle { font-weight: 800; margin: 1rem 0 .5rem; }
.kb-kq-sources { display: flex; flex-direction: column; gap: .6rem; }
.kb-kq-sources small { color: var(--sc-muted); }

/* Corps scrollable de la modale d'intro : réserve une gouttière pour la scrollbar (sinon elle colle au
   texte — règle #21 : scrollbar aux couleurs du site, jamais collée au contenu). */
.kb-kq-introbody {
  max-height: 70vh; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  scrollbar-gutter: stable; padding-right: .75rem;
}

.kb-kq-grade {
  width: 100%; min-height: var(--sc-tap); border-radius: var(--sc-radius);
  border: 2px solid var(--sc-border); background: var(--kb-creme); padding: 0 .75rem; font: inherit;
}

/* Sélecteur de niveau intégré dans la carte « Par niveau » (apparaît sous la description). */
.kb-kq-graderow { display: block; margin-top: .6rem; }
.kb-kq-grade-lbl { display: block; font-weight: 700; margin-bottom: .25rem; }

/* Révélation de la matière tirée (plein cadre, au-dessus de la roue, entre l'arrêt et la question). */
.kb-kq-reveal {
  position: fixed; inset: 0; z-index: 2500;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--kb-encre) 45%, transparent);
  padding: 1rem;
}
/* [hidden] doit l'emporter sur le display:flex ci-dessus (sinon l'overlay reste visible au chargement). */
.kb-kq-reveal[hidden] { display: none; }
.kb-kq-reveal-card {
  background: var(--kb-creme); border: 4px solid var(--sc-accent);
  border-radius: 24px; box-shadow: 0 12px 32px rgba(107,63,38,.3);
  padding: 1.6rem 2rem; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
  max-width: 90vw;
}
.kb-kq-reveal-kapi { width: 7rem; height: 7rem; object-fit: contain; }
.kb-kq-reveal-ic-i { font-size: 2rem; color: var(--sc-primary); }
.kb-kq-reveal-ic img { width: 2.4rem; height: 1.8rem; object-fit: contain; }
.kb-kq-reveal-label { font-weight: 800; font-size: 1.6rem; color: var(--sc-primary); }
.kb-kq-reveal-in { animation: kb-kq-reveal-pop .5s cubic-bezier(.2,.9,.3,1.3); }
.kb-kq-reveal-in .kb-kq-reveal-kapi { animation: kb-kq-reveal-bounce .6s ease .1s; }
@keyframes kb-kq-reveal-pop { from { opacity: 0; transform: scale(.6) rotate(-6deg); } to { opacity: 1; transform: none; } }
@keyframes kb-kq-reveal-bounce { 0% { transform: translateY(0); } 30% { transform: translateY(-14px); } 60% { transform: translateY(0); } 80% { transform: translateY(-6px); } 100% { transform: translateY(0); } }

/* Réduire les animations (accessibilité, règle #15) : coupe les mouvements vifs du jeu. */
html[data-motion="reduced"] .kb-kq-kapi.is-spinning,
html[data-motion="reduced"] .kb-kq-pop,
html[data-motion="reduced"] .kb-kq-reveal-in,
html[data-motion="reduced"] .kb-kq-reveal-in .kb-kq-reveal-kapi { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .kb-kq-kapi.is-spinning,
  .kb-kq-pop,
  .kb-kq-reveal-in,
  .kb-kq-reveal-in .kb-kq-reveal-kapi { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   KapiMémo — jeu de MÉMOIRE famille (portal/kapimemo.html, docs/SPEC-KapiMemo.md).
   Sélecteur « pioche de cartes » (kapipick.js) + grille de Memory. Réutilise kb-wait, kb-check-row,
   kb-kq-subject/ai/pop, et les jetons de marque --kb-*. Accessibilité : mouvements coupés en data-motion=reduced.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* Bandeau de records : meilleur nombre de coups par taille de grille. */
.kb-mm-records {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem;
  margin: 0 0 1.25rem;
}
.kb-mm-record {
  background: var(--kb-creme-fonce); border: 2px solid var(--kb-brun-clair); border-radius: 14px;
  padding: .6rem .4rem; text-align: center; display: flex; flex-direction: column; gap: .15rem;
}
.kb-mm-record-size { font-size: .8rem; color: var(--sc-muted); font-weight: 700; }
.kb-mm-record-val { font-size: 1.5rem; font-weight: 800; color: var(--sc-primary); }
.kb-mm-record-date { font-size: .7rem; color: var(--sc-muted); }

/* Scène de la pioche : le PAQUET (+ bouton Kapi) en haut, la CARTE TIRÉE en dessous (empilement vertical). */
.kb-mm-pick-wrap {
  position: relative; width: 100%; max-width: 340px; margin: 1rem auto 0;
  display: flex; align-items: center; justify-content: center;
}
.kb-mm-pickstage { position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; gap: .75rem; }
/* Zone du paquet (haut) : hauteur fixe pour accueillir l'éventail + le bouton Kapi centré dessus. */
.kb-mm-deckzone { position: relative; width: 100%; height: 9rem; display: flex; align-items: center; justify-content: center; }
/* Zone de la carte tirée (bas) : réserve la place pour éviter tout saut de mise en page à la révélation. */
.kb-mm-drawnzone { position: relative; width: 100%; height: 8rem; display: flex; align-items: center; justify-content: center; }
/* Le bouton central Kapi réutilise .kb-kq-kapi ; centré sur la zone du paquet (pas sur toute la scène). */
.kb-mm-kapi { width: 5rem; height: 5rem; z-index: 20; }

/* Éventail de dos de cartes (centré dans sa zone). */
.kb-mm-deck { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.kb-mm-back {
  position: absolute; width: 5.2rem; height: 7.2rem; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--sc-primary), var(--kb-brun-profond));
  border: 3px solid var(--kb-creme); box-shadow: 0 4px 10px rgba(107,63,38,.22);
  transform-origin: 50% 120%;
}
.kb-mm-back-logo { color: color-mix(in srgb, var(--kb-creme) 85%, transparent); font-size: 1.6rem; }
.kb-mm-deck.is-shuffling { animation: kb-mm-shuffle .22s ease-in-out infinite; }
@keyframes kb-mm-shuffle { 0%,100% { transform: translateX(-2px) rotate(-1deg); } 50% { transform: translateX(2px) rotate(1deg); } }

/* Carte tirée : révélée directement en RECTO (le battage du paquet montre déjà des dos). Masquée tant
   qu'elle n'est pas affichée (JS pose/retire [hidden]). Apparition en « pop » — pas de flip 3D fragile.
   Centrée dans sa zone (sous le paquet). */
.kb-mm-drawn {
  position: relative; width: 5.6rem; height: 7.6rem;
  display: flex; align-items: center; justify-content: center;
}
.kb-mm-drawn[hidden] { display: none; }
.kb-mm-drawn.is-flipped { animation: kb-mm-drawpop .4s cubic-bezier(.2,.9,.3,1.3); }
@keyframes kb-mm-drawpop { 0% { opacity: 0; transform: scale(.5) rotate(-8deg); } 60% { transform: scale(1.08) rotate(2deg); } 100% { opacity: 1; transform: none; } }
.kb-mm-drawn-front {
  position: absolute; inset: 0; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: var(--kb-creme);
  border: 3px solid var(--mm-col, var(--sc-primary)); box-shadow: 0 6px 16px rgba(107,63,38,.28);
  flex-direction: column; gap: .2rem; padding: .3rem;
}
.kb-mm-drawn-kapi { width: 2.6rem; height: 2.6rem; object-fit: contain; }
.kb-mm-drawn-ic-i { font-size: 1.3rem; color: var(--mm-col, var(--sc-primary)); }
.kb-mm-drawn-ic img { width: 1.8rem; height: 1.35rem; object-fit: contain; }
.kb-mm-drawn-label {
  font-weight: 800; font-size: .82rem; color: var(--mm-col, var(--sc-primary));
  text-align: center; line-height: 1.1; max-width: 100%; padding: 0 .15rem;
  word-break: break-word; hyphens: auto;
}

/* Plateau de jeu. */
.kb-mm-board { margin-top: 1.5rem; }
.kb-mm-counters {
  display: flex; justify-content: space-between; gap: .5rem; margin: 0 0 1rem;
  color: var(--sc-muted); font-size: .95rem;
}
.kb-mm-counters strong { color: var(--sc-primary); }
.kb-mm-counters i { color: var(--sc-accent); margin-right: .25rem; }

/* Grille de cartes à retourner. Colonnes selon le nombre de cartes (8/12/16). */
.kb-mm-grid { display: grid; gap: .55rem; }
.kb-mm-grid.cards-8 { grid-template-columns: repeat(4, 1fr); }
.kb-mm-grid.cards-12 { grid-template-columns: repeat(4, 1fr); }
.kb-mm-grid.cards-16 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 420px) {
  .kb-mm-grid.cards-8 { grid-template-columns: repeat(2, 1fr); }
  .kb-mm-grid.cards-12, .kb-mm-grid.cards-16 { grid-template-columns: repeat(3, 1fr); }
}

/* Carte à retourner : bascule ROBUSTE sans flip 3D (on affiche le dos OU la face via display) —
   évite les pièges backface-visibility/preserve-3d (cartes invisibles sur certains moteurs).
   La hauteur vient d'un ratio en padding (fiable sur <button> en grille, contrairement à aspect-ratio
   qui peut s'effondrer à 0 → on ne voyait que l'icône qui débordait, sans le corps de la carte). */
.kb-mm-card {
  position: relative; border: none; background: none; padding: 0 0 133%; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.kb-mm-card:disabled { cursor: default; }
.kb-mm-card-inner { position: absolute; inset: 0; }
.kb-mm-card-back, .kb-mm-card-front {
  position: absolute; inset: 0; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  text-align: center;
}
/* Au repos : dos visible, face cachée. Carte retournée (is-up/is-done) : l'inverse. */
.kb-mm-card-front { display: none; }
.kb-mm-card.is-up .kb-mm-card-back, .kb-mm-card.is-done .kb-mm-card-back { display: none; }
.kb-mm-card.is-up .kb-mm-card-front, .kb-mm-card.is-done .kb-mm-card-front { display: flex; animation: kb-mm-flipin .28s ease; }
@keyframes kb-mm-flipin { from { transform: scale(.82); opacity: .4; } to { transform: none; opacity: 1; } }
.kb-mm-card-back {
  background: linear-gradient(135deg, var(--sc-primary), var(--kb-brun-profond));
  border: 3px solid var(--kb-creme); color: color-mix(in srgb, var(--kb-creme) 80%, transparent); font-size: 1.4rem;
  box-shadow: 0 3px 8px rgba(107,63,38,.2);
}
.kb-mm-card-front {
  background: var(--kb-creme); border: 3px solid var(--kb-brun-clair);
  padding: .25rem .3rem; font-weight: 700; font-size: .82rem; line-height: 1.2; color: var(--sc-ink);
  overflow: hidden;
  /* Garder les MOTS ENTIERS : on retourne à la ligne entre les mots, jamais au milieu (lisibilité dys #15).
     Un mot vraiment trop long pour la carte casse en dernier recours, mais SANS tiret de césure. */
  white-space: normal; word-break: normal; overflow-wrap: break-word; hyphens: manual;
}
/* Police adaptative : texte moyen / long sur une carte (évite le débordement, lisibilité #15). */
.kb-mm-card-front.txt-sm { font-size: .68rem; line-height: 1.15; }
.kb-mm-card-front.txt-xs { font-size: .56rem; line-height: 1.1; }
/* Grille 16 cartes : cartes plus petites → on réduit un cran la base pour garder de l'air. */
.kb-mm-grid.cards-16 .kb-mm-card-front { font-size: .72rem; }
.kb-mm-grid.cards-16 .kb-mm-card-front.txt-sm { font-size: .6rem; }
.kb-mm-grid.cards-16 .kb-mm-card-front.txt-xs { font-size: .5rem; }
/* Deux familles de cartes (notion / réponse) légèrement teintées pour aider au repérage, sans révéler l'appariement. */
.kb-mm-card-front.kb-mm-side-term { border-color: var(--kb-miel); background: color-mix(in srgb, var(--kb-miel) 10%, var(--kb-creme)); }
.kb-mm-card-front.kb-mm-side-match { border-color: var(--kb-vert-eau); background: color-mix(in srgb, var(--kb-vert-eau) 10%, var(--kb-creme)); }
.kb-mm-card.is-done .kb-mm-card-front { border-color: var(--kb-vert-eau); box-shadow: 0 0 0 3px color-mix(in srgb, var(--kb-vert-eau) 35%, transparent); }
.kb-mm-card.is-done { animation: kb-mm-matched .4s ease; }
@keyframes kb-mm-matched { 0% { transform: scale(1); } 40% { transform: scale(1.06); } 100% { transform: scale(1); } }

/* Distribution des cartes (apparition échelonnée à la création de la grille). */
.kb-mm-deal { animation: kb-mm-deal .35s cubic-bezier(.2,.8,.3,1.1) backwards; }
@keyframes kb-mm-deal { from { opacity: 0; transform: translateY(14px) scale(.9); } to { opacity: 1; transform: none; } }

/* Réduire les animations (règle #15) : pas de battage ni d'apparition — bascule immédiate, pas de pulsation. */
html[data-motion="reduced"] .kb-mm-deck.is-shuffling,
html[data-motion="reduced"] .kb-mm-card.is-done,
html[data-motion="reduced"] .kb-mm-deal,
html[data-motion="reduced"] .kb-mm-card.is-up .kb-mm-card-front,
html[data-motion="reduced"] .kb-mm-card.is-done .kb-mm-card-front { animation: none; }
html[data-motion="reduced"] .kb-mm-drawn-inner { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .kb-mm-deck.is-shuffling, .kb-mm-card.is-done, .kb-mm-deal,
  .kb-mm-card.is-up .kb-mm-card-front, .kb-mm-card.is-done .kb-mm-card-front { animation: none; }
  .kb-mm-drawn-inner { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   Module « Verbes irréguliers anglais » (portal/irregular-verbs.html) — 100 % front.
   Couleurs via jetons --kb-* uniquement ; scrollbar globale (règle #21) ; accessibilité dys #15.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* Puces / chips de filtre (nombre de formes, longueur de séance). */
.kb-irr-filters, .kb-irr-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: .6rem 0; }
.kb-irr-chip {
  min-height: var(--sc-tap); padding: .45rem 1rem; border-radius: 999px;
  border: 2px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 700; cursor: pointer;
}
.kb-irr-chip.sel { background: var(--kb-miel); border-color: var(--kb-miel); color: #fff; }

/* Sélection manuelle des verbes (portée « Je choisis »). */
.kb-irr-pick { margin-top: .6rem; }
.kb-irr-pick-search { width: 100%; margin-bottom: .6rem; }
.kb-irr-pick-empty { color: var(--sc-muted); text-align: center; padding: 1rem .5rem; margin: 0; }
.kb-irr-pick-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-bottom: .6rem; }
.kb-irr-pick-count { color: var(--sc-muted); font-weight: 700; margin-left: auto; }
/* Un seul cadre pour toute la liste ; les lignes n'ont plus de bordure individuelle. */
.kb-irr-pick-list {
  max-height: 22rem; overflow: auto; display: flex; flex-direction: column;
  border: 2px solid var(--kb-brun-clair); border-radius: var(--sc-radius);
  background: var(--kb-creme); padding: .3rem;
}
.kb-irr-pick-row {
  min-height: 3rem; border: none; border-radius: .6rem; background: transparent;
}
.kb-irr-pick-row:hover { background: var(--kb-creme-fonce); }
.kb-irr-pick-row.sel { border: none; background: var(--kb-creme-fonce); }
.kb-irr-pick-triplet { line-height: 1.4; }

.kb-irr-legend { color: var(--sc-muted); font-size: .92rem; margin: .4rem 0 .8rem; }

/* Accordéon par nombre de formes (motif library). */
.kb-irr-group { border: 2px solid var(--kb-brun-clair); border-radius: var(--sc-radius); margin: .6rem 0; overflow: hidden; background: var(--sc-surface); }
.kb-irr-group-sum { list-style: none; cursor: pointer; display: flex; align-items: center; gap: .6rem; padding: .9rem 1rem; font-weight: 800; }
.kb-irr-group-sum::-webkit-details-marker { display: none; }
.kb-irr-caret { transition: transform .2s; color: var(--kb-brun-profond); }
.kb-irr-group[open] .kb-irr-caret { transform: rotate(180deg); }
.kb-irr-group-body { padding: .3rem .8rem .8rem; }
.kb-irr-family { margin-top: .6rem; }
.kb-irr-family-head { font-weight: 700; color: var(--kb-brun-profond); font-size: .95rem; margin: .5rem 0 .3rem; }

/* Ligne de verbe (base → prétérit → participe · sens · écouter). */
.kb-verb-row {
  display: flex; align-items: center; gap: .6rem; flex-wrap: nowrap;
  padding: .55rem .2rem; border-bottom: 1px solid var(--kb-creme-fonce);
}
.kb-verb-row:last-child { border-bottom: none; }
.kb-verb-forms { display: flex; align-items: center; gap: .4rem; flex: 0 0 auto; }
.kb-verb-form { font-size: 1.15rem; letter-spacing: .01em; white-space: nowrap; }
.kb-verb-base { font-weight: 800; }
.kb-verb-form strong { color: var(--kb-miel); font-weight: 800; }
.kb-verb-arrow { color: var(--kb-brun-clair); font-weight: 700; }
/* La traduction occupe l'espace central ; le bouton Écouter reste à droite, tout sur une ligne. */
.kb-verb-fr { color: var(--sc-muted); font-style: italic; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-irr-listen { flex: 0 0 auto; margin-left: auto; }
/* État « synthèse en cours » : le bouton Écouter clignote doucement (confort, son bref). */
.kb-irr-listen.is-loading { opacity: .55; pointer-events: none; }

/* Variante « texte long » (histoire-géo, formules maths) : la « forme » est une phrase, pas un mot
   court → on autorise le retour à la ligne et le rétrécissement pour ne pas déborder à droite. */
.kb-verb-row--text { flex-wrap: wrap; align-items: baseline; }
.kb-verb-row--text .kb-verb-forms { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; }
.kb-verb-row--text .kb-verb-form { white-space: normal; }
.kb-verb-row--text .kb-verb-fr { flex: 0 1 auto; }

/* Carte à retourner (flip). Respecte « réduire les animations » (data-motion / media query). */
.kb-flip { perspective: 1000px; margin: .5rem auto 1rem; max-width: 440px; cursor: pointer; }
.kb-flip-inner { position: relative; transform-style: preserve-3d; transition: transform .5s; min-height: 200px; }
.kb-flip.is-flipped .kb-flip-inner { transform: rotateY(180deg); }
.kb-flip-face {
  position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .6rem;
  border: 2px solid var(--kb-brun-clair); border-radius: var(--sc-radius); padding: 1.2rem; text-align: center;
  background: var(--sc-surface);
}
.kb-flip-back { transform: rotateY(180deg); }
.kb-flip-word { font-size: 2rem; font-weight: 800; }
.kb-flip-fr { color: var(--sc-muted); font-style: italic; }
.kb-flip-hint { color: var(--sc-muted); font-size: .9rem; margin: .4rem 0 0; }
.kb-flip-triplet { font-size: 1.4rem; font-weight: 700; }
.kb-flip-triplet strong { color: var(--kb-miel); }
/* Réduire les animations : pas de 3D, on affiche les faces empilées sans rotation. */
html[data-motion="reduced"] .kb-flip-inner { transition: none; }
html[data-motion="reduced"] .kb-flip.is-flipped .kb-flip-inner { transform: none; }
html[data-motion="reduced"] .kb-flip-face { position: static; backface-visibility: visible; }
html[data-motion="reduced"] .kb-flip-front { display: none; }
html[data-motion="reduced"] .kb-flip.is-flipped .kb-flip-front { display: none; }
html[data-motion="reduced"] .kb-flip .kb-flip-back { display: none; }
html[data-motion="reduced"] .kb-flip.is-flipped .kb-flip-back { display: flex; }
@media (prefers-reduced-motion: reduce) {
  .kb-flip-inner { transition: none; }
  .kb-flip.is-flipped .kb-flip-inner { transform: none; }
}

.kb-irr-actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; }

/* Progression de séance. */
.kb-irr-progress { display: flex; align-items: center; gap: .6rem; margin-bottom: 1rem; }
.kb-irr-progress-txt { font-weight: 700; color: var(--kb-brun-profond); white-space: nowrap; }
.kb-irr-progress-track { flex: 1; height: 10px; border-radius: 999px; background: var(--kb-creme-fonce); overflow: hidden; }
.kb-irr-progress-fill { display: block; height: 100%; background: var(--kb-miel); transition: width .3s; }

/* Choix de mode (cartes radio) : espacement entre les cartes + icône + texte. */
#modeChoices { display: flex; flex-direction: column; gap: .7rem; }
.kb-irr-mode-ic { font-size: 1.3rem; color: var(--kb-brun); width: 2rem; text-align: center; }
.kb-irr-mode-txt { display: flex; flex-direction: column; }
.kb-irr-mode-desc { font-weight: 400; color: var(--sc-muted); font-size: .9rem; }

/* QCM / feedback. */
.kb-irr-question { font-size: 1.2rem; font-weight: 700; margin: .4rem 0 1rem; }
.kb-irr-q-fr { color: var(--sc-muted); font-weight: 400; font-style: italic; }
.kb-irr-options { display: flex; flex-direction: column; gap: .5rem; }
.kb-irr-opt {
  min-height: var(--sc-tap); padding: .7rem 1rem; border-radius: var(--sc-radius);
  border: 2px solid var(--kb-brun-clair); background: var(--sc-surface); font: inherit; font-size: 1.1rem; font-weight: 700;
  cursor: pointer; text-align: left;
}
.kb-irr-opt:disabled { cursor: default; }
.kb-irr-opt.good { background: var(--kb-vert-eau); border-color: var(--kb-vert-eau); color: #fff; }
.kb-irr-opt.bad { background: var(--kb-miel); border-color: var(--kb-miel); color: #fff; }

.kb-irr-feedback { margin-top: 1rem; }
.kb-irr-feedback.good { color: var(--kb-vert-eau); }
.kb-irr-triplet { color: var(--sc-ink); font-size: 1.1rem; margin: .4rem 0; }
.kb-irr-triplet strong { color: var(--kb-brun-profond); }
.kb-irr-yours { color: var(--kb-brun-profond); font-size: 1rem; margin: .3rem 0; }

/* Relier. */
.kb-irr-mhead, .kb-irr-mrow { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: .5rem; align-items: center; }
.kb-irr-mhead { font-weight: 700; color: var(--kb-brun-profond); font-size: .85rem; margin-bottom: .4rem; }
.kb-irr-mrow { margin-bottom: .5rem; }
.kb-irr-mbase { font-weight: 800; font-size: 1.05rem; }
.kb-irr-msel {
  min-height: var(--sc-tap); border-radius: var(--sc-radius); border: 2px solid var(--kb-brun-clair);
  background: var(--sc-surface); font: inherit; font-weight: 700; padding: .3rem .5rem;
}
.kb-irr-msel.good { border-color: var(--kb-vert-eau); background: color-mix(in srgb, var(--kb-vert-eau) 15%, var(--sc-surface)); }
.kb-irr-msel.bad { border-color: var(--kb-miel); background: color-mix(in srgb, var(--kb-miel) 15%, var(--sc-surface)); }

/* À écrire. */
.kb-irr-writerow { display: flex; gap: .8rem; flex-wrap: wrap; margin: .6rem 0 1rem; }
.kb-irr-wlabel { display: flex; flex-direction: column; gap: .3rem; font-weight: 700; flex: 1 1 160px; }
.kb-irr-winput { font-size: 1.2rem; }
.kb-irr-winput.good { border-color: var(--kb-vert-eau); }
.kb-irr-winput.bad { border-color: var(--kb-miel); }

/* Fin de séance. */
.kb-irr-score { font-size: 1.3rem; font-weight: 800; color: var(--kb-brun-profond); }
.kb-irr-review { text-align: left; margin-top: 1rem; }
.kb-irr-review-head { color: var(--kb-brun-profond); margin: .5rem 0; }

/* ── Modules bonus additionnels (homophones FR, maths, histoire-géo) — réutilisent .kb-irr-*. ── */
/* Homophones : pastilles de formes, astuce, phrase à trou. */
.kb-homo-forms { display: inline-flex; gap: .4rem; flex-wrap: wrap; }
.kb-homo-chip { display: inline-block; padding: .2rem .7rem; border-radius: 999px; background: color-mix(in srgb, var(--kb-theme-francais) 15%, var(--sc-surface)); border: 2px solid var(--kb-theme-francais); font-weight: 800; }
.kb-homo-hint { color: var(--sc-muted); margin: .3rem 0 .6rem; }
.kb-homo-examples { margin: 0; padding-left: 1.2rem; }
.kb-homo-examples li { margin: .3rem 0; }
.kb-homo-sentence { font-size: 1.25rem; margin: .4rem 0 1rem; line-height: 1.6; }
.kb-homo-blank { display: inline-block; min-width: 3rem; border-bottom: 3px solid var(--kb-miel); }
.kb-homo-fill { color: var(--kb-vert-eau); }
/* Maths : question de calcul en grand. */
.kb-maths-q { font-size: 1.6rem; font-weight: 800; text-align: center; }
/* Histoire-Géo : année mise en avant. */
.kb-hg-year { color: var(--kb-theme-histoire); font-weight: 800; }
/* Conjugaison : pronom + champ de saisie sur une ligne. */
.kb-conj-prompt { display: flex; align-items: center; gap: .6rem; margin-top: .4rem; }
.kb-conj-pronoun { font-weight: 800; font-size: 1.2rem; white-space: nowrap; color: var(--kb-theme-francais); }
.kb-conj-prompt .kb-irr-winput { flex: 1; }

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiGrille » (grille de calculs croisés, portal/game-calc-grid.html) — 100 % front, 0 IA.
   Cercles reliés par des opérateurs ; les trous sont des champs de saisie.
   Grandes cibles tactiles + fort contraste (accessibilité dys, règle #15).
   ─────────────────────────────────────────────────────────────────────────── */
/* Choix des opérateurs : lignes-cartes avec le symbole en évidence (règle #20). */
.kb-cg-ops { display: flex; flex-direction: column; gap: .5rem; margin: .6rem 0; }
.kb-cg-op-row { align-items: center; gap: .75rem; }
.kb-cg-op-sym {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: 50%; flex: 0 0 auto;
  background: var(--kb-creme-fonce); color: var(--kb-brun-profond);
  font-weight: 900; font-size: 1.3rem; line-height: 1;
}
.kb-cg-hint { color: var(--sc-danger, var(--kb-miel)); font-weight: 700; margin: .4rem 0 0; }
.kb-cg-hint2 { color: var(--sc-muted); font-weight: 600; margin: .4rem 0 0; font-size: .95rem; }

/* Rangée de chips TOUJOURS sur une même ligne, à parts égales (pas de retour à
   la ligne, même sur écran étroit). Générique — réutilisable par tout jeu
   (KapiGrille : mode de saisie ; KapiCarte : mode de jeu…). */
.kb-irr-chips.kb-cg-input-row, .kb-irr-chips.kb-chip-row { flex-wrap: nowrap !important; }
.kb-cg-input-row .kb-irr-chip, .kb-chip-row .kb-irr-chip {
  flex: 1 1 0; min-width: 0; text-align: center; white-space: nowrap;
  padding-left: .4rem; padding-right: .4rem;
}

/* ── Décompte « 3, 2, 1, C'est parti ! » avec Kapi (avant la grille) ──────────
   Overlay plein écran fermé automatiquement. Chaque changement de nombre
   relance l'animation de pop (Kapi rebondit). Accessibilité : « réduire les
   animations » coupe les transformations (règle #15). */
.kb-cg-cd {
  position: fixed; inset: 0; z-index: 1200;
  display: none; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--kb-encre, #2B2420) 55%, transparent);
  backdrop-filter: blur(2px);
}
.kb-cg-cd.open { display: flex; }
.kb-cg-cd-card { text-align: center; }
.kb-cg-cd-kapi {
  width: 128px; height: auto; display: block; margin: 0 auto .5rem;
  animation: kb-bob 1.2s ease-in-out infinite;
  filter: drop-shadow(0 10px 18px rgba(0,0,0,.3));
}
.kb-cg-cd-num {
  font-family: var(--sc-font-title, inherit); font-weight: 900;
  color: var(--kb-creme, #FBF3E4); line-height: 1;
  font-size: clamp(4rem, 28vw, 9rem);
  text-shadow: 0 6px 0 var(--kb-brun, #B5794E), 0 12px 24px rgba(0,0,0,.35);
}
/* « C'est parti ! » (texte) plus petit que les chiffres. */
.kb-cg-cd-num.go { font-size: clamp(2.2rem, 12vw, 4.2rem); color: var(--kb-miel, #E0913A); }
/* Chaque affichage relance le pop. */
.kb-cg-cd-num.pop { animation: kb-cd-pop .6s cubic-bezier(.17,.89,.32,1.28); }
@keyframes kb-cd-pop {
  0% { transform: scale(.2); opacity: 0; }
  55% { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
html[data-motion="reduced"] .kb-cg-cd-kapi { animation: none; }
html[data-motion="reduced"] .kb-cg-cd-num.pop { animation: none; }

/* Barre de jeu : chrono + progression + bouton quitter. */
.kb-cg-bar { display: flex; align-items: center; gap: .8rem; margin-bottom: .6rem; }
.kb-cg-timer { font-weight: 800; font-size: 1.1rem; color: var(--kb-brun-profond); }
/* Dernières secondes : chrono en rouge framboise + pulsation (urgence). */
.kb-cg-timer--low { display: inline-block; color: var(--kb-theme-francais, #B5495B); animation: kb-cg-pulse .5s ease-in-out infinite; }
@keyframes kb-cg-pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }
html[data-motion="reduced"] .kb-cg-timer--low { animation: none; }
.kb-cg-left { color: var(--sc-muted); font-weight: 700; }
.kb-cg-bar .kb-close { margin-left: auto; }

/* Règle du tour (saisie libre vs bac de jetons). */
.kb-cg-rule { color: var(--sc-ink); font-weight: 600; margin: 0 0 .8rem; text-align: center; }

/* Grille CROISÉE 2D type CrossMath : cercles reliés HORIZONTALEMENT et
   VERTICALEMENT par des opérateurs VISIBLES. Les cercles sont partagés aux
   croisements → résoudre une équation aide celles qui la croisent. Rendu en
   CSS Grid (tracks posés en JS selon la taille). Débordement => défilement. */
.kb-cg-scroll { overflow-x: auto; margin: 0 -.5rem; padding: .25rem .5rem; }
/* Zone de jeu : grille + pavé. Empilés par défaut (mobile) ; côte à côte dès
   qu'il y a de la place (tablette/PC) → le pavé passe à DROITE, pas de scroll. */
.kb-cg-playarea { display: flex; flex-direction: column; align-items: center; }
@media (min-width: 720px) {
  .kb-cg-playarea { flex-direction: row; align-items: flex-start; justify-content: center; gap: 1.5rem; }
  .kb-cg-playarea .kb-cg-scroll { flex: 0 1 auto; }
  /* Le pavé ne s'étale plus en pleine largeur : il se cale à droite, en haut. */
  .kb-cg-playarea .kb-cg-pad { margin: 0; flex: 0 0 auto; align-self: center; }
}
.kb-cg-grid {
  display: grid;
  justify-content: center;
  gap: .2rem;
  margin: .25rem auto;
  width: max-content;
}
.kb-cg-cell { display: flex; align-items: center; justify-content: center; }
.kb-cg-void { width: .6rem; height: .6rem; }           /* maille vide (hors équation) */
.kb-cg-num, .kb-cg-input, .kb-cg-slot, .kb-cg-type {
  display: inline-flex; align-items: center; justify-content: center;
  width: 3rem; height: 3rem; border-radius: 50%;
  font-size: 1.3rem; font-weight: 800; text-align: center; box-sizing: border-box;
}
/* Cercle à valeur connue : pastille crème bordée. */
.kb-cg-num {
  background: #EAF4F6; border: 2px solid var(--kb-brun-clair); color: var(--sc-ink);
}
/* Cercle à compléter — SAISIE LIBRE (champ de saisie rond). */
.kb-cg-input {
  background: var(--sc-surface); border: 3px solid var(--kb-miel); color: var(--sc-ink);
  font-family: inherit; -moz-appearance: textfield; padding: 0;
}
.kb-cg-input::-webkit-outer-spin-button,
.kb-cg-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.kb-cg-input:focus { outline: 3px solid var(--kb-brun); outline-offset: 2px; }
/* Cercle à compléter — MODE POOL (case tappable où poser un jeton). */
.kb-cg-slot {
  background: var(--sc-surface); border: 3px dashed var(--kb-miel); color: var(--sc-ink);
  cursor: pointer; font-family: inherit;
}
.kb-cg-slot.filled { border-style: solid; background: #FFF6E9; }
.kb-cg-slot:focus-visible { outline: 3px solid var(--kb-brun); outline-offset: 2px; }
/* Cercle à compléter — SAISIE AU PAVÉ (case tappable, pas de clavier natif). */
.kb-cg-type {
  background: var(--sc-surface); border: 3px solid var(--kb-miel); color: var(--sc-ink);
  cursor: pointer; font-family: inherit; padding: 0;
}
.kb-cg-type.filled { background: #FFF6E9; }
/* Case active (en cours de saisie) : fortement mise en avant. */
.kb-cg-type.active { box-shadow: 0 0 0 4px rgba(224, 145, 58, .35); border-color: var(--kb-brun); }
.kb-cg-type:focus-visible { outline: 3px solid var(--kb-brun); outline-offset: 2px; }
/* États de correction (communs saisie/pool). */
.kb-cg-input.is-ok, .kb-cg-slot.is-ok, .kb-cg-type.is-ok { border-color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC; }
.kb-cg-input.is-wrong, .kb-cg-slot.is-wrong, .kb-cg-type.is-wrong { border-color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; }
/* Opérateur / signe égal reliant deux cercles (horizontal ou vertical). */
.kb-cg-op {
  font-size: 1.25rem; font-weight: 900; color: var(--kb-brun-profond);
  line-height: 1; min-width: .9rem;
}

/* Bac de jetons-nombres (mode pool) : à placer dans les cases vides. */
.kb-cg-pool {
  display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center;
  margin: 1rem auto 0; padding: .7rem; border-radius: 14px;
  background: var(--kb-creme-fonce); max-width: 100%;
}
.kb-cg-pool:empty::after { content: ""; }
.kb-cg-token {
  min-width: 2.8rem; height: 2.8rem; padding: 0 .5rem; border-radius: 12px;
  border: 2px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.2rem; cursor: pointer;
}
.kb-cg-token.sel {
  border-color: var(--kb-miel); background: var(--kb-miel); color: #fff;
  box-shadow: 0 0 0 3px rgba(224, 145, 58, .25);
}

/* Pavé numérique intégré (mode saisie) : évite le clavier natif qui masque la
   grille. Grille 3 colonnes de grosses touches tactiles (accessibilité #15). */
.kb-cg-pad {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem;
  max-width: 320px; margin: 1rem auto 0; padding: .7rem; border-radius: 14px;
  background: var(--kb-creme-fonce);
}
.kb-cg-key {
  aspect-ratio: 1 / 1; min-height: 3.2rem; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.5rem; cursor: pointer;
}
.kb-cg-key:active { background: var(--kb-creme); transform: translateY(1px); }
.kb-cg-key-fn { color: var(--kb-brun-profond); font-size: 1.2rem; }

@media (max-width: 480px) {
  .kb-cg-num, .kb-cg-input, .kb-cg-slot, .kb-cg-type { width: 2.5rem; height: 2.5rem; font-size: 1.05rem; }
  .kb-cg-op { font-size: 1rem; min-width: .7rem; }
  .kb-cg-token { min-width: 2.5rem; height: 2.5rem; font-size: 1.05rem; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiCompte » (compte est bon / Mathador, portal/game-compte.html) —
   100 % front, 0 IA. Dé animé pour la cible + jetons-nombres + composition
   étape par étape. Grandes cibles tactiles, fort contraste (accessibilité #15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-cp-score { font-weight: 800; color: var(--kb-brun-profond); }
.kb-cp-score i { color: var(--kb-miel); }

/* Cible : gros « dé » rond mis en avant. */
.kb-cp-targetwrap { text-align: center; margin: .6rem 0 1rem; }
.kb-cp-targetlabel { display: block; font-weight: 700; color: var(--sc-muted); margin-bottom: .4rem; }
.kb-cp-die {
  display: inline-flex; align-items: center; justify-content: center;
  width: 5.2rem; height: 5.2rem; border-radius: 20px;
  background: var(--sc-surface); border: 4px solid var(--kb-theme-francais, #C1583E);
  color: var(--kb-theme-francais, #C1583E); font-weight: 900; font-size: 2.2rem;
  box-shadow: 0 6px 0 color-mix(in srgb, var(--kb-theme-francais, #C1583E) 35%, transparent);
}
.kb-cp-die.rolling { animation: kb-cp-shake .25s linear infinite; }
.kb-cp-die.landed { animation: kb-cp-land .5s cubic-bezier(.17,.89,.32,1.28); }
@keyframes kb-cp-shake {
  0%,100% { transform: rotate(-5deg) translateY(0); }
  25% { transform: rotate(4deg) translateY(-2px); }
  50% { transform: rotate(-3deg) translateY(1px); }
  75% { transform: rotate(5deg) translateY(-1px); }
}
@keyframes kb-cp-land { 0% { transform: scale(1.3); } 60% { transform: scale(.9); } 100% { transform: scale(1); } }
html[data-motion="reduced"] .kb-cp-die.rolling,
html[data-motion="reduced"] .kb-cp-die.landed { animation: none; }

/* Nombres à utiliser (jetons). */
.kb-cp-usetitle { text-align: center; font-weight: 700; color: var(--sc-ink); margin: 0 0 .5rem; }
.kb-cp-tokens { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; min-height: 3.2rem; margin-bottom: 1rem; }
.kb-cp-token {
  min-width: 3.2rem; height: 3.2rem; padding: 0 .6rem; border-radius: 14px;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.4rem; cursor: pointer;
  transition: transform .08s ease, border-color .12s ease;
}
.kb-cp-token:hover { transform: translateY(-2px); }
.kb-cp-token.sel { border-color: var(--kb-miel); background: var(--kb-miel); color: #fff; box-shadow: 0 0 0 3px rgba(224,145,58,.25); }
/* Jeton issu d'un calcul (résultat intermédiaire) : teinte différente. */
.kb-cp-token-res { border-color: var(--kb-theme-sciences, #46907F); border-style: dashed; }
.kb-cp-token-res.sel { border-color: var(--kb-miel); }
/* Apparition d'un jeton (un par un). */
.kb-cp-token-in { animation: kb-cp-pop .32s cubic-bezier(.17,.89,.32,1.28); }
@keyframes kb-cp-pop { 0% { transform: scale(.2); opacity: 0; } 60% { transform: scale(1.15); } 100% { transform: scale(1); opacity: 1; } }
html[data-motion="reduced"] .kb-cp-token-in { animation: none; }

/* Zone de composition : opérateurs + expression a op b = r. */
.kb-cp-builder { background: var(--kb-creme-fonce); border-radius: 16px; padding: .8rem; margin-bottom: 1rem; }
.kb-cp-ops { display: flex; gap: .5rem; justify-content: center; margin-bottom: .7rem; }
.kb-cp-op {
  width: 3rem; height: 3rem; border-radius: 50%;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--kb-brun-profond); font: inherit; font-weight: 900; font-size: 1.5rem; cursor: pointer;
}
.kb-cp-op.sel { border-color: var(--kb-miel); background: var(--kb-miel); color: #fff; }
.kb-cp-expr { display: flex; align-items: center; justify-content: center; gap: .5rem; flex-wrap: wrap; margin-bottom: .7rem; }
.kb-cp-slot {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.8rem; height: 2.8rem; padding: 0 .5rem; border-radius: 12px;
  background: var(--sc-surface); border: 2px solid var(--kb-brun-clair);
  font-weight: 800; font-size: 1.3rem; color: var(--sc-ink);
}
.kb-cp-slot-op { border-color: var(--kb-miel); color: var(--kb-brun-profond); }
.kb-cp-slot-r { border-color: var(--kb-theme-sciences, #46907F); color: var(--kb-theme-sciences, #46907F); }
.kb-cp-eq { font-weight: 900; font-size: 1.4rem; color: var(--kb-brun-profond); }
.kb-cp-builder-actions { display: flex; gap: .5rem; justify-content: center; flex-wrap: wrap; }
.kb-cp-apply, .kb-cp-clear { padding: .5rem 1rem; min-height: 2.6rem; }

/* Journal des opérations faites. */
.kb-cp-steps { list-style: none; padding: 0; margin: 0 0 .5rem; display: flex; flex-direction: column; gap: .3rem; }
.kb-cp-step {
  background: var(--sc-surface); border: 2px solid var(--kb-brun-clair); border-radius: 10px;
  padding: .4rem .8rem; font-weight: 800; color: var(--sc-ink); text-align: center; font-size: 1.1rem;
}

/* Écran de fin : score + badge « coup Mathador ». */
.kb-cp-finalscore { font-weight: 800; font-size: 1.2rem; color: var(--kb-brun-profond); margin-top: .5rem; }
.kb-cp-badge {
  display: inline-block; margin-left: .4rem; padding: .15rem .6rem; border-radius: 999px;
  background: var(--kb-miel); color: #fff; font-size: .9rem; font-weight: 800;
}

@media (max-width: 480px) {
  .kb-cp-die { width: 4.4rem; height: 4.4rem; font-size: 1.8rem; }
  .kb-cp-token { min-width: 2.8rem; height: 2.8rem; font-size: 1.2rem; }
  .kb-cp-op { width: 2.7rem; height: 2.7rem; font-size: 1.3rem; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiVrai » (calculs vrai/faux éclair, portal/game-vraifaux.html) —
   100 % front, 0 IA. Calcul en grand + 2 gros boutons Vrai/Faux. Accessibilité
   dys : grandes cibles, fort contraste, reduced-motion respecté (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-vf-streak { font-weight: 800; color: var(--kb-brun-profond); }
.kb-vf-streak i { color: var(--kb-miel); }
.kb-vf-best { color: var(--sc-muted); font-weight: 700; margin: .6rem 0 0; }
.kb-vf-record { color: var(--kb-theme-italien, #3E8E5A); font-weight: 800; margin-top: .4rem; }

/* Le calcul affiché en grand (feedback vert/rouge au clic). */
.kb-vf-calc {
  text-align: center; font-weight: 900; font-size: clamp(2rem, 11vw, 3.2rem);
  color: var(--sc-ink); margin: 1.6rem 0; padding: 1rem .5rem; border-radius: 16px;
  background: var(--kb-creme-fonce); line-height: 1.1;
}
.kb-vf-calc.is-ok { animation: kb-vf-ok .4s ease; }
.kb-vf-calc.is-ko { animation: kb-vf-ko .4s ease; }
@keyframes kb-vf-ok { 0% { background: #CDEBD6; } 100% { background: var(--kb-creme-fonce); } }
@keyframes kb-vf-ko { 0%,60% { background: #F6D4D9; } 100% { background: var(--kb-creme-fonce); }
  10%,30%,50% { transform: translateX(-4px); } 20%,40% { transform: translateX(4px); } }
html[data-motion="reduced"] .kb-vf-calc.is-ok,
html[data-motion="reduced"] .kb-vf-calc.is-ko { animation: none; }

/* Deux gros boutons Vrai / Faux. */
.kb-vf-choices { display: flex; gap: 1rem; justify-content: center; }
.kb-vf-btn {
  flex: 1 1 0; max-width: 220px; min-height: 5rem; border-radius: 18px;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.4rem; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  transition: transform .08s ease, border-color .12s ease, background .12s ease;
}
.kb-vf-btn:active { transform: translateY(2px); }
.kb-vf-true { border-color: var(--kb-theme-italien, #3E8E5A); color: var(--kb-theme-italien, #3E8E5A); }
.kb-vf-true:hover { background: #E7F4EC; }
.kb-vf-false { border-color: var(--kb-theme-francais, #B5495B); color: var(--kb-theme-francais, #B5495B); }
.kb-vf-false:hover { background: #FBE9EC; }

@media (max-width: 480px) {
  .kb-vf-btn { min-height: 4.2rem; font-size: 1.2rem; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiSuite » (nombre manquant d'une suite, portal/game-suite.html) —
   100 % front, 0 IA. Suite affichée + 4 propositions. Grandes cibles (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-su-rule { text-align: center; color: var(--sc-muted); font-weight: 600; margin: 0 0 1rem; }
.kb-su-seq {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .35rem; margin: 1rem 0 1.6rem;
}
.kb-su-cell {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 3rem; height: 3rem; padding: 0 .5rem; border-radius: 12px;
  background: #EAF4F6; border: 2px solid var(--kb-brun-clair);
  font-weight: 800; font-size: 1.4rem; color: var(--sc-ink);
}
.kb-su-hole { background: var(--sc-surface); border: 3px dashed var(--kb-miel); color: var(--kb-miel); }
.kb-su-sep { font-weight: 800; color: var(--sc-muted); padding: 0 .1rem; }

.kb-su-options { display: grid; grid-template-columns: repeat(2, 1fr); gap: .7rem; max-width: 360px; margin: 0 auto; }
.kb-su-opt {
  min-height: 3.6rem; border-radius: 14px;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.4rem; cursor: pointer;
  transition: transform .08s ease, border-color .12s ease, background .12s ease;
}
.kb-su-opt:hover { transform: translateY(-2px); }
.kb-su-opt:active { transform: translateY(1px); }
.kb-su-opt.is-ok { border-color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC; color: var(--kb-theme-italien, #3E8E5A); }
.kb-su-opt.is-ko { border-color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; color: var(--kb-theme-francais, #B5495B); }

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiTrad » (mot ↔ traduction, portal/game-trad.html) — 100 % front, 0 IA.
   Deux colonnes de mots à relier. Grandes cibles tactiles (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-tr-board { display: flex; gap: 1rem; justify-content: center; align-items: flex-start; }
.kb-tr-col { flex: 1 1 0; max-width: 220px; display: flex; flex-direction: column; gap: .6rem; }
.kb-tr-word {
  min-height: 3.2rem; padding: .4rem .6rem; border-radius: 14px;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.15rem; cursor: pointer;
  transition: transform .08s ease, border-color .12s ease, background .12s ease;
}
.kb-tr-word:hover { transform: translateY(-1px); }
.kb-tr-word.sel { border-color: var(--kb-miel); background: var(--kb-miel); color: #fff; box-shadow: 0 0 0 3px rgba(224,145,58,.25); }
/* Paire trouvée : verrouillée en vert, non cliquable. */
.kb-tr-word.done {
  border-color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC;
  color: var(--kb-theme-italien, #3E8E5A); cursor: default; opacity: .9;
}
.kb-tr-word.is-ko { border-color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; }

@media (max-width: 480px) {
  .kb-tr-word { font-size: 1.05rem; min-height: 2.9rem; }
  .kb-tr-board { gap: .6rem; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiTri » (classer en catégories, portal/game-tri.html) — 100 % front.
   Un élément à classer + des bacs (catégories). Grandes cibles tactiles (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-tri-item {
  text-align: center; font-weight: 900; font-size: clamp(1.6rem, 8vw, 2.6rem);
  color: var(--sc-ink); background: var(--kb-creme-fonce); border-radius: 16px;
  padding: 1.4rem 1rem; margin: 1rem 0 1.4rem; line-height: 1.15;
}
.kb-tri-bins { display: grid; gap: .7rem; max-width: 420px; margin: 0 auto; }
.kb-tri-bin {
  min-height: 3.6rem; padding: .5rem .6rem; border-radius: 14px;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.2rem; cursor: pointer;
  transition: transform .08s ease, border-color .12s ease, background .12s ease;
}
.kb-tri-bin:hover { transform: translateY(-2px); }
.kb-tri-bin:active { transform: translateY(1px); }
.kb-tri-bin.is-ok { border-color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC; color: var(--kb-theme-italien, #3E8E5A); }
.kb-tri-bin.is-ko { border-color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; color: var(--kb-theme-francais, #B5495B); }
/* Indice : le bon bac quand on s'est trompé. */
.kb-tri-bin.is-hint { border-color: var(--kb-theme-italien, #3E8E5A); box-shadow: 0 0 0 3px rgba(62,142,90,.3); }

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiTime » (remettre dans l'ordre, portal/game-time.html) — 100 % front.
   Liste réordonnable avec ↑/↓. Grandes cibles tactiles (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-ti-list { list-style: none; padding: 0; margin: 1rem 0; display: flex; flex-direction: column; gap: .6rem; counter-reset: ti; }
.kb-ti-row {
  display: flex; align-items: center; gap: .6rem;
  background: var(--sc-surface); border: 3px solid var(--kb-brun-clair); border-radius: 14px;
  padding: .6rem .7rem; counter-increment: ti;
}
.kb-ti-row::before {
  content: counter(ti); flex: 0 0 auto;
  width: 1.9rem; height: 1.9rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--kb-creme-fonce); color: var(--kb-brun-profond); font-weight: 900;
}
.kb-ti-label { flex: 1 1 auto; font-weight: 800; font-size: 1.1rem; color: var(--sc-ink); }
/* Indice (ex. la date) révélé seulement après « Vérifier ». */
.kb-ti-hint { font-weight: 800; color: var(--kb-theme-histoire, #C07A2C); }
.kb-ti-moves { flex: 0 0 auto; display: flex; gap: .3rem; }
.kb-ti-move {
  width: 2.6rem; height: 2.6rem; border-radius: 10px;
  border: 2px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--kb-brun-profond); font-size: 1.1rem; cursor: pointer;
}
.kb-ti-move:disabled { opacity: .3; cursor: default; }
.kb-ti-move:not(:disabled):active { background: var(--kb-creme); }
.kb-ti-row.is-ok { border-color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC; }
.kb-ti-row.is-ko { border-color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; }

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiVerbe » (verbes irréguliers anglais, portal/game-verbe.html) —
   100 % front, 0 IA. Les 3 formes avec un trou + 4 propositions (kb-su-opt).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-vb-forms {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .5rem; margin: 1.2rem 0 .4rem;
}
.kb-vb-form {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 4rem; min-height: 3rem; padding: .3rem .7rem; border-radius: 12px;
  background: #EAF4F6; border: 2px solid var(--kb-brun-clair);
  font-weight: 800; font-size: 1.3rem; color: var(--sc-ink);
}
.kb-vb-form.hole { background: var(--sc-surface); border: 3px dashed var(--kb-miel); color: var(--kb-miel); }
.kb-vb-arrow { font-weight: 900; color: var(--kb-brun-profond); }
.kb-vb-meaning { text-align: center; color: var(--sc-muted); font-weight: 600; margin: 0 0 1.2rem; }

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiMot » (mot mystère par anagramme, portal/game-mot.html) — 100 % front.
   Cases de réponse + jetons-lettres à replacer. Grandes cibles tactiles (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-mot-hint { font-weight: 800; color: var(--kb-theme-questions, #7A54B3); }
.kb-mot-slots { display: flex; flex-wrap: wrap; gap: .4rem; justify-content: center; margin: 1.2rem 0; }
.kb-mot-slot {
  width: 3rem; height: 3.4rem; border-radius: 12px;
  border: 3px dashed var(--kb-miel); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 900; font-size: 1.6rem; cursor: pointer;
}
.kb-mot-slot.filled { border-style: solid; background: #FFF6E9; }
.kb-mot-slot.is-ok { border-color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC; }
.kb-mot-slot.is-ko { border-color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; }

.kb-mot-letters { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin-top: .5rem; }
.kb-mot-letter {
  width: 3rem; height: 3.4rem; border-radius: 12px;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 900; font-size: 1.6rem; cursor: pointer;
  transition: transform .08s ease;
}
.kb-mot-letter:not(:disabled):hover { transform: translateY(-2px); }
.kb-mot-letter.used { opacity: .25; cursor: default; }

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiFraction » (fraction ↔ camembert, portal/game-fraction.html) —
   100 % front, 0 IA. Réutilise le board .kb-tr-* ; camembert SVG généré.
   Les 2 colonnes gardent des RANGÉES DE MÊME HAUTEUR → alignées en vis-à-vis.
   ─────────────────────────────────────────────────────────────────────────── */
/* Toutes les cartes du jeu (fraction OU camembert) : hauteur fixe identique,
   contenu centré → les lignes gauche/droite se font parfaitement face. */
#colLeft .kb-tr-word, #colRight .kb-tr-word {
  height: 4.4rem; min-height: 0; padding: .3rem .5rem;
  display: flex; align-items: center; justify-content: center;
}
.kb-frac-num { font-size: 1.7rem; letter-spacing: .02em; }
.kb-frac-pie { padding: 0; }
.kb-frac-pie svg, .kb-frac-svg { display: block; width: 3rem; height: 3rem; }

@media (max-width: 480px) {
  #colLeft .kb-tr-word, #colRight .kb-tr-word { height: 3.9rem; }
  .kb-frac-num { font-size: 1.45rem; }
  .kb-frac-pie svg, .kb-frac-svg { width: 2.6rem; height: 2.6rem; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiAccord » (homophones & accords, portal/game-accord.html) — 100 % front.
   Phrase à trou + 2 propositions + explication. Grandes cibles tactiles (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-ac-sentence {
  text-align: center; font-weight: 800; font-size: clamp(1.3rem, 6vw, 1.8rem);
  color: var(--sc-ink); line-height: 1.5; margin: 1.4rem 0;
  background: var(--kb-creme-fonce); border-radius: 16px; padding: 1.2rem 1rem;
}
.kb-ac-blank {
  display: inline-block; min-width: 2.4rem; border-bottom: 3px dashed var(--kb-miel);
  color: var(--kb-miel); font-weight: 900; margin: 0 .15rem;
}
.kb-ac-fill { display: inline-block; padding: 0 .3rem; border-radius: 6px; font-weight: 900; }
.kb-ac-fill.ok { color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC; }
.kb-ac-fill.ko { color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; }

.kb-ac-options { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }
.kb-ac-opt {
  flex: 1 1 0; max-width: 200px; min-height: 4rem; border-radius: 16px;
  border: 3px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 800; font-size: 1.4rem; cursor: pointer;
  transition: transform .08s ease, border-color .12s ease, background .12s ease;
}
.kb-ac-opt:not(:disabled):hover { transform: translateY(-2px); }
.kb-ac-opt.is-ok { border-color: var(--kb-theme-italien, #3E8E5A); background: #E7F4EC; color: var(--kb-theme-italien, #3E8E5A); }
.kb-ac-opt.is-ko { border-color: var(--kb-theme-francais, #B5495B); background: #FBE9EC; color: var(--kb-theme-francais, #B5495B); }

.kb-ac-explain { text-align: center; color: var(--sc-muted); font-weight: 600; min-height: 1.4rem; margin: 1rem 0 0; opacity: 0; transition: opacity .2s ease; }
.kb-ac-explain.show { opacity: 1; }

/* ───────────────────────────────────────────────────────────────────────────
   Jeu « KapiCarte » (placer sur une carte, portal/game-carte.html) — 100 % front.
   Carte SVG injectée ; zones cliquables surlignées. Grandes cibles (#15).
   ─────────────────────────────────────────────────────────────────────────── */
.kb-ca-target { font-weight: 900; color: var(--kb-theme-sciences, #46907F); }
.kb-ca-map { margin: 1rem auto 0; max-width: 520px; }
.kb-ca-svg { display: block; width: 100%; height: auto; }
/* Zones jouables : couleur de base + survol ; feedback correct/erreur. */
.kb-ca-zone { cursor: pointer; fill: #EAF4F6; stroke: var(--kb-brun-clair); stroke-width: 1; transition: fill .12s ease; }
.kb-ca-zone:hover { fill: #FFF6E9; }
.kb-ca-zone.is-ok { fill: #B6E0C2; stroke: var(--kb-theme-italien, #3E8E5A); }
.kb-ca-zone.is-ko { fill: #F3C4CC; stroke: var(--kb-theme-francais, #B5495B); }
/* La bonne zone montrée après une erreur. */
.kb-ca-zone.is-show { fill: #CDEBD6; stroke: var(--kb-theme-italien, #3E8E5A); stroke-width: 2; }
.kb-ca-credit { text-align: center; margin: .6rem 0 0; font-size: .75rem; }
.kb-ca-credit a { color: var(--sc-muted); text-decoration: none; }
.kb-ca-credit a:hover { text-decoration: underline; }

/* Choix du mode de jeu : 2 boutons sur une MÊME ligne via CSS Grid (2 colonnes
   égales — insensible à la longueur du texte, contrairement à flex). */
.kb-ca-modegrid { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin: .6rem 0; }
.kb-ca-modebtn {
  min-height: var(--sc-tap); padding: .45rem .5rem; border-radius: 999px;
  border: 2px solid var(--kb-brun-clair); background: var(--sc-surface);
  color: var(--sc-ink); font: inherit; font-weight: 700; cursor: pointer;
  text-align: center; line-height: 1.15;
}
.kb-ca-modebtn.sel { background: var(--kb-miel); border-color: var(--kb-miel); color: #fff; }
