/* ===== Design tokens =====
   Le thème clair vit ici, le thème sombre dans :root[data-theme="dark"] en fin
   de fichier — il ne redéfinit QUE des variables, aucune règle de mise en page.
   Corollaire : toute nouvelle couleur doit passer par un token, sinon elle
   restera claire la nuit. Voir aussi appliquerTheme() dans js/app.js, seul
   endroit qui décide du thème affiché. */
:root{
  color-scheme: light;
  --bg: #FAF6FC;
  --surface: #ffffff;
  --surface-alt: #F3ECFA;
  --text: #3D3452;
  --text-muted: #786C8C;
  --border: #E8DFF5;
  --primary: #6E5AA3;
  /* Violet accentué POSÉ SUR UNE SURFACE DU THÈME (titres, libellés, pastilles) :
     foncé le jour, clair la nuit — d'où « accent » et non « dark ». */
  --primary-accent: #4A3B78;
  /* Survol d'un aplat violet (bouton) : reste un fond sur lequel --on-primary
     doit se lire. Distinct de --primary-accent, qui est une couleur de TEXTE. */
  --primary-hover: #4A3B78;
  --primary-light: #EDE6F9;
  /* Ce qui s'écrit SUR un aplat --primary/--danger. Blanc le jour ; la nuit
     l'aplat s'éclaircit, donc l'encre s'assombrit. */
  --on-primary: #ffffff;
  --on-danger: #ffffff;
  --success: #4F9E72;
  --success-light: #E3F5EA;
  --success-border: #C9EAD6;
  --success-strong: #2F7A52;
  --danger: #B84F63;
  --danger-hover: #8C3A48;
  --danger-light: #FBE9ED;
  --danger-strong: #8C3A48;
  --warning: #C99A3E;
  --warning-light: #FBF3E0;
  /* Dégradé de marque (hero, bandeau programme, assistant) : il reste sombre
     dans les deux thèmes, c'est pourquoi le texte qui s'y pose garde #fff. */
  --grad-a: #6E5AA3;
  --grad-b: #C88FC7;
  /* Fondu de l'aperçu de cours : transparent DE LA COULEUR DE --surface,
     sinon le dégradé passe par du blanc au milieu d'une page sombre. */
  --fade-from: rgba(255,255,255,0);
  --overlay: rgba(20,14,40,.55);
  /* Encre posée sur une pastille de matière (SUJETS[].couleur, js/data/core.js) :
     ces pastels sont des données, identiques dans les deux thèmes, donc leur
     encre doit l'être aussi — sinon la nuit on écrit en clair sur du rose.
     Même principe que le bouton blanc du hero. Non redéfini en mode nuit,
     c'est voulu. */
  --on-pastel: #3D3452;
  /* Pastilles de type d'évaluation + badge de points. */
  --tag-qcm-bg:#E8E3FA; --tag-qcm-fg:#5B4FA0;
  --tag-vf-bg:#FBEBD2;  --tag-vf-fg:#8C5A20;
  --tag-exo-bg:#E3F5EA; --tag-exo-fg:#2F7A52;
  --tag-ds-bg:#F7E8CB;  --tag-ds-fg:#8C6A1E;
  --tag-fiche-bg:#DCEEFB; --tag-fiche-fg:#1F5C85;
  --tag-calcul-bg:#D9EFE4; --tag-calcul-fg:#1E6B4C;
  --calcul-juste:#1E6B4C; --calcul-faux:#A32C1C;
  /* Vert Android de la promo d'application. */
  --android-bg:#EAFBF1; --android-fg:#1F7A4C;
  /* Carte mentale (SVG généré par js/app.js) : les couleurs passent par des
     variables CSS et non par des littéraux, pour que la carte déjà affichée
     bascule avec le thème sans être redessinée. */
  --mm1-fill:#EDE6F9; --mm1-stroke:#6E5AA3; --mm1-text:#4A3B78;
  --mm2-fill:#E3F5EA; --mm2-stroke:#4F9E72; --mm2-text:#2F6B49;
  --mm3-fill:#E3EEF7; --mm3-stroke:#3E7CA6; --mm3-text:#2A5A7A;
  --mm4-fill:#FBE9ED; --mm4-stroke:#B84F63; --mm4-text:#8A3A49;
  --mm5-fill:#F0E6F7; --mm5-stroke:#8A5FBF; --mm5-text:#5F3F8A;
  --mm6-fill:#EAF2DD; --mm6-stroke:#6E8F3E; --mm6-text:#4A5F2A;
  --mm-cle-fill:#FCF3DF; --mm-cle-stroke:#C99A3E; --mm-cle-text:#8F6B24;
  --mm-feuille:#ffffff;
  --radius: 14px;
  --shadow: 0 2px 10px rgba(110,90,163,.08), 0 1px 2px rgba(110,90,163,.10);
  --shadow-lg: 0 12px 32px rgba(110,90,163,.16);
  --maxw: 980px;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background:var(--bg);
  color:var(--text);
  line-height:1.55;
}
a{color:var(--primary); text-decoration:none}
a:hover{text-decoration:underline}
img{max-width:100%}
h1,h2,h3,h4{line-height:1.25; margin-top:0}
button{font-family:inherit}

/* ===== Header ===== */
.site-header{
  background:var(--surface);
  border-bottom:1px solid var(--border);
  position:sticky; top:0; z-index:50;
}
.header-inner{
  max-width:1100px; margin:0 auto; padding:12px 20px;
  display:flex; align-items:center; gap:14px;
}
.brand{display:flex; align-items:center; gap:10px; color:var(--text); flex:1}
.brand:hover{text-decoration:none}
/* min-width, et pas seulement flex-shrink:0 : .brand a flex:1, donc c'est
   LUI que le navigateur comprime quand le header déborde, et le logo se
   retrouvait réduit à un filet (mesuré à 0px à 390px pour un élève
   connecté, avatar + bouton de déconnexion en plus dans la barre).
   Ce plancher fait céder la navigation avant la marque, jamais l'inverse. */
.brand-icon{height:52px; width:auto; flex-shrink:0; min-width:75px}
/* nowrap : .brand a flex:1 et se laissait comprimer jusqu'à casser
   « Réviser en ligne » sur deux lignes dès qu'on ajoutait un élément au
   header. Avec nowrap, sa largeur minimale devient celle du texte entier,
   donc c'est la barre de navigation qui cède la place, pas la marque. */
.brand-text{display:flex; flex-direction:column; line-height:1.2; white-space:nowrap}
.brand-text strong{font-size:16px}
.brand-text small{color:var(--text-muted); font-size:12px}
.main-nav{display:flex; gap:5px}
/* nowrap : mesuré le 25/08/2026, .main-nav n'avait pas un pixel de marge à
   1100px — reprendre 5px pour le logo suffisait à casser « Signaler un bug »
   et « Créer un compte » sur deux lignes, faisant passer le header de 76 à
   85px sans que rien ne le signale. Avec nowrap, un libellé ne peut plus se
   plier en silence ; le padding resserré rend au passage 10px de marge. */
.main-nav a{
  padding:8px 8px; border-radius:8px; color:var(--text); font-weight:600; font-size:14px;
  white-space:nowrap;
}
.main-nav a:hover{background:var(--surface-alt); text-decoration:none}
.main-nav a.nav-cta{background:var(--primary); color:var(--on-primary)}
.main-nav a.nav-cta:hover{background:var(--primary-hover)}
.main-nav a.nav-bug{color:var(--warning); border:1px solid var(--warning)}
.main-nav a.nav-bug:hover{background:var(--warning-light)}
.nav-account{display:flex; align-items:center; gap:6px; order:99}
.nav-avatar{
  width:34px; height:34px; padding:0; border-radius:50%; overflow:hidden; flex-shrink:0;
  display:flex; align-items:center; justify-content:center; font-size:18px; background:var(--surface-alt);
}
.nav-avatar img{width:100%; height:100%; object-fit:cover}
.nav-logout{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  background:none; border:1px solid var(--border); cursor:pointer; font-size:13px; font-weight:600;
  line-height:1; padding:7px 12px; border-radius:8px; color:var(--text-muted); flex-shrink:0; white-space:nowrap;
}
.nav-logout-icone{flex:none; display:none}
.nav-logout:hover{background:var(--surface-alt); color:var(--text)}
.nav-toggle{
  display:none; background:none; border:none; font-size:22px; cursor:pointer; color:var(--text);
}

