/*
  Feuille de style de l'application d'étude, alignée sur l'interface V4
  approuvée (apps/ui-v4-preview).

  Trois contraintes non négociables, vérifiées par test/test_handwriting.py :
  - « touch-action: pan-y » sur la page d'écriture, et jamais « touch-action:
    none » : le doigt fait défiler la copie, le stylet écrit ;
  - la paume posée sur l'écran ne doit rien sélectionner (règles sur body),
    mais les champs de saisie restent sélectionnables ;
  - le canevas garde sa taille calculée par la mise en page (display:block,
    width:100%, aspect-ratio A4, height:auto) : sans dimensions non nulles, la
    page ne peut pas être redimensionnée et l'encre disparaît.

  Aucune police distante : la politique servie est default-src 'self'.
*/

/*
  Jetons de style (contrat 5.4 du chantier « 8,5 partout ») : les pages les
  réutilisent au lieu d'écrire des valeurs en dur. Chaque couleur de texte
  (--nn-color-text, -muted, -accent, -success, -warning, -danger) atteint un
  contraste d'au moins 4,5 sur --nn-color-bg et --nn-color-surface, en clair
  comme en sombre. Un fond d'accent porte du texte en --nn-color-on-accent,
  jamais en blanc écrit en dur : en mode sombre, l'accent s'éclaircit.
  --nn-focus-ring est une couleur : outline: 3px solid var(--nn-focus-ring).
*/
:root {
  --nn-space-1: 4px;
  --nn-space-2: 8px;
  --nn-space-3: 12px;
  --nn-space-4: 16px;
  --nn-space-5: 24px;
  --nn-space-6: 32px;
  --nn-radius: 16px;
  --nn-font-size-base: 16px;
  --nn-color-bg: #f5f7fb;
  --nn-color-surface: #ffffff;
  --nn-color-text: #152033;
  --nn-color-muted: #5b6679;
  --nn-color-accent: #3157d5;
  --nn-color-on-accent: #ffffff;
  --nn-color-success: #23755a;
  --nn-color-warning: #8a5a12;
  --nn-color-danger: #b3261e;
  --nn-focus-ring: #3157d5;

  /* Anciens noms, encore employés par les pages : les neutres renvoient aux
     jetons pour suivre le mode sombre. L'accent et les couleurs d'état
     servent de fond sous un texte blanc écrit en dur : ils gardent leur
     valeur propre, assez foncée pour ce texte blanc dans les deux modes. */
  --bg: var(--nn-color-bg);
  --surface: var(--nn-color-surface);
  --surface-soft: #f1f4f9;
  --surface-blue: #f3f6ff;
  --border: #e4e8ef;
  --text: var(--nn-color-text);
  --muted: var(--nn-color-muted);
  --accent: #3157d5;
  --accent-soft: #e9eeff;
  --accent-dark: #1f3ea6;
  --success: #2e8f6f;
  --warn: #d78a2f;
  --danger: #b74d3c;
  --shadow: 0 14px 42px rgba(25, 38, 70, .075);
  --radius-lg: 24px;
  --radius-md: var(--nn-radius);
  --radius-sm: 12px;
  --sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: "STIX Two Text", "Latin Modern Roman", "DejaVu Serif", Georgia, "Times New Roman", serif;
  /* Marquage d'indisponibilité : ces couleurs disent qu'un élément ne
     fonctionne pas, elles ne sont pas décoratives. */
  --miss: #c62828;
  --miss-soft: #fdf1f0;
  --hold: #b26a00;
  --hold-soft: #fff8ec;
}

/* Mode sombre, sur demande seulement : il ne s'active que par
   data-theme="dark" sur <html>, jamais par le réglage de l'appareil
   (prefers-color-scheme). Il sera branché sur ce réglage quand toutes les
   pages auront migré leurs couleurs vers les jetons : d'ici là, une page
   aux couleurs écrites en dur deviendrait illisible. En clair, rien ne
   change pour les pages. Les fonds de marquage (--miss-soft, --hold-soft)
   restent clairs : leur texte est écrit en dur en teinte foncée dans les
   bandeaux. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --nn-color-bg: #0e1420;
  --nn-color-surface: #161e2e;
  --nn-color-text: #e6ebf4;
  --nn-color-muted: #a5afc2;
  --nn-color-accent: #8ca4ff;
  --nn-color-on-accent: #0e1420;
  --nn-color-success: #5fcf9f;
  --nn-color-warning: #f0b35a;
  --nn-color-danger: #ff8a7a;
  --nn-focus-ring: #9db4ff;

  --surface-soft: #1e2738;
  --surface-blue: #1a2440;
  --border: #2c374b;
  --accent: #4a67d6;
  --accent-soft: #1f2b52;
  --accent-dark: #a9bbff;
  /* Texte d'erreur : l'ancien rouge tomberait à 3,3 sur le fond sombre. */
  --danger: var(--nn-color-danger);
  --shadow: 0 14px 42px rgba(0, 0, 0, .35);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  font-family: var(--sans);
  font-size: var(--nn-font-size-base);
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100dvh;
  background: var(--bg);
  /* Une main posée sur l'écran pendant qu'on écrit ne doit rien sélectionner ni
     faire apparaître le menu « Copier » de Safari. Le défilement au doigt et la
     navigation ne sont pas concernés. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/* Ce qui doit rester sélectionnable : les champs de saisie, partout. */
input,
textarea {
  -webkit-user-select: text;
  user-select: text;
}

/* Sur un ordinateur, sélectionner un énoncé ou une correction reste utile. Sur
   une tablette, le doigt sélectionnerait par accident. */
@media (hover: hover) and (pointer: fine) {
  .rich-text,
  .math-display,
  .math-inline,
  code {
    -webkit-user-select: text;
    user-select: text;
  }
}

button, input { font: inherit; }
button { cursor: pointer; color: inherit; }
p { line-height: 1.65; }
h1, h2, h3, p { margin-top: 0; }

/* Le focus du clavier se voit partout, sur tous les fonds. */
:focus-visible {
  outline: 3px solid var(--nn-focus-ring);
  outline-offset: 2px;
}

/* ================================================================
   Coquille : barre latérale, en-tête, zone de page
   ================================================================ */

#root { width: 100%; }

/* Les écrans de la séquence d'étude (chargement, appairage, écriture,
   correction) occupent tout l'écran : ils gardent une colonne de lecture. */
.flow-screen {
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
  padding: 24px 16px 48px;
}

.account-landing, .account-card { min-height: calc(100dvh - 72px); padding: 24px 8px; }
.account-header { display: flex; justify-content: space-between; align-items: center; }
.account-landing main { padding-top: 20vh; }
.account-card { max-width: 460px; margin: 6vh auto; min-height: auto; padding: 32px; border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow); }
.account-card h1 { font-size: 30px; }
.account-form { display: grid; gap: 16px; margin-top: 24px; }
.account-form label { display: grid; gap: 6px; font-size: 14px; font-weight: 650; }
.account-form input { min-height: 46px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
.account-form button, .account-link { min-height: 46px; padding: 10px 16px; border: 0; border-radius: 10px; color: var(--nn-color-on-accent); background: var(--nn-color-accent); font-weight: 700; }
.account-link { min-height: 44px; }
.account-links { display: grid; gap: 10px; margin-top: 20px; }
.account-links button { min-height: 44px; border: 0; background: transparent; color: var(--accent-dark); text-align: left; }
.account-landing main p { max-width: 560px; margin-top: var(--nn-space-3); color: var(--nn-color-muted); font-size: 17px; }
.account-actions { display: flex; flex-wrap: wrap; gap: var(--nn-space-3); margin-top: var(--nn-space-5); }
.account-primary, .account-secondary { min-height: 48px; padding: 0 var(--nn-space-5); border-radius: var(--radius-sm); font-weight: 700; }
.account-primary { border: 0; background: var(--nn-color-text); color: var(--nn-color-surface); }
.account-secondary { border: 1px solid var(--border); background: var(--nn-color-surface); color: var(--nn-color-text); }

.app-shell { min-height: 100dvh; display: grid; grid-template-columns: 250px minmax(0, 1fr); }

/* Lien d'évitement : hors de l'écran tant qu'il n'a pas le focus clavier. */
.skip-link {
  position: fixed;
  top: var(--nn-space-2);
  left: var(--nn-space-2);
  z-index: 30;
  min-height: 44px;
  padding: 0 var(--nn-space-4);
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--nn-color-text);
  color: var(--nn-color-surface);
  font-weight: 600;
  transform: translateY(calc(-100% - var(--nn-space-4)));
}
.skip-link:focus-visible { transform: none; }
.main:focus { outline: none; }

.sidebar {
  position: sticky;
  top: 0;
  height: 100dvh;
  padding: 28px 20px;
  border-right: 1px solid var(--border);
  background: var(--nn-color-surface);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.brand {
  border: 0;
  background: transparent;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 10px 28px;
  text-align: left;
}

.brand-mark, .avatar, .avatar-btn { display: grid; place-items: center; border-radius: 12px; font-weight: 700; }
.brand-mark { width: 38px; height: 38px; background: var(--nn-color-text); color: var(--nn-color-surface); font-family: var(--serif); font-size: 22px; }
.brand strong, .mini-profile strong { display: block; font-size: 14px; }
.brand span, .mini-profile span { display: block; margin-top: 3px; color: var(--nn-color-muted); font-size: 12px; }

.nav { display: grid; gap: 7px; }
.nav-item {
  border: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 12px;
  background: transparent;
  color: var(--nn-color-muted);
  font-size: 14px;
  font-weight: 500;
  text-align: left;
}
.nav-item:hover { color: var(--nn-color-text); background: var(--surface-soft); }
.nav-item.active { color: var(--accent-dark); background: var(--accent-soft); font-weight: 600; }
.nav-item:focus-visible { outline-offset: -3px; }
.nav-icon { width: 22px; text-align: center; font-size: 16px; }
.nav-label { min-width: 0; }

.sidebar-footer { margin-top: auto; }
/* Se déconnecter : en bas de la navigation ; sur téléphone, où ce pied est
   masqué, le pied de page de la coquille prend le relais, après le contenu
   (un seul visible à la fois, jamais dans l'en-tête). */
.sidebar-logout { width: 100%; min-height: 44px; margin-top: 12px; }
.shell-footer { display: none; }

/* « Nabla choisit » (décision 59) : la raison du choix, les jauges de chapitre. */
.exercise-reason { margin: 0 0 var(--nn-space-3); color: var(--nn-color-muted); font-size: 14px; }
.training-card { display: grid; gap: var(--nn-space-3); margin-bottom: var(--nn-space-5); }
.training-card h2 { margin: 0; }
.training-actions { display: flex; flex-wrap: wrap; gap: var(--nn-space-3); }
.chapter-prepare { margin-top: var(--nn-space-5); }
.chapter-meter { display: block; width: 96px; height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; }
.chapter-meter > span { display: block; height: 100%; border-radius: inherit; background: var(--nn-color-accent, var(--accent)); }
.progress-subject .section-heading h2 { margin: 0; }
.progress-subject-percent { margin: 4px 0 0; color: var(--nn-color-muted); font-weight: 600; }
.progress-chapters { display: grid; gap: var(--nn-space-2); margin: var(--nn-space-3) 0 0; padding: 0; list-style: none; }
.progress-chapter { display: flex; align-items: center; justify-content: space-between; gap: var(--nn-space-3); padding: var(--nn-space-3) var(--nn-space-4); border: 1px solid var(--border); border-radius: var(--nn-radius); background: var(--nn-color-surface); }
.progress-chapter-text { display: grid; gap: 2px; min-width: 0; }
.progress-chapter-text span { color: var(--nn-color-muted); font-size: 14px; }
.chapter-progress-line { margin: 0; font-weight: 700; }
.account-notice { margin: 0 0 var(--nn-space-4); padding: var(--nn-space-3) var(--nn-space-4); border-radius: var(--nn-radius); background: var(--nn-color-surface); color: var(--nn-color-text); }
.mini-profile {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding: 16px 10px 0;
  border-top: 1px solid var(--border);
}
.avatar, .avatar-btn { width: 36px; height: 36px; border: none; background: var(--nn-color-text); color: var(--nn-color-surface); }

.main { width: min(1240px, 100%); margin: 0 auto; padding: 42px clamp(24px, 4vw, 64px) 72px; }
.topbar { display: flex; justify-content: space-between; align-items: flex-start; gap: 30px; margin-bottom: var(--nn-space-5); }
.eyebrow { margin: 0 0 var(--nn-space-2); color: var(--nn-color-muted); font-size: 10px; font-weight: 700; letter-spacing: .14em; }
.topbar .eyebrow { font-size: 11px; }
h1 { margin-bottom: 7px; font-size: clamp(28px, 4vw, 42px); letter-spacing: -.045em; }
.subtitle { margin-bottom: 0; color: var(--nn-color-muted); font-size: 15px; }
.top-actions { display: flex; gap: 10px; align-items: flex-start; }
.icon-btn { width: 40px; height: 40px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); color: var(--text); }

.page { display: block; }

/* ================================================================
   Éléments communs
   ================================================================ */

