/*
 * Apprendre (ECL-08) — au-dessus du design system, jamais contre lui.
 *
 * Aucune couleur littérale : tout passe par les jetons de dashboard.css
 * (navy, primary, surfaces, sémantiques). Le jaune de la marque reste au [AI] du
 * logo. Aucun `!important` : une utilitaire qui gagne par la force casse le
 * composant qu'elle habille (scripts/check-css.js).
 */

.learn-body { display: flex; flex-direction: column; gap: var(--space-4); }

.learn-module-open {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}

.learn-module-open:hover { background: var(--surface-2); }

.learn-module-key {
  font-weight: 600;
  color: var(--primary);
  min-width: 2.2em;
}

.learn-module-title { flex: 1; }

/* Les listes de « Ma progression » : un bloc par ligne, un module manquant
 * par ligne. La LISTE des parcours, elle, est la maquette (plus bas). */
.learn-bloc-lines,
.learn-missing {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* Le contenu n'existe qu'en français en vague 0 : la retombée se VOIT. */
.learn-untranslated {
  font-size: 0.72rem;
  color: var(--warning);
  background: var(--warning-soft);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-1);
  white-space: nowrap;
}

.learn-section { margin-top: var(--space-4); }

.learn-section-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.learn-section-head h2,
.learn-section-head h3 { margin: 0; }

.learn-module-head > .btn { margin-bottom: var(--space-3); }

/* La leçon : de la prose, lisible, rien d'autre. */
.learn-prose { max-width: 68ch; line-height: 1.65; }
.learn-prose h2 { font-size: 1.15rem; margin: var(--space-5) 0 var(--space-2); }
.learn-prose h3 { font-size: 1.02rem; margin: var(--space-4) 0 var(--space-2); }
.learn-prose p { margin: 0 0 var(--space-3); }
.learn-prose ul,
.learn-prose ol { margin: 0 0 var(--space-3); padding-left: var(--space-5); }
.learn-prose li { margin-bottom: var(--space-1); }

.learn-prose blockquote {
  margin: 0 0 var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--primary);
  background: var(--surface-2);
  color: var(--text-muted);
}

.learn-code {
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  overflow-x: auto;
}

.learn-video { width: 100%; max-width: 720px; border-radius: var(--radius); }

/* Le quiz : les bonnes réponses n'existent à l'écran qu'après la correction. */
.learn-questions {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-left: var(--space-5);
}

.learn-question p { margin: 0 0 var(--space-2); }

.learn-options { display: flex; flex-direction: column; gap: var(--space-1); }

.learn-option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.learn-option:hover { background: var(--surface-2); }
.learn-option.is-expected { border-color: var(--success); background: var(--success-soft); }
.learn-option.is-wrong { border-color: var(--danger); background: var(--danger-soft); }

.learn-verdict {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: var(--space-2);
}

.learn-explanation { color: var(--text-muted); font-size: 0.875rem; }

.learn-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-4);
}

.learn-quiz-result { margin: 0; }
.learn-quiz-result.is-passed { color: var(--success); }
.learn-quiz-result.is-failed { color: var(--warning); }

.learn-gestures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.learn-gesture h4 { margin: 0 0 var(--space-1); color: var(--text-muted); font-size: 0.85rem; }

/* Le rituel du geste (ECL-39) : maintenant, lundi, ensuite — numérotés. */

.gesture-how {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius);
  background: var(--surface-2);
}

.gesture-how-title { margin: 0; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); }
.gesture-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.gesture-step { display: flex; align-items: baseline; gap: var(--space-2); }

.gesture-step-num {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--primary);
  color: var(--text-invert);
  font-size: 0.8rem;
  font-weight: 600;
}

.gesture-mode { align-self: flex-start; }

/* Les deux versions : deux CARTES qu'on choisit, pas deux colonnes à lire. */

.gesture-pick {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-start;
  text-align: left;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}

.gesture-pick[disabled] { cursor: default; }
.gesture-pick.is-chosen { border-color: var(--primary); background: var(--primary-soft); }
.gesture-pick-title { font-weight: 600; }
/* `hidden` seul ne suffit pas : `.badge` pose un `display`, qui l'emporte. */
.gesture-pick-mark[hidden] { display: none; }
.gesture-hint { margin: 0; }
.gesture-pick-text { line-height: 1.6; }
.gesture-taken { display: flex; flex-direction: column; gap: var(--space-2); align-items: flex-start; }
.gesture-confirm { margin: 0; font-weight: 600; color: var(--success); }

.learn-monday { border-left: 3px solid var(--primary); }

/* ==========================================================================
 * Le lecteur d'écrans (ECL-22).
 *
 * Tout est SCOPÉ sous `.learn-body` — y compris les composants promis par
 * ECL-23 (`.key`, `.pill`, `.hero`, `.rail`, `.progress-dots`). Ils sont
 * dessinés ici avec les jetons, sans ajouter une seule couleur : quand ECL-23
 * les livrera dans dashboard.css, sa version s'appliquera partout ailleurs et
 * ces règles pourront disparaître d'un seul bloc.
 * ========================================================================== */

.learn-body .key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 28px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--navy);
  color: var(--text-invert);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.03em;
}