/* Raccourci « Installer l'application » — icône seule, posée hors de .main-nav
   pour rester visible quand celle-ci se replie dans le hamburger sous 1100px
   (c'est sur téléphone que le lien sert le plus). Icône seule aussi parce que
   le header tient tout juste sur une ligne : un libellé le ferait déborder. */
.nav-app{
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  height:38px; padding:0 12px; flex-shrink:0; border-radius:10px;
  border:1px solid var(--border); background:var(--surface); color:var(--primary-accent);
  font-size:13.5px; font-weight:700; white-space:nowrap;
  transition:border-color .15s, background .15s, color .15s;
}
/* Sous 1100px la place manque : on retombe sur l'icône seule, qui reste
   visible (c'est là qu'elle sert le plus). L'intitulé survit dans le
   title/aria-label. */
@media (max-width:1100px){
  .nav-app{width:38px; padding:0; gap:0}
  .nav-app-texte{display:none}
}
.nav-app:hover{
  border-color:var(--primary); background:var(--surface-alt);
  color:var(--primary); text-decoration:none;
}

/* Options d'affichage — dernier élément de .main-nav, donc replié dans le
   hamburger sous 1100px (voir le commentaire dans index.html : le header n'a
   pas les 40px qu'un bouton permanent coûterait). Deux formes pour un seul
   nœud : icône seule dans la barre, icône + libellé dans le menu déroulant,
   où la place ne manque pas. */
.options-menu{position:relative; display:flex}
.nav-options{
  display:inline-flex; align-items:center; gap:10px;
  padding:8px 8px; border:none; border-radius:8px; background:none;
  font-family:inherit; font-size:14px; font-weight:600; color:var(--text);
  cursor:pointer; white-space:nowrap;
}
.nav-options:hover{background:var(--surface-alt)}
.nav-options:focus-visible{outline:2px solid var(--primary); outline-offset:-2px}
.nav-options svg{width:18px; height:18px; flex:none; display:block; transition:transform .25s}
.nav-options[aria-expanded="true"] svg{transform:rotate(45deg)}

/* Le panneau reprend la mise en forme du menu de niveau : mêmes gabarits de
   ligne, même coche à droite. Un réglage et un choix de niveau se présentent
   de la même façon, l'élève n'a qu'un seul motif à apprendre. */
.options-panel{
  position:absolute; top:calc(100% + 8px); right:0; z-index:60;
  min-width:250px; padding:8px;
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow-lg);
}
.options-groupe-titre{
  font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--text-muted); padding:4px 10px 6px;
}
.options-option{
  display:flex; align-items:center; gap:10px; width:100%;
  background:none; border:none; border-radius:10px; padding:8px 10px;
  cursor:pointer; font-family:inherit; font-size:14px; color:var(--text); text-align:left;
}
.options-option:hover{background:var(--surface-alt)}
.options-option:focus-visible{outline:2px solid var(--primary); outline-offset:-2px}
.options-option-emoji{font-size:15px; line-height:1; flex:none}
.options-option-nom{font-weight:600; flex:1}
/* La coche occupe sa place même invisible, sinon la ligne active serait
   décalée par rapport aux autres (même règle que .niveau-option-coche). */
.options-option-coche{width:14px; flex:none; color:var(--primary); font-weight:700; visibility:hidden}
.options-option[aria-checked="true"]{background:var(--primary-light)}
.options-option[aria-checked="true"] .options-option-nom{color:var(--primary-accent)}
.options-option[aria-checked="true"] .options-option-coche{visibility:visible}

@media (min-width:1101px){
  .nav-options-texte{display:none}
}
/* Sous 1100px, .main-nav EST déjà un panneau déroulant : un second panneau
   flottant par-dessus serait illisible et sortirait de l'écran à droite. Le
   réglage s'ouvre donc en place, dans le flux de la liste. */
@media (max-width:1100px){
  .options-menu{display:block; width:100%}
  .nav-options{width:100%}
  .options-panel{
    position:static; min-width:0; padding:6px 0 2px; margin-top:2px;
    background:none; border:none; border-top:1px solid var(--border);
    border-radius:0; box-shadow:none;
  }
}

/* ===== Menu de niveau du header =====
   Bouton + panneau maison (voir initNiveauMenu(), js/app.js). Le bouton fermé
   invite à choisir et n'affiche pas le niveau courant : celui-ci est coché
   dans le panneau. */
.niveau-select{position:relative; flex-shrink:0}
.niveau-trigger{
  display:inline-flex; align-items:center; gap:9px;
  background:var(--surface); border:1px solid var(--border); border-radius:999px;
  padding:8px 14px; cursor:pointer; font-family:inherit; font-size:13.5px; font-weight:700;
  color:var(--primary-accent); white-space:nowrap; line-height:1;
  transition:border-color .15s, box-shadow .15s;
}
.niveau-trigger-court{display:none}
.niveau-trigger:hover{border-color:var(--primary); box-shadow:var(--shadow)}
.niveau-trigger:focus-visible{outline:2px solid var(--primary); outline-offset:2px}
.niveau-chevron{
  width:0; height:0; flex:none;
  border-left:4.5px solid transparent; border-right:4.5px solid transparent;
  border-top:5px solid var(--primary); transition:transform .15s;
}
.niveau-trigger[aria-expanded="true"] .niveau-chevron{transform:rotate(180deg)}

.niveau-panel{
  position:absolute; top:calc(100% + 8px); right:0; z-index:60;
  min-width:250px; padding:8px;
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:var(--shadow-lg);
}
.niveau-groupe + .niveau-groupe{margin-top:6px; padding-top:8px; border-top:1px solid var(--border)}
.niveau-groupe-titre{
  font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--text-muted); padding:4px 10px 6px;
}
.niveau-option{
  display:flex; align-items:center; gap:10px; width:100%;
  background:none; border:none; border-radius:10px; padding:8px 10px;
  cursor:pointer; font-family:inherit; font-size:14px; color:var(--text); text-align:left;
}
.niveau-option:hover{background:var(--surface-alt)}
.niveau-option:focus-visible{outline:2px solid var(--primary); outline-offset:-2px}
.niveau-option:disabled{opacity:.5; cursor:default}
.niveau-option-emoji{font-size:16px; line-height:1; flex:none}
.niveau-option-nom{font-weight:600; flex:1}
.niveau-option-nb{
  font-size:12px; color:var(--text-muted);
  font-variant-numeric:tabular-nums; flex:none;
}
/* La coche occupe sa place même quand elle est invisible, sinon la ligne
   active serait décalée par rapport aux autres. */
.niveau-option-coche{width:14px; flex:none; color:var(--primary); font-weight:700; visibility:hidden}
.niveau-option[aria-selected="true"]{background:var(--primary-light)}
.niveau-option[aria-selected="true"] .niveau-option-nom{color:var(--primary-accent)}
.niveau-option[aria-selected="true"] .niveau-option-coche{visibility:visible}

@media (max-width: 1100px){
  .niveau-select{margin-left:auto}
  .niveau-trigger{padding:7px 12px; font-size:13px}
}

/* Sur un petit écran, le logo suffit à identifier le site : on retire le
   libellé pour laisser la place au menu de niveau, au raccourci d'installation
   et au hamburger, qui doivent tous rester atteignables. Sans ça, le header
   déborde à droite (mesuré à 375px). */
@media (max-width: 620px){
  .brand-text{display:none}
  /* Gouttière et marges resserrées : un élève connecté ajoute l'avatar et la
     déconnexion à une barre qui n'a déjà plus de marge — à 375px il faut
     368px rien que pour le reste, pour 335px disponibles. Sans ces quelques
     pixels la barre déborde encore de 4px à 360px (Android courant). */
  .header-inner{gap:8px; padding-left:14px; padding-right:14px}
  /* Le reste de la place se prend sur les deux libellés qui peuvent s'en
     passer, jamais sur le logo. « Niveau » ne nomme pas davantage le niveau
     courant que « Choisir mon niveau » : la règle du 23/08 tient. */
  .niveau-trigger-texte{display:none}
  .niveau-trigger-court{display:inline}
  .nav-logout{width:34px; height:34px; padding:0; gap:0}
  .nav-logout-texte{display:none}
  .nav-logout-icone{display:block}
}