.pill {
  display: inline-flex;
  padding: 8px 10px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-dark);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
}
.pill.inverted { background: rgba(255, 255, 255, .12); color: #fff; }

.section-block { margin-top: 52px; }
.section-block.compact { margin-top: 34px; }
.section-heading, .split-heading { display: flex; align-items: end; justify-content: space-between; gap: 20px; margin-bottom: 18px; }
.section-heading h2, .split-heading h2 { margin-bottom: 0; font-size: 24px; letter-spacing: -.03em; }
/* Un lien reste une cible tactile : 44px de haut au minimum, sinon il est
   inatteignable au doigt sur l'iPad. */
.link-btn { border: 0; background: transparent; color: var(--accent-dark); font-size: 12px; font-weight: 600; min-height: 44px; padding: 0 4px; }
.link-btn:disabled { color: var(--muted); cursor: default; }

.primary-btn, .secondary-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 46px;
  padding: 0 18px;
  border-radius: 12px;
  font-weight: 600;
  font-size: 13px;
}
.primary-btn { border: none; background: var(--text); color: var(--nn-color-surface); }
.secondary-btn { border: 1px solid var(--border); background: var(--surface); color: var(--text); }
.primary-btn:disabled, .secondary-btn:disabled { opacity: .5; cursor: default; }
.full { width: 100%; }

/* Boutons des écrans de la séquence d'étude : mêmes couleurs, cible plus
   grande, parce qu'on les touche avec la main qui tient le stylet. */
.primary-button, .secondary-button {
  display: block;
  width: 100%;
  min-height: 52px;
  padding: 14px 18px;
  border-radius: 12px;
  font-size: 1.02rem;
  font-weight: 600;
  text-align: center;
}
.primary-button { border: none; background: var(--text); color: var(--nn-color-surface); }
.secondary-button { border: 1px solid var(--border); background: var(--surface); color: var(--text); }
.primary-button:active:not(:disabled), .secondary-button:active:not(:disabled) { transform: translateY(1px); }
.primary-button:disabled, .secondary-button:disabled { opacity: .5; cursor: default; }

.link-button {
  border: none;
  background: transparent;
  color: var(--accent-dark);
  font-size: 0.95rem;
  font-weight: 600;
  padding: 10px 4px;
  min-height: 44px;
  cursor: pointer;
}
.link-button:disabled { color: var(--muted); cursor: default; }

.back-button {
  /* Le retour reste collé au bord gauche du contenu : étiré sur toute la
     largeur, son libellé se retrouverait centré au milieu de la page. */
  align-self: flex-start;
  text-align: left;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 0.95rem;
  min-height: 44px;
  padding: 10px 0;
  cursor: pointer;
}

