/* app.css — design system unique de Floop : tokens, composants, thèmes.
   ==========================================================================
   Tokens --a-* : aucune couleur en dur ailleurs dans le projet.
   Couleurs : le bleu et le jaune de l'Université de Fribourg. Le jaune est
   celui de la charte (Pantone 7406, RVB 238/194/9). Le bleu part du bleu nuit
   Unifr (Pantone 2768, RVB 10/56/89), rendu plus « royal » pour l'écran : même
   famille, plus lumineux, AA partout. Papier bleuté sous un soleil de rayons ;
   corail = signal, menthe = juste.
   ========================================================================== */
/* Les polices sont servies par floop.ch lui-même (fonts/, SIL OFL) : aucune requête
   vers Google — l'adresse IP d'un enfant ne quitte pas le site (nLPD) — et l'app
   reste identique hors de portée d'un CDN. Sous-ensemble latin (français, allemand,
   anglais, latin ; −, €, guillemets compris). Deux variables, une statique. */
@font-face{font-family:"Bricolage Grotesque"; font-style:normal; font-weight:200 800; font-display:swap;
  src:url(fonts/bricolage-grotesque.woff2) format("woff2")}       /* axes : graisse + taille optique */
@font-face{font-family:"Plus Jakarta Sans"; font-style:normal; font-weight:200 800; font-display:swap;
  src:url(fonts/plus-jakarta-sans.woff2) format("woff2")}
@font-face{font-family:"Plus Jakarta Sans"; font-style:italic; font-weight:200 800; font-display:swap;
  src:url(fonts/plus-jakarta-sans-italic.woff2) format("woff2")}
@font-face{font-family:"Fraunces"; font-style:normal; font-weight:400; font-display:swap; src:url(fonts/fraunces-400-normal.woff2) format("woff2")}
@font-face{font-family:"Fraunces"; font-style:normal; font-weight:600; font-display:swap; src:url(fonts/fraunces-600-normal.woff2) format("woff2")}
@font-face{font-family:"Fraunces"; font-style:italic; font-weight:400; font-display:swap; src:url(fonts/fraunces-400-italic.woff2) format("woff2")}

:root{
  /* ── Une seule encre pour tout Floop ──────────────────────────────────
     Sept teintes par matière donnaient un arc-en-ciel. L'identité tient
     désormais dans un seul bleu nuit (Unifr) ; c'est l'emoji du cours qui
     distingue les matières. Les autres couleurs ne servent qu'au SENS :
     vert = juste, corail = faux, ambre = à revoir. Jamais à décorer.      */
  --a-bg:#F2F5FA; --a-surface:#ffffff; --a-ink:#11212C; --a-soft:#495965; --a-muted:#5E6D78;   /* neutres teintés bleu, ≥ 4,5:1 (AA) */
  --a-line:#DCE3ED;

  --a-bleu:#1258BA;              /* bleu roi (famille Unifr) : boutons, liens    */
  --a-bleu-deep:#0B3D84;         /* titres et libellés                           */
  --a-bleu-soft:#E9F1FC;         /* fonds d'encadrés et pastilles (trame)        */
  --a-bleu-vif:#1269E2;          /* le même bleu, plus vif : barres, accents     */

  --a-mint-deep:#0F7466; --a-mint-soft:#E3F5F1;                         /* juste, terminé — AA sur blanc et sur menthe */
  --a-coral:#F26B5B; --a-coral-deep:#C93B2C; --a-coral-soft:#FDE9E6;   /* faux           */
  --a-cream:#FFF4D6; --a-yellow:#EEC209;        /* le jaune Unifr : mise en avant */
  /* Le soleil : 2ᵉ couleur de la marque (logo, niveau, année choisie).
     --a-sun pour les traits (plus dense en clair), texte toujours encre. */
  --a-sun:#EEC209; --a-on-sun:#11212C;
  --a-amber:#9A5A0C;                            /* à revoir — AA, texte compris */

  --a-r:18px; --a-r-lg:24px; --a-pill:999px; --a-tap:48px;
  /* Échelle d'espacement — une seule progression, partout. */
  --s1:.35rem; --s2:.6rem; --s3:1rem; --s4:1.5rem; --s5:2.25rem; --s6:3.25rem;
  /* Longueur de ligne confortable pour du texte suivi (~62 signes). */
  --mesure:34rem;
  /* Échelle typographique — sept crans, pas vingt-neuf. */
  --t-xs:.72rem; --t-sm:.85rem; --t-md:.95rem;
  --t-lg:1.1rem; --t-xl:1.4rem; --t-2xl:1.75rem;

  --a-shadow:0 1px 0 rgba(17,33,44,.04), 0 8px 28px -14px rgba(18,88,186,.26);
  --a-shadow-lg:0 1px 0 rgba(17,33,44,.06), 0 20px 44px -18px rgba(18,88,186,.36);
  --a-display:"Bricolage Grotesque",system-ui,sans-serif;
  --a-body:"Plus Jakarta Sans",system-ui,sans-serif;
  --a-accent:"Fraunces",Georgia,serif;
  --a-mono:ui-monospace,"Cascadia Code","SF Mono",Menlo,Consolas,monospace;
  /* L'accent courant : une seule valeur, pour toute l'app. */
  --c:var(--a-bleu);
  /* Texte posé SUR une pastille pleine. En mode sombre l'encre s'éclaircit,
     donc le texte doit s'assombrir — sans quoi blanc sur lavande = illisible. */
  --a-on-c:#ffffff;
  --ray:6%;                       /* intensité des rayons du fond */
  color-scheme:light;
}
:root[data-theme="dark"]{
  --a-bg:#0E151B; --a-surface:#19232A; --a-ink:#E8EEF3; --a-soft:#B8C3CC; --a-muted:#92A0AA;
  --a-line:#2D3A43;
  --a-bleu:#7BADF4;              /* le bleu roi éclairci : lisible sur fond sombre */
  --a-bleu-deep:#B4D0F9;
  --a-bleu-soft:#1C2F4A;
  --a-bleu-vif:#4C90F0;
  --a-mint-deep:#2AA893; --a-mint-soft:#18332F;
  --a-coral:#FF8878; --a-coral-deep:#FF6E5B; --a-coral-soft:#3A2224;
  --a-cream:#38301B; --a-yellow:#EEC209; --a-sun:#EEC209;
  --a-amber:#E0952B;
  --a-on-c:#0E151B;
  --a-shadow:0 1px 0 rgba(0,0,0,.3), 0 8px 28px -14px rgba(0,0,0,.65);
  --a-shadow-lg:0 1px 0 rgba(0,0,0,.4), 0 20px 44px -18px rgba(0,0,0,.75);
  --ray:13%;
  color-scheme:dark;
}

*,*::before,*::after{
  box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent;
  /* Glisser la souris ne surligne plus rien : sur un exercice, la sélection
     bleue est une distraction (et sur mobile elle ouvre le menu copier). */
  user-select:none; -webkit-user-select:none;
}
/* Deux exceptions : ce qu'on écrit, et ce qu'on lit pour de vrai. */
.field, .fiche{user-select:text; -webkit-user-select:text}
html{font-size:17px;-webkit-text-size-adjust:100%}
/* Le fond : un soleil de rayons fins qui part du haut de l'écran, comme
   une étoile, et s'efface vers le bas. Fixé : le contenu glisse dessus ;
   les panneaux restent opaques, la lecture n'est jamais gênée. */
body{
  font-family:var(--a-body); color:var(--a-ink);
  background:
    radial-gradient(120% 90% at 50% -8%, transparent 15%, var(--a-bg) 72%),
    repeating-conic-gradient(from 0deg at 50% -8%,
      color-mix(in srgb, var(--a-bleu) var(--ray), transparent) 0deg 3deg, transparent 3deg 10deg),
    var(--a-bg);
  background-attachment:fixed;
  line-height:1.65; min-height:100dvh; display:flex; flex-direction:column;
  text-rendering:optimizeLegibility;
}
em{font-family:var(--a-accent);font-style:italic}
strong{font-weight:700}
.hidden{display:none!important}

/* ── Chrome ───────────────────────────────────────────────────────────── */
.topbar{
  position:sticky; top:0; z-index:20;
  padding:calc(var(--s2) + env(safe-area-inset-top)) var(--s4) var(--s2);
  background:color-mix(in srgb,var(--a-surface) 82%,transparent);
  backdrop-filter:saturate(1.4) blur(14px); -webkit-backdrop-filter:saturate(1.4) blur(14px);
  border-top:3px solid var(--a-bleu);                 /* le filet bleu : la signature, une fois */
  box-shadow:0 1px 0 var(--a-line), 0 10px 24px -20px rgba(18,88,186,.45);
}
/* Même hauteur partout : la marque sur deux lignes à l'accueil, ailleurs
   « où l'on est » en petit au-dessus du titre de l'écran. */