/* Petit téléphone : le logo cède enfin de la hauteur, mais garde son
   rapport et reste lisible — il ne redevient jamais le filet écrasé
   qu'il était avant le plancher posé sur .brand-icon. */
@media (max-width: 380px){
  .brand-icon{height:42px; min-width:61px}
  /* 16px de trop subsistaient à 320px (Galaxy Fold replié, iPhone SE 1re
     génération) : ils se prennent sur la gouttière et les marges. */
  .header-inner{gap:6px; padding-left:10px; padding-right:10px}
  .niveau-trigger{padding:7px 9px}
}

@media (max-width: 1100px){
  .main-nav{
    display:none; position:absolute; top:100%; left:0; right:0;
    background:var(--surface); flex-direction:column; padding:10px; border-bottom:1px solid var(--border);
    box-shadow:var(--shadow);
  }
  .main-nav.open{display:flex}
  .nav-toggle{display:block}
}

/* ===== Layout ===== */
.app-main{max-width:var(--maxw); margin:0 auto; padding:28px 20px 80px}
.site-footer{
  text-align:center; color:var(--text-muted); font-size:13px; padding:26px 20px 40px;
}
.site-footer .footer-links{margin-top:8px}
.site-footer .footer-links a{color:var(--text-muted); font-weight:600}
.site-footer .footer-links a:hover{color:var(--primary)}
/* Les liens réseaux sont plus nombreux que ceux du pied classique : sans
   marge verticale ils se collent quand la ligne se replie sur téléphone. */
.site-footer .footer-social{margin-top:14px; line-height:2}
.site-footer .footer-social a{color:var(--primary-accent)}

/* ===== Breadcrumb ===== */
.breadcrumb{
  display:flex; flex-wrap:wrap; gap:6px; align-items:center;
  font-size:13px; color:var(--text-muted); margin-bottom:18px;
}
.breadcrumb a{color:var(--text-muted); font-weight:600}
.breadcrumb a:hover{color:var(--primary)}
.breadcrumb .sep{opacity:.5}
.breadcrumb .current{color:var(--text); font-weight:700}

/* ===== Hero ===== */
.hero{
  background:linear-gradient(135deg, var(--grad-a) 0%, var(--grad-b) 100%);
  color:#fff; border-radius:20px; padding:40px 32px; margin-bottom:32px;
  box-shadow:var(--shadow-lg);
}
.hero h1{font-size:clamp(24px,4vw,34px); margin-bottom:10px}
.hero p{opacity:.95; max-width:640px; font-size:15.5px}
.hero .pill{
  display:inline-block; background:rgba(255,255,255,.18); padding:5px 12px;
  border-radius:999px; font-size:12.5px; font-weight:700; margin-bottom:14px; letter-spacing:.3px;
}

/* ===== Bandeau bêta (accueil) ===== */
.beta-banner{
  display:flex; gap:14px; align-items:flex-start; background:var(--warning-light);
  border:1px solid var(--warning); border-radius:16px; padding:16px 20px; margin-bottom:24px;
}
.beta-banner .beta-icon{font-size:22px; flex-shrink:0; line-height:1}
.beta-banner strong{color:var(--text)}
.beta-banner p{margin:4px 0 0; font-size:14px; color:var(--text)}
.beta-banner a{font-weight:700; color:var(--primary-accent)}