.learn-body .pill {
  display: inline-block;
  padding: 2px var(--space-2);
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.learn-body .hero {
  background: var(--navy);
  color: var(--text-invert);
  border-radius: var(--radius);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.learn-body .hero-title { margin: 0; font-size: 1rem; }
.learn-body .hero-text { margin: 0; }
.learn-body .hero-note,
.learn-body .hero-example { margin: 0; font-size: 0.85rem; opacity: 0.85; }
.learn-body .hero .pill { border-color: currentColor; align-self: flex-start; }

.learn-body .progress-dots { display: flex; gap: var(--space-1); align-items: center; }

.progress-dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
}

.progress-dot.is-done { background: var(--primary); border-color: var(--primary); }
.progress-dot.is-current { outline: 2px solid var(--primary); outline-offset: 2px; }

/* --------------------------------------------------------------- l'en-tête */

.screens-head { display: flex; flex-direction: column; gap: var(--space-3); }
.screens-head .btn-back { align-self: flex-start; }

.screens-head-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.screens-title { margin: 0; flex: 1 1 220px; }
.screens-tutor { margin-left: auto; }
.screens-meta { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

/* ------------------------------------------------------------- la scène */

.screens-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--space-4);
  align-items: start;
}

.screens-stage { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.screen { display: flex; flex-direction: column; gap: var(--space-3); }
.screen-title { margin: 0; }
/* La consigne de l'écran (ECL-39) : ce qu'on regarde, ce qu'on a à faire. */
.screen-lead { margin: 0; color: var(--text-muted); line-height: 1.6; }
.screen-ask { margin: 0; font-weight: 600; }
.screen-prose, .screen-story-text { margin: 0; line-height: 1.6; }

.screen-story {
  border-left: 3px solid var(--primary);
  background: var(--surface-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
}

.screen-options { display: flex; flex-direction: column; gap: var(--space-2); }

.screen-option {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
  background: var(--surface);
}

.screen-option.is-right { border-color: var(--success); background: var(--success-soft); }
.screen-option.is-wrong { border-color: var(--danger); background: var(--danger-soft); }
.screen-option.is-chosen { border-color: var(--primary); }

.screen-option-pick {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  padding: 0;
}

.screen-option-pick:disabled { cursor: default; }
.screen-why { margin: 0; font-size: 0.9rem; color: var(--text-muted); }

.screens-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  border-top: 1px solid var(--border);
  padding-top: var(--space-3);
}

.screens-hint { margin: 0; flex: 1 1 200px; }

/* ---------------------------------------------------------------- le rail */

.learn-body .rail { display: flex; flex-direction: column; gap: var(--space-4); }
.rail-title { margin: 0 0 var(--space-2); font-size: 0.95rem; }
.screens-rail-list { list-style: none; margin: 0; padding: 0; counter-reset: none; }

.screens-rail-open {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  text-align: left;
  padding: var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.screens-rail-open:disabled { cursor: default; opacity: 0.5; }
.screens-rail-open.is-current { background: var(--primary-soft); color: var(--primary); }

.screens-rail-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: 0.75rem;
}

.screens-rail-open.is-done .screens-rail-num {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--text-invert);
}

.screens-rail-label { flex: 1 1 auto; }
.screens-rail-state { font-size: 0.75rem; color: var(--text-muted); }

/* -------------------------------------------------------------- le schéma */

.schema-board { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-4); }
.schema-figure { display: flex; flex-direction: column; gap: var(--space-2); position: relative; }

.schema-ladder {
  padding-left: var(--space-5);
  background:
    linear-gradient(to bottom, var(--primary), var(--navy))
    no-repeat left var(--space-2) top 0 / 6px 100%;
  border-radius: var(--radius-sm);
}

.schema-matrix { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }

.schema-node {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.schema-node.is-open { border-color: var(--primary); }
.schema-node.is-selected { background: var(--primary); border-color: var(--primary); color: var(--text-invert); }
.schema-node-label { font-weight: 600; }

.schema-link {
  display: block;
  width: 2px;
  height: 14px;
  margin-left: var(--space-4);
  background: var(--border);
}

/* ----------------------------------------------------------------- le tri */

/* ECL-52 — UNE grille, la pioche comprise : toutes les colonnes ont donc la
 * meme largeur, et `stretch` (le defaut d'une grille) leur donne la meme
 * hauteur. Le plancher commun (`min-height` sur la zone de cartes) evite que
 * la colonne saute quand une carte arrive ou part. */
.screen-sort { position: relative; }

.sort-board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
  align-items: stretch;
}

.sort-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
  background: var(--surface-2);
  transition: border-color 120ms ease, background-color 120ms ease;
}

.sort-column-cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* De quoi tenir deux cartes : la hauteur commune ne depend donc pas du
   * contenu de la colonne la plus remplie. */
  min-height: 148px;
  flex: 1;
}

/* Une colonne vide reste un CADRE, pas un trou : c'est ce qui dit « pose ici ». */
.sort-column.is-empty .sort-column-cards {
  border: 1px dashed var(--border-soft);
  border-radius: var(--radius-sm);
}

.sort-drop {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
  text-align: left;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: inherit;
  font: inherit;
  padding: var(--space-2);
  cursor: pointer;
}

.sort-drop:disabled { cursor: default; opacity: 0.55; }

.sort-column-title { font-weight: 600; margin: 0; font-size: 0.95rem; }
.sort-column-hint { font-size: 0.8rem; color: var(--text-muted); }
.sort-column-cta { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); }