.topbar-in{display:flex; align-items:center; gap:var(--s2); width:100%; max-width:720px; margin:0 auto; min-height:3.1rem}
.topbar h1{
  flex:1; min-width:0; margin:0; display:flex; flex-direction:column; justify-content:center; gap:.15rem;
  font-family:var(--a-display); font-size:1.3rem; font-weight:750; letter-spacing:-.025em; line-height:1.1;
}
.topbar h1.home{gap:.3rem; line-height:1}
.topbar h1 .t, .topbar h1 .ctx{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.topbar h1 .t{padding-bottom:.08em}
.topbar h1 .ctx{font-family:var(--a-body); font-weight:600; font-size:var(--t-xs); letter-spacing:0; color:var(--a-bleu)}
/* Le retour : un chevron net dans une pastille, qui recule d'un pas au survol. */
#back{
  width:40px; height:40px; padding:0; margin-right:var(--s1);
  background:var(--a-surface); border:1px solid var(--a-line); color:var(--a-ink);
}
/* Le thème, même pastille que le retour : les deux commandes rondes se répondent. */
#theme{width:40px; height:40px; padding:0; background:var(--a-surface); border:1px solid var(--a-line); color:var(--a-soft)}
#back .ico{width:22px; height:22px; stroke-width:2.3; transition:transform .15s}
@media (hover:hover){#back:hover{background:var(--a-bleu-soft); border-color:transparent; color:var(--a-bleu-deep)}
                     #back:hover .ico{transform:translateX(-2px)}}
#back:active{transform:scale(.94)}
.brand{
  display:inline-flex; align-items:baseline; font-family:var(--a-display); font-weight:800;
  font-size:2rem; letter-spacing:-.05em; line-height:.8; color:var(--a-ink);
}
.brand .loop{
  height:.58em; width:auto; margin:0 .02em 0 .03em; overflow:visible;
  fill:none; stroke-width:4.2;
}
.brand .loop circle, .brand .loop path{stroke:var(--a-ink)}
.brand .loop circle + circle{stroke:var(--a-sun)}   /* le 2ᵉ anneau passe dessous en bas : ils s'enlacent */
.tagline{
  font-family:var(--a-body); font-weight:500; font-size:var(--t-xs); letter-spacing:0;
  color:var(--a-muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  line-height:1.3;
}
.icon-btn{
  height:38px; min-width:38px; padding:0 .55rem; border-radius:var(--a-pill);
  border:1px solid transparent; background:transparent; color:var(--a-soft);
  font-size:var(--t-md); cursor:pointer; display:inline-flex; align-items:center;
  justify-content:center; gap:.35rem; flex:none; font-family:inherit;
  transition:background .15s, color .15s;
}
@media (hover:hover){.icon-btn:hover{background:var(--a-bleu-soft); color:var(--a-bleu-deep)}}
/* Le profil est le seul bouton « plein » : c'est le repère de l'enfant. */
#who{
  background:var(--a-bleu-soft); color:var(--a-bleu-deep);
  font-family:var(--a-display); font-weight:700; font-size:var(--t-sm); padding:0 .85rem;
}
/* Téléphone : le profil se réduit à son avatar (le prénom est sur la carte
   de l'élève) et le titre descend d'un cran — il a enfin la place d'exister. */
@media (max-width:520px){
  #who{padding:0; width:42px} #who > span:not(.av){display:none}
  .topbar h1:not(.home){font-size:var(--t-lg)}
}
main{flex:1;width:100%;max-width:720px;margin:0 auto;
     padding:var(--s4) var(--s3) calc(var(--s6) + env(safe-area-inset-bottom))}
.foot{text-align:center;color:var(--a-muted);font-size:var(--t-xs);padding:var(--s2) 0 var(--s4)}

.icon-btn .ico{width:20px; height:20px}
#who .ico{width:18px; height:18px}
.btn .ico{width:18px; height:18px; margin-right:.1rem; vertical-align:-.2rem}

/* ── Utilitaires de composition ───────────────────────────────────────── */
.center{text-align:center}
.scroll{overflow-x:auto}
.actions.narrow{width:100%;max-width:400px}
.actions.narrow .btn{white-space:nowrap; padding:0 .9rem}
.panel .btn{display:inline-flex;align-items:center;justify-content:center;gap:.35rem}

/* ── Boutons ──────────────────────────────────────────────────────────── */
.btn{
  border:0;border-radius:var(--a-pill);min-height:var(--a-tap);padding:0 1.3rem;
  font-family:var(--a-display);font-weight:700;font-size:var(--t-md);cursor:pointer;
  background:var(--a-bleu);color:var(--a-on-c);transition:transform .1s,filter .15s;
}
.btn:active{transform:scale(.97)}
@media (hover:hover){.btn:hover{filter:brightness(1.07)}}
.btn:disabled{opacity:.4;pointer-events:none}
.btn.wide{width:100%}
.btn.ghost{background:var(--a-surface);color:var(--a-ink);border:1.5px solid var(--a-line)}
.btn.ok{background:var(--a-mint-deep)}
.btn.no{background:var(--a-coral-deep)}
.actions{display:flex;gap:var(--s2);margin-top:var(--s2)}
.actions .btn{flex:1}

.empty{text-align:center;color:var(--a-muted);padding:2.5rem var(--s3);line-height:1.7}
.q code,.focus code{font-size:.82em;font-weight:600;background:var(--a-bleu-soft);color:inherit;padding:.02em .3em}
code{font-family:var(--a-mono);background:var(--a-line);border-radius:5px;padding:.05rem var(--s1);font-size:.9em}


/* ── Barre de progression ─────────────────────────────────────────────── */
.meter{height:8px;background:var(--a-line);border-radius:var(--a-pill);overflow:hidden}
.meter i{display:block;height:100%;border-radius:var(--a-pill);
  background:linear-gradient(90deg,var(--c),color-mix(in srgb,var(--c) 55%,var(--a-surface)));
  transition:width .45s ease}
.meter-label{font-size:var(--t-xs);color:var(--a-muted);margin-top:.3rem}

/* Drapeaux vectoriels : Windows n'a pas de police d'emoji-drapeaux. */
.flag{
  display:inline-block; width:2rem; height:1.35rem; flex:none;
  border-radius:4px; overflow:hidden;
  vertical-align:-.2rem;
}
.flag svg{display:block; width:100%; height:100%}
.eyebrow .flag{width:1.35rem; height:.9rem; vertical-align:-.1rem; margin-right:.2rem}

/* ── La carte de l'élève : avatar, objectif du jour, niveau ──────────────
   L'avatar est cerclé par l'objectif du jour : l'anneau se remplit à
   mesure qu'on apprend. Sous le niveau, ce qui manque pour le suivant —
   un but proche et chiffré motive plus qu'un total.                     */
.hud{
  display:flex; align-items:center; gap:var(--s4);
  background:var(--a-surface);
  border:1px solid var(--a-line); border-radius:var(--a-r-lg); box-shadow:var(--a-shadow);
  padding:var(--s3) var(--s4); margin-bottom:var(--s5);
}
.hud-bar{flex:1; min-width:0; display:grid; gap:.35rem}
.hud-line{display:flex; align-items:center; justify-content:space-between; gap:var(--s2)}
.hud-line b{font-family:var(--a-display); font-weight:800; font-size:var(--t-xl); letter-spacing:-.03em; line-height:1.15;
            overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.hud-streak{
  flex:none; display:inline-flex; align-items:center; gap:.2rem; padding:.15rem .6rem .15rem .45rem;
  border-radius:var(--a-pill); color:var(--a-amber); background:color-mix(in srgb, var(--a-amber) 14%, transparent);
}
.hud-streak .ico{width:18px; height:18px}
.hud-streak b{font-family:var(--a-display); font-weight:800; font-size:var(--t-sm)}
.hud-level{display:grid; grid-template-columns:auto 1fr; align-items:center; gap:.2rem var(--s2)}
.lvl{
  font-family:var(--a-display); font-weight:800; font-size:var(--t-xs); white-space:nowrap;
  padding:.15rem .6rem; border-radius:var(--a-pill); background:var(--a-yellow); color:var(--a-on-sun);
}
.hud-xp{grid-column:2; justify-self:end; font-size:var(--t-xs); color:var(--a-muted); font-variant-numeric:tabular-nums}

/* ── Objectif du jour : l'anneau autour de l'avatar ───────────────────── */
.goal{
  --p:0deg; position:relative; flex:none; width:68px; height:68px; border-radius:50%;
  display:grid; place-items:center; border:0; padding:0; cursor:pointer; font:inherit;
  transition:transform .15s;
  background:conic-gradient(var(--c) var(--p), var(--a-line) 0);
}
.goal span{
  width:56px; height:56px; border-radius:50%; background:var(--a-surface); display:grid; place-items:center;
  font-family:var(--a-display); font-weight:800; font-size:1.75rem; line-height:1; color:var(--c);
}
.goal.reached{background:var(--a-mint-deep)}
.goal:active{transform:scale(.95)}
@media (hover:hover){.goal:hover{transform:scale(1.05) rotate(-3deg)}}
/* Pas encore d'avatar : une silhouette et un « + » qui invite à en choisir un. */
.goal span .ico{width:28px; height:28px; color:var(--a-muted)}
.goal-add{
  position:absolute; right:-2px; top:-2px; width:22px; height:22px; border-radius:50%;
  display:grid; place-items:center; font-style:normal; font-weight:800; font-size:var(--t-sm); line-height:1;
  background:var(--a-yellow); color:var(--a-on-sun); box-shadow:0 0 0 3px var(--a-surface);
}
.goal.reached::after{                /* le macaron « fait » posé sur l'anneau */
  content:'✓'; position:absolute; right:-3px; bottom:-3px; width:24px; height:24px; border-radius:50%;
  display:grid; place-items:center; font-weight:800; font-size:var(--t-xs);
  background:var(--a-mint-deep); color:var(--a-on-c); box-shadow:0 0 0 3px var(--a-surface);
}
@media (max-width:520px){
  .hud{gap:var(--s3); padding:var(--s3)}
  .goal{width:60px; height:60px} .goal span{width:49px; height:49px; font-size:1.5rem}
  .hud-line b{font-size:var(--t-lg)}
}

/* ── Accueil : un panneau par matière, une ligne par cours ─────────────
   Le drapeau vit en tête de panneau, pas sur chaque ligne. Sur grand
   écran, les panneaux se rangent sur deux colonnes (flux vertical), sans
   trou sous les matières à un seul cours.                             */
/* L'année : une seule ligne de pastilles, qui défile si l'écran est étroit. */
.chips.years{margin:0 0 var(--s4); flex-wrap:nowrap; gap:.2rem; overflow-x:auto; scrollbar-width:none}
.years .chip.on{background:var(--a-yellow); border-color:var(--a-yellow); color:var(--a-on-sun)}
.years .chip{flex:none; font-family:var(--a-display); font-weight:700; padding:.4rem .5rem; min-width:2.3rem}
.subjects{columns:2 19rem; column-gap:var(--s4)}
.subject{
  break-inside:avoid; margin:0 0 var(--s4); overflow:hidden;
  background:var(--a-surface); border:1px solid var(--a-line);
  border-radius:var(--a-r-lg); box-shadow:var(--a-shadow);
}
.subject-head{display:flex; align-items:center; gap:var(--s2); padding:var(--s3) var(--s3) var(--s2)}
.subject-head h2{
  font-family:var(--a-display); font-weight:800; font-size:var(--t-lg);
  letter-spacing:-.02em; flex:1;
}
.subject-head .emo{font-size:var(--t-lg); line-height:1}
.subject-n{color:var(--a-muted); font-size:var(--t-xs); font-variant-numeric:tabular-nums}
.courses{display:flex; flex-direction:column}
.course{
  display:flex; align-items:center; gap:var(--s3); width:100%; text-align:left; cursor:pointer;
  padding:.7rem var(--s3); border:0; border-top:1px solid var(--a-line);
  background:transparent; font-family:inherit; color:inherit; transition:background .15s;
}
.course:active{background:var(--a-bleu-soft)}
@media (hover:hover){.course:hover{background:var(--a-bleu-soft)}}
.course-t{flex:1; min-width:0}
.course-p{flex:none; display:flex; align-items:center; gap:var(--s2)}
.course-n{font-family:var(--a-display); font-weight:800; font-size:var(--t-md); line-height:1;
          font-variant-numeric:tabular-nums; min-width:2.9rem; text-align:right}
.course-n small{font-weight:600; font-size:var(--t-xs); color:var(--a-muted)}
.course-p .meter{width:3.2rem; height:6px}
.course.full .course-n{color:var(--a-mint-deep)}
.course.full .meter i{background:var(--a-mint-deep)}

/* Titre + sous-titre italique : le même couple pour un cours et une fiche. */
.course .name, .sheet .name{font-family:var(--a-display); font-weight:700; font-size:var(--t-md);
                            letter-spacing:-.01em; display:block}
.course .sub, .sheet .sub{font-family:var(--a-accent); font-style:italic; color:var(--a-soft);
                          font-size:var(--t-xs); display:block; margin-top:.1rem}

/* ── Autres plateformes : une ligne discrète sous le bandeau ─────────── */
.elsewhere{                     /* en pied d'accueil, discret : d'autres plateformes, pas Floop */
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:var(--s1);
  margin:var(--s5) 0 0; font-size:var(--t-xs); color:var(--a-muted);
}
.elsewhere a{display:inline-flex; align-items:center; gap:.2rem; color:var(--a-soft); text-decoration:none; font-weight:600;
  border-bottom:1px solid var(--a-line)}
@media (hover:hover){.elsewhere a:hover{color:var(--a-bleu-deep); border-color:currentColor}}
.elsewhere a span{color:var(--a-muted); font-size:.9em}

/* ── Reprendre : la prochaine leçon du dernier cours ouvert ──────────── */
.resume{
  width:100%;display:flex;align-items:center;gap:var(--s3);text-align:left;cursor:pointer;
  margin:0 0 var(--s5);padding:var(--s3) var(--s4);border:0;border-radius:var(--a-r-lg);
  background:var(--c);color:var(--a-on-c);font-family:inherit;box-shadow:var(--a-shadow-lg);
  transition:transform .12s;
}
.resume:active{transform:scale(.98)}
.resumes{display:grid; gap:var(--s2); margin:0 0 var(--s5)}
.resumes .resume{margin:0}
.resume.revoir{background:var(--a-surface); color:var(--a-ink); box-shadow:var(--a-shadow); border:1.5px solid var(--a-line)}
.resume.revoir .ico{color:var(--c)}
.resume .ico{width:28px;height:28px;flex:none}
.resume b{display:block;font-family:var(--a-display);font-size:var(--t-lg)}
.resume .sub{font-size:var(--t-sm);opacity:.85}

/* ── Fiches d'un cours : de petites cartes, à côté du chemin ─────────── */
.grid{display:grid; gap:var(--s3)}
@media (min-width:400px){.grid{grid-template-columns:1fr 1fr}}
.sheet{
  display:flex; flex-direction:column; width:100%; text-align:left; cursor:pointer;   /* un <button> centre son contenu */
  padding:.8rem var(--s3); background:var(--a-surface); border:1px solid var(--a-line);
  border-radius:var(--a-r-lg); box-shadow:var(--a-shadow); font-family:inherit; color:inherit;
  transition:transform .12s, box-shadow .2s;
}
.sheet:active{transform:scale(.985)}
@media (hover:hover){.sheet:hover{transform:translateY(-2px); box-shadow:var(--a-shadow-lg)}}

/* ── Le chemin : un fil continu traverse tout le cours ─────────────────
   Les unités ne sont pas des îlots : elles se suivent. Un trait vertical
   unique relie les numéros d'unité du haut du cours jusqu'au bas, et les
   leçons s'y accrochent. Le numéro encode l'ordre, qui est réel ici :
   une unité ne s'ouvre qu'après la précédente.                          */
.unit{position:relative; padding-left:3.1rem; margin:var(--s6) 0 0}
.unit:first-of-type{margin-top:var(--s5)}
.unit::before{                       /* le fil, prolongé jusqu'à l'unité suivante */
  content:''; position:absolute; left:1.05rem; top:1.6rem;
  bottom:calc(-1 * var(--s6)); width:2px;
  background:linear-gradient(var(--a-line), var(--a-line));
}
.unit:last-of-type::before{bottom:1.2rem}

.unit-head{display:flex; align-items:center; gap:var(--s3); margin-bottom:var(--s4)}
.unit-head .n{                       /* la pastille est posée SUR le fil */
  position:absolute; left:0; width:2.2rem; height:2.2rem; border-radius:var(--a-pill);
  display:grid; place-items:center; background:var(--c); color:var(--a-on-c);
  font-family:var(--a-display); font-weight:800; font-size:var(--t-md);
  box-shadow:0 0 0 5px var(--a-bg);   /* le fil ne traverse pas la pastille */
}
.unit-head h3{
  font-family:var(--a-display); font-weight:700; font-size:var(--t-lg); flex:1;
  letter-spacing:-.01em; line-height:1.3;
}
/* Le mot « Unité » n'est plus écrit : le chiffre dans le disque le dit.
   Il reste lu par les lecteurs d'écran, pour qui « 1 » seul serait obscur. */
.sr{position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap}
/* Surtitre — désormais réservé à l'en-tête d'une fiche, où il nomme le cours
   d'appartenance. Ni les unités ni le bloc Fiches n'en ont besoin : leur titre
   se suffit. */
.eyebrow{
  display:block; font-family:var(--a-display); font-weight:700; font-size:var(--t-xs);
  letter-spacing:.1em; text-transform:uppercase; color:var(--a-muted); margin-bottom:.1rem;
}
.path{display:flex; flex-direction:column; gap:var(--s2)}
.node{display:flex; align-items:center; gap:var(--s2); position:relative}
.node::before{                       /* la petite amarre qui relie la carte au fil */
  content:''; position:absolute; left:-2.05rem; width:1.35rem; height:2px;
  background:var(--a-line);
}
.lesson{
  display:flex; align-items:center; gap:var(--s3); width:100%; text-align:left; flex:1;
  background:var(--a-surface); border:1px solid var(--a-line); border-radius:var(--a-r);
  padding:var(--s3); cursor:pointer; font-family:inherit; color:inherit;
  transition:transform .12s, box-shadow .2s; box-shadow:var(--a-shadow);
}
.lesson:active{transform:scale(.99)}
@media (hover:hover){.lesson:not(:disabled):hover{transform:translateX(3px)}}
.lesson:disabled{opacity:.55; cursor:not-allowed; box-shadow:none}
.lesson .dot{
  width:2rem; height:2rem; border-radius:var(--a-pill); flex:none;
  display:grid; place-items:center; font-size:var(--t-sm); font-weight:700;
  background:var(--a-bleu-soft); color:var(--a-bleu-deep); font-family:var(--a-display);
}
.lesson.done .dot{background:var(--a-mint-deep); color:var(--a-on-c)}
.lesson.next{border:2px solid var(--c); box-shadow:var(--a-shadow-lg)}
.lesson.next .dot{background:var(--c); color:var(--a-on-c)}
.lesson.next .stars::after{        /* « c'est ici » : on sait toujours où reprendre */
  content:'À toi !'; font-family:var(--a-display); font-weight:700; font-size:var(--t-xs); letter-spacing:0;
  padding:.2rem .6rem; border-radius:var(--a-pill); background:var(--a-yellow); color:var(--a-on-sun);
}
.lesson.locked .dot{background:var(--a-line); color:var(--a-muted)}
.lesson .t{flex:1; min-width:0}
.lesson .t b{font-family:var(--a-display); font-weight:600; font-size:var(--t-md); display:block}
.lesson .t span{color:var(--a-muted); font-size:var(--t-xs); display:block; margin-top:.1rem}
.lesson .stars{font-size:var(--t-sm); letter-spacing:.05em; flex:none}

/* Les fiches ne font pas partie du chemin : elles vivent à côté. */
.sheets{margin:var(--s6) 0 0; padding-bottom:var(--s5); border-bottom:1px solid var(--a-line)}
.sheets h3{font-family:var(--a-display); font-weight:700; font-size:var(--t-lg); margin-bottom:var(--s3)}

@media (max-width:520px){
  .unit{padding-left:2.6rem}
  .unit::before{left:.85rem}
  .unit-head .n{width:1.9rem; height:1.9rem}
  .node::before{left:-1.75rem; width:1.15rem}
}
.lesson .cool{display:inline-flex; margin-left:.25rem; color:var(--a-amber)}
.lesson .cool .ico{width:16px; height:16px}
.lesson .dot .ico{width:17px; height:17px}

/* ── Bouton ↺ à côté d'une leçon terminée ─────────────────────────────── */
.icon-btn.tiny{width:32px;height:32px;font-size:var(--t-sm);color:var(--a-muted)}
@media (hover:hover){.icon-btn.tiny:hover{color:var(--a-coral);border-color:var(--a-coral)}}

/* ── Contrôle d'unité : le dernier nœud du fil ────────────────────────── */
.lesson.test .dot{background:var(--a-cream); color:var(--a-ink); font-size:var(--t-md)}
.lesson.test.locked .dot{background:var(--a-line)}
.lesson.test b{font-family:var(--a-display)}

/* ── En-tête d'un cours : l'emblème, le titre entier, l'avancement ───── */
.course-head{
  display:flex; align-items:center; gap:var(--s4); margin-bottom:var(--s5); padding:var(--s4);
  background:var(--a-surface);
  border:1px solid var(--a-line); border-radius:var(--a-r-lg); box-shadow:var(--a-shadow);
}
.course-head > .emo{font-size:2.6rem; line-height:1; flex:none}
.course-head > .flag{width:3.2rem; height:2.15rem; border-radius:6px}
.ch-t{flex:1; min-width:0}
.ch-t h2{font-family:var(--a-display); font-weight:800; font-size:var(--t-xl); letter-spacing:-.03em; line-height:1.15}
.ch-t .sub{font-family:var(--a-accent); font-style:italic; color:var(--a-soft); font-size:var(--t-sm)}
.ch-p{display:flex; align-items:center; gap:var(--s2); margin-top:var(--s2)}
.ch-p .meter{flex:1}
.ch-p span{font-size:var(--t-xs); color:var(--a-muted); white-space:nowrap; font-variant-numeric:tabular-nums}

/* ── Accès rapides (drill) ────────────────────────────────────────────── */
.quick{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s3);margin:0 0 var(--s5)}
@media (max-width:520px){.quick{gap:var(--s2)} .tile{padding:var(--s3) var(--s1)} .tile b{font-size:.8rem; white-space:nowrap} .tile .sub{font-size:.66rem; text-align:center; line-height:1.3}}
.tile{
  background:var(--a-surface);border:1px solid var(--a-line);border-radius:var(--a-r-lg);
  box-shadow:var(--a-shadow);padding:var(--s4) var(--s3);cursor:pointer;font-family:inherit;color:inherit;
  display:flex;flex-direction:column;align-items:center;gap:var(--s1);transition:transform .12s;
}
.tile:active{transform:scale(.97)}
@media (hover:hover){.tile:not(.off):hover{transform:translateY(-2px)}}
.tile.off{opacity:.45;cursor:default}
/* Les icônes des accès rapides : au trait, dans l'encre — pas d'emoji,
   dont le rendu varie trop d'un système à l'autre. */
.tile .ico{width:26px; height:26px; color:var(--c); margin-bottom:.15rem}
.tile.off .ico{color:var(--a-muted)}
.tile b{font-family:var(--a-display);font-size:var(--t-md)}
.tile .sub{font-family:var(--a-accent);font-style:italic;color:var(--a-muted);font-size:var(--t-xs)}

/* ── Écran de leçon ───────────────────────────────────────────────────── */
.lesson-top{display:flex;align-items:center;gap:var(--s3);margin-bottom:var(--s2)}
.lesson-top .meter{flex:1; overflow:visible}
.lesson-top .meter i{position:relative; min-width:6px}
.lesson-top .meter i::after{       /* la tête de la barre : on voit avancer */
  content:''; position:absolute; right:-5px; top:50%; width:14px; height:14px; border-radius:50%;
  transform:translateY(-50%); background:var(--c);
  box-shadow:0 0 0 4px color-mix(in srgb, var(--c) 22%, transparent);
}
.combo{
  flex:none; font-family:var(--a-display); font-weight:800; font-size:var(--t-xs); white-space:nowrap;
  padding:.2rem .6rem; border-radius:var(--a-pill); color:var(--a-amber);
  background:color-mix(in srgb, var(--a-amber) 14%, transparent);
}
.combo i{display:inline-block; font-style:normal}
.step{
  background:var(--a-surface);border:1px solid var(--a-line);border-radius:var(--a-r-lg);
  box-shadow:var(--a-shadow);overflow:hidden;margin-bottom:var(--s4);
}
.step-head{
  padding:var(--s2) var(--s4);background:var(--c);color:var(--a-on-c);
  font-family:var(--a-display);font-weight:700;font-size:var(--t-sm);letter-spacing:.06em;
}
.step-body{padding:var(--s5) var(--s4) var(--s4)}
.step-body > * + *{margin-top:var(--s4)}
/* le texte suivi ne dépasse jamais la mesure de lecture confortable */
.step-body .rule, .step-body .tip, .step-body .warn,
.step-body .exs, .step-body table{max-width:var(--mesure);margin-inline:auto}

/* contenu pédagogique */
.q{font-family:var(--a-display);font-weight:700;font-size:var(--t-lg);text-align:center;
   line-height:1.35;letter-spacing:-.01em;max-width:var(--mesure);margin-inline:auto}
.focus{
  font-family:var(--a-display);font-weight:800;font-size:clamp(1.5rem,6vw,2.1rem);
  color:var(--c);text-align:center;line-height:1.255;overflow-wrap:anywhere;
}
.prompt{color:var(--a-soft);text-align:center;font-family:var(--a-accent);font-style:italic;
        font-size:var(--t-md)}
.answer{font-family:var(--a-display);font-weight:800;font-size:var(--t-xl);text-align:center}
.rule{
  background:var(--a-bleu-soft);border-radius:14px;padding:var(--s3) var(--s4);
  font-size:var(--t-md);line-height:1.7;
}
.rule .lbl{
  display:block;font-family:var(--a-display);font-weight:700;font-size:var(--t-xs);
  letter-spacing:.09em;text-transform:uppercase;color:var(--a-bleu-deep);margin-bottom:.25rem;
}
.tip{background:var(--a-cream);border-radius:14px;padding:var(--s3) var(--s4);font-size:var(--t-md);line-height:1.65}
.warn{background:var(--a-coral-soft);border-radius:14px;padding:var(--s3) var(--s4);font-size:var(--t-md);line-height:1.65}
.exs{list-style:none;display:grid;gap:var(--s2)}
.exs li{padding-left:1.2rem;position:relative;font-size:var(--t-md);line-height:1.6}
.exs li::before{content:"›";position:absolute;left:0;color:var(--c);font-weight:700}
table{width:100%;border-collapse:collapse;font-size:var(--t-sm)}
th{
  font-family:var(--a-display);font-weight:700;font-size:var(--t-xs);letter-spacing:.07em;
  text-transform:uppercase;color:var(--a-bleu-deep);text-align:left;
  padding:var(--s2) var(--s2) var(--s1);border-bottom:2px solid var(--a-bleu-soft);
}
td{padding:var(--s2);border-bottom:1px solid var(--a-line);line-height:1.5}
tr:last-child td{border-bottom:none}
td:first-child{font-family:var(--a-display);font-weight:600}
mark{background:var(--a-cream);border-radius:5px;padding:0 .25rem;color:inherit}
.blank{
  background:color-mix(in srgb,var(--c) 16%,transparent);
  border-bottom:2px solid var(--c);border-radius:5px;
  padding:0 var(--s2);color:transparent;
}
.blank.on{color:var(--c);font-weight:700}
.speak{
  border:0; background:color-mix(in srgb,var(--c) 12%, transparent); color:var(--c);
  border-radius:var(--a-pill); width:42px; height:42px; cursor:pointer; flex:none;
  display:inline-grid; place-items:center; transition:background .15s, transform .1s;
}
.speak:active{transform:scale(.94)}
@media (hover:hover){.speak:hover{background:color-mix(in srgb,var(--c) 22%, transparent)}}
.speak .ico{width:22px; height:22px}
.verdict .speak{width:34px; height:34px; vertical-align:-.55rem; margin-left:.25rem}
.verdict .speak .ico{width:18px; height:18px}
.row{display:flex;align-items:center;gap:var(--s2);justify-content:center;flex-wrap:wrap}

/* choix multiples */
.choices{display:grid;gap:var(--s2)}
@media (min-width:560px){.choices.two{grid-template-columns:1fr 1fr}}
.choice{
  border:2px solid var(--a-line);background:var(--a-surface);color:var(--a-ink);
  border-radius:var(--a-pill);min-height:56px;padding:var(--s2) var(--s4);
  font-family:var(--a-body);font-weight:700;font-size:var(--t-lg);cursor:pointer;text-align:center;
  transition:transform .1s, border-color .15s, background .15s;
}
@media (hover:hover){.choice:not(:disabled):hover{border-color:var(--c); background:var(--a-bleu-soft)}}
.choice:active{transform:scale(.97)}
.choice.good{animation:bump .35s ease}
.choice.good{background:var(--a-mint-deep);border-color:var(--a-mint-deep);color:var(--a-on-c)}
.choice.bad{background:var(--a-coral-deep);border-color:var(--a-coral-deep);color:var(--a-on-c)}
.choice:disabled{cursor:default}

/* remise en ordre */
.slotbar{
  min-height:52px;border:2px dashed var(--a-line);border-radius:14px;
  padding:.4rem;display:flex;gap:.4rem;flex-wrap:wrap;align-items:center;
}
.bank{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:.6rem}
.tok{
  border:1.5px solid var(--a-line);background:var(--a-surface);color:var(--a-ink);
  border-radius:12px;padding:.45rem .8rem;font-family:var(--a-body);font-weight:600;
  font-size:var(--t-md);cursor:pointer;
}
.tok:active{transform:scale(.96)}
.tok.used{opacity:.25;pointer-events:none}

/* saisie */
.field{
  width:100%;border:1.5px solid var(--a-line);border-radius:14px;background:var(--a-bg);
  color:var(--a-ink);font-family:var(--a-body);font-size:var(--t-lg);padding:.8rem var(--s3);
  text-align:center;
}
.field:focus{outline:0;border-color:var(--a-bleu)}

/* verdict */
.verdict{
  border-radius:14px;padding:.8rem var(--s3);font-size:var(--t-md);
  display:flex;gap:var(--s2);align-items:flex-start;
}
.verdict.good{background:var(--a-mint-soft)}
.verdict.bad{background:var(--a-coral-soft)}
.verdict b{font-family:var(--a-display)}
.verdict .mascotte{flex:none; margin-top:-.2rem}
.v-titre{font-size:var(--t-lg)}
.verdict.good .v-titre{color:var(--a-mint-deep)}
.v-gain{display:inline-block; margin-left:.3rem; padding:.05rem .55rem; border-radius:var(--a-pill);
  background:var(--a-yellow); color:var(--a-on-sun); font:800 var(--t-xs)/1.6 var(--a-display); vertical-align:.15rem}
.verdict .why{
  display:inline-block;margin-top:var(--s1);
  font-family:var(--a-accent);font-style:italic;color:var(--a-soft);font-size:var(--t-md);
}

/* ── Fin de leçon ─────────────────────────────────────────────────────── */
.finish{text-align:center;display:grid;gap:var(--s2);justify-items:center;padding:1.6rem var(--s2)}
.finish .stars{font-size:2.8rem;letter-spacing:.1em;}
.finish h2{font-family:var(--a-display);font-size:var(--t-xl)}
.finish .stat{color:var(--a-soft)}
.finish .xp{font-family:var(--a-display);font-weight:800;color:var(--a-mint-deep);font-size:var(--t-lg)}
.finish .hint{max-width:28rem; font-family:var(--a-accent); font-style:italic; font-size:var(--t-sm)}
.levelup{
  font-family:var(--a-display); font-weight:800; font-size:var(--t-lg); color:var(--a-on-c);
  padding:.4rem 1.1rem; border-radius:var(--a-pill);
  background:linear-gradient(90deg, var(--a-bleu), var(--a-bleu-vif));
  box-shadow:var(--a-shadow-lg);
}
/* ── Fiches libres : document lisible d'un trait, imprimable ──────────── */
.fiche{
  background:var(--a-surface);border:1px solid var(--a-line);border-radius:var(--a-r-lg);
  box-shadow:var(--a-shadow);padding:var(--s5) var(--s4);margin-bottom:var(--s4);
  line-height:1.7;
}
.fiche-h{border-bottom:2px solid var(--a-bleu-soft);padding-bottom:var(--s3);margin-bottom:var(--s5)}
.fiche-h .eyebrow{
  font-family:var(--a-display);font-weight:700;font-size:var(--t-xs);letter-spacing:.09em;
  text-transform:uppercase;color:var(--c);
}
.fiche-h h2{font-family:var(--a-display);font-size:var(--t-2xl);letter-spacing:-.025em;line-height:1.12;margin-top:var(--s1)}
.fsec{margin-bottom:var(--s5)}
.fsec-h{
  font-family:var(--a-display);font-weight:700;font-size:var(--t-lg);margin-bottom:var(--s3);
  padding-left:var(--s2);border-left:3px solid var(--c);
  letter-spacing:-.01em;
}
.fsec-b > * + *{margin-top:var(--s3)}
.fsec-b .exs li{line-height:1.7}
.fiche-f{
  font-family:var(--a-accent);font-style:italic;color:var(--c);
  text-align:center;margin-top:var(--s6);padding-top:var(--s4);
  border-top:1px solid var(--a-line);
}
.hero-t{font-family:var(--a-display);font-weight:800;font-size:var(--t-lg);color:var(--c)}
.hero-x{color:var(--a-soft);margin-top:.3rem}
.formula{display:flex;gap:.4rem;align-items:center;flex-wrap:wrap;margin-top:.8rem}
.fblock{
  background:var(--a-bleu-soft);border-radius:11px;padding:var(--s2) var(--s3);text-align:center;flex:1;
  min-width:5rem;display:flex;flex-direction:column;
}
.fblock.key{box-shadow:0 0 0 2px var(--a-yellow)}
.fblock b{font-family:var(--a-display);font-size:var(--t-sm)}
.fblock i{font-family:var(--a-accent);font-size:var(--t-xs);color:var(--a-soft)}
.plus{color:var(--a-muted);font-weight:700}
.contrast{
  display:grid;grid-template-columns:1fr auto 1fr;gap:var(--s4);
  background:var(--a-bg);border:1px solid var(--a-line);border-radius:14px;padding:var(--s4);
}
@media (max-width:520px){
  .contrast{grid-template-columns:1fr;gap:var(--s3)}
  .contrast .cr{width:auto;height:1px}
}
.contrast .cr{width:1px;background:var(--a-line)}
.contrast .cl{
  display:block;font-family:var(--a-display);font-weight:700;font-size:var(--t-xs);
  letter-spacing:.07em;text-transform:uppercase;color:var(--c);margin-bottom:.3rem;
}
.traps{display:grid;gap:var(--s3)}
.trap{
  background:var(--a-surface);border:1px solid var(--a-line);border-left:4px solid var(--a-coral);
  border-radius:11px;padding:var(--s3);display:grid;gap:var(--s1);
}
.trap b{font-family:var(--a-display);font-size:var(--t-md)}
.trap .ok{color:var(--a-mint-deep)}
.trap .ko{color:var(--a-coral-deep);text-decoration:line-through}
.fig{background:var(--a-bg);border-radius:14px;padding:.8rem;text-align:center}
.fig svg{max-width:100%;height:auto}
/* ── Panneaux de réglages ─────────────────────────────────────────────── */
.panel{
  background:var(--a-surface);border:1px solid var(--a-line);border-radius:var(--a-r-lg);
  box-shadow:var(--a-shadow);padding:var(--s4);margin-bottom:var(--s4);
}
.panel h3{font-family:var(--a-display);font-size:var(--t-lg);margin-bottom:var(--s3)}
.panel .line{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s2);
  padding:.45rem 0;border-bottom:1px solid var(--a-line);font-size:var(--t-sm);
}
.panel .line:last-of-type{border-bottom:none}
.chips{display:flex;flex-wrap:wrap;gap:var(--s2);margin-bottom:.8rem}
.chip{
  border:1.5px solid var(--a-line);background:var(--a-bg);color:var(--a-ink);
  border-radius:var(--a-pill);padding:.45rem var(--s3);font-family:inherit;font-size:var(--t-sm);cursor:pointer;
}
.chip.on{background:var(--a-bleu);border-color:var(--a-bleu);color:var(--a-on-c);font-weight:700}
.btn.sm{min-height:34px;padding:0 var(--s3);font-size:var(--t-sm)}