/* ===== Accueil marketing ===== */
.home-hero{text-align:left}
.cta-buttons{display:flex; gap:12px; flex-wrap:wrap; margin-top:22px}
.cta-buttons .cta-primary{background:#fff; color:#4A3B78; font-size:15px; padding:12px 20px}
.cta-buttons .cta-primary:hover{background:#fff; opacity:.92; color:#4A3B78}
.cta-buttons .cta-secondary{background:rgba(255,255,255,.16); color:#fff; font-size:15px; padding:12px 20px}
.cta-buttons .cta-secondary:hover{background:rgba(255,255,255,.28)}

.home-features .card{text-align:center; align-items:center}
.home-features .card-icon{font-size:30px}

.niveaux-grid{grid-template-columns:repeat(auto-fill, minmax(160px,1fr))}
.niveau-card{
  font-family:inherit; text-align:center; align-items:center; cursor:pointer;
}
.niveau-card:disabled{opacity:.7; cursor:default}


.programme-badge{
  display:flex; gap:24px; align-items:center;
  background:linear-gradient(135deg, var(--grad-a) 0%, var(--grad-b) 100%);
  border-radius:20px; padding:30px 32px; margin:32px 0; box-shadow:var(--shadow-lg);
  color:#fff;
}
.programme-icon{flex-shrink:0}
.programme-texte h2{font-size:21px; margin:6px 0 10px; color:#fff}
.programme-texte p{font-size:14.5px; margin:0; color:rgba(255,255,255,.92)}
.programme-tag{background:rgba(255,255,255,.2); color:#fff}

@media (max-width:640px){
  .programme-badge{flex-direction:column; align-items:center; text-align:center; padding:26px 20px}
}

/* Mise en avant de l'application Android sur l'accueil. Volontairement sobre
   (fond clair, pas de dégradé) pour ne pas concurrencer .programme-badge, qui
   est le bloc coloré de la page. */
.app-promo{
  display:flex; gap:24px; align-items:center;
  background:var(--surface); border:1px solid var(--border); border-radius:20px;
  padding:28px 32px; margin:32px 0; box-shadow:var(--shadow);
}
.app-promo-icone{
  flex-shrink:0; width:86px; height:86px; border-radius:22px;
  display:flex; align-items:center; justify-content:center; background:var(--android-bg);
}
.app-promo-texte h2{font-size:21px; margin:6px 0 10px}
.app-promo-texte p{font-size:14.5px; margin:0 0 16px; color:var(--text-muted)}
.app-promo-tag{background:var(--android-bg); color:var(--android-fg)}
.app-promo-actions{display:flex; align-items:center; gap:16px; flex-wrap:wrap}
.app-promo-lien{font-size:13.5px; font-weight:600; color:var(--text-muted)}

@media (max-width:640px){
  .app-promo{flex-direction:column; align-items:center; text-align:center; padding:26px 20px}
  .app-promo-actions{justify-content:center}
}

.fondatrice-section{
  display:flex; gap:28px; align-items:flex-start; background:var(--surface);
  border:1px solid var(--border); border-radius:20px; padding:32px; margin:40px 0;
  box-shadow:var(--shadow);
}
.fondatrice-avatar{flex-shrink:0}
.fondatrice-texte h2{font-size:22px; margin:6px 0 14px}
.fondatrice-texte p{font-size:15px}
.fondatrice-signature{color:var(--text-muted); font-weight:700; font-style:italic}

.cta-band{
  text-align:center; background:var(--surface-alt); border-radius:20px; padding:40px 24px; margin:40px 0 8px;
}
.cta-band h2{font-size:24px}
.cta-band p{color:var(--text-muted); max-width:520px; margin:8px auto 20px}

@media (max-width:640px){
  .fondatrice-section{flex-direction:column; align-items:center; text-align:center; padding:26px 20px}
}

/* ===== Cards / grid ===== */
.grid{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(230px,1fr)); gap:16px;
}
.card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  padding:20px; box-shadow:var(--shadow); transition:transform .15s ease, box-shadow .15s ease;
  display:flex; flex-direction:column; gap:8px;
}
.card:hover{transform:translateY(-3px); box-shadow:var(--shadow-lg); text-decoration:none}
.card .card-icon{
  font-size:26px; width:52px; height:52px; display:flex; align-items:center; justify-content:center;
  border-radius:14px; background:var(--surface-alt);
}
.card .card-icon svg{width:26px; height:26px; stroke:var(--text); flex-shrink:0}
.card h3{font-size:17px; margin:0; color:var(--text)}
.card p{font-size:13px; color:var(--text-muted); margin:0}
.card .card-meta{font-size:12px; color:var(--primary); font-weight:700; margin-top:auto}

.section-title{
  display:flex; align-items:baseline; justify-content:space-between; margin:36px 0 16px;
}
.section-title h2{font-size:20px}
.section-title .count{color:var(--text-muted); font-size:13px}

/* ===== Chapter page ===== */
.chapter-header{margin-bottom:24px}
.chapter-header .tag{
  display:inline-flex; align-items:center; gap:5px; background:var(--primary-light); color:var(--primary-accent);
  font-size:12px; font-weight:700; padding:4px 10px; border-radius:999px; margin-bottom:10px;
}
.chapter-header .tag svg{width:14px; height:14px; stroke:currentColor; flex-shrink:0}
/* Pastille colorée par la matière : le fond vient des données (SUJETS[].couleur),
   il est le même dans les deux thèmes — l'encre l'est donc aussi. Posée APRÈS
   .chapter-header .tag, de même spécificité : c'est l'ordre qui tranche. */
.card-icon.pastel, .tag.pastel, .cbot-badge.pastel{color:var(--on-pastel)}
.card .card-icon.pastel svg{stroke:var(--on-pastel)}
.chapter-header h1{font-size:26px}

.tabs{display:flex; gap:6px; border-bottom:2px solid var(--border); margin-bottom:24px; flex-wrap:wrap}
.tab-btn{
  background:none; border:none; padding:11px 16px; font-size:14px; font-weight:700;
  color:var(--text-muted); cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-2px;
}
.tab-btn:hover{color:var(--primary)}
.tab-btn.active{color:var(--primary); border-color:var(--primary)}
/* Dernier élément de la barre d'onglets de l'espace élève : ce n'est pas
   un onglet mais une sortie vers le catalogue des matières. Poussé à droite
   pour qu'il ne se lise pas comme une cinquième section ; il passe à la
   ligne comme les autres quand la barre est trop étroite. */
.tab-sortie{margin-left:auto; color:var(--primary-accent)}
.tab-sortie:hover{color:var(--primary)}

.cours-block{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  padding:26px 28px; box-shadow:var(--shadow);
}
.cours-block .intro{font-size:15.5px; color:var(--text-muted); margin-bottom:20px; font-style:italic}
.cours-block h3{font-size:17px; margin-top:26px; color:var(--primary-accent); border-left:4px solid var(--primary); padding-left:10px}
.cours-block h3:first-of-type{margin-top:6px}
.cours-block p{font-size:15px}
.cours-block ul, .cours-block ol{padding-left:22px; font-size:15px}
.vocab-box{
  background:var(--surface-alt); border-radius:10px; padding:14px 18px; margin:14px 0; font-size:14px;
}
.vocab-box strong{color:var(--primary-accent)}
.key-points{
  background:var(--success-light); border:1px solid var(--success-border); border-radius:12px; padding:18px 20px; margin-top:28px;
}
.key-points h4{color:var(--success-strong); margin:0 0 10px; font-size:15px}
.key-points ul{margin:0; padding-left:20px; font-size:14.5px}

/* ===== Carte mentale ===== */
.mindmap-wrap{
  position:relative; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:12px;
}
.mindmap-wrap svg, .mindmap-overlay-scroll svg{display:block; margin:0 auto}
.mindmap-wrap text, .mindmap-overlay-scroll text{font-family:inherit; user-select:none}

/* Aperçu : la carte est réduite pour tenir entièrement dans un cadre carré
   (au lieu de déborder avec un défilement horizontal) — on clique dessus
   (ou sur la loupe) pour l'ouvrir en plein écran à taille réelle. */
.mindmap-preview{
  width:100%; aspect-ratio:1/1; max-height:480px;
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  cursor:zoom-in; border-radius:calc(var(--radius) - 6px);
}
.mindmap-preview:hover{background:var(--surface-alt)}
.mindmap-preview svg{width:100%; height:100%; max-width:100%; max-height:100%; margin:0}

.mindmap-zoom-btn{
  position:absolute; top:22px; right:22px; z-index:2;
  width:38px; height:38px; border-radius:50%; border:1px solid var(--border);
  background:var(--surface); box-shadow:var(--shadow); cursor:pointer; font-size:15px;
  display:flex; align-items:center; justify-content:center; padding:0;
}
.mindmap-zoom-btn:hover{background:var(--primary-light)}

/* Plein écran : la même carte, à taille réelle, avec défilement si elle
   déborde de l'écran (cf. centrerCarteMentale() qui centre le scroll). */
.mindmap-overlay{
  position:fixed; inset:0; z-index:1000; background:#241a3d;
  display:flex; flex-direction:column;
}
.mindmap-overlay-bar{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:14px 20px; flex-shrink:0;
}
.mindmap-overlay-title{color:#fff; font-weight:700; font-size:16px}
.mindmap-overlay-close{
  width:38px; height:38px; border-radius:50%; border:none; flex-shrink:0;
  background:rgba(255,255,255,.15); color:#fff; font-size:18px; cursor:pointer;
}
.mindmap-overlay-close:hover{background:rgba(255,255,255,.28)}
.mindmap-overlay-scroll{flex:1; overflow:auto; padding:12px 24px 32px}

/* ===== Aperçu cours (visiteur non connecté) ===== */
.cours-preview-wrap{position:relative; max-height:300px; overflow:hidden; margin-top:20px; border-radius:0 0 var(--radius) var(--radius)}
.cours-preview-masque{filter:blur(5px); user-select:none; pointer-events:none}
.cours-preview-cta{
  position:absolute; inset:0; display:flex; align-items:flex-end; justify-content:center;
  background:linear-gradient(to bottom, var(--fade-from) 0%, var(--surface) 62%); padding-bottom:22px;
}
.cours-preview-cta-inner{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow-lg); padding:22px 26px; max-width:400px; text-align:center;
}
.cours-preview-cta-inner h4{font-size:16px; margin:8px 0 6px}
.cours-preview-cta-inner p{font-size:13.5px; color:var(--text-muted); margin:0 0 14px}

/* ===== Verrou d'accès (onglets réservés au compte gratuit) =====
   Pendant du .cours-preview-* ci-dessus, mais pour les onglets où il n'y a
   rien à flouter : carte mentale, flashcards, évaluations. Voir blocVerrou()
   dans js/app.js et CHAPITRES_VITRINE dans js/data/core.js. */
.verrou{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:38px 28px; max-width:460px; margin:24px auto; text-align:center;
}
.verrou-icone{font-size:32px; line-height:1; margin-bottom:14px}
.verrou h3{font-size:18px; margin:0 0 8px}
.verrou > p{font-size:14px; color:var(--text-muted); margin:0 0 18px; line-height:1.55}
.verrou .btn{margin-bottom:12px}
.verrou-alt{font-size:13px; margin:0}
.verrou-note{font-size:12.5px; color:var(--text-muted); margin:12px 0 0; padding-top:12px; border-top:1px solid var(--border)}

/* Chapitre verrouillé dans la liste d'une matière : lisible, mais visiblement
   en retrait — le visiteur doit voir ce qui existe, pas croire que c'est vide. */
.card-verrouille{opacity:.72}
.card-verrouille:hover{opacity:1}
.card-verrouille .card-meta{color:var(--primary)}

/* ===== Flashcards ===== */
.flashcard-grid{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(240px,1fr)); gap:18px;
}
.flashcard{
  background:none; border:none; padding:0; margin:0; cursor:pointer; text-align:left;
  height:180px; perspective:1200px; font-family:inherit;
}
.flashcard-inner{
  position:relative; width:100%; height:100%; display:block;
  transform-style:preserve-3d; transition:transform .5s cubic-bezier(.4,.2,.2,1);
}
.flashcard.flipped .flashcard-inner{transform:rotateY(180deg)}
.flashcard-face{
  position:absolute; inset:0; backface-visibility:hidden; -webkit-backface-visibility:hidden;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px;
  border-radius:var(--radius); box-shadow:var(--shadow); padding:18px; text-align:center;
}
.flashcard-front{background:var(--surface); border:1px solid var(--border)}
.flashcard-back{background:var(--primary); color:var(--on-primary); transform:rotateY(180deg)}
.flashcard-tag{
  font-size:11px; font-weight:800; text-transform:uppercase; letter-spacing:.5px;
  color:var(--primary); opacity:.8;
}
.flashcard-back .flashcard-tag{color:var(--on-primary); opacity:.75}
.flashcard-text{font-size:15px; font-weight:600; line-height:1.4}
.flashcard:hover .flashcard-front{border-color:var(--primary)}
.flashcard:focus-visible .flashcard-inner{outline:2px solid var(--primary); outline-offset:3px}

/* ===== Evaluations list ===== */
.eval-grid{display:grid; grid-template-columns:repeat(auto-fit, minmax(260px,1fr)); gap:16px}
.eval-card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  padding:20px; box-shadow:var(--shadow);
}
.eval-type{
  display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:800;
  text-transform:uppercase; letter-spacing:.4px; padding:4px 10px; border-radius:999px; margin-bottom:10px;
}
.eval-type.qcm{background:var(--tag-qcm-bg); color:var(--tag-qcm-fg)}
.eval-type.vf{background:var(--tag-vf-bg); color:var(--tag-vf-fg)}
.eval-type.exo{background:var(--tag-exo-bg); color:var(--tag-exo-fg)}
.eval-type.ds{background:var(--tag-ds-bg); color:var(--tag-ds-fg)}
.eval-type.fiche{background:var(--tag-fiche-bg); color:var(--tag-fiche-fg)}
.eval-type.calcul{background:var(--tag-calcul-bg); color:var(--tag-calcul-fg)}
.eval-card h3{font-size:16px; margin:0 0 6px}
.eval-card p{font-size:13px; color:var(--text-muted); margin:0 0 14px}
.btn{
  display:inline-flex; align-items:center; gap:6px; background:var(--primary); color:var(--on-primary);
  border:none; padding:10px 16px; border-radius:9px; font-weight:700; font-size:14px; cursor:pointer;
}
.btn:hover{background:var(--primary-hover); text-decoration:none; color:var(--on-primary)}
.btn.secondary{background:var(--surface-alt); color:var(--text)}
.btn.secondary:hover{background:var(--border)}
.btn.block{width:100%; justify-content:center}
.btn.danger{background:var(--danger); color:var(--on-danger)}
.btn.danger:hover{background:var(--danger-hover); color:var(--on-danger)}
.btn:disabled{opacity:.55; cursor:not-allowed}

/* ===== Quiz ===== */
.quiz-header{margin-bottom:20px}
.quiz-progress{
  height:8px; background:var(--surface-alt); border-radius:999px; overflow:hidden; margin-top:10px;
}
.quiz-progress-bar{height:100%; background:var(--primary); width:0%; transition:width .2s ease}
.question-card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  padding:22px 24px; margin-bottom:16px; box-shadow:var(--shadow);
}
.question-card .qnum{font-size:12px; font-weight:800; color:var(--primary); text-transform:uppercase; letter-spacing:.4px}
.question-card .qtext{font-size:16px; font-weight:600; margin:8px 0 16px}
/* Quiz en langue vivante : barème annoncé en tête, bouton de traduction
   sous chaque énoncé (une bonne réponse traduite ne vaut qu'un demi-point,
   voir renderBaremeTraduction/bindTraduction dans js/app.js). */