/* Une carte prise au clic : toutes les colonnes possibles s'ouvrent. */
.sort-column.is-target { border-color: var(--primary); border-style: solid; }
.sort-column.is-target .sort-column-cta { color: var(--primary); font-weight: 600; }

/* La case CIBLE, sous le fantome : elle se distingue des autres colonnes
 * ouvertes, sinon « ou ca tombe » resterait a deviner. */
.sort-column.is-over {
  border-color: var(--primary);
  border-style: solid;
  background: var(--primary-soft);
}

.sort-column.is-over .sort-column-cta { color: var(--primary); font-weight: 600; }

/* L'emplacement RESERVE : la place que la carte prendra, pendant qu'elle vole. */
.sort-placeholder {
  min-height: 64px;
  border: 2px dashed var(--primary);
  border-radius: var(--radius-sm);
  background: var(--surface);
  pointer-events: none;
}

/* L'etat vide de la pioche, DESSINE dans un cadre de la meme taille. */
.sort-empty {
  margin: 0;
  padding: var(--space-3);
  font-size: 0.85rem;
  color: var(--text-muted);
  text-align: center;
}

.sort-tally { margin: var(--space-3) 0 0; }

.sort-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  text-align: left;
  /* Une hauteur minimale COMMUNE : deux cartes de longueurs differentes font
   * deux blocs de la meme taille, et la colonne ne se deforme pas. */
  min-height: 64px;
  justify-content: center;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: inherit;
  font: inherit;
  cursor: grab;
  touch-action: none;
  transition: box-shadow 120ms ease, border-color 120ms ease, transform 120ms ease;
}

.sort-card:active { cursor: grabbing; }
.sort-card:disabled { cursor: default; }
.sort-card.is-picked { border-color: var(--primary); box-shadow: var(--shadow); transform: translateY(-2px); }
.sort-card.is-right { border-color: var(--success); background: var(--success-soft); cursor: default; }
.sort-card.is-wrong { border-color: var(--danger); background: var(--danger-soft); }
.sort-card-mark { font-size: 0.75rem; font-weight: 600; }
.sort-card-text { font-weight: 500; }

/* Le FANTOME : la carte prise, soulevee, qui suit le pointeur. Il ne recoit
 * aucun evenement — sinon `elementFromPoint` le retrouverait lui-meme sous le
 * doigt et aucune colonne ne s'allumerait. En ABSOLU dans l'ecran, pas en
 * fixe : un ancetre transforme casserait `fixed`, et le noeud part avec
 * l'ecran quand le lecteur le remplace. */
.sort-ghost {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-3);
  border: 1px solid var(--primary);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow);
  pointer-events: none;
  cursor: grabbing;
}

/* Le vol : 180 ms vers la case visee, ou vers la place d'origine si on a
 * lache hors zone. `public/js/pages/screens/sort.js` tient la meme duree. */
.sort-ghost.is-landing { transition: transform 180ms ease-out; }

/* Pendant le glisser, la carte d'origine garde sa PLACE (le navigateur la
 * masque, il ne la retire pas) : la colonne ne se reorganise pas sous le
 * doigt, et le clavier ne perd pas le noeud qu'il tenait. */

/* ---------------------------------------------------------- la simulation */

.sim-trace { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.sim-step {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-left-width: 4px;
  border-radius: var(--radius-sm);
}

.sim-step.is-ok { border-left-color: var(--success); }
.sim-step.is-broken { border-left-color: var(--danger); background: var(--danger-soft); }
.sim-step-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: var(--space-1); }
.sim-step-label { font-weight: 600; }
.sim-step-note { margin: 0; font-size: 0.85rem; color: var(--text-muted); }

.sim-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 0.75rem;
}

/* ------------------------------------------------------------- l'exemple */

.screen-annotated { line-height: 2; }

.screen-quote {
  border: 0;
  border-bottom: 2px solid var(--primary);
  background: var(--primary-soft);
  color: inherit;
  font: inherit;
  padding: 0 2px;
  cursor: pointer;
}

.screen-quote.is-open { background: var(--surface-2); }
.screen-notes { margin: 0; padding-left: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.screen-note-quote { font-weight: 600; }

/* --------------------------------------------------------- la construction */

.build-fields { display: flex; flex-direction: column; gap: var(--space-3); }
.build-field { display: flex; flex-direction: column; gap: var(--space-1); }
.build-checks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.build-check { display: flex; align-items: baseline; gap: var(--space-2); }

/* --------------------------------------------------------------- la carte */

.map-canvas { overflow-x: auto; }
.map-svg { width: 100%; min-width: 320px; height: auto; }
.map-node rect { fill: var(--surface); stroke: var(--border); stroke-width: 1; }
.map-node text { fill: var(--text); font-size: 12px; font-family: var(--font); }
.map-node.is-centre rect { fill: var(--navy); stroke: var(--navy); }
.map-node.is-centre text { fill: var(--text-invert); font-weight: 600; }
.map-node.is-branch rect { fill: var(--surface-2); stroke: var(--navy); }
.map-node.is-done rect { fill: var(--primary); stroke: var(--primary); }
.map-node.is-done text { fill: var(--text-invert); }
.map-node.is-free rect { fill: none; stroke: var(--primary); stroke-dasharray: 5 4; }
.map-node.is-free text { fill: var(--text-muted); }
.map-node.is-mine rect { fill: var(--primary-soft); stroke: var(--primary); }
.map-node.is-mine text { fill: var(--text); font-weight: 600; }
.map-edge { fill: none; stroke: var(--navy); stroke-width: 2; }
.map-edge.is-thin { stroke: var(--border); }

/* Les emplacements, EN CLAIR sous le dessin (ECL-39) : un pointillé ne dit pas
 * quoi écrire, et la saisie s'ouvre là où l'exemple se rangera. */

.map-slots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-3);
}