/* ── Trophées et avatars ──────────────────────────────────────────────── */
.trophy-new{
  background:var(--a-cream); border-radius:var(--a-pill); padding:var(--s1) var(--s3);
  font-size:var(--t-sm);
}
.trophies{display:grid; grid-template-columns:repeat(auto-fill,minmax(130px,1fr)); gap:var(--s2); margin-top:var(--s2)}
.trophy{
  display:grid; justify-items:center; text-align:center; gap:.1rem; padding:var(--s3) var(--s2);
  border:1px solid var(--a-line); border-radius:var(--a-r); opacity:.45; filter:grayscale(1);
}
.trophy.got{opacity:1; filter:none; background:var(--a-bleu-soft); border-color:transparent}
.trophy .t-ico{font-size:1.8rem; line-height:1.2}
.trophy b{font-family:var(--a-display); font-size:var(--t-sm)}
.trophy span:last-child{font-size:var(--t-xs); color:var(--a-muted); line-height:1.35}
.avatars{display:flex; flex-wrap:wrap; gap:var(--s2); margin-top:var(--s2)}
.avatar{
  width:48px; height:48px; border-radius:50%; border:2px solid var(--a-line); background:var(--a-surface);
  font-size:1.5rem; cursor:pointer; transition:transform .1s;
}
.avatar:active{transform:scale(.92)}
.avatar.on{border-color:var(--c); background:var(--a-bleu-soft)}
#who .av{font-size:1.05rem; line-height:1}