.quiz-bareme{
  margin:12px 0 0; padding:10px 14px; font-size:13.5px; line-height:1.5;
  background:var(--surface-alt); border:1px dashed var(--border);
  border-radius:calc(var(--radius) - 6px); color:var(--text);
}
.btn-traduire{
  display:inline-flex; align-items:center; gap:6px; margin:-8px 0 14px;
  padding:5px 11px; font-size:12.5px; font-weight:700; font-family:inherit;
  color:var(--primary); background:transparent; cursor:pointer;
  border:1.5px solid var(--border); border-radius:999px; transition:all .15s ease;
}
.btn-traduire:hover{border-color:var(--primary); background:var(--surface-alt)}
.btn-traduire.actif{background:var(--primary); border-color:var(--primary); color:var(--on-primary)}
.choice-list{display:flex; flex-direction:column; gap:8px}
.choice{
  display:flex; align-items:center; gap:10px; padding:11px 14px; border:1.5px solid var(--border);
  border-radius:10px; cursor:pointer; font-size:14.5px; transition:all .12s ease;
}
.choice:hover{border-color:var(--primary); background:var(--primary-light)}
.choice input{accent-color:var(--primary); width:16px; height:16px; flex-shrink:0}
.choice.correct{border-color:var(--success); background:var(--success-light)}
.choice.incorrect{border-color:var(--danger); background:var(--danger-light)}
.choice.disabled{cursor:default}
.choice.disabled:hover{background:none}
.choice.correct:hover, .choice.incorrect:hover{background:inherit}

.vf-row{display:flex; gap:10px}
.vf-btn{
  flex:1; padding:11px; border:1.5px solid var(--border); border-radius:10px; background:var(--surface);
  cursor:pointer; font-weight:700; font-size:14px;
}
.vf-btn:hover{border-color:var(--primary)}
.vf-btn.selected{background:var(--primary-light); border-color:var(--primary)}
.vf-btn.correct{background:var(--success-light); border-color:var(--success); color:var(--success-strong)}
.vf-btn.incorrect{background:var(--danger-light); border-color:var(--danger); color:var(--danger-strong)}

.explication{
  margin-top:12px; padding:12px 14px; background:var(--surface-alt); border-radius:10px; font-size:13.5px;
  border-left:3px solid var(--primary);
}

textarea.answer-box{
  width:100%; min-height:110px; border:1.5px solid var(--border); border-radius:10px; padding:12px;
  font-family:inherit; font-size:14.5px; resize:vertical;
  background:var(--surface); color:var(--text);
}
.correction-box{
  margin-top:14px; padding:16px 18px; background:var(--success-light); border:1px solid var(--success-border);
  border-radius:10px; font-size:14.5px; display:none;
}
.correction-box.show{display:block}
.correction-box h4{margin:0 0 8px; color:var(--success-strong); font-size:14px}

.quiz-result{
  text-align:center; padding:36px 20px; background:var(--surface); border-radius:var(--radius);
  box-shadow:var(--shadow); margin-bottom:20px;
}
.quiz-result .score{font-size:44px; font-weight:800; color:var(--primary)}
.quiz-result .score-label{color:var(--text-muted); font-size:14px; margin-top:4px}
.quiz-result .appreciation{margin-top:10px; font-weight:700; font-size:16px}

.actions-row{display:flex; gap:10px; margin-top:20px; flex-wrap:wrap}