.card {
  padding: 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.card-title { font-size: 1.05rem; font-weight: 700; margin-bottom: 8px; }
.card-text { color: var(--muted); font-size: 0.95rem; }
.card-note { color: var(--muted); font-size: 0.85rem; margin-top: 8px; }

/* Lu par les lecteurs d'écran, invisible pour les yeux : la classe classique. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.banner {
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: 0.95rem;
  margin-bottom: 16px;
}
.banner-error { border-left-color: var(--miss); background: var(--miss-soft); color: #8e2019; }
/* Le fond du bandeau reste clair dans les deux modes : le bouton garde le
   bleu foncé de l'accent clair au lieu de suivre l'accent éclairci. */
.banner-error .link-button { color: #1f3ea6; }
.banner-error .link-button:disabled { color: var(--muted); }
.banner-action { margin-top: 10px; }

.screen-header { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.screen-title { font-size: 1.6rem; font-weight: 700; letter-spacing: -.02em; }
.app-brand { font-size: 1.5rem; font-weight: 700; color: var(--accent-dark); text-align: center; margin-bottom: 8px; }

.row-list { display: flex; flex-direction: column; gap: 10px; }
.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  text-align: left;
  width: 100%;
}
.row-tappable { cursor: pointer; }
.row-tappable:active { background: var(--surface-soft); }
.row-title { font-size: 1rem; font-weight: 600; }
.row-chevron { color: var(--muted); font-size: 1.1rem; }

/* Étiquettes d'état d'une notion. Le vocabulaire est celui du serveur. */
.status-badge {
  display: inline-flex;
  align-items: center;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  white-space: nowrap;
}
.status-mastered { color: #23755a; background: #e9f7f1; border-color: #b8decf; }
.status-consolidating { color: var(--accent-dark); background: var(--accent-soft); border-color: #c7d4ff; }
.status-learning, .status-started { color: #8a5a12; background: #fff8ef; border-color: #ffe3bf; }
.status-unknown { color: var(--muted); background: var(--surface-soft); border-color: #d5dbe6; }
.status-review-due { color: #795c16; background: #fff5d9; border-color: #f0dca6; }
.status-available { color: #4d5f80; background: #fbfcff; border-color: #cdd6e6; }
.status-locked { color: #7b8497; background: var(--surface-soft); border-color: #d5dbe6; }

.dot, .status-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; flex: none; }
.status-dot { width: 8px; height: 8px; }
.dot.mastered, .status-dot.mastered { background: var(--success); }
.dot.consolidating, .status-dot.consolidating { background: var(--accent); }
.dot.learning, .status-dot.learning,
.dot.started, .status-dot.started { background: var(--warn); }
.dot.review-due, .status-dot.review-due { background: #c9a227; }
.dot.available, .status-dot.available { background: #8fa1c4; }
.dot.locked, .status-dot.locked { background: #c3cad8; }

.star {
  width: 52px;
  min-height: 52px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  color: var(--muted);
  font-size: 1.2rem;
  cursor: pointer;
}
.star:disabled { opacity: .5; cursor: default; }

.spinner {
  width: 36px;
  height: 36px;
  border: 3px solid rgba(49, 87, 213, .2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ================================================================
   Accueil
   ================================================================ */

.hero-card {
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(300px, .7fr);
  min-height: 320px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--nn-color-surface);
  box-shadow: var(--shadow);
}
/* Sans proposition (compte neuf, choix libre), pas de panneau de matière. */
.hero-card.hero-solo { grid-template-columns: minmax(0, 1fr); min-height: 0; }
.hero-copy { padding: clamp(24px, 5vw, 54px); }
.hero-subject { margin: var(--nn-space-5) 0 0; color: var(--nn-color-muted); font-size: 13px; font-weight: 600; }
.hero-copy .hero-subject + h2 { margin-top: var(--nn-space-1); }
.hero-reason { max-width: 720px; margin-bottom: var(--nn-space-5); color: var(--nn-color-muted); }
.hero-action { min-width: 200px; font-size: 15px; }
.hero-action + .helper-text { font-size: 13px; }
.hero-copy h2, .training-reco h2, .course-toolbar h2, .progress-hero h2 {
  margin: 24px 0 10px;
  font-size: clamp(30px, 4vw, 44px);
  letter-spacing: -.045em;
}
.hero-copy > div > p { max-width: 720px; margin-bottom: 16px; color: var(--muted); }

.math-panel {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 34px;
  background: radial-gradient(circle at top right, rgba(255, 255, 255, .26), transparent 28%), linear-gradient(145deg, #2f55d4, #213a8c);
  color: #fff;
}
.math-panel::before, .math-panel::after { content: ""; position: absolute; border: 1px solid rgba(255, 255, 255, .12); border-radius: 50%; }
.math-panel::before { width: 260px; height: 260px; right: -120px; top: -100px; }
.math-panel::after { width: 180px; height: 180px; left: -100px; bottom: -70px; }
.math-label { position: relative; z-index: 1; font-size: 10px; font-weight: 700; letter-spacing: .12em; opacity: .72; }
.simple-symbol {
  position: relative;
  z-index: 1;
  align-self: center;
  margin: 10px 0 12px;
  font-family: var(--serif);
  font-size: clamp(72px, 11vw, 130px);
  line-height: 1;
}
.math-caption { position: relative; z-index: 1; }
.math-caption strong { display: block; font-size: 16px; }

/* L'anneau lit sa part depuis --ring, posée par le script à partir de la
   maîtrise mesurée. Sans mesure, il n'y a pas d'anneau du tout. */
.mastery-ring {
  position: relative;
  z-index: 1;
  align-self: flex-end;
  width: 94px;
  height: 94px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: conic-gradient(#fff 0 var(--ring, 0%), rgba(255, 255, 255, .18) var(--ring, 0%) 100%);
}
.mastery-ring::after { content: ""; position: absolute; inset: 7px; border-radius: 50%; background: #2948b5; }
.mastery-ring div { position: relative; z-index: 2; text-align: center; }
.mastery-ring strong, .mastery-ring span { display: block; }
.mastery-ring strong { font-size: 19px; }
.mastery-ring span { margin-top: 2px; font-size: 8px; opacity: .8; }

.stats-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.stat-card { min-height: 130px; padding: 22px; border-radius: var(--nn-radius); border: 1px solid var(--border); background: var(--nn-color-surface); height: auto; }
.stat-label, .stat-note { display: block; color: var(--nn-color-muted); }
.stat-label { min-height: 36px; font-size: 13px; font-weight: 500; }
.stat-card strong { display: block; margin: 6px 0; font-size: 29px; letter-spacing: -.04em; }
.stat-note { font-size: 12px; }

.progress-card { margin-top: 14px; padding: 8px 24px; border-radius: var(--nn-radius); border: 1px solid var(--border); background: var(--nn-color-surface); }
.progress-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, .8fr); align-items: center; gap: 32px; padding: 18px 0; }
/* Une rangée cliquable est un bouton : sans ces règles il se réduirait à son
   contenu et les rangées ne seraient plus alignées entre elles. */
.progress-row.row-tappable { width: 100%; border: 0; background: transparent; color: inherit; text-align: left; }
.progress-row.row-tappable:active { background: var(--surface-soft); }
.progress-row + .progress-row { border-top: 1px solid var(--border); }
.progress-info { display: flex; align-items: center; gap: 14px; }
.subject-icon { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 12px; background: var(--surface-soft); font-family: var(--serif); font-size: 20px; }
.progress-info strong, .progress-info span { display: block; }
.progress-info strong { font-size: 14px; }
.progress-info span { margin-top: 4px; color: var(--nn-color-muted); font-size: 12px; }
/* La colonne du chiffre tient « pas encore commencé » sur une ligne (46 px
   l'écrasait sur trois) ; elle est fixe pour que les jauges restent alignées. */
.progress-side { display: grid; grid-template-columns: 170px minmax(0, 1fr); align-items: center; gap: 12px; }
.progress-side > strong { font-size: 13px; }
.progress-side > strong.empty { color: var(--nn-color-muted); font-weight: 500; }
.progress-track { overflow: hidden; height: 7px; border-radius: 999px; background: var(--surface-soft); }
/* La jauge d'une matière (chapters.js) remplit la piste ; seul son remplissage
   est peint. Un sélecteur « .progress-track span » peignait aussi son
   conteneur, et une matière à 0 % montrait une barre pleine à 40 %. */
.progress-track > .chapter-meter { width: 100%; height: 100%; background: transparent; }
.progress-track.dark { background: rgba(255, 255, 255, .13); }
.progress-track.dark span { background: #fff; }

.quick-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.quick-card {
  min-height: 132px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 20px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 16px;
  text-align: left;
}
.quick-card:hover { box-shadow: var(--shadow); border-color: #d7ddea; }
.quick-icon { width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; background: var(--surface-soft); font-size: 18px; }
.quick-card strong { display: block; font-size: 15px; }
.quick-card p { margin: 5px 0 0; color: var(--muted); font-size: 11px; line-height: 1.5; }

.home-header { display: flex; flex-direction: column; gap: 4px; margin-bottom: 18px; }
.home-greeting { font-size: 1.6rem; font-weight: 700; }
.card-today { border-left: 4px solid var(--accent); }
.today-subject { color: var(--muted); font-size: 0.85rem; text-transform: uppercase; letter-spacing: .08em; }
.today-concept { font-size: 1.15rem; font-weight: 700; margin: 6px 0; }
.today-reason { color: var(--muted); font-size: 0.95rem; margin-bottom: 14px; }
.alternative-title { font-size: 0.9rem; color: var(--muted); margin: 22px 0 8px; }
.progress-list { display: flex; flex-direction: column; }
.progress-entry { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; }
.progress-entry + .progress-entry { border-top: 1px solid var(--border); }
.progress-name { font-size: 0.98rem; }

/* ================================================================
   Chapitres, entraînement, bibliothèque d'exercices
   ================================================================ */

.chapter-list { overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.chapter-row {
  width: 100%;
  min-height: 44px;
  border: 0;
  background: transparent;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  padding: 20px 22px;
  text-align: left;
}
.chapter-row + .chapter-row { border-top: 1px solid var(--border); }
.chapter-row:hover { background: #fafbfe; }
.chapter-row:disabled { cursor: default; }
.chapter-main, .chapter-status { display: flex; align-items: center; }
.chapter-main { gap: 15px; min-width: 0; }
.chapter-main > div { min-width: 0; }
.chapter-number { color: #a4adbc; font-size: 11px; font-weight: 700; }
.chapter-main strong, .chapter-main span { display: block; }
.chapter-main strong { font-size: 14px; overflow-wrap: break-word; }
.chapter-main div span { margin-top: 4px; color: var(--muted); font-size: 13px; }
.chapter-status { gap: 11px; font-size: 12px; }
/* Ancienne page Entraînement (retirée par la décision 59) : règle gardée
   seulement tant que test/test_courses_page.py l'exige encore. */
.training-layout .chapter-main div .training-only-hint {
  padding-left: 6px; border-left: 3px solid var(--nn-color-warning, #d78a2f);
  color: var(--nn-color-text, #152033); font-weight: 600;
}
.chapter-row:focus-visible { outline: 3px solid var(--nn-focus-ring, #3157d5); outline-offset: -3px; }

.training-reco {
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.training-copy { padding: 42px; }
.training-copy > div > p { max-width: 670px; color: var(--muted); }
.training-path { display: flex; align-items: flex-start; max-width: 660px; margin: 28px 0 30px; }
.path-step { min-width: 125px; text-align: center; color: var(--muted); }
.path-step > span {
  width: 32px;
  height: 32px;
  margin: 0 auto 9px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 11px;
  font-weight: 700;
}
.path-step strong, .path-step small { display: block; }
.path-step strong { color: var(--text); font-size: 11px; }
.path-step small { margin-top: 4px; font-size: 9px; }
.path-step.done > span { background: var(--success); color: #fff; border-color: var(--success); }
.path-step.active > span { background: var(--accent); color: #fff; border-color: var(--accent); }
.path-line { flex: 1; height: 1px; background: var(--border); margin-top: 16px; }
.path-line.done { background: var(--success); }

.reco-summary {
  padding: 32px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
  background: linear-gradient(160deg, #f0f4ff, #e9efff);
  border-left: 1px solid #dde5ff;
}
.math-mini { font-family: var(--serif); font-size: 42px; color: var(--accent-dark); }
.reco-summary > div { padding-top: 14px; border-top: 1px solid rgba(49, 87, 213, .13); }
.reco-summary > div span, .reco-summary > div strong { display: block; }
.reco-summary > div span { color: var(--muted); font-size: 9px; text-transform: uppercase; letter-spacing: .08em; }
.reco-summary > div strong { margin-top: 5px; font-size: 14px; }

.filter-panel { padding: 22px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--surface); }
.filter-group { margin-bottom: 22px; }
.filter-group > label { display: block; margin-bottom: 8px; color: var(--muted); font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.select-like {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  padding: 0 12px;
  font-size: 12px;
  text-align: left;
}
.select-like.active { border-color: #cad4ff; background: var(--accent-soft); color: var(--accent-dark); font-weight: 700; }
.star-levels { display: grid; gap: 8px; }
.helper-text { margin: 10px 0 0; color: var(--muted); font-size: 13px; }

.exercise-library { display: grid; gap: 12px; }
.exercise-card { padding: 22px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--surface); }
.exercise-head, .exercise-foot { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.exercise-head { color: var(--muted); font-size: 10px; }
.difficulty { padding: 6px 8px; border-radius: 999px; font-weight: 700; }
.difficulty.easy { color: #23755a; background: #e9f7f1; }
.difficulty.medium { color: #795c16; background: #fff5d9; }
.difficulty.hard { color: #9a4438; background: #fff0ed; }
.exercise-card h3 { margin-bottom: 6px; font-size: 16px; }
.exercise-card p { color: var(--muted); font-size: 11px; }
.exercise-foot { margin-top: 18px; padding-top: 15px; border-top: 1px solid var(--border); color: var(--muted); font-size: 9px; }
.exercise-foot button { border: 0; background: transparent; color: var(--accent-dark); font-weight: 700; font-size: 11px; }

.mode-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.mode-grid.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.mode-card { min-height: 392px; padding: 24px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--surface); display: flex; flex-direction: column; height: auto; }
.mode-card.featured { border-color: #cad4ff; }
.mode-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mode-icon { width: 46px; height: 46px; display: grid; place-items: center; border-radius: 14px; background: var(--surface-soft); font-family: var(--serif); font-size: 22px; }
.soft-tag { padding: 6px 8px; background: var(--surface-soft); border-radius: 999px; color: var(--muted); font-size: 9px; font-weight: 700; }
.mode-card h3 { margin: 24px 0 8px; font-size: 21px; }
.mode-card p { color: var(--muted); font-size: 12px; }
.clean-list { list-style: none; margin: 7px 0 24px; padding: 0; display: grid; gap: 9px; color: var(--muted); font-size: 11px; }
.clean-list li::before { content: "·"; margin-right: 8px; color: var(--accent); font-weight: 700; }
.mode-card .full { margin-top: auto; }

.intro-banner {
  min-height: 220px;
  border-radius: var(--radius-lg);
  padding: 38px 42px;
  display: grid;
  grid-template-columns: 1fr 300px;
  align-items: center;
  gap: 40px;
  background: linear-gradient(145deg, #162238, #253b65);
  color: #fff;
  box-shadow: var(--shadow);
}
.intro-banner h2 { margin: 0 0 10px; font-size: clamp(26px, 3vw, 36px); letter-spacing: -.04em; }
.intro-banner p { max-width: 680px; margin: 0; color: rgba(255, 255, 255, .7); }
.focus-score { padding: 24px; border: 1px solid rgba(255, 255, 255, .13); border-radius: 16px; background: rgba(255, 255, 255, .06); }
.focus-score > span, .focus-score > strong { display: block; }
.focus-score > span { color: rgba(255, 255, 255, .65); font-size: 11px; }
.focus-score > strong { margin: 8px 0 15px; font-size: 32px; }
/* Sur le panneau bleu, le gris des pages tombait à un contraste de 1,07. */
.math-panel .helper-text { color: rgba(255, 255, 255, .9); }

/* ================================================================
   Cours
   ================================================================ */

/* Le titre d'un document peut être long : il garde toute la largeur et les
   matières passent en dessous, sinon le titre se coupait au milieu d'un mot. */
.course-toolbar { display: grid; gap: 14px; margin-bottom: 20px; }
/* Le titre est le nom de la matière : il peut être long, il se coupe. */
.course-toolbar h2 { margin: 16px 0 6px; font-size: clamp(24px, 4vw, 32px); overflow-wrap: anywhere; }
/* Le titre du chapitre reste plus petit que le nom de la matière : la matière
   situe l'écran, le chapitre n'est qu'un contenu ouvert. */
.course-chapter { margin: 0 0 6px; font-family: var(--serif); font-size: 20px; font-weight: 600; color: #3f4b5f; }
.course-toolbar p { margin: 0; color: var(--nn-color-muted, #6f7b8f); font-size: 14px; }
.course-toolbar-actions { display: flex; flex-wrap: wrap; gap: var(--nn-space-2, 10px); }
/* Ajout d'une matière et import d'un document. */
.course-import { display: grid; gap: 14px; margin-bottom: 20px; }
.course-import-title { font-size: 18px; }
/* Les trois gestes du dépôt, numérotés : ce qui se passe après l'import y
   est dit, pour que l'attente de l'analyse ne surprenne pas. */
.course-import-steps { display: grid; gap: 6px; padding-left: 22px; color: var(--nn-color-text, #152033); font-size: 15px; line-height: 1.5; }
.course-import-row, .course-import-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.course-import .field { display: grid; gap: 5px; min-width: 190px; flex: 1 1 190px; }
.course-import .field > span { color: var(--nn-color-text, #152033); font-size: 13px; font-weight: 600; }
/* 16 px au moins : en dessous, Safari sur iPhone zoome la page à la saisie. */
.course-import input, .course-import select {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  padding: 0 11px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  font-size: 16px;
}
.course-import input[type="file"] { padding: 10px; }
.course-import .form-error { margin: 0; color: var(--danger, #b3261e); font-size: 14px; }
.course-import .helper-text, .course-outline .helper-text, .level-tests .helper-text,
.course-danger-zone .helper-text { font-size: 13px; }
.level-tests { display: grid; gap: 12px; margin-top: 20px; }
/* Supprimer la matière : en bas de page, séparé du reste, jamais à côté des
   gestes de lecture. La confirmation est dans main.js. */
.course-danger-zone {
  display: grid; justify-items: start; gap: var(--nn-space-2, 10px);
  margin-top: var(--nn-space-5, 32px); padding-top: var(--nn-space-4, 20px);
  border-top: 1px solid var(--border);
}
.danger-btn { color: var(--nn-color-danger, #b74d3c); border-color: var(--nn-color-danger, #b74d3c); }
.danger-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--nn-color-danger, #b74d3c) 8%, transparent); }
.view-switch { display: flex; padding: 4px; background: var(--surface-soft); border-radius: 11px; }
.view-switch button { border: 0; min-height: 36px; padding: 0 13px; border-radius: 8px; background: transparent; color: var(--muted); font-size: 10px; font-weight: 600; }
.view-switch button.active { background: var(--surface); color: var(--text); }

/* 320 px : un titre de document se coupe entre les mots, jamais au milieu
   (245 px, avec « Supprimer » à côté, donnait « Mathémati / ques »). */
.course-shell { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 16px; align-items: start; }
.course-outline { border-radius: var(--radius-md); padding: 20px 14px; border: 1px solid var(--border); background: var(--surface); max-height: 78dvh; overflow-y: auto; }
.course-outline > .eyebrow { padding: 0 8px; margin-bottom: 14px; }
.outline-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px; align-items: center; }
.outline-item {
  width: 100%;
  min-height: 44px;
  border: 0;
  background: transparent;
  padding: 11px 9px;
  border-radius: 10px;
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 8px;
  text-align: left;
  color: var(--nn-color-text, #152033);
}
.outline-item.active { background: var(--accent-soft); color: var(--accent-dark); }
.outline-item > span { width: 24px; height: 24px; border: 1px solid var(--border); border-radius: 50%; display: grid; place-items: center; font-size: 12px; }
.outline-item.done > span { background: var(--success); border-color: var(--success); color: #fff; }
.outline-item strong, .outline-item small { display: block; }
.outline-item strong { font-size: 15px; line-height: 1.35; overflow-wrap: break-word; -webkit-hyphens: auto; hyphens: auto; }
.outline-item small { margin-top: 3px; font-size: 12px; color: var(--nn-color-muted, #6f7b8f); }
.outline-delete {
  min-height: 44px;
  border: 0;
  border-radius: 9px;
  padding: 0 10px;
  background: transparent;
  color: var(--danger);
  font-size: 13px;
}
.outline-delete:hover, .outline-delete:focus-visible { background: #fff0ed; }
/* Focus visible au clavier sur tout ce qui se touche dans la page Cours. */
.outline-item:focus-visible, .outline-delete:focus-visible, .course-subject-fold summary:focus-visible {
  outline: 3px solid var(--nn-focus-ring, #3157d5);
  outline-offset: 2px;
}
/* Vue générale : une matière à la fois, chacune repliable. */
.course-subject-fold { border-top: 1px solid var(--border); padding: 6px 0; }
.course-subject-fold:first-of-type { border-top: 0; }
.course-subject-fold summary {
  list-style: none; cursor: pointer; display: grid; grid-template-columns: 1fr auto;
  align-items: center; gap: 2px 10px; min-height: 44px; padding: 8px; border-radius: 10px;
}
.course-subject-fold summary > * { grid-column: 1; }
.course-subject-fold summary::-webkit-details-marker { display: none; }
/* Le chevron dit que le bloc se déplie, comme les chapitres (.chapter-fold). */
.course-subject-fold summary::after {
  content: "›"; grid-column: 2; grid-row: 1 / span 2;
  color: var(--nn-color-muted, #6f7b8f); font-size: 20px; transition: transform 120ms ease;
}
.course-subject-fold[open] summary::after { transform: rotate(90deg); }
.course-subject-fold summary strong { font-size: 16px; overflow-wrap: anywhere; }
.course-subject-fold[open] summary strong { color: var(--accent-dark); }
.course-subject-count { color: var(--nn-color-muted, #6f7b8f); font-size: 12px; }
.course-subject-fold > .eyebrow { padding: 0 8px; margin: 10px 0 6px; }
.course-subject-fold > .link-button { padding-left: 8px; font-size: 14px; }
/* Une analyse en cours : une ligne et un bouton pour relire la liste. */
.analysis-refresh {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 4px 10px; margin-bottom: 12px; padding: 6px 10px; border-radius: 10px;
  background: var(--accent-soft); color: var(--accent-dark); font-size: 13px;
}
.outline-progress { margin-top: 16px; padding: 16px 8px 4px; border-top: 1px solid var(--border); }
.outline-progress > span, .outline-progress > strong { display: block; font-size: 9px; }
.outline-progress > span { color: var(--muted); }
.outline-progress > strong { margin: 5px 0 10px; font-size: 16px; }
/* Sommaire des pages : un sélecteur compact, une ligne quoi qu'il arrive.
   Les boutons de navigation sous le texte gardent le déplacement page à page. */
.page-select {
  width: 100%;
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: inherit;
  font-size: 12px;
}

.course-content { border-radius: var(--radius-md); padding: 28px; border: 1px solid var(--border); background: var(--surface); }
.course-block + .course-block { margin-top: 28px; }
.block-label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .1em;
}
.paper { padding: 44px clamp(28px, 5vw, 64px); border: 1px solid #dfe3eb; border-radius: 12px; background: #fff; }
.paper-top { display: flex; justify-content: space-between; margin-bottom: 38px; color: var(--nn-color-muted, #6f7b8f); font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
.paper h3 { margin-bottom: 20px; font-family: var(--serif); font-size: 28px; }
.paper p { color: #3f4b5f; font-family: var(--serif); font-size: 15px; line-height: 1.8; }
/* Le texte extrait d'un PDF garde ses retours à la ligne : les reproduire est
   la seule façon honnête de montrer une page dont la mise en page est perdue.
   Les formules, elles, sont composées : du TeX brut ne serait pas lisible. */
.paper-extract {
  margin: 0;
  color: #3f4b5f;
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.8;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.paper-extract p, .paper-extract li { white-space: pre-wrap; }
/* Les auteurs signent la page, en bas à droite. */
.paper-authors {
  margin: 26px 0 0;
  color: #9aa3b2;
  font-family: var(--serif);
  font-size: 11px;
  font-style: italic;
  text-align: right;
}
.pdf-reader {
  display: grid;
  gap: 14px;
  min-width: 0;
}
.pdf-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-soft);
}
.pdf-nav, .pdf-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pdf-toolbar .secondary-btn { min-width: 44px; min-height: 44px; padding: 0 12px; }
.pdf-page-input {
  width: 64px;
  min-height: 44px;
  padding: 0 8px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--surface);
  color: inherit;
  text-align: center;
}
.pdf-page-count { color: var(--muted); font-size: 12px; white-space: nowrap; }
.pdf-stage {
  min-height: 280px;
  display: flex;
  justify-content: center;
  overflow: auto;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #e9edf4;
  -webkit-overflow-scrolling: touch;
}
.pdf-canvas {
  display: block;
  max-width: none;
  background: #fff;
  box-shadow: 0 3px 18px rgba(25, 38, 70, .16);
}
.pdf-status { min-height: 1.5em; color: var(--muted); font-size: 13px; text-align: center; }
.pdf-status:empty { display: none; }
.pdf-status-error, .form-error { color: var(--danger, #b3261e); }
.pdf-text-link { justify-self: start; }
.pdf-unindexed {
  margin-top: 8px;
  padding: 12px;
  border: 1px solid #e6c99a;
  border-radius: 10px;
  background: var(--hold-soft);
  color: #7d4b00;
  font-size: 13px;
}
.course-actions { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 28px; padding-top: 22px; border-top: 1px solid var(--border); flex-wrap: wrap; }
.page-position { color: var(--muted); font-size: 13px; white-space: nowrap; }
.theorem-box {
  margin-top: 24px;
  padding: 18px;
  border-left: 3px solid var(--accent);
  background: var(--surface-blue);
  color: #46536a;
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.7;
}

/* ================================================================
   Compétences : graphe de prérequis
   ================================================================ */

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.training-subjects { margin-bottom: var(--nn-space-4); }
.chip {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: inherit;
  font-size: 12px;
}
.chip.active { border-color: #cad4ff; background: var(--accent-soft); color: var(--accent-dark); font-weight: 700; }
.chip small { color: var(--muted); font-size: 10px; }
.chip.active small { color: var(--accent-dark); }
/* Le graphe est une suite de colonnes : une notion se place après tous ses
   prérequis. Les liens sont tracés après mesure des boîtes, donc aucune
   coordonnée n'est devinée et rien ne peut sortir du cadre. */
.graph-canvas {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 34px;
  padding: 26px;
  width: max-content;
  min-width: 100%;
}
.graph-column { display: flex; flex-direction: column; justify-content: center; gap: 14px; }

.explain-panels { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.mini-panel { padding: 20px; border-radius: 14px; border: 1px solid var(--border); background: var(--surface); height: auto; }
.mini-panel h3 { margin: 0 0 8px; font-size: 16px; }
.mini-panel p { margin: 0; color: var(--muted); font-size: 12px; }

/* ================================================================
   Progression
   ================================================================ */

.progress-hero { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--nn-color-surface, var(--surface)); padding: 42px; box-shadow: var(--shadow); }
.progress-hero-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 28px; }
.mini-stat { padding: 20px; border-radius: 14px; background: var(--surface-soft); border: 1px solid var(--border); height: auto; }
.mini-stat > span, .mini-stat > strong { display: block; }
.mini-stat > span { color: var(--nn-color-muted, var(--muted)); font-size: 13px; }
.mini-stat > strong { margin-top: 8px; font-size: 26px; }
.mini-stat small { display: block; margin-top: 6px; color: var(--nn-color-muted, var(--muted)); font-size: 12px; line-height: 1.5; }
.dimension-section { display: grid; gap: 14px; }
.dimension-sources { color: var(--nn-color-muted, var(--muted)); font-size: 13px; }
.progress-dimensions { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.dimension-card { padding: 20px; border: 1px solid var(--border); border-radius: 14px; background: var(--nn-color-surface, var(--surface)); }
.dimension-card > span, .dimension-card > strong, .dimension-card small { display: block; }
.dimension-card > span { color: var(--nn-color-muted, var(--muted)); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.dimension-card > strong { margin-top: 10px; font-size: 26px; }
.dimension-card p { min-height: 34px; margin: 12px 0 8px; color: var(--nn-color-muted, #46536a); font-size: 13px; line-height: 1.55; }
.dimension-card small { color: var(--nn-color-muted, var(--muted)); font-size: 12px; line-height: 1.45; }
.dimension-track { overflow: hidden; height: 6px; margin-top: 12px; border-radius: 999px; background: var(--surface-soft); }
.dimension-track span { display: block; height: 100%; border-radius: inherit; background: var(--nn-color-accent, var(--accent)); }
.activity-chart { display: grid; grid-template-columns: repeat(7, minmax(42px, 1fr)); gap: 10px; align-items: end; min-height: 210px; margin-top: 22px; }
.activity-day { display: grid; grid-template-rows: 28px 130px 22px; gap: 7px; align-items: end; text-align: center; }
.activity-day strong { color: var(--nn-color-muted, var(--muted)); font-size: 11px; font-weight: 600; }
.activity-day small { color: var(--nn-color-muted, var(--muted)); font-size: 12px; text-transform: capitalize; }
.activity-column { display: flex; align-items: end; height: 130px; padding: 0 5px; border-radius: 10px; background: var(--surface-soft); }
.activity-column span { display: block; width: 100%; min-height: 2px; border-radius: 7px 7px 3px 3px; background: var(--accent); }

/* Les panneaux gardent leur hauteur naturelle : étirés, un bloc marqué
   deviendrait une grande zone vide. */
.dashboard-grid { display: grid; grid-template-columns: 1.35fr 1fr 1fr; gap: 14px; align-items: start; }
.dashboard-grid.lower { grid-template-columns: repeat(3, 1fr); }
/* Page Révision : les formats de séance que Nabla ne sait pas tenir
   restent visibles, côte à côte, chacun avec sa raison. */
.revision-readiness { margin-top: 16px; }
.revision-readiness > span { font-size: 11px; color: var(--muted); }
.revision-formats { margin-top: 18px; display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; }
.revision-format { padding: 16px; border-radius: 12px; background: var(--surface-soft); display: grid; gap: 10px; align-content: start; }
.revision-format strong { font-size: 13px; }
.revision-format button { min-height: 44px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: inherit; font-size: 11px; }
.panel { padding: 22px; border-radius: var(--radius-md); border: 1px solid var(--border); background: var(--surface); height: auto; }
.panel-head h3 { margin: 2px 0 0; font-size: 20px; letter-spacing: -.02em; }
.insight-list, .stack-list { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 12px; }
.insight-list li, .stack-list li { padding: 14px; border-radius: 12px; background: var(--surface-soft); }
.insight-list strong, .insight-list span, .stack-list strong, .stack-list span { display: block; }
.insight-list strong, .stack-list strong { font-size: 14px; }
.insight-list span, .stack-list span { margin-top: 5px; color: var(--nn-color-muted, var(--muted)); font-size: 13px; }

.mastery-table { overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.table-row { display: grid; grid-template-columns: 1.2fr 1fr 120px 150px; gap: 18px; align-items: center; padding: 18px 20px; }
.table-row + .table-row { border-top: 1px solid var(--border); }
.table-head { background: var(--nn-color-bg, #fafbfe); color: var(--nn-color-muted, var(--muted)); font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.table-chapter strong, .table-chapter small { display: block; }
.table-chapter strong { font-size: 15px; }
.table-chapter small { margin-top: 5px; color: var(--nn-color-muted, var(--muted)); font-size: 13px; }
.table-progress { display: grid; grid-template-columns: 48px minmax(0, 1fr); align-items: center; gap: 12px; }
.table-progress span { font-size: 12px; font-weight: 700; }
.status-pill { display: inline-flex; justify-content: center; padding: 7px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; }
.status-pill.success { background: #e9f7f1; color: #23755a; }
.status-pill.warn { background: #fff5d9; color: #795c16; }
.status-pill.mid { background: var(--accent-soft); color: var(--accent-dark); }
.status-pill.danger { background: #eef0f4; color: #5c6779; }
/* Les pastilles portent le vocabulaire du serveur, pour qu'aucune traduction
   intermédiaire ne puisse dériver. */
.status-pill.mastered { background: #e9f7f1; color: #23755a; }
.status-pill.consolidating { background: var(--accent-soft); color: var(--accent-dark); }
.status-pill.learning { background: #fff5d9; color: #795c16; }
.status-pill.review-due { background: #fffbee; color: #795c16; }
.status-pill.available { background: #eef2f8; color: #4d5f80; }
.status-pill.locked { background: #eef0f4; color: #5c6779; }
/* Une ligne de tableau cliquable est un bouton : sans largeur imposée elle se
   réduirait à son contenu et la grille se désalignerait. */
.table-row.row-tappable { width: 100%; min-height: 44px; border: 0; background: transparent; color: inherit; text-align: left; font: inherit; }
.summary-box { margin-top: 18px; padding: 18px; border-radius: 12px; background: var(--surface-soft); }
.summary-box p { color: #46536a; font-size: 12px; }

/* ---- Progression : où j'en suis, ce que je travaille ensuite, le détail -- */
/* Le détail replié : un volet par sujet, son titre dit ce qu'il contient. */
.progress-folds { display: grid; gap: 10px; margin-top: 34px; }
.progress-fold { border: 1px solid var(--border); border-radius: var(--nn-radius, var(--radius-md)); background: var(--nn-color-surface, var(--surface)); }
.progress-fold > summary {
  list-style: none; cursor: pointer; min-height: 52px; display: flex; align-items: center;
  gap: 12px; padding: 12px 18px;
}
.progress-fold > summary::-webkit-details-marker { display: none; }
.progress-fold > summary::after { content: "›"; content: "›" / ""; margin-left: auto; color: var(--nn-color-muted, var(--muted)); font-size: 20px; transition: transform 120ms ease; }
.progress-fold[open] > summary::after { transform: rotate(90deg); }
.progress-fold-title { flex: 0 1 auto; font-size: 16px; font-weight: 700; }
.progress-fold-teaser { flex: 1 1 0; min-width: 0; color: var(--nn-color-muted, var(--muted)); font-size: 13px; }
.progress-fold-body { padding: 4px 18px 18px; border-top: 1px solid var(--border); padding-top: 16px; }
.progress-subtitle { margin: 20px 0 0; font-size: 17px; }

/* ================================================================
   Séquence d'étude : chargement, appairage, préparation
   ================================================================ */

.loading-screen { display: flex; flex-direction: column; align-items: center; padding-top: 48px; gap: 16px; }
.loading-text { color: var(--nn-color-muted); font-size: 0.95rem; }
/* Entre deux pages : la zone de page garde une hauteur, la navigation reste. */
.loading-inline { min-height: 40vh; padding-top: var(--nn-space-6); }

.pairing-screen { display: flex; flex-direction: column; align-items: center; padding-top: 24px; gap: 12px; }
.pairing-intro { color: var(--muted); font-size: 0.95rem; text-align: center; max-width: 400px; margin: 8px 0 12px; }
.pairing-form { display: flex; flex-direction: column; width: 100%; max-width: 360px; gap: 8px; }
.pairing-label { font-size: 0.85rem; color: var(--muted); margin-top: 4px; }
.pairing-input {
  font-size: 1.1rem;
  padding: 14px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  width: 100%;
}
.pairing-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.pairing-input::placeholder { color: var(--nn-color-muted); }
.pairing-button {
  min-height: 52px;
  margin-top: 8px;
  border: none;
  border-radius: 12px;
  background: var(--nn-color-text);
  color: var(--nn-color-surface);
  font-size: 1.02rem;
  font-weight: 600;
  cursor: pointer;
}
.pairing-button:active { transform: translateY(1px); }
.pairing-button:disabled { opacity: .5; cursor: default; }
.pairing-error {
  color: #8e2019;
  background: var(--miss-soft);
  border: 1px solid var(--miss);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 0.95rem;
  max-width: 360px;
}
/* An alert with nothing to say must not paint an empty red box. */
.pairing-error:empty { display: none; }

.preparing-screen { display: flex; flex-direction: column; align-items: center; padding-top: 48px; gap: 14px; text-align: center; }
.preparing-title { font-size: 1.25rem; font-weight: 700; }
.preparing-phase { color: var(--nn-color-muted, var(--muted)); font-size: 0.95rem; }
/* La place dans la file : la ligne la plus utile de l'attente, lue d'abord. */
.preparing-queue { color: var(--nn-color-text, var(--text)); font-size: 1rem; font-weight: 600; }
.preparing-elapsed { color: var(--nn-color-muted, #a4adbc); font-size: 0.85rem; }

/* ================================================================
   Énoncé et indices
   ================================================================ */

.exercise-title { font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em; }
.exercise-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; color: var(--nn-color-muted, var(--muted)); font-size: 0.9rem; margin: 6px 0 16px; }
.meta-stars { color: var(--accent-dark); font-weight: 700; }
/* Un exercice de la banque Nabla Nova se reconnaît d'un coup d'œil. */
.meta-origin-bank {
  padding: 1px 10px;
  border: 1px solid currentColor;
  border-radius: 999px;
  color: var(--nn-color-accent, var(--accent-dark));
  font-weight: 600;
}
.statement {
  padding: 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.rich-text > * + * { margin-top: 12px; }
.rich-heading { font-size: 1.05rem; font-weight: 700; }
.rich-text h5.rich-heading { font-size: 0.98rem; color: var(--muted); }
.rich-list { padding-left: 22px; }
.rich-list li { margin-top: 6px; }
.rich-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92rem;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2px 6px;
}
/* Une formule large défile horizontalement ; les fractions dépassent de
   quelques pixels en hauteur, d'où la marge intérieure verticale : sans elle
   le navigateur ajoute une barre de défilement verticale par-dessus la
   formule. */
.math-display { margin: 14px 0; padding: 8px 0; text-align: center; overflow-x: auto; overflow-y: hidden; }
.math-fallback {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.95rem;
  color: var(--muted);
  /* Une source trop longue pour le moteur s'affiche telle quelle : un seul
     « mot » de milliers de caractères ne doit pas élargir la page. */
  overflow-wrap: anywhere;
}
.katex { font-size: 1.05em; }
.katex-display { margin: 0; }
.math-inline .katex { font-size: 1em; }

.hint-list { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.hint {
  padding: 14px 16px 14px 44px;
  position: relative;
  border: 1px solid #dce4ff;
  border-radius: var(--radius-sm);
  background: var(--surface-blue);
  font-size: 0.98rem;
}
.hint::before {
  content: "?";
  position: absolute;
  left: 14px;
  top: 13px;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
}
.hint-error { color: #8e2019; font-size: 0.92rem; margin-top: 8px; }

/* ================================================================
   Copie manuscrite
   Les propriétés de structure de cette section commandent le stylet :
   ne rien y changer sans repasser par une validation sur l'iPad.
   ================================================================ */

.notebook {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* Écrire à la main demande plus de largeur que lire un énoncé : la copie
     déborde de la colonne de lecture jusqu'aux bords de l'écran. */
  --notebook-bleed: max(0px, (100vw - 48px - 680px) / 2);
  margin-inline: calc(-1 * var(--notebook-bleed));
}

.notebook-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 0;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.notebook-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tool-button {
  min-height: 44px;
  min-width: 88px;
  padding: 10px 16px;
  font: inherit;
  font-size: 0.98rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
}

.tool-button:disabled {
  opacity: 0.45;
  cursor: default;
}

.tool-button.is-active {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}

.notebook-status {
  margin: 0;
  font-size: 0.9rem;
  color: var(--muted);
}

/* Jetons AA (T18 M3) : l'ancien --success tombait à 3,71:1 sur le fond clair en 14 px. */
.notebook-status[data-state="saved"] { color: var(--nn-color-success); }
.notebook-status[data-state="failed"] { color: var(--nn-color-danger); }

.notebook-notice {
  margin: 0;
  padding: 10px 12px;
  font-size: 0.94rem;
  color: #7d4b00;
  background: var(--hold-soft);
  border: 1px solid #e6c99a;
  border-radius: 8px;
}

.notebook-pages {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.notebook-page {
  position: relative;
}

.notebook-canvas {
  display: block;
  width: 100%;
  /* Format A4 : la page garde ses proportions quelle que soit la largeur. */
  aspect-ratio: 1000 / 1414;
  height: auto;
  background: #ffffff;
  border-radius: 4px;
  box-shadow: 0 2px 14px rgba(25, 38, 70, 0.12);
  /* Le doigt fait défiler la copie, le stylet écrit. */
  touch-action: pan-y;
}

.notebook-page-number {
  position: absolute;
  right: 10px;
  bottom: 8px;
  font-size: 0.85rem;
  color: #a4adbc;
}

/* ---- Le moteur LaTeX intégré : réponse tapée, aperçu composé en direct.
   Même langage visuel que le reste de la copie : une carte douce, l'accent
   bleu au focus, saisie à gauche et rendu KaTeX à droite (empilés sur
   écran étroit). */
.typed-answer { display: grid; gap: 10px; }
.typed-answer-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.typed-answer-head .card-title { margin: 0; }
.typed-answer-hint { color: var(--muted); font-size: 12px; }
.typed-answer-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px;
  align-items: start;   /* rien n'est étiré : l'aperçu reçoit la hauteur du champ (session.js) */
}
.typed-answer-input {
  min-height: 320px; resize: none; padding: 12px 14px;
  /* Contour à 3:1 au moins et texte indicatif à 4,5:1 (T18 M4) : --border ne donnait que 1,23:1. */
  border: 1px solid var(--nn-color-muted); border-radius: var(--radius-md);
  background: var(--surface); color: inherit;
  /* 16 px au moins : en dessous, Safari sur iPhone zoome la page à la saisie. */
  font: inherit; font-size: 16px; line-height: 1.6;
}
.typed-answer-input::placeholder { color: var(--nn-color-muted); }
.typed-answer-input:focus {
  outline: none; border-color: var(--accent, #2a78d6);
  box-shadow: 0 0 0 3px rgba(42, 120, 214, 0.14);
}
.typed-answer-preview {
  min-height: 320px; height: auto; padding: 12px 14px;
  border: 1px dashed var(--border); border-radius: var(--radius-md);
  background: var(--surface-soft, #f7f8fb); overflow-x: auto;
}
@media (max-width: 760px) {
  .typed-answer-grid { grid-template-columns: minmax(0, 1fr); }
  .typed-answer-input, .typed-answer-preview { min-height: 220px; }
}

/* ---- Aide à la saisie LaTeX (drawing/latex-saisie.js) : la commande se
   complète pendant qu'on la tape, et le tableau des symboles usuels insère la
   commande. L'aperçu porte un titre. */
.latex-aide { margin-top: 6px; color: var(--nn-color-muted); font-size: 13px; }
.typed-answer-preview-column { display: grid; gap: 6px; align-content: start; min-width: 0; }
.typed-answer-preview-title { color: var(--nn-color-muted); font-size: 13px; font-weight: 600; }
/* Le champ et sa liste : la liste se place sous le jeton tapé. */
.latex-saisie { position: relative; display: grid; min-width: 0; }
.latex-propositions {
  position: absolute; z-index: 20; min-width: 240px; max-width: 100%; max-height: 272px;
  overflow-y: auto; padding: 4px; list-style: none;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); box-shadow: var(--shadow);
}
.latex-propositions[hidden] { display: none; }
.latex-option {
  display: flex; align-items: baseline; gap: 10px; padding: 6px 10px;
  border-radius: 8px; color: var(--nn-color-text); cursor: pointer;
}
/* L'option active se voit aussi sans la couleur : trait à gauche et gras. */
.latex-option.est-active {
  background: var(--accent-soft); font-weight: 600;
  box-shadow: inset 3px 0 0 var(--nn-color-text);
}
.latex-option-commande { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; }
.latex-option-description { color: var(--nn-color-muted); font-size: 13px; }
/* Écran tactile : une bande défilante sous le champ, options au doigt. */
.latex-propositions.est-bande {
  position: static; display: flex; gap: 6px; min-width: 0; max-width: none; max-height: none;
  margin-top: 6px; overflow-x: auto; overflow-y: hidden; box-shadow: none;
}
.latex-propositions.est-bande .latex-option {
  flex: 0 0 auto; align-items: center; min-height: 44px; border: 1px solid var(--border);
}
/* Même spécificité que la bande, écrite après : une bande fermée disparaît. */
.latex-propositions.est-bande[hidden] { display: none; }
/* Refus d'une insertion (longueur maximale), visible près du champ. */
.latex-refus { margin-top: 6px; color: var(--nn-color-danger); font-size: 13px; }
/* Copie invisible du champ, qui sert seulement à mesurer où est le jeton. */
.latex-miroir {
  position: absolute; height: 0; overflow: hidden; visibility: hidden; pointer-events: none;
}
/* Le tableau des symboles, replié par défaut. */
.latex-palette { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.latex-palette > summary {
  list-style: none; display: flex; align-items: center; min-height: 44px; padding: 0 14px;
  border-radius: var(--radius-md); font-size: 14px; font-weight: 600; cursor: pointer;
}
/* Le chevron des autres volets (.progress-fold) : il dit que le tableau se déplie. */
.latex-palette > summary::-webkit-details-marker { display: none; }
.latex-palette > summary::after { content: "›"; content: "›" / ""; margin-left: auto; color: var(--nn-color-muted); font-size: 20px; transition: transform 120ms ease; }
.latex-palette[open] > summary::after { transform: rotate(90deg); }
.latex-palette-groupe { display: grid; gap: 6px; padding: 0 14px 12px; }
.latex-palette-groupe-titre { color: var(--nn-color-muted); font-size: 13px; font-weight: 600; }
.latex-palette-symboles { display: flex; flex-wrap: wrap; gap: 6px; }
.latex-palette-symbole {
  display: inline-grid; place-items: center; min-width: 44px; min-height: 44px; padding: 0 8px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--nn-color-text); font: inherit; cursor: pointer;
}
.latex-palette-symbole:hover { background: var(--surface-soft); }

/* ---- Mise en page de la copie tapée (drawing/edition-copie.js) : le refus
   d'une action (longueur maximale). Couleurs par jetons : le mode sombre suit
   sans règle propre. */
/* Refus d'une mise en page (longueur maximale), juste au-dessus du champ. Une
   longue copie étire le champ et l'aperçu sur des milliers de pixels : collé au
   haut et au bas de la fenêtre, le message reste en vue tant qu'une partie de la
   carte l'est. Fond opaque : il passe sur le texte du champ et de l'aperçu. */
.edition-refus {
  position: sticky; top: 0; bottom: 0; z-index: 1; margin: 0; padding: 8px 12px;
  color: var(--nn-color-danger); font-size: 13px;
  background: var(--surface); border: 1px solid var(--nn-color-danger); border-radius: 8px;
}

/* Copie tapée : les lignes, retraits et lignes vides de l'élève sont respectés. */
.rich-text-copie p, .rich-text-copie blockquote { white-space: pre-wrap; overflow-wrap: anywhere; tab-size: 4; }
.rich-text-copie .rich-blank { height: calc(1.65em - 12px); margin-top: 0; }   /* + 12 px de la règle voisine = 1 ligne */
.typed-answer-input { tab-size: 4; }   /* même taquet que l'aperçu (défaut navigateur : 8) */

.notebook-footer {
  display: flex;
  justify-content: center;
  max-width: 420px;
  margin: 0 auto;
  padding-bottom: 24px;
}
.notebook-footer .secondary-button { flex: 1; }

/* ---- rendre la copie ---- */
.notebook-submit {
  max-width: 420px;
  margin: 0 auto;
  padding-bottom: 48px;
}
.notebook-confirm-question {
  color: var(--text);
  text-align: center;
}
.notebook-confirm {
  display: flex;
  gap: 12px;
}
.notebook-confirm .primary-button,
.notebook-confirm .secondary-button {
  flex: 1;
}

/* ================================================================
   Correction
   ================================================================ */

.correction-screen { padding-bottom: 8px; }
.correction-screen > .card + .card { margin-top: 12px; }
/* « Continuer » et « Refaire cet exercice » : espacés entre eux et du
   paragraphe au-dessus (ils se touchaient). */
.correction-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }
.chapter-progress-card .card-note + .card-note { margin-top: 4px; }
.verdict-card { text-align: left; }
/* L'essentiel : trois lignes au plus sous le verdict. */
.correction-essentials { list-style: none; display: grid; gap: 12px; margin-top: 14px; }
.essential { display: grid; gap: 2px; }
.essential-label {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--nn-color-muted, var(--muted));
}
/* Le détail, replié section par section : le résumé est une cible de doigt. */
.correction-fold > .fold-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  cursor: pointer;
  list-style: none;
}
.correction-fold > .fold-summary::-webkit-details-marker { display: none; }
.correction-fold > .fold-summary::after {
  content: "›";
  margin-left: auto;
  color: var(--nn-color-muted, var(--muted));
  font-size: 1.2rem;
  transition: transform 120ms ease;
}
.correction-fold[open] > .fold-summary { margin-bottom: 10px; }
.correction-fold[open] > .fold-summary::after { transform: rotate(90deg); }
.correction-fold > .fold-summary:focus-visible {
  outline: 2px solid var(--nn-focus-ring);
  outline-offset: 4px;
  border-radius: 8px;
}
.fold-summary .card-title { margin: 0; }
.fold-count {
  min-width: 26px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-soft);
  color: var(--nn-color-text, var(--text));
  font-size: 0.82rem;
  font-weight: 700;
  text-align: center;
}
@media (prefers-reduced-motion: reduce) {
  .correction-fold > .fold-summary::after { transition: none; }
}
.verdict {
  display: inline-block;
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 7px 14px;
  border-radius: 999px;
}
.verdict-correct { color: #23755a; background: #e9f7f1; }
.verdict-partial { color: #795c16; background: #fff5d9; }
.verdict-incorrect { color: #9a4438; background: #fff0ed; }
.verdict-uncertain { color: #4d5f80; background: var(--surface-soft); }

.score-row { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; }
.score-label { display: flex; justify-content: space-between; font-size: 0.92rem; color: var(--muted); }
.score-value { font-weight: 700; color: var(--text); }
.score-track { height: 8px; border-radius: 999px; background: var(--surface-soft); overflow: hidden; }
.score-fill { display: block; height: 100%; border-radius: inherit; background: var(--accent); }

.observation-list { display: flex; flex-direction: column; }
.observation + .observation { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 12px; }
.observation-labels { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 6px; }
.observation-category { font-size: 0.82rem; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.severity-blocking { color: #9a4438; font-weight: 700; }
.severity-major { color: #795c16; font-weight: 700; }
.severity-minor { color: var(--muted); }

.doubt-card { border-left: 4px solid var(--warn); }

/* ================================================================
   QCM (views/qcm.js) : des cases à cocher, puis le résultat
   ================================================================ */

.qcm-screen { padding-bottom: 8px; }
.qcm-intro { margin: 6px 0 4px; }
.qcm-screen > .card, .qcm-screen > .correction-actions { margin-top: 12px; }
/* Un fieldset garde par défaut la largeur de son contenu : une longue
   formule élargirait la page au lieu de défiler dans son choix. */
.qcm-question { min-width: 0; }
/* La légende reste dans la carte, pas posée sur sa bordure. */
.qcm-question > legend { float: left; width: 100%; padding: 0; }
.qcm-question > legend + * { clear: both; }
.qcm-number { font-size: 0.9rem; font-weight: 700; color: var(--muted); margin-bottom: 8px; }
.qcm-choices { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; padding: 0; list-style: none; }
/* Toute la ligne se touche : la case est dans son libellé. */
.qcm-choice, .qcm-choice-line {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.qcm-choice { cursor: pointer; }
.qcm-choice:has(.qcm-radio:checked) { border-color: var(--nn-color-accent); background: var(--accent-soft); }
.qcm-choice:focus-within { outline: 3px solid var(--nn-focus-ring); outline-offset: 2px; }
.qcm-radio { flex: 0 0 auto; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--nn-color-accent); }
.qcm-letter { flex: 0 0 auto; font-weight: 700; color: var(--muted); }
/* Une longue formule en ligne défile dans son choix au lieu d'élargir la page. */
.qcm-choice-text { display: block; flex: 1 1 auto; min-width: 0; overflow-x: auto; overflow-wrap: anywhere; }
.qcm-progress { color: var(--muted); font-size: 0.95rem; margin-bottom: 12px; }
.qcm-score { font-size: 2rem; font-weight: 700; letter-spacing: -.02em; }
.qcm-to-review { padding-left: 22px; }
.qcm-to-review li + li { margin-top: 6px; }
.qcm-reviewed .qcm-number { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }
.qcm-verdict { padding: 2px 10px; border-radius: 999px; font-size: 0.85rem; }
.qcm-verdict-right { color: #23755a; background: #e9f7f1; }
.qcm-verdict-wrong { color: #9a4438; background: #fff0ed; }
/* Juste et choisi se lisent aussi en mots (« Bonne réponse », « Ta
   réponse ») : la couleur n'est qu'un renfort, portée par la bordure. */
.qcm-choice-line { flex-wrap: wrap; }
.qcm-choice-correct { border-color: var(--nn-color-success); box-shadow: inset 4px 0 0 var(--nn-color-success); }
.qcm-choice-chosen:not(.qcm-choice-correct) { border-color: var(--nn-color-danger); box-shadow: inset 4px 0 0 var(--nn-color-danger); }
.qcm-mark { flex-basis: 100%; font-size: 0.85rem; font-weight: 600; color: var(--muted); }
.qcm-explanation { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
/* Téléphone : en fin de feuille (le premier bloc 720 px reste celui de la coquille). */

.concept-list { display: flex; flex-direction: column; gap: 10px; }
.concept {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.concept-locked { opacity: .72; }
.concept-name { font-size: 1rem; font-weight: 600; }
.concept-reason { color: var(--muted); font-size: 0.88rem; margin-top: 4px; }
.concept-open { border: none; background: transparent; color: var(--accent-dark); font-weight: 700; cursor: pointer; min-height: 44px; }
.concept-open:active { opacity: .7; }
.concept-head { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
/* Décision 57-A : notion verrouillée ouverte en entraînement. Un avertissement,
   pas une erreur : l'ambre est porté par la bordure, le texte reste foncé
   pour le contraste. */
.concept-training-warning {
  margin: 0 0 16px; padding: 12px 14px;
  border: 1px solid var(--nn-color-warning, #d78a2f); border-left-width: 4px;
  border-radius: var(--radius-sm); background: var(--nn-color-surface, var(--hold-soft));
  color: var(--nn-color-text, #152033); font-size: 0.95rem;
}
.concept-description { margin-bottom: 16px; }

/* ================================================================
   Adaptations d'écran
   ================================================================ */

@media (max-width: 1200px) {
  .mode-grid.four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dashboard-grid { grid-template-columns: 1fr 1fr; }
  .dashboard-grid.lower { grid-template-columns: 1fr 1fr; }
  .panel.large { grid-column: 1 / -1; }
  .explain-panels { grid-template-columns: 1fr; }
}

@media (max-width: 1040px) {
  .app-shell { grid-template-columns: 88px minmax(0, 1fr); }
  .sidebar { padding-left: 8px; padding-right: 8px; }
  .brand { justify-content: center; padding-left: 0; padding-right: 0; }
  .brand > div:last-child, .mini-profile > div:last-child { display: none; }
  /* Chaque page garde son libellé, en petit sous l'icône : un bouton réduit
     à son glyphe n'était ni lisible pour l'élève ni nommé pour un lecteur
     d'écran. */
  .nav-item { flex-direction: column; justify-content: center; gap: 2px; min-height: 56px; padding: 6px 2px; text-align: center; }
  .nav-label { max-width: 100%; font-size: 10px; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .mini-profile { justify-content: center; padding-left: 0; padding-right: 0; }
  /* La barre repliée est trop étroite pour la phrase : la marque devient un
     glyphe, la raison reste dans l'infobulle et revient en entier dès que la
     barre se déplie. Sans cela le mot « INDISPONIBLE » était tronqué. */
  .hero-card, .training-reco { grid-template-columns: 1fr; }
  .math-panel { min-height: 260px; }
  .reco-summary { border-left: 0; border-top: 1px solid #dde5ff; }
  .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .quick-actions { grid-template-columns: 1fr; }
  .course-shell { grid-template-columns: 260px minmax(0, 1fr); }
  .progress-hero-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .progress-dimensions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
  .intro-banner { grid-template-columns: 1fr; }
  .course-shell { grid-template-columns: 1fr; }
  .table-row { grid-template-columns: 1fr; }
  .table-head { display: none; }
  .dashboard-grid, .dashboard-grid.lower { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .app-shell { display: block; }
  /* Sur téléphone, la navigation devient une barre d'onglets en bas, à
     portée de pouce : le haut de l'écran reste à l'action du jour. */
  .sidebar {
    position: fixed; top: auto; right: 0; bottom: 0; left: 0; z-index: 20;
    height: auto; overflow: visible;
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    border-right: 0; border-top: 1px solid var(--border);
  }
  .brand, .sidebar-footer { display: none; }
  /* « Se déconnecter » passe en bas de page, après le contenu : jamais avant
     l'action principale, jamais sous le pouce en haut de l'écran. */
  .shell-footer { display: flex; justify-content: center; margin-top: var(--nn-space-6); padding-top: var(--nn-space-4); border-top: 1px solid var(--border); }
  /* Sur-titres et pastilles : 13 px au moins sur téléphone (10 et 9 px
     étaient illisibles pour un collégien). */
  .eyebrow { font-size: 13px; letter-spacing: .08em; }
  .pill { font-size: 13px; letter-spacing: .06em; }
  /* Entraînement : les matières sur une ligne qui défile au doigt, au-dessus
     de l'action principale, sans la repousser sous le pli. */
  .training-subjects { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }
  .training-subjects .chip { flex: 0 0 auto; }
  /* Une colonne par page, quel que soit leur nombre (défini dans PAGES). */
  .nav { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 0; }
  .nav-item { border-radius: 0; }
  /* Un libellé long (« Entraînement ») passe sur deux lignes plutôt que
     d'être coupé ; jamais sous 11 px. */
  .nav-label { font-size: 11px; line-height: 1.15; white-space: normal; -webkit-hyphens: auto; hyphens: auto; overflow-wrap: anywhere; letter-spacing: -.01em; }
  /* L'onglet actif se distingue par sa couleur et son fond, pas par sa
     graisse : plus gras, « Entraînement » passait sur deux lignes. */
  .nav-item.active { font-weight: 500; }
  .main { padding: 20px 16px calc(80px + env(safe-area-inset-bottom)); }
  .topbar { flex-direction: column; }
  .hero-copy, .training-copy, .progress-hero { padding: 28px 22px; }
  /* Le panneau de la matière est décoratif et répète la maîtrise donnée plus
     bas : sur téléphone, l'accueil se resserre sur l'action du jour. */
  .math-panel { display: none; }
  .hero-card { min-height: 0; border-radius: var(--nn-radius); }
  .hero-copy h2 { margin: 14px 0 8px; font-size: 26px; line-height: 1.2; }
  .hero-subject { margin-top: var(--nn-space-4); }
  .hero-subject + h2 { margin-top: var(--nn-space-1); }
  .hero-action { width: 100%; }
  .stats-grid, .progress-hero-stats, .mode-grid.four { grid-template-columns: 1fr; }
  .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .stat-card { min-height: 0; padding: var(--nn-space-4); }
  .stat-label { min-height: 0; }
  .stat-card strong { font-size: 24px; }
  .progress-dimensions { grid-template-columns: 1fr; }
  .activity-chart { gap: 5px; overflow-x: auto; }
  .progress-card { padding: 0 18px; }
  .progress-row { grid-template-columns: 1fr; gap: 14px; }
  .intro-banner { padding: 28px 22px; }
  .course-content { padding: 18px; }
  .paper { padding: 30px 22px; }
  .course-actions { flex-direction: column-reverse; }
  .pdf-toolbar { align-items: stretch; }
  .pdf-nav, .pdf-tools { width: 100%; }
  .pdf-tools .secondary-btn, .pdf-nav .secondary-btn { flex: 1; }
  .pdf-stage { padding: 8px; }
}

.analysis-note { display: block; margin-top: 4px; font-size: 12px; line-height: 1.4; }
.analysis-note.running { color: var(--accent-dark, #4756c8); }
.analysis-note.failed { color: var(--danger, #b3261e); }
/* Vert foncé plutôt que --success : un texte de 12 px doit tenir le contraste AA. */
.analysis-note.ready { color: var(--nn-color-success, #23755a); }
/* Le détail d'un échec se lit : couleur de texte, pas le gris (4,28:1). */
.analysis-detail { display: block; margin-top: 2px; color: var(--nn-color-text, #152033); }

.node-class { display: inline-block; font-size: 10px; padding: 1px 6px; border-radius: 8px; margin: 2px 0; border: 1px solid var(--border); color: var(--muted, #667); }
.node-class.defined_object { color: #23639c; border-color: #a9c6e4; }
.node-class.result { color: #7c4a9c; border-color: #cdb2e0; }
.node-class.know_how { color: #2b7a4b; border-color: #a9d8bd; }

/* ── Réseau des notions ─────────────────────────────────────────────── */
.graph-mode-row { margin: 10px 0 4px; }
.network-shell { position: relative; background: var(--surface, #fff); border: 1px solid var(--border); border-radius: 16px; padding: 10px; }
/* L'épine de lecture : présente pour que rien ne flotte, discrète pour que
   les vraies dépendances gardent le premier plan — mais jamais invisible :
   quand elle est le seul pont entre deux régions, elle doit se lire. */
/* Passerelle entre deux chapitres : le moment où un chapitre s'appuie sur un
   autre, en rouge pour être lisible d'un coup d'œil. */
.bridge-swatch { background: #c0392b; }
/* Le fil du parcours : l'ordre du cours, notion par notion. */
/* Les dépendances non voisines n'apparaissent qu'au survol : le fil reste
   propre, le détail reste à portée de souris. */
/* Mode silencieux (défaut) : toutes les notions, presque aucune flèche.
   La spirale porte l'ordre ; les chemins s'illuminent au survol ; seules
   les flèches rouges de fin de chapitre restent. */
.network-legend { display: flex; flex-wrap: wrap; gap: 10px 16px; padding: 10px 6px 2px; font-size: 12px; }
.network-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.network-legend-item i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.network-legend-item i.pale { background: #cfd3dc; }
.network-legend-item.muted { color: var(--muted, #667); }

/* ---- Compétences : l'arbre de progression -------------------------------- */

/* Surtout pas de position:relative ici : les cartes doivent mesurer leurs
   offsets depuis .tree-canvas, où vit la couche de flèches. */
/* Les colonnes se centrent verticalement : le graphe prend une silhouette
   en pyramide (large au cœur du chapitre, effilée aux extrémités) au lieu
   d'un peigne aligné en haut. */

.tree-card {
  min-height: 44px;
  position: relative; text-align: left; padding: 10px 12px 12px 14px;
  border: 1px solid var(--border); border-left: 4px solid var(--chapter, #8a8886);
  border-radius: 10px; background: var(--surface); cursor: default;
  display: grid; gap: 5px; font: inherit; color: inherit;
  transition: box-shadow 120ms ease, border-color 120ms ease, opacity 120ms ease;
}

/* ---- Entraînement : chapitres repliables ---------------------------------- */

.chapter-fold { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); overflow: hidden; }
.chapter-fold + .chapter-fold { margin-top: 12px; }
.chapter-fold summary {
  list-style: none; cursor: pointer; display: flex; align-items: baseline;
  justify-content: space-between; gap: 12px; padding: 14px 18px;
}
.chapter-fold summary::-webkit-details-marker { display: none; }
.chapter-fold summary::after { content: "›"; color: var(--muted); transition: transform 120ms ease; }
.chapter-fold[open] summary::after { transform: rotate(90deg); }
.chapter-fold summary strong { font-size: 15px; }
.chapter-fold-count { color: var(--muted); font-size: 12px; margin-left: auto; }
.chapter-fold .chapter-list { border: 0; border-top: 1px solid var(--border); border-radius: 0; }

/* ---- Révision : formats QCM / Contrôle / DS ------------------------------- */

.revision-corrections { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; margin-top: 14px; }
.revision-toolbar .card-text { margin-bottom: 12px; }
.revision-panel { display: grid; gap: 12px; margin-top: 14px; }
/* Élément de grille : sans min-width:0 un titre de chapitre sans espace élargit la page. */
.revision-chapters { min-width: 0; }
.revision-panel .block-label { color: var(--nn-color-muted, var(--muted)); font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
/* Trois boutons courts sur une ligne : le choix tient sur un téléphone. */
.revision-format-picker { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.revision-format-option {
  min-height: 64px; display: grid; justify-items: center; align-content: center; gap: 2px;
  padding: 8px 6px; border: 1px solid var(--border); border-radius: var(--nn-radius, var(--radius-md));
  background: var(--nn-color-surface, var(--surface)); color: inherit; font: inherit; cursor: pointer; text-align: center;
}
.revision-format-option strong { font-size: 16px; }
.revision-format-option small { color: var(--nn-color-muted, var(--muted)); font-size: 13px; }
.revision-format-option.active { border: 2px solid var(--nn-color-accent, var(--accent)); background: var(--accent-soft); }
.revision-format-option:disabled { opacity: .6; cursor: default; }
.revision-format-tag { color: var(--nn-color-accent, var(--accent-dark)); font-size: 12px; font-weight: 700; }
.revision-format-chosen { display: grid; gap: 4px; padding: 12px 14px; border-radius: var(--nn-radius, var(--radius-sm)); background: var(--surface-soft); }
.revision-format-chosen p { margin: 0; font-size: 15px; line-height: 1.5; }
.revision-format-chosen small { color: var(--nn-color-muted, var(--muted)); font-size: 13px; line-height: 1.5; }
.revision-launch { width: 100%; min-height: 52px; font-size: 15px; }
.revision-panel > .helper-text { margin: 0; font-size: 13px; }
.revision-why-body { padding: 0 18px 16px; }
.revision-why-body .helper-text { margin: 0; font-size: 13px; }

/* ---- Compétences : le graphe du chapitre choisi --------------------------- */

.chapter-zone { margin-top: 4px; }

/* ---- Le parcours adaptatif ------------------------------------------------ */
.parcours-screen { display: grid; gap: 14px; }
.parcours-intro { color: var(--nn-color-muted, var(--muted)); font-size: 15px; }
.parcours-how summary { min-height: 44px; display: flex; align-items: center; cursor: pointer; color: var(--nn-color-accent, var(--accent-dark)); font-size: 14px; font-weight: 600; }
.parcours-how .helper-text { font-size: 13px; }
.parcours-next { display: grid; gap: 10px; }
.parcours-next .primary-button { justify-self: start; }
.parcours-next-notion { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.parcours-next-notion strong { font-size: 17px; }
.parcours-chapters { display: grid; gap: 8px; }
.parcours-chapter {
  display: grid; gap: 6px;
  padding: 10px 12px; border: 1px solid var(--border);
  border-radius: var(--nn-radius, var(--radius-md)); background: var(--nn-color-surface, var(--surface));
}
.parcours-chapter-head { display: flex; align-items: baseline; gap: 10px; }
.parcours-chapter-head strong { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.parcours-chapter-state { color: var(--nn-color-muted, var(--muted)); font-size: 13px; }
.parcours-chapter-mark { flex: none; color: var(--nn-color-success, var(--success)); font-weight: 700; }
.parcours-chapter-bar { overflow: hidden; height: 6px; border-radius: 999px; background: var(--surface-soft); }
.parcours-chapter-bar span { display: block; height: 100%; border-radius: inherit; background: var(--nn-color-accent, var(--accent)); }
.parcours-chapter.done .parcours-chapter-bar span { background: var(--nn-color-success, var(--success)); }

/* ---- Mode TD : la fiche d'un TD déposé et son export imprimé -------------- */
.td-screen { display: grid; gap: 14px; }
.td-intro { color: var(--nn-color-muted, var(--muted)); font-size: 15px; }
.td-start { justify-self: start; margin-bottom: 14px; }
.td-exercises { display: grid; gap: 8px; }
.td-exercise {
  display: grid; gap: 8px;
  padding: 10px 12px; border: 1px solid var(--border);
  border-radius: var(--nn-radius, var(--radius-md)); background: var(--nn-color-surface, var(--surface));
}
.td-exercise-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.td-exercise-head strong { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.td-exercise-state { color: var(--nn-color-muted, var(--muted)); font-size: 13px; }
.td-exercise-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.td-pdf-link { display: inline-flex; align-items: center; min-height: 44px; }
.td-export-card { display: grid; gap: 10px; }
.td-export-card .primary-button { justify-self: start; }
/* L'énoncé d'un TD vient du texte lu dans le document : ses retours à la ligne
   (questions numérotées) sont gardés, comme le texte extrait d'une page. */
.td-statement p, .td-statement li { white-space: pre-wrap; }
/* Un énoncé de PDF pas encore transcrit : ses pages en images, à la largeur de
   la carte (téléphone compris), jamais le texte lu par pdftotext. */
.td-statement-pages { display: grid; gap: 10px; }
.td-statement-page { display: block; width: 100%; height: auto; border: 1px solid var(--border); background: #fff; }
.td-statement-page[hidden] { display: none; }
.td-export-statement-page { display: block; max-width: 100%; height: auto; border: 1px solid var(--border); }
.td-export { display: grid; gap: 18px; max-width: 820px; margin: 0 auto; padding: 24px 16px; }
.td-export-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.td-export-item { display: grid; gap: 10px; padding-top: 14px; border-top: 1px solid var(--border); }
.td-export-title { font-size: 1.15rem; }
.td-export-subtitle { margin-top: 6px; font-size: 1rem; }
.td-export-page, .td-export-photo { display: block; max-width: 100%; height: auto; border: 1px solid var(--border); }
/* L'export s'imprime seul : ni boutons ni liens. Un exercice plus haut qu'une
   page n'est pas tenu d'un tenant (Chrome le repoussait à la page suivante avant
   de le couper quand même : pages presque vides). Un titre ne finit jamais une
   page, l'énoncé reste entier et part avec le début de sa copie, et une image de
   copie, bornée en hauteur, tient sur une page avec un énoncé de longueur
   ordinaire. */
@media print {
  .td-export-actions, .td-export .ai-notice a { display: none; }
  .td-export { max-width: none; padding: 0; }
  .td-export h1, .td-export-title, .td-export-subtitle { break-after: avoid; }
  .td-export-item > .td-statement { break-inside: avoid; break-after: avoid; }
  .td-export-page, .td-export-photo { break-inside: avoid; max-height: 16cm; width: auto; }
  .td-export-statement-page { break-inside: avoid; max-height: 24cm; width: auto; }
}

/* ---- Lecture guidée : « Travailler ce cours », bloc par bloc ------------- */
/* Écran plein cadre plus large que la colonne de lecture : le sommaire à
   gauche, le fil de la partie courante à droite. Sous 860 px, le sommaire
   devient un tiroir ouvert par « Sommaire ». */
.flow-screen.flow-screen-wide { max-width: 1180px; }
.lecture-screen { display: grid; gap: 14px; }
.lecture-head { margin-bottom: 0; }
.lecture-eyebrow { margin: 0; color: var(--nn-color-muted); font-size: 13px; font-weight: 700; }
.lecture-corps { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 32px; align-items: start; }
/* Une colonne bornée (minmax(0, 1fr)) : sans elle, la colonne implicite prend la
   largeur du plus long titre de bloc (nowrap), et compteurs et « … » sortent du cadre. */
.lecture-sommaire {
  position: sticky; top: 16px; max-height: calc(100dvh - 32px); overflow-y: auto;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; align-content: start; min-width: 0;
}
.lecture-sommaire-tete {
  display: grid; gap: 6px; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: var(--nn-radius); background: var(--nn-color-surface);
}
.lecture-sommaire-titre { margin: 0; font-weight: 700; }
.lecture-sommaire-compte { margin: 0; color: var(--nn-color-muted); font-size: 14px; }
.lecture-jauge { height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; }
.lecture-jauge > span { display: block; height: 100%; border-radius: inherit; background: var(--nn-color-accent); }
.lecture-jauge-finie > span { background: var(--nn-color-success); }
.lecture-sommaire-partie {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; padding-top: 8px; border-top: 1px solid var(--border);
}
.lecture-partie {
  display: grid; gap: 6px; width: 100%; min-height: 44px; padding: 8px 0;
  border: 0; background: transparent; color: var(--nn-color-text); text-align: left; font-weight: 700;
}
.lecture-sommaire-partie.courante .lecture-partie { color: var(--accent-dark); }
.lecture-partie-ligne { display: flex; justify-content: space-between; gap: 8px; }
.lecture-partie-nom { min-width: 0; overflow-wrap: anywhere; }
.lecture-partie-compte { flex: none; color: var(--nn-color-muted); font-size: 13px; font-weight: 600; }
.lecture-sommaire-sous {
  margin: 8px 0 2px; color: var(--nn-color-muted); font-size: 13px; font-weight: 700; line-height: 1.4;
}
.lecture-sommaire-bloc {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 44px; padding: 4px 8px;
  border: 0; border-radius: 10px; background: transparent; color: var(--nn-color-text);
  font-size: 14px; text-align: left;
}
.lecture-sommaire-bloc:hover, .lecture-sommaire-bloc.courant { background: var(--accent-soft); }
.lecture-sommaire-bloc.courant { font-weight: 700; }
.lecture-sommaire-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lecture-point { flex: none; width: 12px; height: 12px; border: 2px solid var(--nn-color-muted); border-radius: 50%; }
.lecture-point-lu { border-color: var(--nn-color-accent); background: var(--accent-soft); }
.lecture-point-travaille { border-color: var(--nn-color-warning); background: var(--nn-color-warning); }
.lecture-point-maitrise { border-color: var(--nn-color-success); background: var(--nn-color-success); }
.lecture-fermer, .lecture-barre-mobile, .lecture-voile { display: none; }

.lecture-fil { display: grid; gap: 16px; min-width: 0; max-width: 760px; }
.lecture-fil > * { min-width: 0; }
.lecture-partie-tete { display: grid; gap: 4px; }
.lecture-partie-rang { margin: 0; color: var(--nn-color-muted); font-size: 14px; }
.lecture-partie-titre { margin: 0; font-family: var(--serif); font-size: 1.75rem; line-height: 1.2; }
.lecture-sous-titre { margin: 12px 0 0; color: var(--nn-color-muted); font-size: 1rem; }
/* Un chapitre qui regroupe des parties : intertitre du sommaire, pas un bouton. */
.lecture-sommaire-groupe {
  margin: 10px 0 -4px; color: var(--nn-color-muted); font-size: 13px; font-weight: 700; line-height: 1.4;
  overflow-wrap: anywhere;
}
/* Pages que la lecture n'a pas pu lire : une ligne sobre en tête. */
.lecture-pages-illisibles { margin: 0; }
/* La table des matières, générée depuis le plan : numéros dans leur colonne, retrait par niveau. */
.lecture-toc-liste { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.lecture-toc-entree { min-width: 0; }
.lecture-toc-entree[data-niveau="1"] { padding-left: 1.25em; }
.lecture-toc-entree[data-niveau="2"] { padding-left: 2.5em; }
.lecture-toc-entree[data-niveau="3"] { padding-left: 3.75em; }
.lecture-toc-lien {
  display: flex; align-items: baseline; gap: 10px; width: 100%; min-height: 44px; padding: 10px 8px;
  border-radius: 10px; color: var(--nn-color-text); text-align: left; font-size: 1rem; font-weight: 400;
}
/* Une entrée cliquable se distingue d'un intertitre sans le survol : couleur de lien et titre
   souligné finement (le numéro, dans sa colonne, ne l'est pas : l'alignement ne bouge pas). */
button.lecture-toc-lien { color: var(--accent-dark); }
button.lecture-toc-lien .lecture-toc-titre { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
button.lecture-toc-lien:hover { background: var(--accent-soft); color: var(--accent-dark); }
.lecture-toc-chapitre { font-weight: 700; }
.lecture-toc-entree[data-niveau="0"] .lecture-toc-lien { font-weight: 700; }
.lecture-toc-numero { flex: none; min-width: 3.5em; color: var(--nn-color-muted); font-variant-numeric: tabular-nums; }
.lecture-toc-titre { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.lecture-texte, .lecture-annexe, .lecture-paragraphe {
  min-width: 0; overflow-x: auto; font-family: var(--serif); font-size: 1.08rem; line-height: 1.6;
}
.lecture-bloc {
  display: grid; gap: 12px; padding: 18px 20px; scroll-margin-top: 72px;
  border: 1px solid var(--border); border-radius: var(--nn-radius); background: var(--nn-color-surface);
}
.lecture-bloc > * { min-width: 0; }
.lecture-bloc-courant { border-color: var(--nn-color-accent); }
.lecture-bloc-leger { border-style: dashed; color: var(--nn-color-muted); }
.lecture-bloc-tete { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lecture-type, .lecture-etat {
  display: inline-flex; align-items: center; min-height: 24px; padding: 2px 12px;
  border-radius: 999px; font-size: 13px; font-weight: 700; line-height: 1.2;
}
.lecture-type { background: var(--accent-soft); color: var(--accent-dark); }
.lecture-titre { flex: 1 1 160px; min-width: 0; font-weight: 700; overflow-wrap: anywhere; }
.lecture-etat { background: var(--surface-soft); color: var(--nn-color-muted); }
.lecture-etat-lu { color: var(--accent-dark); }
.lecture-etat-travaille { color: var(--nn-color-warning); }
.lecture-etat-maitrise { color: var(--nn-color-success); }
.lecture-masque {
  margin: 0; padding: 14px; text-align: center; color: var(--nn-color-muted); font-size: 15px;
  border: 1px dashed var(--nn-color-muted); border-radius: var(--radius-sm);
}
.lecture-actions, .lecture-activite-actions, .lecture-auto-eval { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lecture-actions .primary-button, .lecture-actions .secondary-button,
.lecture-activite-actions .primary-button, .lecture-activite-actions .secondary-button,
.lecture-auto-eval .secondary-button, .lecture-pied .primary-button, .lecture-pied .secondary-button {
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; min-height: 44px; padding: 8px 16px; font-size: 0.98rem;
}
.lecture-lu { min-height: 44px; }
.lecture-panneau { display: grid; gap: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.lecture-panneau > * { min-width: 0; }
.lecture-restitution, .lecture-activite {
  display: grid; gap: 10px; padding: 12px 14px; min-width: 0;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.lecture-activite-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.lecture-activite-tete strong { flex: 1 1 160px; min-width: 0; }
.lecture-activite-etat { color: var(--nn-color-muted); font-size: 13px; }
.lecture-reponse-etiquette { font-size: 14px; font-weight: 600; }
.lecture-reponse {
  display: block; width: 100%; min-height: 110px; padding: 12px; resize: vertical; font: inherit;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--nn-color-bg); color: var(--nn-color-text);
}
.lecture-erreur { margin: 0; color: var(--nn-color-danger); font-size: 14px; font-weight: 600; }
.lecture-comparaison { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.lecture-colonne { min-width: 0; padding: 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.lecture-colonne h4 { margin: 0 0 6px; color: var(--nn-color-muted); font-size: 13px; }
/* Une formule centrée de 323 px dépassait la colonne à 1440 (312 px, V3 M3) comme à une
   colonne sous 720 px (294 px, T8 B1) : corps réduit dans la comparaison, à toutes les largeurs. */
.lecture-colonne .katex-display { font-size: 0.9em; }
.lecture-ma-version { min-width: 0; overflow-x: auto; overflow-wrap: anywhere; font-family: var(--serif); font-size: 1.05rem; }
.lecture-question { margin: 0; font-weight: 700; }
.lecture-preuve {
  padding: 0 16px; border: 1px dashed var(--border); border-radius: var(--nn-radius);
  background: var(--nn-color-surface);
}
.lecture-preuve[open] { display: grid; gap: 10px; padding-bottom: 14px; }
.lecture-preuve > summary { display: flex; align-items: center; min-height: 44px; font-weight: 700; cursor: pointer; }
/* Une démonstration, un renvoi ou une résolution ouverts restent dans leur colonne (à 390 px, une formule en ligne l'élargissait). */
.lecture-preuve[open] { grid-template-columns: minmax(0, 1fr); }
.lecture-preuve > * { min-width: 0; }
/* Renvoi : même tiroir que « Démonstration », avec la flèche vers l'énoncé visé. */
.lecture-renvoi > summary { gap: 8px; color: var(--accent-dark); }
.lecture-fleche { font-weight: 400; }
/* « ▶ Vidéo » : lien du cours, à la manière des liens de l'application. */
.lecture-videos { display: flex; flex-wrap: wrap; gap: 0 18px; }
.lecture-video { display: inline-flex; align-items: center; padding: 8px 2px; min-height: 44px; font-family: inherit; text-decoration: none; }
.lecture-video:hover { text-decoration: underline; }
/* Figures du cours : jamais plus larges que leur colonne. */
.lecture-figure { margin: 0; }
.lecture-figure img { display: block; max-width: 100%; height: auto; border-radius: var(--radius-sm); background: var(--nn-color-surface); }
.lecture-legende { margin: 0; color: var(--nn-color-muted); font-size: 0.95rem; }
.lecture-morceau > * + * { margin-top: 12px; }
/* Portrait à côté du texte, comme le cadre du PDF : le texte passe à droite puis dessous. */
.lecture-portrait { float: left; width: 168px; margin: 4px 20px 8px 0; }
.lecture-portrait + * { margin-top: 0; }
/* Texte et figure côte à côte sur ordinateur. */
.lecture-cote { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 300px); gap: 20px; align-items: start; }
.lecture-cote[data-cote="gauche"] { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); }
.lecture-cote > * { min-width: 0; }
.lecture-fin { display: grid; gap: 12px; margin-top: 8px; }
.lecture-pied { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; }
.lecture-fin-texte { text-align: center; }
@media (max-width: 860px) {
  /* La barre collante fait 62 px : un élément qui reçoit le focus ou un bloc visé défile sous elle, pas derrière. */
  html:has(.lecture-screen) { scroll-padding-top: 76px; }
  .lecture-corps { grid-template-columns: minmax(0, 1fr); }
  .lecture-barre-mobile {
    display: flex; align-items: center; gap: 12px; position: sticky; top: 0; z-index: 20;
    padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--nn-color-surface);
  }
  .lecture-barre-mobile .lecture-ouvrir-sommaire {
    display: inline-flex; align-items: center; width: auto; min-height: 44px; padding: 8px 14px; font-size: 0.95rem;
  }
  .lecture-barre-mobile .lecture-jauge { flex: 1; }
  .lecture-barre-compte { color: var(--nn-color-muted); font-size: 14px; }
  .lecture-sommaire {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 50; width: min(88vw, 340px); max-height: none;
    padding: 16px; border-right: 1px solid var(--border); background: var(--nn-color-bg);
    transform: translateX(-105%); visibility: hidden; transition: transform .2s, visibility .2s;
  }
  .lecture-sommaire.ouvert { transform: none; visibility: visible; }
  .lecture-fermer { display: block; min-height: 44px; }
  .lecture-voile { display: block; position: fixed; inset: 0; z-index: 40; background: rgba(14, 20, 32, .5); }
  .lecture-voile[hidden] { display: none; }
}
@media (max-width: 720px) {
  .lecture-bloc { padding: 16px; }
  /* Figures du cours : l'une sous l'autre, le portrait au-dessus du texte. */
  .lecture-portrait { float: none; width: 150px; margin: 0 0 4px; }
  .lecture-portrait + * { margin-top: 12px; }
  .lecture-cote, .lecture-cote[data-cote="gauche"] { grid-template-columns: minmax(0, 1fr); }
  .lecture-cote .lecture-figure img { margin: 0 auto; max-width: min(100%, 320px); }
  .lecture-partie-titre { font-size: 1.5rem; }
  .lecture-comparaison { grid-template-columns: minmax(0, 1fr); }
  /* À une colonne, le cadre coupait une formule centrée de 26 px (T8 B1). */
  .lecture-colonne { padding: 0; border: 0; }
  .lecture-actions .primary-button, .lecture-actions .secondary-button,
  .lecture-pied .primary-button, .lecture-pied .secondary-button { flex: 1 1 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .lecture-sommaire { transition: none; }
}

/* ---- Progression, révision, parcours : téléphone ------------------------- */
/* Placé après les adaptations d'écran communes, qu'il complète pour ces trois
   pages seulement. */
@media (max-width: 1040px) {
  /* Trois chiffres sur deux colonnes en laisseraient un orphelin. */
  .progress-hero-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  /* Les en-têtes de colonne disparaissent : chaque cellule dit ce qu'elle compte. */
  .table-cell[data-label]::before,
  .table-progress[data-label]::before { content: attr(data-label) " : "; color: var(--nn-color-muted, var(--muted)); }
  /* Son étiquette et son chiffre se lisent sur une ligne, pas en deux colonnes. */
  .table-progress[data-label] { display: block; }
}
@media (max-width: 720px) {
  .progress-hero { padding: 22px 18px; }
  .progress-hero-stats { grid-template-columns: 1fr; gap: 8px; margin-top: 20px; }
  .mini-stat { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; column-gap: 12px; padding: 12px 14px; }
  .mini-stat > strong { margin-top: 0; font-size: 20px; }
  .mini-stat small { grid-column: 1 / -1; margin-top: 2px; }
  /* Neuf matières en pastilles repousseraient la liste sous le pli : une
     seule ligne, qui défile au doigt. */
  .progress-dimensions { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .dimension-card { padding: 14px; }
  .dimension-card p { min-height: 0; }
  .progress-folds { margin-top: 26px; }
  .progress-fold-body { padding: 14px 14px 16px; }
  .table-row { gap: 6px; padding: 14px 16px; }
  .revision-format-option strong { font-size: 15px; }
  .parcours-next .primary-button { justify-self: stretch; }
}

/* ---- Trois façons de répondre : stylet, clavier, photo ------------------ */
.answer-modes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}
.answer-mode {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 44px;
  padding: 10px 12px;
  /* --line n'a jamais existé dans :root : la bordure prenait la couleur du
     texte. --border est celle de toutes les autres cartes. */
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--nn-color-surface, var(--surface));
  color: var(--nn-color-text, var(--text));
  text-align: left;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.answer-mode:hover { border-color: var(--nn-color-accent, var(--accent)); }
.answer-mode:focus-visible {
  outline: 2px solid var(--nn-focus-ring);
  outline-offset: 2px;
}
.answer-mode.is-active {
  border-color: var(--nn-color-accent, var(--accent));
  background: var(--accent-soft, rgba(37, 99, 235, .08));
}
.answer-mode strong { font-size: 0.95rem; font-weight: 600; }
.answer-mode-hint { font-size: 0.78rem; color: var(--nn-color-muted, var(--muted)); }
.answer-panel[hidden], .typed-answer[hidden], .photo-answer[hidden] { display: none; }

.photo-answer-input { display: none; }
.photo-answer-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.photo-answer-item {
  margin: 0;
  position: relative;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
}
.photo-answer-item img { display: block; width: 100%; height: auto; }
.photo-answer-remove {
  position: absolute;
  right: 6px;
  bottom: 6px;
  padding: 4px 10px;
  font-size: 0.78rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(255, 255, 255, .92);
  cursor: pointer;
}

/* Une barre d'attente qui avance toute seule, sans compter les secondes. */
.preparing-track {
  width: min(320px, 70vw);
  height: 3px;
  margin: 14px auto 6px;
  border-radius: 999px;
  /* --line n'existe pas dans :root : le rail restait invisible. */
  background: var(--border);
  overflow: hidden;
}
.preparing-track span {
  display: block;
  width: 38%;
  height: 100%;
  border-radius: 999px;
  background: var(--nn-color-accent, var(--accent));
  animation: preparing-slide 1.6s ease-in-out infinite;
}
@keyframes preparing-slide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(320%); }
}
@media (prefers-reduced-motion: reduce) {
  .preparing-track span { animation: none; width: 100%; opacity: .5; }
}

/* Le séparateur et le tableau d'un énoncé : ils sortaient en texte brut. */
.rich-rule {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 18px 0;
}
.rich-quote {
  margin: 0;
  padding: 8px 14px;
  border-left: 3px solid var(--border);
  color: var(--muted);
}
.rich-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.rich-table th, .rich-table td {
  border: 1px solid var(--border);
  padding: 6px 10px;
  text-align: left;
}
.rich-table th { background: var(--surface-2, rgba(0, 0, 0, .03)); font-weight: 600; }

/* QCM sur téléphone : cibles gardées à 44 px, rien sous 13 px. */
@media (max-width: 720px) {
  .qcm-question { padding: 16px; }
  .qcm-choice, .qcm-choice-line { padding: 10px; }
  .qcm-number, .qcm-progress { font-size: 14px; }
  .qcm-mark, .qcm-verdict { font-size: 13px; }
  .qcm-score { font-size: 28px; }
}