/* ── Mouvement : peu, et seulement quand il dit quelque chose ──────────
   1. le logo se dessine à l'ouverture de l'app (classe .intro, 2 s) ;
   2. les jauges se remplissent depuis zéro quand l'écran s'affiche ;
   3. une réponse fait réagir la carte : hochement si juste, secousse si faux ;
   4. en fin de leçon, les étoiles tombent une à une et les XP défilent ;
   5. la prochaine leçon du chemin émet un signal, la série de jours vacille,
      la série de bonnes réponses rebondit à chaque nouvelle.
   Tout passe en `backwards` : l'animation ne masque jamais une valeur réelle. */
@property --p{syntax:'<angle>'; inherits:false; initial-value:0deg}
@property --n{syntax:'<integer>'; inherits:false; initial-value:0}

.intro .brand .loop :is(circle, path){stroke-dasharray:1; animation:draw .8s cubic-bezier(.6,0,.2,1) backwards}
.intro .brand .loop circle + circle{animation-delay:.3s}
.intro .brand .loop path{animation-duration:.25s; animation-delay:.95s}
.intro .tagline{animation:rise .5s ease backwards .9s}
@keyframes draw{from{stroke-dashoffset:1}}

.meter i{animation:grow .9s cubic-bezier(.2,.8,.2,1) backwards .1s}
.goal{animation:fill 1.1s cubic-bezier(.2,.8,.2,1) backwards .15s}
@keyframes grow{from{width:0}}
@keyframes fill{from{--p:0deg}}