.ds-meta{display:flex; gap:16px; flex-wrap:wrap; font-size:13px; color:var(--text-muted); margin:6px 0 4px}
.ds-meta strong{color:var(--text)}
.ds-consigne{font-size:14.5px; color:var(--text-muted); margin:-8px 0 14px}
.ds-figure{
  background:var(--surface-alt); border:1px solid var(--border); border-radius:12px;
  padding:18px; margin:6px 0 18px; display:flex; flex-direction:column; align-items:center; gap:8px;
}
.ds-figure svg{max-width:100%; height:auto}
.ds-figure img{max-width:100%; max-height:420px; height:auto; object-fit:contain; border-radius:8px; display:block}
.doc-map{position:relative; display:inline-block; max-width:100%}
.doc-map img{max-width:100%; height:auto; border-radius:8px; display:block}
.doc-label{
  position:absolute; transform:translate(-50%,-50%); background:rgba(255,255,255,.9);
  color:#2E6E8E; font-size:12px; font-weight:700; padding:2px 7px; border-radius:6px;
  white-space:nowrap; border:1px solid rgba(46,110,142,.35);
}
.doc-credit{font-size:11.5px; color:var(--text-muted); text-align:center}
.ds-champs{display:flex; flex-direction:column; gap:10px; margin:14px 0}
.ds-champ{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.ds-champ-label{font-weight:600; font-size:14.5px}
.ds-input{
  border:none; border-bottom:2px dotted var(--text-muted); background:transparent;
  font-family:inherit; font-size:14.5px; padding:4px 6px; min-width:110px; outline:none;
}
.ds-input:focus{border-bottom-color:var(--primary)}

/* Exercices calculés : l'élève écrit son résultat, il ne le choisit pas.
   Le champ est donc l'élément principal de la carte, pas un accessoire —
   d'où une vraie boîte plutôt que le trait pointillé des devoirs surveillés. */
.calcul-saisie{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:14px 0 4px}
.calcul-label{font-weight:600; font-size:14px; color:var(--text-muted)}
.calcul-input{
  font-family:inherit; font-size:16px; padding:9px 12px; min-width:150px;
  border:1.5px solid var(--border); border-radius:8px;
  background:var(--surface); color:var(--text); outline:none;
}
.calcul-input:focus{border-color:var(--primary)}
.calcul-input:disabled{opacity:1}   /* corrigé, mais toujours lisible */
.calcul-input.juste{border-color:var(--calcul-juste); color:var(--calcul-juste); font-weight:600}
.calcul-input.faux{border-color:var(--calcul-faux); color:var(--calcul-faux); font-weight:600}
.calcul-unite{font-size:15px; color:var(--text-muted)}
/* Barre de symboles sous le champ de réponse. Elle existe parce que le pavé
   « decimal » des téléphones n'a ni moins ni barre de fraction (voir
   CALCUL_SYMBOLES dans js/app.js). Cibles larges : 44px de haut, c'est le
   minimum tactile recommandé, et on saisit ici avec le pouce. */
.calcul-symboles{display:flex; gap:6px; flex-wrap:wrap; margin:0 0 6px}
.calcul-sym{
  font-family:inherit; font-size:17px; line-height:1;
  min-width:44px; min-height:44px; padding:0 10px;
  border:1.5px solid var(--border); border-radius:8px;
  background:var(--surface); color:var(--text); cursor:pointer;
}
.calcul-sym:hover{border-color:var(--primary); color:var(--primary-accent)}
.calcul-sym:active{background:var(--bg)}
.calcul-sym:focus-visible{outline:2px solid var(--primary); outline-offset:2px}
.calcul-sym:disabled{opacity:.35; cursor:default}

/* ===== Prof / admin ===== */
.login-box{
  max-width:380px; margin:60px auto; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); padding:30px; box-shadow:var(--shadow); text-align:center;
}
.login-box input, .login-box select{
  width:100%; padding:11px 14px; border:1.5px solid var(--border); border-radius:9px; font-size:15px;
  margin:14px 0; text-align:center; font-family:inherit; background:var(--surface); color:var(--text);
}
.login-box .error{color:var(--danger); font-size:13px; min-height:18px}
/* Bloc de consentement parental, affiché par js/eleve.js quand la date de
   naissance saisie place l'élève sous 15 ans (seuil légal français).
   ⚠️ Volontairement NON préfixé par .login-box : le même bloc sert à
   l'inscription ET au formulaire de profil (/eleve/profil), qui n'est pas
   dans une .login-box. Le préfixer laisserait le second sans aucun style. */
.bloc-parental{
  text-align:left; background:var(--bg); border:1px solid var(--border);
  border-radius:9px; padding:14px; margin:14px 0; font-size:13px;
}
.bloc-parental > p{margin:0 0 10px; color:var(--text-muted)}
.bloc-parental input[type="email"]{margin:10px 0 0; text-align:left; font-size:14px}
.case-consentement{display:flex; gap:9px; align-items:flex-start; cursor:pointer}
.case-consentement input{width:auto; margin:2px 0 0; flex:0 0 auto}
.petite-note{margin:8px 0 0; font-size:12px; color:var(--text-muted)}
.login-box .pass-field{position:relative; margin:14px 0}
.login-box .pass-field input{margin:0; padding-right:42px}
.login-box .pass-toggle{
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  background:none; border:none; cursor:pointer; font-size:16px; padding:6px; line-height:1;
}
.stacked-form{display:flex; flex-direction:column; gap:12px; max-width:340px; margin-top:14px}
.stacked-form .pass-field{position:relative}
.stacked-form input, .stacked-form select, .stacked-form textarea{
  width:100%; padding:11px 14px; border:1.5px solid var(--border); border-radius:9px; font-size:15px; font-family:inherit;
  background:var(--surface); color:var(--text);
}
.stacked-form textarea{resize:vertical; min-height:110px}
.stacked-form .pass-field input{padding-right:42px}
.stacked-form .pass-toggle{
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  background:none; border:none; cursor:pointer; font-size:16px; padding:6px; line-height:1;
}
.stacked-form .error{color:var(--danger); font-size:13px; min-height:18px}
.stacked-form .success{color:var(--success); font-size:13px}

/* ===== Plan du site ===== */
.sitemap-list{list-style:none; padding:0; margin:0 0 28px; display:flex; flex-direction:column; gap:8px}
.sitemap-list li a{font-size:15px; font-weight:600}
.sitemap-niveaux .card{align-items:flex-start}
/* C'est un <a> depuis le 03/09/2026, plus un <button> : un moteur de recherche
   ne suit pas un bouton, et cette page est justement celle qui doit exposer le
   catalogue à l'exploration. Les règles de remise à plat restent utiles pour
   qu'il garde l'aspect qu'il avait. */
.sitemap-niveau-link{
  display:inline-block; background:none; border:none; padding:0;
  font-family:inherit; font-size:13px; font-weight:700;
  color:var(--primary); cursor:pointer; text-decoration:none;
}
.sitemap-niveau-link:hover{text-decoration:underline}
.table-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch}
.admin-table{width:100%; border-collapse:collapse; margin-top:10px}
.admin-table th, .admin-table td{
  text-align:left; padding:10px 12px; border-bottom:1px solid var(--border); font-size:14px;
}
.admin-table th{color:var(--text-muted); font-size:12px; text-transform:uppercase}
.admin-table .td-icon{display:inline-flex; vertical-align:middle}
.admin-table .td-icon svg{width:16px; height:16px; stroke:var(--text); vertical-align:middle}
.info-box{
  background:var(--primary-light); border-radius:12px; padding:18px 20px; font-size:14px; margin:18px 0;
  border-left:4px solid var(--primary);
}
.badge{
  display:inline-block; background:var(--surface-alt); padding:2px 9px; border-radius:999px;
  font-size:11.5px; font-weight:700; color:var(--text-muted);
}
.badge.points{background:var(--tag-ds-bg); color:var(--tag-ds-fg); font-weight:800; margin-left:8px}

.empty-state{text-align:center; padding:60px 20px; color:var(--text-muted)}
.back-link{display:inline-block; margin-bottom:16px; font-weight:700; font-size:14px}

/* ===== Import de cours ===== */
.import-form-row{display:flex; gap:10px; flex-wrap:wrap}
.import-form-row select, .import-form-row input[type="text"]{
  flex:1; min-width:200px; padding:10px 12px; border:1.5px solid var(--border); border-radius:9px; font-size:14.5px; font-family:inherit;
  background:var(--surface); color:var(--text);
}
#impFile{
  display:block; margin-top:8px; font-size:14px;
}


/* ============================================================
   ASSISTANT DE RÉVISION (chatbot de recherche)
   ============================================================ */
.cbot-wrap{position:fixed; right:20px; bottom:20px; z-index:1000; font-family:inherit;}
.cbot-toggle{
  width:60px; height:60px; border-radius:50%; border:none; cursor:pointer;
  background:linear-gradient(135deg, var(--grad-a) 0%, var(--grad-b) 100%); color:#fff;
  box-shadow:var(--shadow-lg); display:flex; align-items:center; justify-content:center;
  transition:transform .15s ease, box-shadow .15s ease;
}
.cbot-toggle:hover{transform:translateY(-2px) scale(1.04);}
.cbot-toggle svg{width:28px; height:28px;}
.cbot-toggle.hidden{display:none;}

.cbot-panel{
  position:absolute; right:0; bottom:0; width:min(380px, calc(100vw - 32px));
  height:min(560px, calc(100vh - 90px));
  background:var(--surface); border:1px solid var(--border); border-radius:20px;
  box-shadow:var(--shadow-lg); display:none; flex-direction:column; overflow:hidden;
}
.cbot-panel.open{display:flex; animation:cbotPop .18s ease;}
@keyframes cbotPop{from{opacity:0; transform:translateY(12px) scale(.98);} to{opacity:1; transform:none;}}