.map-slot {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
  padding: var(--space-3);
  border-radius: var(--radius);
  border: 1px dashed var(--primary);
  background: var(--surface);
}

.map-slot.is-filled { border-style: solid; border-color: var(--border); background: var(--surface-2); }
.map-slot.is-writing { border-style: solid; }
.map-slot-label {
  margin: 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
.map-slot-hint { margin: 0; color: var(--text-muted); }
.map-slot-text { margin: 0; font-weight: 600; }
.map-slot-branch { margin: 0; font-size: 0.85rem; color: var(--text-muted); }
.map-slot-ask { margin: 0; font-weight: 600; font-size: 0.85rem; }
.map-slot-form { display: flex; flex-direction: column; gap: var(--space-2); width: 100%; }
.map-slot-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.map-slot-note { margin: 0; }
.map-branch-picks { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.map-branch-pick {
  padding: 2px var(--space-2);
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.map-branch-pick.is-chosen { border-color: var(--primary); background: var(--primary-soft); color: var(--primary); }

/* ------------------------------------- le tuteur écrit : le panneau latéral */

/* Il FLOTTE au-dessus du lecteur plutôt que de rétrécir la scène : un écran
 * qui se réagence pendant qu'on lit une correction fait perdre sa place. */
.tutor-chat {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  width: min(420px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow);
}

.tutor-chat-head {
  padding: var(--space-4);
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.tutor-chat-title { margin: 0; font-family: var(--font-display); }
.tutor-chat-module { margin: 0; color: var(--text-muted); font-size: 0.9rem; }
.tutor-chat-lead { margin: 0; }
.tutor-chat-close { align-self: flex-start; margin-top: var(--space-2); }

.tutor-chat-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.tutor-chat-thread {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.tutor-chat-turn { display: flex; flex-direction: column; gap: var(--space-2); }

.tutor-chat-bubble {
  border-radius: var(--radius);
  padding: var(--space-3);
  border: 1px solid var(--border-soft);
}

.tutor-chat-asked { background: var(--primary-soft); border-color: transparent; }
.tutor-chat-said { background: var(--surface-2); }
.tutor-chat-text { margin: 0; white-space: pre-wrap; line-height: 1.55; }

/* La citation VÉRIFIÉE. Elle est discrète mais toujours là : une réponse sans
 * source est une réponse qu'on ne peut pas vérifier. */
.tutor-chat-source {
  margin: var(--space-2) 0 0;
  font-size: 0.8rem;
  color: var(--primary);
}

/* « Ça dépasse ce module » : un ÉTAT, donc une couleur sémantique. */
.tutor-chat-offtopic {
  margin: var(--space-2) 0 0;
  font-size: 0.8rem;
  color: var(--warning);
}

.tutor-chat-form { display: flex; flex-direction: column; gap: var(--space-2); }
.tutor-chat-label { font-size: 0.85rem; color: var(--text-muted); }
.tutor-chat-input { width: 100%; }
.tutor-chat-cap { margin: 0; }
.tutor-chat-empty { margin: 0; }

/* --------------------------------------------- `demo` : les mécanismes animés
 *
 * ECL-37. Une démo MONTRE un geste (un mot qui se coupe en deux tokens, une
 * barre de probabilité qui monte, une fenêtre qui déborde, une boucle qui
 * continue sur un résultat faux). Tout est dessiné aux jetons : aucune couleur
 * littérale, le jaune de la marque reste la marque. Les états d'une démo sont des
 * ÉTATS (succès, danger, attention), pas une décoration.
 *
 * Le mouvement est une TRANSITION, jamais un contenu : sous
 * `prefers-reduced-motion` (plus bas), tout tombe d'un coup et la démo affiche
 * son état final — elle reste jouée, l'écran reste franchissable.
 */

.screen-demo { gap: var(--space-3); }
.demo-stage { display: flex; flex-direction: column; gap: var(--space-3); }
.demo-note { margin: 0; min-height: 1.3em; font-size: 0.9rem; color: var(--text-muted); }
.demo-controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.demo-temp { display: flex; gap: var(--space-1); }
.demo-temp .btn.is-current {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--text-invert);
}

/* tokenize */
.demo-source { margin: 0; color: var(--text-muted); }
.demo-tokens { display: flex; flex-wrap: wrap; gap: 4px; }
.demo-token {
  padding: 2px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 0.9rem;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 160ms ease, transform 160ms ease;
}
.demo-token.is-alt { background: var(--primary-soft); }
.demo-token.is-in { opacity: 1; transform: none; }
/* Un mot long = deux morceaux : la coupe se VOIT, elle ne se raconte pas. */
.demo-token.is-cut-head {
  border-right-style: dashed;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.demo-token.is-cut-tail {
  border-left-style: dashed;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  color: var(--primary);
}
.demo-count { margin: 0; font-weight: 600; opacity: 0; transition: opacity 200ms ease; }
.demo-count.is-in { opacity: 1; }

/* next_token · temperature */
.demo-prefix {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.demo-picked { font-weight: 700; color: var(--primary); opacity: 0; transition: opacity 200ms ease; }
.demo-picked.is-in { opacity: 1; }
.demo-caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: var(--text-muted);
  animation: demo-caret 1000ms steps(2) infinite;
}
.demo-bars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.demo-bar {
  display: grid;
  grid-template-columns: minmax(72px, 132px) minmax(0, 1fr) 52px;
  gap: var(--space-2);
  align-items: center;
  padding: 2px var(--space-1);
  border-radius: var(--radius-sm);
}
.demo-bar-token { font-weight: 600; }
.demo-bar-track { display: block; height: 10px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.demo-bar-fill { display: block; width: 0; height: 100%; border-radius: 999px; background: var(--border); transition: width 420ms ease; }
.demo-bar-value { text-align: right; font-size: 0.85rem; color: var(--text-muted); }
.demo-bar.is-chosen { background: var(--primary-soft); }
.demo-bar.is-chosen .demo-bar-fill { background: var(--primary); }
.demo-draws { margin: 0; min-height: 1.3em; }

/* context_window */
.demo-window-cap { margin: 0; font-size: 0.9rem; color: var(--text-muted); }
.demo-window {
  padding: var(--space-2);
  border: 2px solid var(--primary);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.demo-window-slots { display: flex; flex-direction: column; gap: var(--space-1); }
.demo-chunk {
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.9rem;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 200ms ease, transform 200ms ease;
}
.demo-chunk.is-in { opacity: 1; transform: none; }
.demo-chunk.is-important { border-color: var(--primary); font-weight: 600; }
.demo-chunk.is-out { border-style: dashed; color: var(--text-muted); }
.demo-window-out {
  display: none;
  padding: var(--space-2);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}
.demo-window-out.is-active { display: block; }
.demo-window-out-title {
  margin: 0 0 var(--space-1);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--danger);
}
.demo-window-out-list { display: flex; flex-direction: column; gap: var(--space-1); }
.demo-window-ask,
.demo-window-answer { margin: 0; opacity: 0; transition: opacity 200ms ease; }
.demo-window-ask.is-in,
.demo-window-answer.is-in { opacity: 1; }
.demo-window-answer { font-weight: 600; color: var(--danger); }

/* loop */
.demo-loop { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.demo-loop-step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  opacity: 0.45;
  transition: opacity 180ms ease;
}
.demo-loop-step.is-ok,
.demo-loop-step.is-failed,
.demo-loop-step.is-blind { opacity: 1; }
.demo-loop-step.is-ok { border-left-color: var(--success); }
.demo-loop-step.is-failed { border-left-color: var(--danger); background: var(--danger-soft); }
.demo-loop-step.is-blind { border-left-color: var(--warning); }
.demo-loop-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
  border-radius: 50%;
  background: var(--surface-2);
  font-size: 0.75rem;
  font-weight: 600;
}
.demo-loop-label { flex: 1 1 auto; }
/* Un badge vide n'est pas un badge : il n'apparaît qu'avec son verdict. */
.demo-loop-mark:empty { display: none; }
.demo-counter { margin: 0; font-weight: 600; color: var(--danger); opacity: 0; transition: opacity 200ms ease; }
.demo-counter.is-in { opacity: 1; }

/* transcribe (ECL-47) — du son au texte : les mots tombent, l'un tombe faux.
 * Pendant la dictée rien ne le signale ; le marquage arrive APRÈS, sur le
 * transcript, parce que c'est là que le SDR le découvre. */
.demo-caption { margin: 0; font-size: 0.85rem; color: var(--text-muted); }
.demo-heard { display: flex; flex-wrap: wrap; gap: 6px; min-height: 1.8em; }
.demo-word {
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 160ms ease, transform 160ms ease, background 200ms ease;
}
.demo-word.is-in { opacity: 1; transform: none; }
.demo-word.is-misheard { background: var(--danger-soft); text-decoration: line-through; }
.demo-transcript-title,
.demo-transcript { opacity: 0; transition: opacity 200ms ease; }
.demo-transcript-title.is-in,
.demo-transcript.is-in { opacity: 1; }
.demo-transcript {
  margin: 0;
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.demo-wrong { color: var(--danger); font-weight: 700; }

/* speakers (ECL-47) — deux voix, une ligne au mauvais nom. Le transcript se
 * déroule sans rien signaler ; la marque arrive APRÈS, sur la ligne fausse. */
.demo-turns { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.demo-turn {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 180ms ease, transform 180ms ease;
}
.demo-turn.is-in { opacity: 1; transform: none; }
.demo-turn.is-wrong { border-left-color: var(--danger); background: var(--danger-soft); }
.demo-turn-who { flex: 0 0 auto; font-weight: 600; }
.demo-turn-text { flex: 1 1 160px; }
/* Un badge vide n'est pas un badge : il n'apparaît qu'avec son verdict. */
.demo-turn-mark:empty { display: none; }

/* injection (ECL-47) — le document collé donne des ordres. On lit la sortie
 * fausse AVANT de retrouver la phrase qui l'a commandée : c'est l'ordre dans
 * lequel un SDR le vit. La phrase s'allume en danger, jamais en jaune : le
 * jaune de la marque reste la marque (ADR-0004). */
.demo-doc {
  margin: 0;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 0.9rem;
  opacity: 0;
  transition: opacity 200ms ease;
}
.demo-doc.is-in { opacity: 1; }
.demo-doc-hidden { border-radius: var(--radius-sm); transition: background 260ms ease, color 260ms ease; }
.demo-doc-hidden.is-lit {
  padding: 1px 4px;
  background: var(--danger-soft);
  color: var(--danger);
  font-weight: 600;
}
.demo-ask,
.demo-output,
.demo-injection-mark { margin: 0; opacity: 0; transition: opacity 200ms ease; }
.demo-ask.is-in,
.demo-output.is-in,
.demo-injection-mark.is-in { opacity: 1; }
.demo-output { font-weight: 600; color: var(--danger); }
.demo-injection-mark { font-size: 0.85rem; color: var(--text-muted); }

/* timeline (ECL-47) — la journée d'un SDR, avant et après. Les deux barres
 * d'une tâche sont à l'échelle de la MÊME journée : c'est ce qui rend le gain
 * visible sans qu'on l'annonce. */
.demo-timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.demo-task {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  opacity: 0;
  transition: opacity 180ms ease;
}
.demo-task.is-in { opacity: 1; }
.demo-task-label { font-weight: 600; }
.demo-task-line {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) 64px;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.85rem;
}
.demo-task-tag { color: var(--text-muted); }
.demo-task-track { display: block; height: 10px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.demo-task-fill { display: block; width: 0; height: 100%; border-radius: 999px; transition: width 420ms ease; }
.demo-task-before { background: var(--border); }
.demo-task-after { background: var(--primary); }
.demo-task-value { text-align: right; color: var(--text-muted); }
.demo-total { margin: 0; font-weight: 600; opacity: 0; transition: opacity 200ms ease; }
.demo-total.is-in { opacity: 1; }

@keyframes demo-caret {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* ------------------------------------- l'invitation à cliquer, et le fil remonté
 *
 * ECL-37, retours de Steven (11/09) : un schéma dont personne ne devine qu'il
 * se clique, et une simulation qu'on lit à l'envers. Le nœud à ouvrir pulse
 * (sobrement, et l'anneau reste quand le mouvement est coupé) ; la simulation
 * qui part du problème pose son bandeau avant sa trace.
 */

.schema-node.is-inviting {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
  animation: schema-invite 1800ms ease-in-out infinite;
}

@keyframes schema-invite {
  from { box-shadow: 0 0 0 2px var(--primary-soft); }
  50% { box-shadow: 0 0 0 7px var(--primary-soft); }
  to { box-shadow: 0 0 0 2px var(--primary-soft); }
}

.sim-problem { gap: var(--space-2); }
.sim-rewind-hint { margin: 0; }
.sim-ask { display: flex; flex-direction: column; gap: var(--space-3); }

/* ------------------------------------------------------- petit écran, sobre */

@media (max-width: 900px) {
  .screens-layout,
  .schema-board { grid-template-columns: minmax(0, 1fr); }
  .learn-body .rail { order: 2; }
  .screens-tutor { margin-left: 0; }

  /* Au doigt, le panneau prend l'écran : un fil de conversation coincé dans
   * 100 pixels ne se lit pas. */
  .tutor-chat { width: 100vw; border-left: 0; }

  /* Au doigt, les colonnes s'EMPILENT (la grille passe a une colonne) et la
   * pioche, toujours la premiere, etale ses cartes en RANGEE : un glisser doit
   * tenir dans un ecran, sinon il faudrait faire defiler en pleine
   * manipulation. Le repli au clic reste, il ne remplace pas ca. */
  .sort-board { grid-template-columns: minmax(0, 1fr); }

  .sort-pile .sort-column-cards {
    flex-direction: row;
    overflow-x: auto;
    min-height: 96px;
    padding-bottom: var(--space-2);
  }

  .sort-pile .sort-card { flex: 0 0 200px; }
  .sort-pile .sort-empty { flex: 1; align-self: center; }

  /* Une colonne de destination n'a plus besoin de tenir deux cartes de haut :
   * l'ecran serait plus long que le geste. */
  .sort-column:not(.sort-pile) .sort-column-cards { min-height: 76px; }

  /* La barre de probabilité garde ses trois colonnes, en plus serré. */
  .demo-bar { grid-template-columns: 84px minmax(0, 1fr) 44px; }
}

/* Le mouvement qui dérange s'arrête ici ; le glisser, lui, reste — c'est de
 * la manipulation directe, pas une animation. La carte cesse simplement de
 * pencher (public/js/pages/screens/sort.js lit la même préférence).
 *
 * `.sort-ghost.is-landing` est répété tel quel : `.sort-ghost` seul (0,1,0)
 * PERDRAIT contre lui (0,2,0) et le vol tiendrait quand même. Le JS ne pose
 * plus la classe sous cette préférence, mais une feuille de style ne doit pas
 * dépendre d'un `if` pour dire vrai. */
@media (prefers-reduced-motion: reduce) {
  .sort-card,
  .sort-column,
  .sort-ghost,
  .sort-ghost.is-landing,
  .screens-rail-open,
  .schema-node { transition: none; }

  /* Une démo qui ne bouge plus AFFICHE son état final : les transitions
   * tombent, les deux animations (le curseur, la pulsation du nœud) s'arrêtent,
   * et l'anneau de l'invitation reste — il ne dépendait pas du mouvement. */
  .demo-token,
  .demo-count,
  .demo-picked,
  .demo-bar-fill,
  .demo-chunk,
  .demo-window-ask,
  .demo-window-answer,
  .demo-loop-step,
  .demo-counter,
  .demo-word,
  .demo-transcript-title,
  .demo-transcript,
  .demo-turn,
  .demo-doc,
  .demo-doc-hidden,
  .demo-ask,
  .demo-output,
  .demo-injection-mark,
  .demo-task,
  .demo-task-fill,
  .demo-total { transition: none; }
  .demo-caret,
  .schema-node.is-inviting { animation: none; }
}

/* ==========================================================================
 * La page Apprendre (ECL-31) — la maquette Studio.
 *
 * Aucune couleur littérale : tout est composé avec les jetons de
 * dashboard.css. Le jaune de la marque n'apparaît nulle part ici : il est au
 * [AI] du logo, et c'est tout ce qu'il a le droit d'être (ADR-0006).
 *
 * Le verrou est un ÉTAT, pas une décoration : un module fermé est grisé et
 * porte un cadenas, un bloc fermé l'est en entier. Le serveur refuse de
 * toute façon (403).
 * ========================================================================== */

.learn-head { padding: var(--space-4) 0 var(--space-5); max-width: 62ch; }

.learn-title {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 var(--space-2);
}

.learn-lead { color: var(--text-muted); margin: 0; }

.learn-layout { align-items: start; }
.learn-main { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.learn-main .card { margin-bottom: 0; }

/* Une carte de parcours porte un liseré : la page ne se lit plus comme une
 * liste de rectangles blancs. */
.learn-card { position: relative; overflow: hidden; }

.learn-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: linear-gradient(90deg, var(--primary), var(--navy));
}

.learn-card-head { align-items: flex-start; }
.learn-card-ident { min-width: 0; }
.learn-card-title { margin: 0 0 var(--space-1); font-size: 1.15rem; }
.learn-card-lead { margin: 0; color: var(--text-muted); font-size: 0.9rem; }
.learn-card-count { flex: 0 0 auto; white-space: nowrap; }

/* ------------------------------------------------------ une ligne de module */

.learn-rows { gap: 2px; }

.learn-row {
  gap: var(--space-3);
  padding: var(--space-3);
  border-top: 1px solid var(--border-soft);
  transition: background 140ms ease, transform 140ms ease;
}

.learn-row:hover:enabled:not([aria-disabled='true']) {
  background: var(--surface-2);
  transform: translateX(2px);
}
/* Le titre et la duree sont deux LIGNES : colles, ils se lisaient
 * « Comprendre les niveaux d'IA12 min ». */
.learn-row .row-text { display: flex; flex-direction: column; gap: 1px; }
.learn-row .row-title { font-weight: 600; line-height: 1.35; }
.learn-row .row-note { font-size: 0.8rem; }
.learn-row .row-chevron { transition: transform 140ms ease; }
.learn-row:hover:enabled:not([aria-disabled='true']) .row-chevron { transform: translateX(2px); }

/* Le prochain module : c'est LUI qu'on ouvre, et ça se voit. */
.learn-row.is-next { background: var(--primary-soft); border-radius: var(--radius); }
.learn-row.is-next .row-title { color: var(--text); }
.learn-cta { flex: 0 0 auto; pointer-events: none; }

/* Un module verrouillé : grisé, avec son cadenas — mais TOUJOURS focusable
 * et cliquable (`aria-disabled`, pas `disabled`), parce qu'il a quelque chose
 * à dire : ce qu'il attend. Un bouton `disabled` ne prend pas le focus, ne
 * montre pas son infobulle au clavier et ne répond à aucun clic. */
.learn-row[aria-disabled='true'] { cursor: not-allowed; opacity: 0.55; }
.learn-row[aria-disabled='true'] .row-chevron { color: var(--text-muted); }

.learn-mark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  flex: 0 0 auto;
  white-space: nowrap;
}

.learn-mark-icon { width: 13px; height: 13px; flex: 0 0 13px; }
.learn-mark-lock { color: var(--text-muted); }

/* La puce d'un module, en primary : le texte inversé la garde lisible dans
 * les deux thèmes, contrairement à du primary posé sur du primary-soft. */
.learn-body .key-primary {
  min-width: 34px;
  height: 26px;
  background: var(--primary);
  color: var(--text-invert);
  flex: 0 0 auto;
}

.learn-body .key-primary.is-locked { background: var(--text-muted); }

/* -------------------------------------------------------- la grille de blocs */

.learn-blocs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
  gap: var(--space-4);
  align-items: stretch;
}

.learn-bloc-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease;
}

.learn-bloc-card:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--primary); }
.learn-bloc-card[data-complete='true'] { border-color: var(--success); }

/* Un bloc entier verrouillé : grisé, d'un bloc, cadenas en tête. */
.learn-bloc-card[data-locked='true'] { opacity: 0.6; }
.learn-bloc-card[data-locked='true']:hover { transform: none; box-shadow: none; border-color: var(--border); }

.learn-bloc-head { display: flex; align-items: center; gap: var(--space-3); }
.learn-bloc-ident { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); }
.learn-bloc-name { margin: 0; font-size: 1rem; font-family: var(--font-display); }

.learn-bloc-letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  border-radius: var(--radius);
  background: var(--navy);
  color: var(--text-invert);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
}

.learn-bloc-card[data-complete='true'] .learn-bloc-letter { background: var(--primary); }
.learn-bloc-lock { display: inline-flex; color: var(--text-muted); }
.learn-bloc-lock svg { width: 18px; height: 18px; }

.learn-bloc-card .learn-rows { gap: 0; }
.learn-bloc-card .learn-row { padding: var(--space-2); gap: var(--space-2); }
.learn-bloc-card .row-chevron { width: 14px; height: 14px; flex: 0 0 14px; }
.learn-bloc-card .learn-row:hover:enabled:not([aria-disabled='true']) { background: var(--surface); }
.learn-bloc-card .row-note { font-size: 0.75rem; }

.learn-bloc-foot { display: flex; align-items: center; gap: var(--space-3); margin-top: auto; }
.learn-bloc-count { color: var(--text-muted); font-size: 0.78rem; white-space: nowrap; }

/* La barre de progression : un rail, une part. Le pourcentage vient des
 * comptes du serveur, jamais d'un calcul inventé ici. */
.learn-progress {
  display: block;
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: var(--border-soft);
  overflow: hidden;
}

.learn-progress-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--primary), var(--primary-hover));
  transition: width 260ms ease;
}