.step{animation:rise .25s ease}
.verdict{animation:rise .2s ease}
.step.yes{animation:nod .35s ease}
.step.nope{animation:shake .4s ease}
.choice.good{animation:bump .4s ease}
@keyframes nod{40%{transform:scale(1.012)}}
@keyframes bump{50%{transform:scale(1.05)}}
@keyframes shake{20%,60%{transform:translateX(-7px)}40%,80%{transform:translateX(7px)}}

.finish .stars span{--i:0; display:inline-block; animation:pop .5s ease backwards calc(.15s + var(--i) * .18s)}
.finish .xp b{animation:count 1s ease-out backwards .5s; counter-reset:n var(--n)}
.finish .xp b::after{content:counter(n)}
.levelup{animation:pop .6s ease backwards .9s}
.trophy-new{animation:pop .5s ease backwards 1.1s}
.combo:not(.hidden){animation:pop .35s ease}
.combo i{animation:bump .4s ease}
.hud-streak .ico{animation:flicker 2.4s ease-in-out infinite; transform-origin:50% 90%}
.lesson.next .dot{animation:beacon 2s ease-out infinite}
@keyframes flicker{50%{transform:scale(1.12) rotate(-4deg)}}
@keyframes beacon{
  0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--c) 45%, transparent)}
  70%,100%{box-shadow:0 0 0 12px transparent}
}
@keyframes count{from{--n:0}}