.cbot-header{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:14px 16px; background:linear-gradient(135deg, var(--grad-a) 0%, var(--grad-b) 100%); color:#fff;
}
.cbot-header-title{display:flex; align-items:center; gap:10px;}
.cbot-avatar{
  width:38px; height:38px; border-radius:50%; background:rgba(255,255,255,.22);
  display:flex; align-items:center; justify-content:center; flex-shrink:0;
}
.cbot-avatar svg{width:22px; height:22px;}
.cbot-header-title strong{display:block; font-size:15px; line-height:1.2;}
.cbot-header-title small{font-size:12px; opacity:.9;}
.cbot-close{
  background:rgba(255,255,255,.18); border:none; color:#fff; width:30px; height:30px;
  border-radius:50%; cursor:pointer; font-size:14px; line-height:1; flex-shrink:0;
}
.cbot-close:hover{background:rgba(255,255,255,.32);}

.cbot-messages{flex:1; overflow-y:auto; padding:16px; display:flex; flex-direction:column; gap:12px; background:var(--bg);}
.cbot-msg{display:flex; max-width:100%;}
.cbot-msg.cbot-user{justify-content:flex-end;}
.cbot-bubble{
  padding:11px 14px; border-radius:16px; font-size:14px; line-height:1.5; max-width:88%;
  box-shadow:var(--shadow);
}
.cbot-bot .cbot-bubble{background:var(--surface); color:var(--text); border-bottom-left-radius:5px;}
.cbot-user .cbot-bubble{background:var(--primary); color:var(--on-primary); border-bottom-right-radius:5px;}
.cbot-bubble p{margin:0 0 8px;}
.cbot-bubble p:last-child{margin-bottom:0;}
.cbot-hint{display:block; margin-top:6px; font-size:12.5px; color:var(--text-muted); font-style:italic;}

.cbot-result{
  background:var(--surface-alt); border:1px solid var(--border); border-radius:12px;
  padding:11px 12px; margin-top:10px;
}
.cbot-result-head{display:flex; align-items:center; gap:8px; margin-bottom:6px; flex-wrap:wrap;}
.cbot-badge{
  display:inline-flex; align-items:center; gap:4px; font-size:11.5px; font-weight:700;
  color:var(--primary-accent); padding:3px 9px; border-radius:999px;
}
.cbot-badge svg{width:13px; height:13px; stroke:currentColor;}
.cbot-type{font-size:11px; font-weight:700; color:var(--text-muted); text-transform:uppercase; letter-spacing:.03em;}
.cbot-result-title{font-weight:700; font-size:13.5px; color:var(--text); margin-bottom:4px;}
.cbot-result-text{font-size:13.5px; color:var(--text); line-height:1.5;}
.cbot-result-text em{color:var(--primary-accent);}
.cbot-result-link{display:inline-block; margin-top:8px; font-size:12.5px; font-weight:700; color:var(--primary);}

.cbot-form{display:flex; gap:8px; padding:12px; border-top:1px solid var(--border); background:var(--surface);}
.cbot-form input{
  flex:1; padding:10px 14px; border:1.5px solid var(--border); border-radius:999px;
  font-size:14px; font-family:inherit; outline:none;
  background:var(--surface); color:var(--text);
}
.cbot-form input:focus{border-color:var(--primary);}
.cbot-form button{
  width:42px; height:42px; border-radius:50%; border:none; cursor:pointer; flex-shrink:0;
  background:var(--primary); color:var(--on-primary); display:flex; align-items:center; justify-content:center;
}
.cbot-form button:hover{background:var(--primary-hover);}
.cbot-form button svg{width:19px; height:19px;}

.cbot-thinking{display:flex; gap:4px; align-items:center;}
.cbot-thinking span{
  width:7px; height:7px; border-radius:50%; background:var(--text-muted); opacity:.5;
  animation:cbotBlink 1s infinite;
}
.cbot-thinking span:nth-child(2){animation-delay:.2s;}
.cbot-thinking span:nth-child(3){animation-delay:.4s;}
@keyframes cbotBlink{0%,80%,100%{opacity:.3; transform:translateY(0);} 40%{opacity:1; transform:translateY(-3px);}}

@media (max-width:520px){
  .cbot-wrap{right:14px; bottom:14px;}
  .cbot-panel{height:min(70vh, calc(100vh - 80px));}
}

/* ===== Dashboard admin ===== */
.admin-kpi-grid{grid-template-columns:repeat(auto-fill, minmax(200px,1fr)); margin-bottom:8px}
.admin-kpi-card{transform:none; cursor:pointer}
.admin-kpi-card:hover{transform:none; box-shadow:var(--shadow); border-color:var(--primary)}
.admin-kpi-label{font-size:12.5px; font-weight:700; color:var(--text-muted); text-transform:uppercase; letter-spacing:.03em}
.admin-kpi-value{font-size:32px; font-weight:800; color:var(--primary-accent)}
.admin-kpi-sub{font-size:13px; color:var(--text-muted)}
.admin-kpi-delta{font-weight:700}
.admin-kpi-delta.up{color:var(--success)}
.admin-kpi-delta.down{color:var(--danger)}
.admin-kpi-delta.flat{color:var(--text-muted)}
.admin-niveau-bars{display:flex; flex-direction:column; gap:10px; margin-bottom:8px}
.admin-niveau-row{display:flex; align-items:center; gap:12px}
.admin-niveau-nom{width:90px; font-size:13.5px; font-weight:600; flex-shrink:0}
.admin-niveau-bar-track{flex:1; height:10px; background:var(--surface-alt); border-radius:999px; overflow:hidden}
.admin-niveau-bar-fill{height:100%; background:var(--primary); border-radius:999px}
.admin-niveau-count{width:32px; text-align:right; font-size:13.5px; font-weight:700; color:var(--text-muted); flex-shrink:0}

.admin-detail-table-wrap{overflow-x:auto; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow)}
.admin-detail-table{width:100%; border-collapse:collapse; font-size:13.5px; white-space:nowrap}
.admin-detail-table th, .admin-detail-table td{padding:10px 14px; text-align:left; border-bottom:1px solid var(--border)}
.admin-detail-table th{color:var(--text-muted); font-size:12px; text-transform:uppercase; letter-spacing:.03em; font-weight:700; background:var(--surface-alt)}
.admin-detail-table tr:last-child td{border-bottom:none}
.admin-detail-table tr.marquant td:first-child{box-shadow:inset 3px 0 0 var(--warning)}
.admin-detail-table tr.marquant{background:var(--warning-light)}

/* Colonne "œil" (aperçu d'un cours déposé) + bouton par ligne. */
.admin-detail-apercu-cell{text-align:center; width:1%}
.admin-detail-apercu-btn{
  border:1px solid var(--border); background:var(--surface); border-radius:8px;
  padding:4px 9px; font-size:16px; line-height:1; cursor:pointer;
}
.admin-detail-apercu-btn:hover{background:var(--surface-alt); border-color:var(--primary)}

/* Lecture plein écran d'un cours déposé (voir ouvrirApercuCours, js/admin.js). */
.apercu-overlay{
  position:fixed; inset:0; z-index:1000; background:var(--overlay);
  display:flex; align-items:flex-start; justify-content:center; padding:24px; overflow:auto;
}
.apercu-doc{
  background:var(--surface); border-radius:var(--radius); box-shadow:var(--shadow);
  width:100%; max-width:820px; max-height:calc(100vh - 48px);
  display:flex; flex-direction:column; overflow:hidden;
}
.apercu-bar{
  display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
  padding:16px 20px; border-bottom:1px solid var(--border); flex-shrink:0;
}
.apercu-meta{display:flex; flex-direction:column; gap:3px; min-width:0}
.apercu-titre{font-weight:700; font-size:17px}
.apercu-sub{color:var(--text-muted); font-size:13px}
.apercu-close{
  width:36px; height:36px; border-radius:50%; border:1px solid var(--border); flex-shrink:0;
  background:var(--surface-alt); font-size:16px; cursor:pointer;
}
.apercu-close:hover{background:var(--border)}
.apercu-scroll{flex:1; overflow:auto; padding:20px 24px 28px}
.apercu-fichier{display:inline-flex; margin-bottom:16px}
.apercu-texte{white-space:pre-wrap; line-height:1.6; margin:0}