/* -------------------------------------------------------------- le rail */

.learn-rail { position: sticky; top: var(--space-4); }
.learn-rail .card { margin-bottom: 0; }

.learn-week { gap: var(--space-3); }
.learn-week-eyebrow { display: flex; align-items: center; gap: var(--space-2); margin: 0; }
/* L'horloge de la semaine : un pictogramme de l'en-tête, aucune couleur de marque (ADR-0006). */
.learn-week-icon { width: 16px; height: 16px; }
.learn-week-line { display: flex; align-items: center; gap: var(--space-2); }
/* Sur fond navy, la puce navy d'ECL-22 disparaîtrait : elle prend le trait
 * du bandeau. */
.learn-body .learn-week .key { background: var(--on-navy-line); color: var(--text-invert); }
.learn-week .hero-title { font-size: 1.15rem; margin: 0; }
.learn-week .hero-lead { margin: 0; }
.learn-week .pill { border-color: var(--on-navy-line); color: var(--on-navy-muted); background: none; }

.learn-cert { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.learn-cert-line { display: flex; align-items: center; gap: var(--space-2); color: var(--text-muted); font-size: 0.9rem; }
.learn-cert-line.is-done { color: var(--text); }
.learn-cert-icon { width: 16px; height: 16px; flex: 0 0 16px; color: var(--border); }
.learn-cert-line.is-done .learn-cert-icon { color: var(--success); }
.learn-cert-label { flex: 1; min-width: 0; }
.learn-cert-count { color: var(--text-muted); font-size: 0.8rem; white-space: nowrap; }

.learn-gains .stat { margin-bottom: var(--space-3); }
.learn-gains .learn-progress { margin-bottom: var(--space-2); }
.learn-gains .stat-note { margin: 0; }

/* ------------------------------------------------------------ la VUE (coach) */

/* Le bandeau d'un compte qui n'est pas soumis au verrou (ECL-36) : il dit
 * pourquoi rien n'est fermé, sinon « tout est ouvert » se lirait « tu as tout
 * validé » — et il porte la bascule vers la vue apprenant. Le même bandeau, en
 * vue apprenant, dit comment en sortir. Les jetons de la marque, jamais une
 * couleur en dur. */
.learn-coach {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  border-color: var(--primary);
  background: var(--primary-soft);
}
.learn-coach-text {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-weight: 600;
}
.learn-coach-icon { width: 16px; height: 16px; flex: 0 0 16px; color: var(--primary); }
/* En vue apprenant, le bandeau reste SOBRE : il informe, il n'alerte pas —
 * rien n'est cassé, c'est la vue qui a été demandée. */
.learn-coach[data-block='learner-view'] {
  border-color: var(--border);
  background: var(--surface-2);
}
.learn-coach[data-block='learner-view'] .learn-coach-icon { color: var(--text-muted); }

/* ------------------------------------------------------- un module fermé */

.learn-locked { text-align: center; }
.learn-locked-mark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}
.learn-locked-icon { width: 18px; height: 18px; }