.confetti{position:fixed; top:-5vh; font-size:var(--t-xl); pointer-events:none; z-index:50;
          animation:fall 1.8s ease-in forwards}
@keyframes fall{to{transform:translateY(115vh) rotate(240deg); opacity:0}}
@keyframes rise{from{opacity:0; transform:translateY(12px)}}
@keyframes pop{0%{transform:scale(.4); opacity:0} 60%{transform:scale(1.14)}}

/* ── Socle qualité ────────────────────────────────────────────────────── */
/* Le clavier doit voir où il est — invisible jusqu'ici. */
:focus-visible{
  outline:3px solid var(--c);
  outline-offset:3px;
  border-radius:var(--a-pill);
}
.course:focus-visible,.sheet:focus-visible,.lesson:focus-visible,.tile:focus-visible,
.step:focus-visible,.panel:focus-visible{border-radius:var(--a-r)}
.field:focus-visible{outline-offset:1px;border-radius:14px}

/* Certains enfants — et certains réglages système — ne supportent pas le mouvement. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important; animation-iteration-count:1!important;
    transition-duration:.01ms!important; scroll-behavior:auto!important;
  }
  .confetti{display:none}
}

/* ── Impression : la fiche seule, sur du papier ───────────────────────── */
@media print{
  @page{size:A4;margin:1.4cm 1.5cm}
  html{font-size:10.5pt}
  body{background:#fff;color:#000;display:block}
  .topbar,.foot,.no-print,.quick,.hud{display:none!important}
  main{max-width:none;padding:0}
  .fiche{border:none;box-shadow:none;border-radius:0;padding:0;margin:0}
  .fsec,.trap,.contrast,.fig,.formula,table{break-inside:avoid}
  .fsec{margin-bottom:.9rem}
  .fiche-h h2{font-size:18pt}
  .rule,.tip,.warn,.fblock,.contrast{background:#f6f6fa!important;-webkit-print-color-adjust:exact;print-color-adjust:exact}
}

/* ── La tortue : scène, éditeur, console (tortue.js) ──────────────────── */
main.wide{max-width:1180px}
body:has(main.wide) .topbar-in{max-width:1180px}

.tt{display:grid; gap:var(--s3); text-align:left}
.tt-gauche{display:grid; gap:var(--s2); align-content:start; min-width:0; width:100%; max-width:380px; margin-inline:auto}
.tt.tt-texte{grid-template-columns:minmax(0,1fr)}       /* exercice de console : pas de feuille, la console sous le code */
.tt-texte .tt-vue{display:none}
.tt-texte .tt-gauche{order:2; max-width:none}
/* Côte à côte dès que la place le permet — dans une leçon comme dans l'atelier :
   la scène à gauche, le code à droite, sans faire défiler entre les deux. */
.step-body,.atelier{container-type:inline-size}
@container (min-width:620px){
  .tt{grid-template-columns:minmax(0,290px) minmax(0,1fr); align-items:start}
  .tt-gauche{max-width:none; position:sticky; top:5.5rem}
}
@container (min-width:960px){.tt{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr)}}
.tt-scene{
  position:relative; width:100%; aspect-ratio:1; border-radius:var(--a-r);
  overflow:hidden; border:1px solid var(--a-line); background:#fff; box-shadow:var(--a-shadow);
}
.tt-scene canvas{position:absolute; inset:0; width:100%; height:100%}
.tt-cote{display:grid; gap:var(--s2); min-width:0}

.tt-barre{display:flex; flex-wrap:wrap; gap:var(--s1); align-items:center}
.tt-barre .btn{min-height:42px; padding:0 1rem; font-size:var(--t-sm); display:inline-flex; align-items:center; gap:.35rem}
.tt-barre .tt-ico{width:42px; padding:0; justify-content:center; color:var(--a-soft)}
.tt-barre .tt-ico .ico{width:20px; height:20px; margin:0}
@media (hover:hover){.tt-barre .tt-ico:hover{color:var(--a-bleu-deep)}}
.tt-barre .tt-lance{padding:0 1.3rem}
.tt-barre .tt-grille.on{background:var(--a-bleu-soft); border-color:transparent; color:var(--a-bleu-deep)}
.tt-ex{
  min-height:40px; border-radius:var(--a-pill); border:1.5px solid var(--a-line); background:var(--a-surface);
  color:var(--a-ink); font:inherit; font-size:var(--t-sm); padding:0 .8rem; cursor:pointer;
}

/* L'éditeur : un <textarea> transparent posé sur un <pre> surligné.
   Mêmes police, taille, interligne et marges — sinon le surlignage glisse. */
.tt-ed{
  display:grid; grid-template-columns:auto minmax(0,1fr); border:1.5px solid var(--a-line);
  border-radius:14px; background:var(--a-surface); overflow:hidden;
  font:15px/1.55 var(--a-mono); font-variant-ligatures:none;   /* « i++ » reste deux + */
}
.tt-ed:focus-within{border-color:var(--c)}
.tt-lignes{
  margin:0; padding:.7rem .5rem .7rem .7rem; text-align:right; color:var(--a-muted);
  background:var(--a-bg); font:inherit; overflow:hidden; min-width:2.6em;
}
.tt-lignes b{color:var(--a-coral-deep)}
.tt-lignes i{font-style:normal; color:var(--a-amber); font-weight:700}
.tt-zone{position:relative; height:clamp(11rem, 34vh, 20rem)}
main.wide .tt-zone{height:clamp(16rem, 52vh, 34rem)}
.tt-hl,.tt-src{
  position:absolute; inset:0; margin:0; padding:.7rem .8rem; border:0; font:inherit; tab-size:2;
  white-space:pre; overflow:auto; letter-spacing:0; word-spacing:0;
}
.tt-hl{pointer-events:none; overflow:hidden; color:var(--a-ink)}
.tt-src{
  background:transparent; color:transparent; caret-color:var(--a-ink); resize:none; outline:none;
  user-select:text; -webkit-user-select:text;
}
/* Le socle arrondit tout ce qui a le focus (:focus-visible → pilule) : sur la
   zone de code, cela découpait la sélection en arc de cercle. Le cadre de
   l'éditeur (.tt-ed:focus-within) signale déjà le focus. */
.tt-src:focus-visible{border-radius:0; outline:none}
.tt-src::selection{background:color-mix(in srgb,var(--c) 28%,transparent); color:transparent}
.tt-hl i,.tt-code i{font-style:normal}
.tt-mot{color:var(--a-bleu-deep)}
.tt-cmd{color:var(--a-bleu)}
.tt-num{color:var(--a-mint-deep)}
.tt-str{color:var(--a-amber)}
.tt-com{color:var(--a-muted)}
.tt-hl .tt-com,.tt-code .tt-com{font-style:italic}
@media (max-width:520px){.tt-ed{font-size:16px}}      /* iOS ne zoome pas sous 16 px */

.tt-pal{display:grid; gap:.35rem}
.tt-groupe{display:grid; grid-template-columns:5.6rem minmax(0,1fr); align-items:start; gap:.4rem}
.tt-fam{padding-top:.4rem; font:700 var(--t-sm)/1 var(--a-display); color:var(--a-soft)}
.tt-mots{display:flex; flex-wrap:wrap; gap:.3rem}
@media (max-width:520px){.tt-groupe{grid-template-columns:4.8rem minmax(0,1fr)} .tt-fam{font-size:var(--t-xs)}}
.tt-chip{
  border:1px solid var(--a-line); background:var(--a-surface); color:var(--a-bleu-deep);
  border-radius:var(--a-pill); padding:.15rem .6rem; font:600 var(--t-xs)/1.6 var(--a-mono); cursor:pointer;
}
@media (hover:hover){.tt-chip:hover{background:var(--a-bleu-soft); border-color:transparent}}
.tt-chip:active{transform:scale(.95)}

/* La console, sous la feuille et repliable : ce qu'affiche le programme, ses
   questions, les réponses tapées, les messages. Vide, elle se fait discrète. */
.tt-console{border:1.5px solid var(--a-line); border-radius:14px; background:var(--a-surface); overflow:hidden}
.tt-console-tete{
  width:100%; display:flex; align-items:center; gap:.4rem; padding:.45rem .8rem; background:none; border:0;
  font:700 var(--t-sm)/1.4 var(--a-display); color:var(--a-bleu-deep); cursor:pointer;
}
.tt-console-tete::after{content:'▾'; margin-left:auto; transition:transform .15s}
.tt-console.ferme .tt-console-tete::after{transform:rotate(-90deg)}
.tt-console.vide .tt-console-tete{color:var(--a-muted); cursor:default}
.tt-console.vide .tt-console-tete::after{content:none}
.tt-nb{font:500 var(--t-xs)/1.4 var(--a-body); color:var(--a-muted)}
.tt-out{display:grid; gap:.25rem; max-height:16rem; overflow-y:auto; padding:.55rem .6rem .7rem; border-top:1px solid var(--a-line)}
.tt-console.ferme .tt-out{display:none}
.tt-ligne{font:var(--t-sm)/1.5 var(--a-mono); padding:.1rem .7rem; border-left:3px solid var(--c); white-space:pre-wrap; user-select:text; -webkit-user-select:text}
.tt-ligne.tt-q{border-color:var(--a-amber); color:var(--a-ink); font-weight:600}
.tt-ligne.tt-r{border-color:transparent; color:var(--a-bleu-deep)}
.tt-saisie{display:flex; align-items:center; gap:.4rem; padding:.1rem .7rem; font:var(--t-sm)/1.5 var(--a-mono); color:var(--a-bleu-deep)}
.tt-saisie input{
  flex:1; min-width:0; font:inherit; font-size:16px; color:var(--a-ink); background:var(--a-surface);
  border:1.5px solid var(--c); border-radius:10px; padding:.3rem .6rem; outline:none; user-select:text; -webkit-user-select:text;
}
.tt-saisie input:focus-visible{border-radius:10px; outline:none}
.tt-msg{border-radius:12px; padding:var(--s2) var(--s3); font-size:var(--t-sm); line-height:1.5; background:var(--a-cream)}
.tt-msg.mal{background:var(--a-coral-soft)}

/* Le mode d'emploi : barre sous l'éditeur (curseur, tablette) et bulle au survol (souris). */
.tt-aide{
  font-size:var(--t-sm); line-height:1.45; color:var(--a-muted); padding:.35rem .2rem; min-height:2.2rem;
}
.tt-aide b{font-family:var(--a-mono); color:var(--a-bleu-deep); margin-right:.3rem}
.tt-aide.mode span{color:var(--a-ink)}
.tt-aide .tt-code,.tt-bulle .tt-code{margin:.35rem 0 0; padding:.45rem .7rem; font-size:var(--t-xs); max-width:none; max-height:9.5em; overflow:auto}
.tt-aide.alerte{color:var(--a-ink); background:color-mix(in srgb,var(--a-amber) 16%,transparent); border-radius:12px; padding:.45rem .7rem}
.tt-aide.alerte b{font-family:inherit; color:var(--a-amber)}
.tt-bulle{
  position:absolute; z-index:5; width:min(300px, 90%); padding:.55rem .7rem; border-radius:12px; pointer-events:none;
  background:var(--a-surface); border:1px solid var(--a-line); box-shadow:var(--a-shadow);
  font:var(--t-xs)/1.45 var(--a-body); white-space:normal; color:var(--a-ink);
}
.tt-bulle b{display:block; font-family:var(--a-mono); color:var(--a-bleu-deep); margin-bottom:.15rem}
.tt-bulle[hidden]{display:none}

/* Un programme à lire (explications, démos, fiches). */
.tt-code{
  margin:0 auto; max-width:var(--mesure); background:var(--a-bleu-soft); border-radius:14px;
  padding:var(--s3) var(--s4); font:var(--t-sm)/1.6 var(--a-mono); overflow-x:auto;
  white-space:pre; user-select:text; -webkit-user-select:text; color:var(--a-ink); font-variant-ligatures:none;
}
.tt-demo{display:grid; gap:var(--s3); align-items:center}
.tt-demo .tt-hote{width:100%; max-width:300px; margin-inline:auto}
@media (min-width:600px){.tt-demo{grid-template-columns:minmax(0,1fr) 260px}.tt-demo .tt-code{margin:0; max-width:none}}
.tt-attendu{
  display:flex; flex-wrap:wrap; gap:.35rem; justify-content:center; align-items:center;
  max-width:var(--mesure); margin-inline:auto;
}
.tt-attendu .lbl{
  width:100%; text-align:center; font-family:var(--a-display); font-weight:700; font-size:var(--t-sm); color:var(--a-bleu-deep);
}
.atelier > * + *{margin-top:var(--s3)}
.course.tool .name{color:var(--a-bleu-deep)}
.course.tool .course-p .ico{width:22px; height:22px; color:var(--c)}
@media print{.tt-code{background:#f6f6fa!important; -webkit-print-color-adjust:exact; print-color-adjust:exact}}

/* ── Mes créations (atelier) ─────────────────────────────────────────── */
.creations-box{margin-top:var(--s4)}
.crea-head{display:flex; flex-wrap:wrap; align-items:center; gap:var(--s2); margin-bottom:var(--s3)}
.crea-head h3{margin:0}
.crea-nom{flex:1; min-width:10rem; color:var(--a-muted); font-size:var(--t-sm); font-family:var(--a-accent); font-style:italic}
.crea-head .btn{display:inline-flex; align-items:center; gap:.35rem}
.creations{display:grid; grid-template-columns:repeat(auto-fill,minmax(132px,1fr)); gap:var(--s3)}
.crea{position:relative}
.crea-open{
  width:100%; display:flex; flex-direction:column; align-items:stretch; gap:.15rem; text-align:left;
  border:1.5px solid var(--a-line); border-radius:var(--a-r); background:var(--a-surface); color:inherit;
  padding:.45rem .45rem .55rem; cursor:pointer; font-family:inherit; transition:transform .12s, border-color .15s;
}
.crea-open img,.crea-vide{
  width:100%; aspect-ratio:1; border-radius:12px; background:#fff; display:grid; place-items:center;
  font-size:2rem; object-fit:cover; margin-bottom:.25rem; border:1px solid var(--a-line);
}
.crea-open b{font-family:var(--a-display); font-size:var(--t-sm); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.crea-open span:last-child{font-size:var(--t-xs); color:var(--a-muted)}
.crea.on .crea-open{border-color:var(--c)}
@media (hover:hover){.crea-open:hover{transform:translateY(-2px)}}
.crea-del{position:absolute; top:.2rem; right:.2rem; background:var(--a-surface)}

/* ── Fenêtres de dialogue (ui.js : jamais celles du système) ──────────── */
/* ── Calcul et droite graduée ──────────────────────────────────────────── */
.focus.calc{white-space:nowrap; overflow-x:auto; font-variant-numeric:tabular-nums}
.droite{display:block; width:100%; max-width:640px; margin:var(--s2) auto 0; touch-action:none; cursor:pointer;
  border-radius:14px; outline:none; user-select:none}
.droite:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--c) 35%,transparent)}
.droite [hidden]{display:none}                 /* « hidden » n'a pas d'effet par défaut en SVG */
.droite .axe{stroke:var(--a-ink); stroke-width:2.5}
.droite .fleche{fill:var(--a-ink)}
.droite .g{stroke:var(--a-ink); stroke-width:2.5}
.droite .p{stroke:var(--a-muted); stroke-width:1.5}
.droite text{font:600 15px var(--a-body); fill:var(--a-ink); text-anchor:middle}
.droite .moi circle{fill:var(--c); stroke:var(--a-surface); stroke-width:3}
.droite .moi text{font:800 16px var(--a-display); fill:var(--c)}
.droite .sol circle{fill:none; stroke:var(--a-mint-deep); stroke-width:4}
@media (max-width:560px){                 /* au doigt : des graduations qu'on lit, un repère qu'on voit */
  .droite text{font-size:24px} .droite .moi text{font-size:28px}
  .droite .moi circle{r:14} .droite .sol circle{r:13} .droite .axe,.droite .g{stroke-width:3.5}
}
.hint-droite{margin:var(--s1) 0 var(--s3); text-align:center; color:var(--a-muted); font-size:var(--t-xs)}

.dlg{position:fixed; inset:0; z-index:50; display:grid; place-items:center; padding:var(--s4);
  background:rgba(20,18,40,.38); backdrop-filter:blur(3px); animation:dlg-in .15s ease-out}
.dlg-boite{width:min(26rem,100%); background:var(--a-surface); color:var(--a-ink); border-radius:var(--a-r);
  box-shadow:var(--a-shadow); padding:var(--s5) var(--s5) var(--s4); display:grid; gap:var(--s4)}
.dlg-texte{margin:0; font-family:var(--a-display); font-weight:700; font-size:var(--t-md); line-height:1.4; text-align:center}
.dlg-champ{font:inherit; font-size:16px; padding:.65rem .9rem; border-radius:12px; border:1.5px solid var(--a-line);
  background:var(--a-bg); color:var(--a-ink); outline:none; user-select:text; -webkit-user-select:text}
.dlg-champ:focus{border-color:var(--c)}
.dlg-btns{display:flex; gap:var(--s2); justify-content:center; flex-wrap:wrap}
.dlg-btns .btn{min-width:8rem}
.btn.danger{background:var(--a-coral-deep); border-color:var(--a-coral-deep); color:#fff}
@keyframes dlg-in{from{opacity:0; transform:scale(.97)}}

/* ── La mascotte : la boucle du logo, ses anneaux sont des yeux (ui.js) ─── */
.mascotte{display:block; overflow:visible}
.mascotte :is(circle, path){fill:none; stroke-width:3.1; stroke-linecap:round; stroke-linejoin:round}
.mascotte .m-a{stroke:var(--a-ink)}
.mascotte .m-b{stroke:var(--a-sun)}
.mascotte .m-p{fill:var(--a-ink); stroke:none}
.mascotte .m-rire path{stroke:var(--a-ink); stroke-width:2.4}
.mascotte .m-bouche{stroke:var(--a-ink); stroke-width:2}
.mascotte .m-grand{fill:var(--a-coral); stroke-width:1.6}
.mascotte .m-corps, .mascotte .m-yeux, .mascotte .m-p{transform-box:fill-box; transform-origin:center}
/* chaque humeur montre ses yeux et sa bouche */
.mascotte .m-rire, .mascotte .m-grand, .mascotte .m-hum{display:none}
.mascotte:is(.contente, .fete) .m-yeux, .mascotte:is(.contente, .fete) .m-sourire{display:none}
.mascotte:is(.contente, .fete) .m-rire, .mascotte:is(.contente, .fete) .m-grand{display:inline}
.mascotte.oups .m-sourire{display:none}
.mascotte.oups .m-hum{display:inline}
/* calme : elle cligne, elle regarde autour — fête : elle saute — oups : tête penchée */
.mascotte.calme .m-yeux{animation:m-cligne 5.5s infinite}
.mascotte.calme .m-p{animation:m-regard 7s ease-in-out infinite}
.mascotte.contente .m-corps{animation:pop .45s ease}
.mascotte.fete .m-corps{animation:m-saute .55s ease 3}
.mascotte.oups .m-corps{transform:rotate(-7deg)}
.mascotte.oups .m-p{transform:translate(-1px, 1.6px)}
@keyframes m-cligne{0%, 94%, 100%{transform:scaleY(1)} 96%{transform:scaleY(.12)}}
@keyframes m-regard{0%, 30%, 100%{transform:translate(0, 0)} 40%, 55%{transform:translate(1.6px, -.4px)} 65%, 80%{transform:translate(-1.6px, .3px)}}
@keyframes m-saute{40%{transform:translateY(-14%) rotate(-8deg)} 75%{transform:translateY(0) rotate(5deg)}}

/* La mascotte parle, sur l'accueil */
.parle{display:flex; align-items:center; gap:var(--s3); margin:0 0 var(--s3)}
.parle .mascotte{flex:none}
.bulle{position:relative; flex:1; background:var(--a-surface); border:1.5px solid var(--a-line); border-radius:18px;
  padding:.7rem 1rem; font-weight:600; line-height:1.4; box-shadow:var(--a-shadow)}
.bulle::before{content:''; position:absolute; left:-9px; top:50%; width:16px; height:16px; margin-top:-8px;
  background:var(--a-surface); border-left:1.5px solid var(--a-line); border-bottom:1.5px solid var(--a-line); transform:rotate(45deg)}
.finish .mascotte{margin:0 auto var(--s2)}

/* Au doigt : des cibles de 40 px au moins (puces de la palette, suppression d'une création). */
@media (pointer:coarse){
  .tt-chip{min-height:40px; padding:.3rem .8rem; font-size:var(--t-sm)}
  .crea-del{width:40px; height:40px}
}
.crea-open:focus-visible,.tt-console-tete:focus-visible{border-radius:var(--a-r)}

/* ── Signaler une question ─────────────────────────────────────────────── */
.step-head{position:relative}
.signaler{position:absolute; right:.55rem; top:50%; transform:translateY(-50%); width:32px; height:32px; padding:0;
  display:grid; place-items:center; border:0; border-radius:var(--a-pill); background:transparent; color:inherit;
  opacity:.75; cursor:pointer; transition:opacity .15s, background .15s}
.signaler .ico{width:17px; height:17px}
@media (hover:hover){.signaler:hover{opacity:1; background:color-mix(in srgb, currentColor 16%, transparent)}}
.dlg-choix{display:grid; gap:var(--s1)}
.dlg-opt{font:600 var(--t-md) var(--a-body); text-align:left; padding:.6rem .9rem; border-radius:12px; cursor:pointer;
  border:1.5px solid var(--a-line); background:var(--a-surface); color:var(--a-ink)}
.dlg-opt.on{border-color:var(--c); background:var(--a-bleu-soft); color:var(--a-bleu-deep)}
.dlg-note{resize:vertical; min-height:4.5rem; font-family:var(--a-body)}
.toast{position:fixed; left:50%; bottom:calc(var(--s4) + env(safe-area-inset-bottom)); transform:translateX(-50%); z-index:60;
  background:var(--a-ink); color:var(--a-bg); padding:.6rem 1.1rem; border-radius:var(--a-pill); font-weight:600;
  box-shadow:var(--a-shadow-lg); animation:rise .2s ease}
.sig{border-top:1px solid var(--a-line); padding:var(--s2) 0; display:grid; gap:.2rem}
.sig-raison{margin-left:.4rem; font-size:var(--t-xs); color:var(--a-amber); font-weight:700}
.sig-q{font-weight:600}
.sig-note{font-family:var(--a-accent); font-style:italic; color:var(--a-soft)}
.sig-meta{display:flex; align-items:center; justify-content:space-between; gap:var(--s2); font-size:var(--t-xs); color:var(--a-muted)}