/* ===== Podium par niveau (tableau de bord élève) ===== */
.podium-section{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:18px 20px;
}
.podium-entete{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin-bottom:14px;
}
.podium-onglets{display:flex; gap:4px; background:var(--surface-alt); padding:3px; border-radius:999px}
.podium-onglet{
  background:none; border:none; padding:6px 14px; font-size:13px; font-weight:700;
  color:var(--text-muted); cursor:pointer; border-radius:999px; white-space:nowrap;
}
.podium-onglet:hover{color:var(--primary)}
.podium-onglet.active{background:var(--surface); color:var(--primary); box-shadow:var(--shadow)}

.podium{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px}
.podium-place{
  display:flex; align-items:center; gap:12px;
  background:var(--surface-alt); border:1px solid var(--border); border-radius:12px;
  padding:12px 16px;
}
.podium-place.podium-1{background:linear-gradient(90deg, var(--warning-light), var(--surface-alt)); border-color:var(--warning)}
.podium-medaille{font-size:24px; flex-shrink:0; width:28px; text-align:center}
.podium-prenom{font-weight:700; font-size:15px; flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.podium-prenom em{font-weight:600; font-style:normal; color:var(--text-muted); font-size:13px}
.podium-points{font-weight:800; color:var(--primary); flex-shrink:0}
.podium-place.podium-moi{outline:2px solid var(--primary); outline-offset:-1px}
.podium-vide{
  color:var(--text-muted); font-size:14px; text-align:center;
  padding:18px 12px; background:var(--surface-alt); border-radius:12px;
}

/* Extrait verrouillé dans l'assistant de révision (voir renderResults(),
   js/chatbot.js) : le résultat reste visible, seul le corps est écourté. */
.cbot-result-verrou{
  font-size:12.5px; color:var(--text-muted); margin-top:8px; padding-top:8px;
  border-top:1px dashed var(--border);
}

/* ===== Accueil : essai sans compte + comparatif d'accès =====
   Contrepartie visible du verrou (voir CHAPITRES_VITRINE, js/data/core.js) :
   ce que le visiteur peut faire tout de suite, et ce que le compte ajoute. */
/* Le hero est un aplat violet à texte blanc : la note doit s'y lire, donc pas
   de --text-muted (gris foncé, prévu pour un fond clair). */
.hero-note{font-size:13px; color:rgba(255,255,255,.82); margin:14px 0 0}

.essai-section{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:28px 26px; margin:26px 0;
}
.essai-head{max-width:640px; margin-bottom:20px}
.essai-tag{background:var(--success-light); color:var(--success-strong)}
.essai-head h2{font-size:22px; margin:12px 0 8px}
.essai-head p{color:var(--text-muted); font-size:14.5px; margin:0; line-height:1.6}
.essai-grid{grid-template-columns:repeat(auto-fit, minmax(230px,1fr))}
.essai-card{border-color:var(--success); border-width:1px}
.essai-matiere{
  display:inline-flex; align-items:center; gap:6px; font-size:12.5px; font-weight:600;
  color:var(--primary-accent); background:var(--primary-light);
  padding:4px 10px; border-radius:20px; margin-bottom:10px;
}
.essai-card h3{margin:0 0 4px}
/* subjectIcon() rend un SVG sans dimension propre : sans cette règle il occupe
   toute la largeur de la pastille (même piège que .chapter-header .tag svg). */
.essai-matiere svg{width:15px; height:15px; stroke:currentColor; flex-shrink:0}

.section-chapo{
  color:var(--text-muted); font-size:14.5px; line-height:1.65;
  max-width:640px; margin:-8px 0 20px;
}
.acces-compare{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(280px,1fr)); gap:18px; margin-bottom:8px;
}
.acces-col{
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); padding:24px 24px 26px;
}
.acces-col-compte{border-color:var(--primary); box-shadow:var(--shadow)}
.acces-col h3{display:flex; align-items:center; gap:9px; font-size:16px; margin:0 0 14px}
.acces-puce{
  display:inline-flex; align-items:center; justify-content:center;
  width:24px; height:24px; border-radius:50%; font-size:13px; flex:none;
}
.acces-puce-libre{background:var(--success-light); color:var(--success-strong)}
.acces-puce-compte{background:var(--primary-light); color:var(--primary-accent)}
.acces-col ul{margin:0; padding-left:20px; color:var(--text-muted); font-size:14px; line-height:1.6}
.acces-col li{margin-bottom:9px}
.acces-col li:last-child{margin-bottom:0}
.acces-cta{margin-top:18px; display:inline-block}

/* ============================================================
   MODE NUIT
   ============================================================
   Ce bloc ne redéfinit QUE des variables : aucune règle de mise en page, aucun
   sélecteur dupliqué. Une couleur qui manque ici est une couleur écrite en dur
   ailleurs — c'est le seul symptôme, et il ne se voit qu'à l'œil.

   Pas de @media (prefers-color-scheme) : js/app.js pose TOUJOURS un
   data-theme explicite sur <html> (choix mémorisé, sinon préférence système),
   et suit le système tant que l'élève n'a rien choisi. Un seul point de
   décision, comme accesLibre() pour le verrou — dupliquer la palette dans une
   media query en créerait un second, qui divergerait au premier oubli. */
:root[data-theme="dark"]{
  color-scheme: dark;
  --bg: #14101C;
  --surface: #1D1828;
  --surface-alt: #292136;
  --text: #EAE4F4;
  --text-muted: #A79BBC;
  --border: #372E48;
  /* L'aplat violet s'éclaircit (il doit ressortir sur un fond sombre), donc
     l'encre qui s'y pose s'assombrit : c'est tout le rôle de --on-primary. */
  --primary: #B79CF0;
  --primary-accent: #CFBEF8;
  --primary-hover: #C9B4F8;
  --primary-light: #312545;
  --on-primary: #1A1426;
  --on-danger: #2A1219;
  --success: #63C08D;
  --success-light: #1C3327;
  --success-border: #2C5340;
  --success-strong: #8FDBAF;
  --danger: #E48198;
  --danger-hover: #F0A0B2;
  --danger-light: #3A2229;
  --danger-strong: #F2A8B6;
  --warning: #DFB45E;
  --warning-light: #332A17;
  /* Le dégradé de marque reste sombre : c'est ce qui permet au texte blanc
     posé dessus (hero, assistant, bandeau programme) de ne pas changer. */
  --grad-a: #4E3D80;
  --grad-b: #7C4E86;
  --fade-from: rgba(29,24,40,0);
  --overlay: rgba(0,0,0,.66);
  /* Les ombres violettes du thème clair disparaissent sur fond sombre :
     on repasse au noir, plus marqué, sinon les cartes n'ont plus de relief. */
  --shadow: 0 2px 10px rgba(0,0,0,.45), 0 1px 2px rgba(0,0,0,.35);
  --shadow-lg: 0 12px 32px rgba(0,0,0,.55);
  --tag-qcm-bg:#332B52; --tag-qcm-fg:#C5BAF3;
  --tag-vf-bg:#3A2E1A;  --tag-vf-fg:#E6C288;
  --tag-exo-bg:#1C3327; --tag-exo-fg:#8FDBAF;
  --tag-ds-bg:#3A3018;  --tag-ds-fg:#EBCE8C;
  --tag-calcul-bg:#17392B; --tag-calcul-fg:#8FD9B6;
  --calcul-juste:#8FD9B6; --calcul-faux:#F0A99B;
  --tag-fiche-bg:#1C2E3D; --tag-fiche-fg:#9CC9E8;
  --android-bg:#123021; --android-fg:#7FD9A6;
  --mm1-fill:#332748; --mm1-stroke:#9F86D8; --mm1-text:#D8CAF6;
  --mm2-fill:#1F3B2C; --mm2-stroke:#5FAE84; --mm2-text:#ABE0C3;
  --mm3-fill:#1C3140; --mm3-stroke:#5E9BC4; --mm3-text:#ABD1EB;
  --mm4-fill:#3B222A; --mm4-stroke:#CE7A8C; --mm4-text:#F0B4C0;
  --mm5-fill:#312444; --mm5-stroke:#A57BD3; --mm5-text:#DCC3F3;
  --mm6-fill:#2A3320; --mm6-stroke:#96B45F; --mm6-text:#CDDDA7;
  --mm-cle-fill:#3A3018; --mm-cle-stroke:#D0A64E; --mm-cle-text:#F0D89C;
  --mm-feuille:#241E31;
}