/* ------------------------------------------- l'apparition, sobre et brève */

@keyframes learn-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.learn-main > .card,
.learn-rail > * { animation: learn-in 260ms ease both; }
.learn-main > .card:nth-child(2) { animation-delay: 60ms; }
.learn-rail > :nth-child(2) { animation-delay: 60ms; }
.learn-rail > :nth-child(3) { animation-delay: 120ms; }

/* ------------------------------------------------------------ 390 px */

@media (max-width: 900px) {
  .learn-rail { position: static; }
  .learn-blocs { grid-template-columns: minmax(0, 1fr); }
  .learn-title { font-size: 28px; }
  .learn-head { padding-top: var(--space-2); }
  .learn-card-head { flex-direction: column; gap: var(--space-2); }
}

/* Le mouvement qui dérange s'arrête ici : l'apparition et le survol
 * disparaissent, la page reste entière. */
@media (prefers-reduced-motion: reduce) {
  .learn-main > .card,
  .learn-rail > * { animation: none; }
  .learn-row,
  .learn-row .row-chevron,
  .learn-bloc-card,
  .learn-progress-fill { transition: none; }
  .learn-row:hover:enabled:not([aria-disabled='true']) { transform: none; }
  .learn-row:hover:enabled:not([aria-disabled='true']) .row-chevron { transform: none; }
  .learn-bloc-card:hover { transform: none; }
}
