﻿:root {
  /* Palette — verts biologiques désaturés, conformité AA */
  --bg: #f7f9f8;
  --surface: #ffffff;
  --surface-2: #f0f4f1;
  --text: #1c2b23;
  --muted: #57655d;
  --primary: #1e6b47;
  --primary-dark: #145033;
  --primary-soft: #e9f2ed;
  --accent: #2c5f8a;
  --warning: #9c6414;
  --danger: #b42c2c;
  --border: #dce4df;

  /* Typographie */
  --font-body: Inter, 'Segoe UI', Arial, sans-serif;
  --font-heading: 'Source Serif 4', Georgia, 'Times New Roman', serif;
  /* Arabe (darija de la section paiement) — ni Inter ni Source Serif 4 ne
     couvrent l'arabe : sans jeton dédié, chaque système choisirait sa police
     de secours et la bulle du guichet changerait d'aspect d'un appareil à
     l'autre. */
  --font-ar: 'Noto Sans Arabic', 'Segoe UI', Tahoma, sans-serif;

  /* Élévation — 2 niveaux discrets, neutres */
  --shadow-sm: 0 1px 2px rgba(28, 43, 35, 0.06);
  --shadow: 0 2px 10px rgba(28, 43, 35, 0.08);

  /* Rayons — échelle réduite */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius: 12px;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;

  /* Échelle générale ramenée à 93,75 % (1rem = 15px au lieu de 16). Toute la
     typographie du site est en rem : titres, corps, formules KaTeX et champs
     de formulaire suivent d'un bloc, sans retoucher chaque règle. Exprimé en
     pourcentage et non en px, pour respecter la taille de police choisie par
     l'utilisateur dans son navigateur. */
  font-size: 93.75%;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: 0;
  color: var(--text);
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
select,
textarea {
  font: inherit;
}

button {
  cursor: pointer;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 9px clamp(14px, 3.4vw, 44px);
  background: rgba(255, 255, 255, 0.96);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow);
  backdrop-filter: blur(16px);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-width: max-content;
}

.brand-logo {
  display: grid;
  width: 54px;
  height: 54px;
  place-items: center;
  border: 2px solid var(--primary);
  border-radius: 999px;
  background: var(--primary-soft);
  box-shadow: var(--shadow);
}

.brand-logo svg {
  width: 38px;
  height: 38px;
  fill: none;
  stroke: var(--primary);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 3.4;
}

.brand strong {
  display: block;
}

.brand strong {
  color: var(--primary-dark);
  font-size: 1.42rem;
  font-weight: 700;
  letter-spacing: 0;
}

.top-nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.top-nav a,
.logout-button {
  position: relative;
  border: 0;
  border-radius: 4px;
  padding: 12px 14px;
  color: #263c32;
  background: transparent;
  font-weight: 700;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  transition: color 0.22s ease, background 0.22s ease, transform 0.22s ease;
}

.top-nav a::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 5px;
  height: 3px;
  border-radius: 999px;
  background: var(--primary);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 0.24s ease;
}

.top-nav a:hover,
.top-nav a.active,
.logout-button:hover {
  background: var(--primary-soft);
  color: var(--primary-dark);
  transform: translateY(-1px);
}

.top-nav a:hover::after,
.top-nav a.active::after {
  transform: scaleX(1);
}

.mobile-toggle {
  display: none;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  padding: 9px 12px;
  color: var(--primary-dark);
  font-weight: 700;
}

/* Espacements resserrés d'environ 15 % en même temps que l'échelle typographique
   (voir html{font-size}) : réduire les seules polices aurait laissé des marges
   surdimensionnées et la page aurait paru encore trop aérée. */
.app-shell {
  display: grid;
  grid-template-columns: 262px minmax(0, 1fr);
  gap: 20px;
  width: min(1440px, calc(100% - 32px));
  margin: 22px auto;
  align-items: start;
}

.semester-sidebar,
.content-area,
.site-footer {
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.86);
  box-shadow: var(--shadow);
  backdrop-filter: blur(12px);
}

.semester-sidebar {
  position: sticky;
  top: 92px;
  padding: 14px;
  border-radius: 12px;
}

.sidebar-title {
  margin-bottom: 12px;
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.semester-button,
.module-link {
  width: 100%;
  border: 0;
  text-align: left;
}

.semester-button {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 6px 0;
  padding: 10px 12px;
  border: 1px solid #d8ead1;
  border-radius: 6px;
  background: #f7fcf4;
  font-weight: 700;
  color: #23401a;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}

.semester-button.active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

.semester-button:hover {
  transform: translateX(3px);
  border-color: var(--primary);
}

.module-list {
  display: block;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  padding: 2px 0 9px 9px;
  transform: translateY(-4px);
  transition: max-height 0.28s ease, opacity 0.22s ease, transform 0.22s ease;
}

.module-list.open {
  max-height: 260px;
  opacity: 1;
  transform: translateY(0);
}

.module-link {
  display: block;
  margin: 3px 0;
  padding: 8px 10px;
  border-left: 2px solid #cbe7c0;
  background: transparent;
  color: #40564b;
  border-radius: 0 8px 8px 0;
  font-weight: 700;
  font-size: 0.92rem;
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.module-link:hover,
.module-link.active {
  border-left-color: var(--primary);
  background: #f0fbf5;
  color: var(--primary-dark);
  transform: translateX(3px);
}

.access-card {
  margin-top: 16px;
  padding: 14px;
  border-radius: 8px;
  background: var(--primary-dark);
  color: #fff;
}

.access-card strong {
  display: block;
  margin-bottom: 7px;
}

.access-card p {
  margin: 0;
  color: rgba(255, 255, 255, 0.76);
  font-size: 0.9rem;
  line-height: 1.5;
}

.content-area {
  min-height: 620px;
  padding: clamp(17px, 3.4vw, 38px);
  border-radius: var(--radius);
}

.content-area.page-enter {
  animation: pageEnter 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes pageEnter {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.992);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

.hero {
  display: grid;
  grid-template-columns: 1.25fr 0.75fr;
  gap: 28px;
  align-items: center;
}

.hero-stacked {
  grid-template-columns: 1fr;
  gap: 24px;
}

.hero-text {
  max-width: 960px;
}

.home-lab {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(360px, 1.1fr);
  gap: clamp(16px, 4vw, 46px);
  min-height: clamp(470px, 58vw, 640px);
  align-items: center;
  overflow: hidden;
  border: 1px solid rgba(30, 107, 71, 0.18);
  border-radius: 16px;
  background:
    radial-gradient(circle at 78% 22%, rgba(30, 107, 71, 0.4), transparent 30%),
    radial-gradient(circle at 15% 85%, rgba(122, 190, 150, 0.16), transparent 30%),
    linear-gradient(135deg, #0a2417, #14402b 48%, #f4f8f6);
  box-shadow: var(--shadow);
}

.home-lab::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: linear-gradient(90deg, #000, transparent 76%);
  pointer-events: none;
}

.home-lab::after {
  content: "";
  position: absolute;
  left: 30%;
  top: -35%;
  width: 640px;
  height: 640px;
  border-radius: 999px;
  background: radial-gradient(circle, rgba(30, 107, 71, 0.28), transparent 65%);
  animation: glowPulse 4.8s ease-in-out infinite;
}

.lab-visual {
  position: relative;
  z-index: 2;
  min-height: 450px;
  margin-right: clamp(10px, 3vw, 42px);
}

.orbit {
  position: absolute;
  border: 1px solid rgba(143, 207, 168, 0.3);
  border-radius: 999px;
  inset: 12%;
  animation: rotateOrbit 18s linear infinite;
}

.orbit-two {
  inset: 22% 6% 10% 20%;
  border-color: rgba(255, 255, 255, 0.3);
  animation-duration: 26s;
  animation-direction: reverse;
}

.dna-helix {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 170px;
  height: 380px;
  transform: translate(-50%, -50%);
}

.dna-helix span {
  position: absolute;
  left: 50%;
  top: calc(var(--i) * 34px);
  width: 110px;
  height: 16px;
  transform: translateX(-50%) rotate(calc(var(--i) * 24deg));
  transform-origin: center;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.8), rgba(143, 207, 168, 0.72));
  border-radius: 999px;
  animation: dnaFloat 3.8s ease-in-out infinite;
  animation-delay: calc(var(--i) * -0.12s);
}

.dna-helix span::before,
.dna-helix span::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 0 24px rgba(255, 255, 255, 0.7);
}

.dna-helix span::before {
  left: 0;
  transform: translateY(-50%);
}

.dna-helix span::after {
  right: 0;
  transform: translateY(-50%);
  background: #8fcfa8;
}

.floating-card {
  position: absolute;
  display: grid;
  gap: 4px;
  min-width: 150px;
  border: 1px solid rgba(255, 255, 255, 0.44);
  border-radius: var(--radius);
  padding: 16px;
  background: rgba(255, 255, 255, 0.78);
  box-shadow: var(--shadow);
  backdrop-filter: blur(16px);
  animation: cardFloat 4.4s ease-in-out infinite;
}

/* Même police que le titre du hero placé à côté (Source Serif 4) */
.floating-card strong {
  color: var(--primary-dark);
  font-family: var(--font-heading);
  font-size: 1.15rem;
  font-weight: 600;
}

.floating-card span {
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 600;
}

.card-resume {
  left: 4%;
  top: 16%;
}

.card-exercice {
  right: 4%;
  top: 38%;
  animation-delay: -1.4s;
}

.card-examen {
  left: 10%;
  bottom: 11%;
  animation-delay: -2.4s;
}

.cell-bubble {
  position: absolute;
  border-radius: 999px;
  background:
    radial-gradient(circle at 35% 35%, rgba(255, 255, 255, 0.95), rgba(143, 207, 168, 0.2) 38%, rgba(30, 107, 71, 0.32));
  border: 1px solid rgba(255, 255, 255, 0.42);
  box-shadow: var(--shadow-sm);
  animation: bubbleDrift 7s ease-in-out infinite;
}

.bubble-one {
  width: 82px;
  height: 82px;
  right: 17%;
  top: 9%;
}

.bubble-two {
  width: 48px;
  height: 48px;
  left: 27%;
  top: 7%;
  animation-delay: -2s;
}

.bubble-three {
  width: 64px;
  height: 64px;
  right: 19%;
  bottom: 13%;
  animation-delay: -4s;
}

.showcase-content {
  position: relative;
  z-index: 2;
  display: grid;
  align-content: center;
  width: min(760px, 100%);
  padding: clamp(24px, 5.8vw, 62px);
}

.showcase-content h1 {
  color: #fff;
  font-size: clamp(2.15rem, 4.4vw, 3.6rem);
}

.showcase-content .lead {
  color: rgba(255, 255, 255, 0.86);
  font-size: clamp(0.98rem, 1.45vw, 1.14rem);
}

/* Libellés informatifs, pas des commandes : ni bordure, ni pastille — le hero
   ne doit proposer qu'une seule zone cliquable, celle des boutons .actions. */
.showcase-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin-top: 14px;
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.showcase-badges span:not(:last-child)::after {
  content: "·";
  margin-left: 14px;
  color: rgba(255, 255, 255, 0.5);
}

@keyframes rotateOrbit {
  to {
    transform: rotate(360deg);
  }
}

@keyframes glowPulse {
  50% {
    opacity: 0.55;
    transform: scale(1.12);
  }
}

@keyframes dnaFloat {
  50% {
    transform: translateX(-50%) rotate(calc(var(--i) * 24deg + 10deg)) scaleX(0.92);
  }
}

@keyframes cardFloat {
  50% {
    transform: translateY(-12px);
  }
}

@keyframes bubbleDrift {
  50% {
    transform: translate(12px, -18px) scale(1.05);
  }
}

/* Accessibilité : désactiver les animations décoratives si demandé */
@media (prefers-reduced-motion: reduce) {
  .home-lab::after,
  .orbit,
  .dna-helix span,
  .floating-card,
  .cell-bubble {
    animation: none;
  }
}

.learning-path {
  display: grid;
  grid-template-columns: 0.82fr 1.18fr;
  gap: 24px;
  align-items: start;
}

.path-steps {
  display: grid;
  gap: 14px;
}

.path-steps article,
.dashboard-grid article,
.start-panel {
  border: 1px solid #d6edcd;
  border-radius: 16px;
  background: #ffffff;
  box-shadow: var(--shadow);
}

.path-steps article {
  position: relative;
  padding: 22px 22px 22px 78px;
}

.path-steps article span {
  position: absolute;
  left: 20px;
  top: 22px;
  display: grid;
  width: 42px;
  height: 42px;
  place-items: center;
  border-radius: 12px;
  background: var(--primary);
  color: #fff;
  font-weight: 700;
}

.path-steps p,
.dashboard-grid p,
.start-panel p {
  color: var(--muted);
  line-height: 1.7;
}

.home-dashboard {
  display: grid;
  gap: 22px;
}

.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.dashboard-grid article {
  padding: 24px;
  transition: transform 0.22s ease, box-shadow 0.22s ease;
}

.dashboard-grid article:hover,
.path-steps article:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
}

.start-panel {
  padding: clamp(24px, 4vw, 38px);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 18px;
  padding: 8px 12px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-weight: 700;
  font-size: 0.86rem;
}

h1,
h2,
h3 {
  margin: 0;
  line-height: 1.08;
}

/* Échelle typographique (revue juillet 2026)
   ------------------------------------------
   Sur écran large : h1 41,6 px / h2 29,6 px / h3 20,5 px, soit des rapports
   de 1,4 entre niveaux consécutifs. Auparavant h1 et h2 plafonnaient à 60,8
   et 49,6 px : des tailles de hero appliquées à *tous* les titres, ce qui
   laissait une marche de 2,1 entre h2 et h3 et faisait lire un intertitre
   comme une seconde bannière. Le hero de l accueil garde sa grande taille,
   mais par sa propre règle (.showcase-content h1), pas par le défaut. */
h1 {
  max-width: 840px;
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  letter-spacing: 0;
}

h2 {
  font-size: clamp(1.45rem, 2.3vw, 1.85rem);
  letter-spacing: 0;
}

h3 {
  font-size: 1.28rem;
}

.lead {
  max-width: 780px;
  color: var(--muted);
  font-size: 1.1rem;
  line-height: 1.75;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  border: 0;
  border-radius: 6px;
  padding: 12px 18px;
  background: var(--primary);
  color: #fff;
  font-weight: 700;
  box-shadow: var(--shadow);
}

.btn:hover {
  background: var(--primary-dark);
}

.btn.secondary {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--primary-dark);
  box-shadow: none;
}

.btn.danger {
  background: var(--danger);
  box-shadow: 0 14px 28px rgba(197, 48, 48, 0.18);
}

.hero-card,
.card,
.module-card,
.form-card,
.admin-user {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 0 14px 38px rgba(8, 54, 35, 0.08);
}

.hero-card {
  padding: 0;
  overflow: hidden;
}

.instructor-visual {
  position: relative;
  min-height: clamp(340px, 45vw, 540px);
  border-radius: 10px;
  overflow: hidden;
  background: #17230f;
}

.instructor-visual img {
  display: block;
  width: 100%;
  min-height: clamp(340px, 45vw, 540px);
  object-fit: cover;
  object-position: center;
  filter: saturate(0.95) hue-rotate(35deg);
}

.instructor-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12, 38, 0, 0.28), rgba(20, 75, 0, 0.72));
}

.instructor-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-content: end center;
  gap: 10px;
  padding: clamp(28px, 5vw, 58px);
  color: #fff;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}

.instructor-overlay span,
.instructor-overlay em {
  font-size: clamp(0.8rem, 1.6vw, 1rem);
  font-style: normal;
  font-weight: 700;
}

.instructor-overlay strong {
  font-size: clamp(2rem, 4vw, 3.3rem);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-shadow: 0 4px 20px rgba(0, 0, 0, 0.34);
}

.quote-panel {
  position: relative;
  border-left: 6px solid var(--primary);
  border-radius: 6px;
  padding: 24px 28px;
  background: #ffffff;
  box-shadow: var(--shadow);
}

.quote-panel p {
  margin: 0;
  color: #24411b;
  font-size: clamp(1.1rem, 2vw, 1.45rem);
  font-weight: 700;
  line-height: 1.65;
}

.quote-panel p::before {
  content: "“";
  color: var(--primary);
  font-size: 2.4rem;
  line-height: 0;
  margin-right: 6px;
  vertical-align: -0.24em;
}

.grid {
  display: grid;
  gap: 18px;
}

.grid.three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.grid.two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.section {
  margin-top: 36px;
}

.card,
.module-card {
  padding: 22px;
}

.card p,
.module-card p {
  color: var(--muted);
  line-height: 1.7;
}

.stat {
  display: block;
  color: var(--primary);
  font-size: 2rem;
  font-weight: 700;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: max-content;
  border-radius: 999px;
  padding: 8px 12px;
  background: #edf2f7;
  color: #344054;
  font-weight: 700;
  font-size: 0.86rem;
}

.status-pill.pending_payment {
  background: #fff7e6;
  color: var(--warning);
}

.status-pill.awaiting_approval {
  background: #e8f1ff;
  color: var(--accent);
}

.status-pill.approved {
  background: var(--primary-soft);
  color: var(--primary-dark);
}

.status-pill.rejected {
  background: #ffecec;
  color: var(--danger);
}

.form-card {
  max-width: 760px;
  padding: 26px;
}

.form-grid {
  display: grid;
  gap: 16px;
}

.form-grid.two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

label {
  display: grid;
  gap: 7px;
  color: #334a3f;
  font-weight: 700;
}

input,
select,
textarea {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: #fbfefc;
  padding: 13px 14px;
  color: var(--text);
}

textarea {
  min-height: 120px;
  resize: vertical;
}

input:focus,
select:focus,
textarea:focus {
  outline: 3px solid rgba(30, 107, 71, 0.14);
  border-color: var(--primary);
}

.contact-highlight {
  border: 1px solid #d6edcd;
  border-radius: 10px;
  padding: 24px;
  background: #ffffff;
  box-shadow: var(--shadow);
}

.contact-highlight h3 {
  color: var(--primary-dark);
}

.contact-highlight p {
  color: var(--muted);
  line-height: 1.75;
}

.contact-form-card {
  max-width: 880px;
}

/* Le formulaire est la raison d'être de la page : il s'ouvre à hauteur du
   titre, sans défilement. Empilé sous l'accroche et les trois rubriques, il
   commençait à 860 px du haut, soit une page entière plus bas. */
.contact-layout {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(360px, 0.95fr);
  gap: clamp(22px, 3vw, 40px);
  align-items: start;
}

.contact-intro {
  display: grid;
  gap: 14px;
  align-content: start;
}

.contact-intro h1 {
  font-size: clamp(1.6rem, 2.4vw, 2rem);
  margin: 0;
}

.contact-intro .lead {
  margin: 0;
}

.contact-layout .contact-grid {
  grid-template-columns: 1fr;
  gap: 12px;
  margin-top: 4px;
}

/* Trois sélecteurs : .contact-grid .contact-highlight impose 190px plus bas
   dans la feuille, à égalité de spécificité. */
.contact-layout .contact-grid .contact-highlight {
  min-height: 0;
  padding: 14px 16px;
}

.contact-layout .contact-highlight h3 {
  font-size: 1.02rem;
}

.contact-layout .contact-highlight p {
  margin: 4px 0 0;
  font-size: 0.92rem;
  line-height: 1.6;
}

.contact-layout .contact-form-card {
  max-width: 100%;
  padding: 20px;
}

.contact-form-card h2 {
  margin: 0;
  font-size: 1.35rem;
}

.contact-form-note {
  margin: 8px 0 14px;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.6;
}

.contact-layout .form-grid {
  gap: 13px;
}

.contact-layout label {
  gap: 6px;
}

.contact-layout input,
.contact-layout select {
  padding: 11px 14px;
}

.contact-layout textarea {
  min-height: 86px;
  padding: 11px 14px;
}

/* Tant qu'aucun message d'envoi n'est affiché, la ligne ne réserve pas de place */
.contact-layout .form-message:empty {
  display: none;
}

@media (max-width: 1080px) {
  .contact-layout {
    grid-template-columns: 1fr;
  }

  .contact-layout .contact-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.auth-card {
  animation: authEnter 0.34s ease both;
  overflow: hidden;
}

.auth-card.leaving {
  animation: authLeave 0.2s ease both;
}

.auth-form-panel {
  animation: panelSlide 0.34s ease both;
}

@keyframes authEnter {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes authLeave {
  to {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }
}

@keyframes panelSlide {
  from {
    opacity: 0;
    transform: translateX(18px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.form-message {
  min-height: 24px;
  margin: 14px 0 0;
  color: var(--danger);
  font-weight: 700;
}

.form-message.success {
  color: var(--primary-dark);
}

.auth-forgot {
  margin: 12px 0 0;
  font-size: 0.95rem;
}

.auth-forgot a {
  color: var(--primary-dark);
  font-weight: 600;
  text-decoration: none;
}

.auth-forgot a:hover {
  text-decoration: underline;
}

.tabs {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.tab {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 15px;
  background: var(--surface);
  color: var(--muted);
  font-weight: 700;
}

.tab.active {
  border-color: var(--primary);
  background: var(--primary-soft);
  color: var(--primary-dark);
}

.locked {
  border: 1px dashed rgba(183, 121, 31, 0.5);
  border-radius: 18px;
  padding: 18px;
  background: #fffaf0;
  color: #7a4b0d;
  font-weight: 700;
}

.content-list {
  margin: 16px 0 0;
  padding-left: 20px;
  color: var(--muted);
  line-height: 1.8;
}

.stats-hero {
  display: grid;
  gap: 24px;
  align-items: center;
  overflow: hidden;
  background:
    #ffffff;
  border-color: #d7dee8;
}

.chapter-pill {
  display: inline-flex;
  margin-bottom: 12px;
  border-radius: 999px;
  padding: 8px 12px;
  background: #243447;
  color: #fff;
  font-size: 0.82rem;
  font-weight: 700;
}

.course-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}

.course-meta span {
  border: 1px solid #d2dae5;
  border-radius: 999px;
  padding: 7px 11px;
  background: #fff;
  color: #415064;
  font-size: 0.86rem;
  font-weight: 700;
}

.chapter-map-container {
  margin: 0 0 24px 0;
  padding: 20px;
  background: #f8fafc;
  border-radius: 12px;
  border: 1px solid var(--border);
}

.stats-hero-mini {
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.stats-hero-mini h3 {
  margin: 8px 0;
  font-size: 1.25rem;
  color: var(--text);
}

.stats-hero-mini p {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
}

.chapter-map {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.chapter-map button {
  display: grid;
  text-align: left;
  gap: 5px;
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 14px;
  background: #fff;
  cursor: pointer;
  font: inherit;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

.chapter-map button:hover:not(:disabled) {
  border-color: #94a3b8;
  transform: translateY(-2px);
}

.chapter-map button.active {
  border-color: #243447;
  background: #f6f8fb;
}

.chapter-map button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
  background: #f1f5f9;
  border-color: #e2e8f0;
}

.chapter-map button:disabled strong {
  color: #94a3b8;
}

.chapter-map button:disabled em {
  color: #64748b;
  font-style: italic;
}

.chapter-map span {
  color: #243447;
  font-weight: 700;
}

.chapter-map strong {
  color: var(--text);
}

.chapter-map em {
  color: var(--muted);
  font-size: 0.82rem;
  font-style: normal;
  font-weight: 700;
}

.course-flow{
  display: grid;
  gap: 18px;
}

.mature-course {
  gap: 28px;
}

.course-section {
  display: grid;
  gap: 16px;
}

.course-section-header {
  border-left: 5px solid #243447;
  padding: 10px 0 10px 16px;
}

.course-section-header span {
  display: block;
  margin-bottom: 4px;
  color: #64748b;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.course-section-header h2 {
  margin: 0;
  /* Sous le h2 global : un titre de section de cours ne peut pas être le
     plus gros h2 du site. */
  color: #172033;
  font-size: clamp(1.35rem, 2.1vw, 1.7rem);
}

.lesson-card {
  border: 1px solid #d8e0ea;
  border-radius: 14px;
  padding: clamp(18px, 3vw, 28px);
  background: #fff;
  box-shadow: 0 12px 34px rgba(15, 23, 42, 0.06);
}

.lesson-card h3 {
  margin-bottom: 18px;
  /* Doit rester nettement sous le titre de section (.course-section-header
     h2) : à 1,55rem il n en était plus distinct que de 9 %. */
  color: #172033;
  font-size: clamp(1.16rem, 1.7vw, 1.35rem);
}

.lesson-card h4 {
  margin-bottom: 8px;
  color: #243447;
  font-size: 1.02rem;
}

.subsection {
  border-top: 1px solid #e5eaf0;
  padding-top: 16px;
  margin-top: 16px;
}

.subsection:first-of-type {
  border-top: 0;
  padding-top: 0;
  margin-top: 0;
}

.concept-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.concept-card {
  border: 1px solid #d8e0ea;
  border-radius: 14px;
  padding: 18px;
  background: #fff;
  box-shadow: 0 10px 28px rgba(15, 23, 42, 0.04);
}

.concept-card h3 {
  margin-bottom: 10px;
  color: #172033;
  font-size: 1.08rem;
}

.set-visual {
  position: relative;
  min-height: 180px;
  margin: 18px 0;
  border-radius: 18px;
  background: #ffffff;
}

.set-circle {
  position: absolute;
  top: 34px;
  display: grid;
  place-items: center;
  width: 128px;
  height: 128px;
  border: 2px solid rgba(30, 107, 71, 0.42);
  border-radius: 999px;
  background: rgba(30, 107, 71, 0.12);
  color: var(--primary-dark);
  font-weight: 700;
}

.set-a {
  left: calc(50% - 118px);
}

.set-b {
  right: calc(50% - 118px);
  background: rgba(145, 230, 109, 0.18);
}

.set-visual strong {
  position: absolute;
  left: 50%;
  top: 82px;
  transform: translateX(-50%);
  color: var(--primary-dark);
}

.law-grid,
.repeat-grid,
.checkpoint-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.law-grid span,
.repeat-grid div,
.checkpoint-grid article {
  border: 1px solid #d8e0ea;
  border-radius: 14px;
  padding: 14px;
  background: #f8fafc;
  color: #334155;
  font-weight: 600;
}

.law-grid.compact {
  grid-template-columns: 1fr;
  gap: 8px;
}

.law-grid.compact span {
  padding: 10px 12px;
}

.formula-box {
  display: grid;
  gap: 6px;
  margin: 16px 0;
  border-left: 4px solid #475569;
  border-radius: 10px;
  padding: 12px 14px;
  background: #f8fafc;
  color: #1f2937;
}

.formula-box strong {
  font-size: clamp(1rem, 1.35vw, 1.18rem);
}

.formula-box span {
  color: #475569;
  font-weight: 700;
}

.example-block {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 0.82fr);
  gap: 18px;
  align-items: start;
}

.token-cloud {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}

.token-cloud span {
  border-radius: 999px;
  padding: 8px 12px;
  background: #eef2f7;
  color: #263244;
  font-weight: 700;
}

.token-cloud.sober span {
  border-radius: 8px;
  background: #f8fafc;
  border: 1px solid #d8e0ea;
  color: #334155;
}

.repeat-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.repeat-grid strong,
.repeat-grid span {
  display: block;
  margin-top: 8px;
  color: #243447;
  font-weight: 700;
}

.checkpoint-grid article {
  display: grid;
  gap: 8px;
}

.checkpoint-grid span {
  color: var(--primary);
  font-weight: 700;
}

.checkpoint-grid strong,
.checkpoint-grid em {
  display: block;
}

.checkpoint-grid em {
  color: var(--muted);
  font-style: normal;
  font-weight: 700;
}

.letter-source,
.demo-slots{
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.letter-source span,
.demo-slots span{
  display: inline-grid;
  place-items: center;
  min-width: 42px;
  min-height: 42px;
  border: 1px solid #cbd5e1;
  border-radius: 10px;
  background: #fff;
  color: #243447;
  font-weight: 700;
}

.lab-panel {
  border: 1px solid #d8e0ea;
  border-radius: 16px;
  padding: 16px;
  background: #fbfdff;
}

.lab-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.lab-header strong {
  color: #172033;
}

.lab-tag {
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  padding: 4px 10px;
  color: #64748b;
  font-size: 0.74rem;
  font-weight: 700;
  white-space: nowrap;
}

.lab-readout {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin-top: 14px;
}

.lab-readout div {
  display: grid;
  gap: 6px;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 10px;
  background: #fff;
}

.lab-readout span {
  color: #64748b;
  font-size: 0.78rem;
  font-weight: 700;
}

.lab-readout strong {
  color: #172033;
  font-size: 1.05rem;
}

.law-table {
  width: 100%;
  border-collapse: collapse;
  margin: 4px 0 6px;
  font-size: 0.92rem;
}

.law-table th,
.law-table td {
  border: 1px solid #e2e8f0;
  padding: 8px 10px;
  text-align: center;
}

.law-table th {
  background: #f1f5fb;
  color: #243447;
  font-weight: 700;
}

.law-table thead th {
  color: #64748b;
}

.worked-solution {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 12px;
}

.worked-solution div {
  display: grid;
  gap: 8px;
  border: 1px solid #d8e0ea;
  border-radius: 14px;
  padding: 12px;
  background: #f8fafc;
}

.worked-solution span {
  color: #64748b;
  font-size: 0.84rem;
  font-weight: 700;
}

.worked-solution strong {
  color: #172033;
}

.static-example-card {
  border-left: 5px solid #243447;
}

.urn {
  position: relative;
  display: flex;
  justify-content: center;
  gap: 8px;
  min-height: 112px;
  border: 2px solid #94a3b8;
  border-top: 0;
  border-radius: 10px 10px 34px 34px;
  padding: 36px 12px 12px;
  background: #ffffff;
}

.admin-list {
  display: grid;
  gap: 18px;
  margin-top: 20px;
}

.admin-user {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 220px;
  gap: 18px;
  padding: 20px;
  border-left: 6px solid var(--border);
}

.admin-user p {
  margin: 6px 0;
  color: var(--muted);
}

.admin-user.approved {
  border-left-color: var(--primary);
}

.admin-user.rejected {
  border-left-color: var(--danger);
}

.admin-user-heading {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
}

.access-summary {
  display: grid;
  gap: 4px;
  margin: 14px 0;
  border-radius: 12px;
  padding: 12px 14px;
  background: #f6f8f7;
  color: var(--muted);
}

.access-summary.active {
  border: 1px solid #c8efba;
  background: #f1fcec;
  color: var(--primary-dark);
}

.access-summary.inactive {
  border: 1px dashed var(--border);
}

.access-summary strong,
.access-summary span {
  display: block;
}

.admin-actions {
  display: grid;
  gap: 8px;
  align-content: start;
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.72;
  box-shadow: none;
}

.custom-access {
  display: grid;
  gap: 14px;
  margin-top: 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px;
  background: #fbfefc;
}

.custom-access-title {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

.custom-access-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.custom-access fieldset {
  display: grid;
  gap: 8px;
  margin: 0;
  border: 1px solid #dcebdd;
  border-radius: 12px;
  padding: 12px;
  background: #ffffff;
}

.custom-access legend {
  padding: 0 6px;
  color: var(--primary-dark);
  font-weight: 700;
}

.check-line {
  display: flex;
  grid-template-columns: none;
  gap: 8px;
  align-items: center;
  color: #334a3f;
  font-size: 0.9rem;
  font-weight: 700;
}

.check-line input {
  width: auto;
  accent-color: var(--primary);
}

.module-check {
  color: var(--muted);
  font-weight: 700;
}

.empty-state {
  border: 1px dashed var(--border);
  border-radius: 18px;
  padding: 24px;
  background: #fbfefc;
  color: var(--muted);
  text-align: center;
}

.site-footer {
  display: grid;
  grid-template-columns: 1fr auto;
  justify-content: space-between;
  gap: 18px;
  width: min(1440px, calc(100% - 32px));
  margin: 0 auto 28px;
  padding: 22px clamp(18px, 4vw, 34px);
  border-radius: var(--radius);
  color: var(--muted);
}

.site-footer strong,
.site-footer span {
  display: block;
}

.site-footer strong {
  color: var(--text);
}

.site-footer a {
  color: var(--primary-dark);
  font-weight: 700;
}

.footer-links {
  display: grid;
  justify-items: end;
  gap: 6px;
  text-align: right;
}

.toast {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 100;
  max-width: 320px;
  border-left: 5px solid var(--primary);
  border-radius: 8px;
  padding: 14px 16px;
  background: #fff;
  color: var(--text);
  box-shadow: 0 18px 42px rgba(0, 0, 0, 0.16);
  font-weight: 700;
  opacity: 0;
  transform: translateY(16px);
  pointer-events: none;
  transition: opacity 0.24s ease, transform 0.24s ease;
}

.toast.show {
  opacity: 1;
  transform: translateY(0);
}

.logout-button.loading {
  opacity: 0.72;
}

[hidden] {
  display: none !important;
}

@media (max-width: 1020px) {
  .app-shell,
  .learning-path,
  .dashboard-grid,
  .grid.three,
  .grid.two,
  .form-grid.two {
    grid-template-columns: 1fr;
  }

  .semester-sidebar {
    position: static;
  }

  .home-lab {
    grid-template-columns: 1fr;
    min-height: auto;
  }

  .lab-visual {
    min-height: 420px;
    margin: 0 20px 30px;
  }

  .custom-access-grid {
    grid-template-columns: 1fr;
  }

  .stats-hero,
  .chapter-map-container,
  .chapter-map,
  .repeat-grid,
  .concept-grid,
  .example-block,
  .worked-solution,
  .lab-readout {
    grid-template-columns: 1fr;
  }

}

@media (max-width: 760px) {
  .site-header {
    align-items: flex-start;
    flex-wrap: wrap;
  }
  
  .chapter-map {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  
  .chapter-map-container {
    padding: 12px;
  }
  
  .td-tab {
    font-size: 0.8rem;
    padding: 8px 12px;
  }

  .mobile-toggle {
    display: inline-flex;
  }

  .top-nav {
    display: none;
    width: 100%;
    justify-content: stretch;
  }

  .top-nav.open {
    display: grid;
  }

  .top-nav a,
  .logout-button {
    width: 100%;
    text-align: left;
  }

  .content-area,
  .semester-sidebar {
    padding: 18px;
  }

  .home-lab {
    border-radius: 16px;
  }

  .showcase-content {
    padding: 26px;
  }

  .lab-visual {
    min-height: 390px;
    margin: 0 0 24px;
  }

  .floating-card {
    min-width: 126px;
    padding: 12px;
  }

  .card-resume {
    left: 0;
  }

  .card-exercice {
    right: 0;
  }

  .showcase-badges {
    display: grid;
    justify-items: start;
  }

  /* Empilés : le point médian de séparation n'a plus de sens */
  .showcase-badges span:not(:last-child)::after {
    content: none;
  }

  .path-steps article {
    padding: 72px 18px 18px;
  }

  .admin-user {
    grid-template-columns: 1fr;
  }

  .admin-user-heading,
  .custom-access-title {
    display: grid;
  }

  .stats-hero {
    padding: 18px;
  }

  .law-grid,
  .checkpoint-grid {
    grid-template-columns: 1fr;
  }

  .course-section-header h2 {
    font-size: 1.35rem;
  }

  .set-circle {
    width: 108px;
    height: 108px;
  }

  .set-a {
    left: calc(50% - 96px);
  }

  .set-b {
    right: calc(50% - 96px);
  }

  .site-footer {
    display: grid;
    grid-template-columns: 1fr;
  }

  .footer-links {
    justify-items: start;
    text-align: left;
  }
}

/* Maintenance Styles - Academic gray theme */
.semester-button.maintenance {
  background: #f1f5f9;
  border-color: #cbd5e1;
  color: #475569;
  cursor: pointer;
}

.semester-button.maintenance:hover {
  transform: translateY(-2px);
  border-color: #94a3b8;
  box-shadow: 0 8px 24px rgba(100, 116, 139, 0.1);
}

.maintenance-badge {
  background: #64748b;
  color: #fff;
  font-size: 0.65rem;
  padding: 3px 10px;
  border-radius: 999px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  line-height: 1;
  white-space: nowrap;
}

/* Maintenance Page Styles */
.maintenance-hero {
  text-align: center;
  padding: 40px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.maintenance-hero h1 {
  width: 100%;
  max-width: 600px;
  margin: 0 auto 16px;
  line-height: 1.3;
}

.maintenance-icon {
  font-size: 3rem;
  margin-bottom: 20px;
  color: var(--primary);
  opacity: 0.8;
  display: flex;
  justify-content: center;
  align-items: center;
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

.maintenance-subtitle {
  color: var(--muted);
  font-size: 1.1rem;
  margin-bottom: 30px;
  text-align: center;
  width: 100%;
  max-width: 500px;
  margin-left: auto;
  margin-right: auto;
}

.maintenance-content {
  max-width: 700px;
  margin: 0 auto;
}

.maintenance-card {
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 32px;
  margin-bottom: 24px;
  text-align: left;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.maintenance-card h3 {
  color: var(--text);
  margin-bottom: 16px;
  font-size: 1.2rem;
  font-weight: 600;
  border-bottom: 2px solid var(--border);
  padding-bottom: 12px;
}

.maintenance-card p {
  color: var(--text);
  line-height: 1.7;
  margin-bottom: 12px;
}

.maintenance-list {
  list-style: none;
  padding: 0;
  margin: 20px 0;
}

.maintenance-list li {
  padding: 10px 0;
  padding-left: 28px;
  position: relative;
  border-bottom: 1px dashed var(--border);
}

.maintenance-list li:before {
  content: "▸";
  color: var(--primary);
  position: absolute;
  left: 0;
  font-size: 1.1rem;
}

.maintenance-list li:last-child {
  border-bottom: none;
}

.maintenance-notify {
  background: var(--primary-soft);
  border-radius: 10px;
  padding: 16px;
  margin-top: 24px;
  text-align: center;
}

.maintenance-notify p {
  margin: 0;
  color: var(--primary-dark);
  font-weight: 600;
}

.maintenance-actions {
  display: flex;
  gap: 16px;
  justify-content: center;
  flex-wrap: wrap;
}

/* Fraction Display Styles */
.fraction {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  vertical-align: middle;
  font-size: 0.95em;
  line-height: 1;
}

.fraction .num {
  border-bottom: 1.5px solid currentColor;
  padding: 0 4px 2px;
  text-align: center;
}

.fraction .den {
  padding: 2px 4px 0;
  text-align: center;
}

.fraction-inline {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  vertical-align: middle;
}


/* Exercise Split View Styles - Academic Design */
.exercise-split-view {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  min-height: 500px;
}

.exercise-panel,
.solution-panel {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 32px;
  background: #ffffff;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04);
  font-family: 'Georgia', 'Times New Roman', serif;
  line-height: 1.8;
}

.exercise-panel {
  border-top: 4px solid var(--primary);
}

.solution-panel {
  border-top: 4px solid var(--accent);
  position: relative;
}

.solution-panel.hidden {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  border: 2px dashed var(--border);
}

.solution-panel.hidden .solution-content {
  display: none;
}

.reveal-solution-btn {
  padding: 14px 28px;
  font-size: 1rem;
  font-weight: 700;
}

.exercise-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 2px solid var(--border);
}

.exercise-title {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text);
  font-family: Inter, Arial, sans-serif;
  letter-spacing: 0;
}

.exercise-badge {
  background: var(--primary-soft);
  color: var(--primary-dark);
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-family: Inter, Arial, sans-serif;
}

.solution-badge {
  background: #dbeafe;
  color: #1e40af;
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-family: Inter, Arial, sans-serif;
}

.exercise-content {
  font-size: 1rem;
  color: #334155;
  text-align: justify;
}

.exercise-content strong {
  color: var(--primary-dark);
  font-weight: 600;
}

.solution-content {
  font-size: 0.95rem;
  color: #334155;
  text-align: justify;
}

.solution-content strong {
  color: var(--accent);
  font-weight: 600;
}

.exercise-navigation {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.nav-btn {
  padding: 10px 20px;
  font-weight: 700;
}

.nav-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.exercise-counter {
  font-weight: 700;
  color: var(--muted);
}

/* TD Series Navigation - Academic Style */
.td-series-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 28px;
  padding: 20px 24px;
  background: #ffffff;
  border-radius: 10px;
  border: 1px solid var(--border);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.03);
}

.td-series-btn {
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.95rem;
  transition: all 0.2s ease;
  border: 1px solid var(--border);
  background: #ffffff;
  color: var(--text);
}

.td-series-btn:hover {
  border-color: var(--primary);
  color: var(--primary);
  transform: translateY(-1px);
}

.td-series-btn.active {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
  box-shadow: var(--shadow);
}

.td-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 16px;
  flex-wrap: nowrap;
  overflow-x: auto;
  border-bottom: 2px solid var(--border);
  padding-bottom: 0;
}

.td-tab {
  padding: 10px 16px;
  border-radius: 8px 8px 0 0;
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
  transition: all 0.2s ease;
  border: none;
  border-bottom: 3px solid transparent;
  background: transparent;
  color: var(--muted);
  margin-bottom: -2px;
}

.td-tab:hover {
  color: var(--primary-dark);
  background: var(--primary-soft);
}

.td-tab.active {
  background: #ffffff;
  color: var(--primary-dark);
  border-bottom-color: var(--primary);
  font-weight: 700;
}

/* Onglet dont le corpus n'est pas encore lu : le clic doit se voir pendant
   l'aller-retour réseau, sinon il paraît sans effet. */
.td-tab.is-loading {
  color: var(--primary-dark);
  cursor: progress;
}

.td-tab.is-loading::after {
  content: '';
  display: inline-block;
  width: 11px;
  height: 11px;
  margin-left: 7px;
  vertical-align: -1px;
  border: 2px solid var(--border);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: td-tab-spin 0.7s linear infinite;
}

@keyframes td-tab-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .td-tab.is-loading::after { animation-duration: 2.4s; }
}

/* Random Exercise Generator - Academic Style */
.random-exercise-panel {
  text-align: center;
  padding: 48px;
  background: #ffffff;
  border-radius: 12px;
  border: 1px solid var(--border);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}

.random-exercise-panel h2 {
  font-size: 1.5rem;
  margin-bottom: 12px;
  color: var(--text);
}

.random-exercise-panel p {
  color: var(--muted);
  margin-bottom: 24px;
}

.random-exercise-btn {
  padding: 14px 32px;
  font-size: 1rem;
  font-weight: 700;
  border-radius: 8px;
}

.generator-info {
  color: var(--muted);
  margin-top: 16px;
  font-size: 0.9rem;
  font-style: italic;
}

/* Math and Table Styles for Exercises */
.math-table {
  width: 100%;
  border-collapse: collapse;
  margin: 20px 0;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 1rem;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.math-table th,
.math-table td {
  border: 1px solid var(--border);
  padding: 12px 16px;
  text-align: center;
}

.math-table th {
  background: #f0fdf4;
  font-weight: 600;
  color: var(--text);
  border-bottom: 2px solid var(--primary);
}

.math-table td {
  background: #ffffff;
}

.math-table tr:nth-child(even) td {
  background: #fafbfc;
}

/* Combination notation C(n,k) */
.combination {
  display: inline-block;
  font-family: Georgia, serif;
  font-style: italic;
  position: relative;
  vertical-align: middle;
}

.combination sub,
.combination sup {
  font-size: 0.7em;
  display: inline-block;
}

.exercise-content sub,
.solution-content sub,
.exercise-content sup,
.solution-content sup {
  font-size: 0.75em;
  vertical-align: baseline;
  position: relative;
  top: -0.4em;
}

.exercise-content sub,
.solution-content sub {
  top: 0.4em;
}

/* Legacy table styles */
.exercise-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 20px 0;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 1rem;
}

.exercise-content th,
.exercise-content td {
  border: 1px solid var(--border);
  padding: 12px 16px;
  text-align: center;
}

.exercise-content th {
  background: #f8fafc;
  font-weight: 600;
  color: var(--text);
}

.exercise-content td {
  background: #ffffff;
}

.exercise-content tr:nth-child(even) td {
  background: #fafbfc;
}

/* Math notation styling */
.exercise-content sup,
.solution-content sup {
  font-size: 0.75em;
  vertical-align: super;
  line-height: 0;
}

.exercise-content sub,
.solution-content sub {
  font-size: 0.75em;
  vertical-align: sub;
  line-height: 0;
}

/* Fraction display */
.fraction {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  vertical-align: middle;
  font-size: 0.9em;
  margin: 0 4px;
}

.fraction .numerator {
  border-bottom: 1px solid var(--text);
  padding: 0 4px;
}

.fraction .denominator {
  padding: 0 4px;
}

/* Greek letters and math symbols */
.math-symbol {
  font-family: 'Times New Roman', Georgia, serif;
  font-style: italic;
}

/* Probability notation */
.prob-not {
  font-family: Georgia, serif;
  letter-spacing: 0.5px;
}

/* Exam Display Styles - Academic */
.exam-container {
  display: grid;
  gap: 32px;
}

.exam-section {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 40px;
  background: #ffffff;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04);
}

.exam-section-title {
  font-size: 1.25rem;
  font-weight: 700;
  margin-bottom: 24px;
  color: var(--text);
  padding-bottom: 16px;
  border-bottom: 3px solid var(--primary);
  font-family: Inter, Arial, sans-serif;
}

.exam-content {
  font-family: 'Georgia', 'Times New Roman', serif;
  line-height: 1.9;
  font-size: 0.98rem;
  color: #334155;
}

.exam-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 20px 0;
  font-family: Inter, Arial, sans-serif;
  font-size: 0.9rem;
}

.exam-content th,
.exam-content td {
  border: 1px solid var(--border);
  padding: 10px 12px;
  text-align: center;
}

.exam-content th {
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-weight: 600;
}

.exam-content tr:nth-child(even) {
  background: #f8fafc;
}

.exam-content sub,
.exam-content sup {
  font-size: 0.75em;
  vertical-align: baseline;
  position: relative;
  top: -0.4em;
}

.exam-content sub {
  top: 0.4em;
}

/* Math tables in exam content */
.exam-content-doc .math-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 16px 0 !important;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 0.95rem;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}

.exam-content-doc .math-table th,
.exam-content-doc .math-table td {
  border: 1px solid var(--border);
  padding: 10px 14px;
  text-align: center;
}

.exam-content-doc .math-table th {
  background: #f0fdf4;
  font-weight: 600;
  color: var(--text);
}

.exam-content-doc .math-table tr:nth-child(even) td {
  background: #fafbfc;
}

/* Exam Selector Tabs */
.exam-selector {
  display: flex;
  gap: 12px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}

.exam-tab {
  padding: 12px 20px;
  border: 1px solid var(--border);
  background: #ffffff;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 500;
  transition: all 0.2s ease;
}

.exam-tab:hover {
  background: #f0fdf4;
  border-color: var(--primary);
}

.exam-tab.active {
  background: var(--primary);
  color: white;
  border-color: var(--primary);
}

/* Exam Document - Word-like Style */
.exam-document {
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.exam-paper,
.correction-paper {
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  overflow: hidden;
}

.correction-paper {
  border-top: 4px solid var(--accent);
}

.exam-header-doc {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 28px;
  background: #f8fafc;
  border-bottom: 1px solid var(--border);
}

.correction-header {
  background: #fdf0d5;
}

.exam-title-doc {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--text);
  margin: 0;
}

.exam-badge {
  display: inline-block;
  padding: 6px 16px;
  background: var(--primary);
  color: white;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-radius: 4px;
}

.correction-badge {
  background: var(--accent);
  color: #78350f;
}

.exam-content-doc {
  padding: 32px;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 1rem;
  line-height: 1.9;
  color: #334155;
}

.correction-section {
  border-top: 4px solid var(--accent);
  background: #ffffff;
}

.correction-section .exam-section-title {
  border-bottom-color: var(--accent);
}

/* Summary Tree Styles */
.summary-tree {
  display: grid;
  gap: 16px;
}

/* ── Résumé statistiques : hiérarchie des titres ─────────────── */
.summary-content {
  color: var(--text);
  line-height: 1.6;
}

.summary-content .md-h {
  font-family: var(--font-heading);
  color: var(--text);
  line-height: 1.25;
}

/* Titre principal du résumé */
.summary-content .md-h2 {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 4px 0 20px;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--primary);
}

/* Sections numérotées (1., 2., …) */
.summary-content .md-h3 {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--primary);
  margin: 28px 0 10px;
  padding: 8px 14px;
  background: var(--primary-soft);
  border-radius: var(--radius-md);
}

/* Sous-titres */
.summary-content .md-h4 {
  font-size: 1.02rem;
  font-weight: 700;
  margin: 20px 0 8px;
  padding-left: 12px;
  border-left: 3px solid var(--primary);
}

.summary-content .md-h5 {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--muted);
  margin: 16px 0 6px;
}

.summary-content p {
  margin: 8px 0;
}

.summary-content ul,
.summary-content li {
  line-height: 1.65;
}

.summary-content .math-table {
  margin: 12px 0 20px;
}

/* Résumé Maths S1 = aide-mémoire compact : un seul document, 8 chapitres à la
   suite, tableaux et espacements resserrés (à parcourir/imprimer). */
.maths-resume-intro {
  margin: 0 0 18px;
  color: var(--muted);
  font-size: 0.92rem;
}
.maths-resume-sheet .maths-resume-chapter {
  padding: 18px 0;
  border-top: 1px solid var(--border);
}
.maths-resume-sheet .maths-resume-chapter:first-of-type {
  border-top: 0;
  padding-top: 0;
}
.maths-resume-sheet .maths-resume-chapter h2 {
  font-size: 1.06rem;
  color: var(--primary-dark);
  margin: 0 0 10px;
}
.maths-resume-sheet .math-table {
  margin: 12px 0;
  font-size: 0.92rem;
}
.maths-resume-sheet .math-table th,
.maths-resume-sheet .math-table td {
  padding: 7px 12px;
}

/* Un tableau plus large que la place disponible doit DÉFILER DANS SON CADRE,
   jamais pousser la page — même principe que `.bc-cours-table` pour les
   tableaux du cours.

   Le cas qui l'a imposé : les deux chaînes d'ordre énergétique des orbitales
   moléculaires, au chapitre 6 du résumé de Chimie. Ce sont des formules KaTeX
   INSÉCABLES de ~375 px ; dans une cellule, elles poussaient la page 210 px
   hors cadre dès que la colonne de contenu descendait sous ~400 px.

   PAS de media query ici, et c'est délibéré : la largeur utile ne dépend pas de
   celle de la FENÊTRE mais de la colonne de contenu, que le menu latéral
   rétrécit. Une règle conditionnée à la fenêtre laisserait passer le
   débordement sur un écran large au menu déplié. `display: block` + `width:
   100%` donne un cadre qui occupe toute la largeur offerte et fait défiler son
   contenu à l'intérieur ; `min-width: 0` empêche les conteneurs de grille de se
   dilater à la largeur min-content du tableau. */
.maths-resume-sheet .math-table {
  display: block;
  width: 100%;
  overflow-x: auto;
}
.maths-resume-sheet .maths-resume-chapter,
.maths-resume-sheet .maths-resume-content { min-width: 0; }

.tree-node {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  background: var(--surface);
  position: relative;
}

.tree-node.main {
  background: var(--primary-soft);
  border-color: var(--primary);
}

.tree-children {
  display: grid;
  gap: 12px;
  margin-left: 24px;
  margin-top: 12px;
  padding-left: 16px;
  border-left: 2px solid var(--border);
}

.tree-node-title {
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
}

.tree-node-content {
  margin-top: 8px;
  color: var(--muted);
  font-size: 0.95rem;
}

.tree-icon {
  font-size: 1.2rem;
}

@media (max-width: 1020px) {
  .exercise-split-view {
    grid-template-columns: 1fr;
  }
}

/* ── Maths S1 Module ──────────────────────────────────────────── */

.maths-chapters {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: 20px;
}

.maths-chapter-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px 28px;
}

.maths-chapter-card h3 {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--primary-dark);
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--primary-soft);
}

.maths-chapter-content {
  font-size: 0.95rem;
  color: var(--text);
  line-height: 1.75;
}

.maths-chapter-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0;
  font-size: 0.9rem;
}

.maths-chapter-content table th,
.maths-chapter-content table td {
  border: 1px solid var(--border);
  padding: 8px 12px;
  text-align: left;
}

.maths-chapter-content table th {
  background: var(--primary-soft);
  font-weight: 600;
  color: var(--primary-dark);
}

.series-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
  margin-top: 20px;
}

.series-card {
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: 14px;
  padding: 20px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}

.series-card:hover {
  border-color: var(--primary);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}

.series-num {
  font-size: 1rem;
  font-weight: 700;
  color: var(--primary-dark);
}

.series-subtitle {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text);
}

.series-meta {
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 4px;
}

.exam-card {
  border-color: var(--accent);
}

.exam-card:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow);
}

.maths-chapitres-tag {
  font-size: 0.85rem;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 14px;
  margin-bottom: 20px;
  display: inline-block;
}

.maths-exercises {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-top: 20px;
}

.maths-exercise {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}

.maths-exercise-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.exercise-num {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--primary-dark);
  background: var(--primary-soft);
  border-radius: 8px;
  padding: 4px 12px;
}

/* Biologie cellulaire — intitulé de partie au-dessus du premier bloc */
.bc-part-heading {
  font-family: var(--font-heading);
  font-size: 1.05rem;
  color: var(--primary-dark);
  margin: 12px 0 -4px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.bc-part-heading:first-child {
  margin-top: 0;
}

/* Les figures des examens de biologie cellulaire sont des schémas à légender :
   le flottant 320px de `.md-img` les rend illisibles. Pleine largeur, centrées. */
.bc-statement .md-img {
  float: none;
  display: block;
  max-width: 100%;
  margin: 16px auto;
}

/* Tableaux à compléter : les cellules vides sont l'espace de réponse, elles
   doivent rester visibles et alignées au lieu de s'écraser. */
.bc-statement .math-table td:empty,
.bc-statement .math-table th:empty {
  height: 2.4rem;
}

/* Hiérarchie visuelle des corrigés de biologie cellulaire.
   Sans ces trois niveaux, la réponse, son explication et les réserves de
   relecture se lisaient au même plan — tout en gras ou en italique. */

/* La réponse elle-même : repérable d'un coup d'œil, sans lire le paragraphe. */
.maths-solution .bc-answer,
.qcm-correction .bc-answer,
.qcm-explication .bc-answer {
  margin: 14px 0;
  padding: 12px 16px;
  background: var(--primary-soft);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-md, 8px);
  font-size: 0.96rem;
  line-height: 1.6;
  color: var(--text);
}

/* Une formule d'affichage trop large défile DANS SON PROPRE CADRE, elle ne
   pousse jamais la page. Sans cette règle, les chaînes de pivot de Gauss des
   séries de maths (matrice augmentée → flèche → matrice augmentée, ~630 px de
   large) débordaient sur mobile : 11 blocs sur 57 mesurés à 340 px de large.
   Même principe que `.bc-cours-table` pour les tableaux du cours.
   `padding-bottom` réserve la place de la barre de défilement, sans quoi elle
   recouvre le bas des fractions. */
.maths-solution .katex-display,
.maths-exercise-statement .katex-display,
.qcm-correction .katex-display,
.qcm-preamble .katex-display,
.qcm-explication .katex-display,
.physics-solution .katex-display,
.physics-statement .katex-display {
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 4px;
}
/* `.qcm-preamble` et `.qcm-explication` ont été ajoutés le 27 août 2026 : la
   règle ne couvrait que le corrigé détaillé d'un QCM (`.qcm-correction`), pas
   les deux autres endroits où un bloc `qcm[]` accueille du display math —
   l'énoncé commun placé en tête d'exercice et l'explication par question. Sur
   le sujet de Maths S1 en QCM, 11 blocs sur 53 débordaient de leur cadre à
   375 px (systèmes en `cases`, produits matrice × colonne). Même défaut, même
   cause et même remède que pour `.maths-solution` ci-dessus ; la règle vaut
   pour tout module au moteur `qcm[]` partagé. */

/* L'aparté explicatif : « pourquoi cette réponse », « le piège ». */
.maths-solution .bc-aside,
.qcm-correction .bc-aside,
.qcm-explication .bc-aside {
  margin: 12px 0;
  padding: 10px 14px;
  background: #fbfdfc;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--muted);
}

/* Réserve de relecture : doit sauter aux yeux du propriétaire, discrètement
   pour l'étudiant. Repérable au balayage, pas alarmant. */
.maths-solution .bc-todo,
.qcm-correction .bc-todo {
  margin: 12px 0;
  padding: 10px 14px;
  background: #fdf8ec;
  border-left: 3px solid #c9922f;
  border-radius: var(--radius-md, 8px);
  font-size: 0.86rem;
  line-height: 1.5;
  color: #7a5a18;
}

.bc-solution-pending {
  margin: 14px 0 0;
  font-size: 0.9rem;
  color: var(--muted);
  font-style: italic;
}

/* Provenance d'UN corrigé, quand elle varie d'un exercice à l'autre du même
   document (moteur de corpus partagé, champ `origine`). Discret et en tête du
   corrigé : l'étudiant doit savoir s'il lit la parole de l'enseignant ou un
   corrigé rédigé pour BioPrep, sans que la mention prenne le pas sur le fond. */
.corpus-origine {
  margin: 0 0 12px;
  font-size: 0.82rem;
  color: var(--muted);
  font-style: italic;
  letter-spacing: 0.01em;
}

.exercise-points {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
  background: #e8f0fe;
  border-radius: 8px;
  padding: 4px 12px;
}

.maths-exercise-statement {
  font-size: 0.95rem;
  line-height: 1.75;
  color: var(--text);
  margin-bottom: 16px;
}

.solution-toggle {
  background: none;
  border: 2px solid var(--primary);
  color: var(--primary-dark);
  border-radius: 8px;
  padding: 8px 18px;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}

.solution-toggle:hover {
  background: var(--primary-soft);
}

.maths-solution {
  margin-top: 16px;
  padding: 20px;
  background: var(--surface-2);
  border-left: 4px solid var(--primary);
  border-radius: 0 10px 10px 0;
  font-size: 0.93rem;
  line-height: 1.75;
  color: var(--text);
}

.maths-solution table {
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0;
  font-size: 0.88rem;
}

.maths-solution table th,
.maths-solution table td {
  border: 1px solid var(--border);
  padding: 7px 10px;
  text-align: left;
}

.maths-solution table th {
  background: var(--primary-soft);
  font-weight: 600;
}

.btn-back {
  background: none;
  border: none;
  color: var(--primary-dark);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  margin-bottom: 20px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.btn-back:hover {
  text-decoration: underline;
}

.exam-header-info {
  margin-bottom: 24px;
}

.exam-meta-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.exam-tag {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent);
  background: #e8f0fe;
  border-radius: 20px;
  padding: 4px 12px;
}

/* Navigation compacte du module physique : sous-module + partie + onglets */
.physics-nav {
  margin-bottom: 14px;
}

.physics-track-map {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 10px;
}

.physics-part-selector {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 14px;
}

.physics-nav-btn {
  padding: 8px 16px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}

.physics-nav-btn:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.physics-nav-btn.active {
  border-color: var(--primary);
  background: var(--primary);
  color: #fff;
}

.physics-nav-btn.subtle {
  padding: 6px 14px;
  font-weight: 500;
  font-size: 0.86rem;
}

.physics-nav-btn.subtle.active {
  background: var(--primary-soft);
  color: var(--primary-dark);
  border-color: var(--primary);
}

.physics-course,
.physics-resume {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.035);
}

.physics-course h2,
.physics-resume h2 {
  color: var(--primary-dark);
  margin-top: 0;
}

.physics-course-content,
.physics-resume-content,
.maths-course-content {
  line-height: 1.8;
  color: var(--text);
}

/* ── Cours en chapitres : sommaire cliquable + accordéon ── */
.course-reader-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.course-reader-count {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--primary-dark);
  background: var(--primary-soft);
  border-radius: 999px;
  padding: 4px 12px;
  white-space: nowrap;
}

.course-intro {
  padding-bottom: 18px;
  margin-bottom: 22px;
  border-bottom: 1px solid var(--border);
}

.course-reader-grid {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  gap: 22px;
  align-items: start;
}

/* Sommaire latéral collant — compact et sobre */
.course-toc {
  position: sticky;
  top: 84px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 12px;
}

.course-toc-title {
  margin: 0 0 8px;
  font-family: var(--font-heading);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.course-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: none;
  max-height: min(56vh, 440px);
  overflow-y: auto;
}

.course-toc-list li { margin: 0; }

.course-toc-link {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  cursor: pointer;
  color: var(--text);
  font-size: 0.8rem;
  line-height: 1.3;
  transition: background 0.15s ease, color 0.15s ease;
}

.course-toc-link:hover,
.course-toc-link:focus-visible {
  background: var(--primary-soft);
  color: var(--primary-dark);
  outline: none;
}

.course-toc-num {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.7rem;
  color: var(--primary);
  padding-top: 1px;
}

.course-toc-actions {
  display: flex;
  gap: 6px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}

.course-toc-btn {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 5px 6px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.course-toc-btn:hover {
  border-color: var(--primary);
  color: var(--primary-dark);
}

/* Chapitres en accordéon */
.course-chapters {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.course-chapter {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  scroll-margin-top: 80px;
}

.course-chapter.open {
  border-color: var(--primary);
  box-shadow: var(--shadow-sm);
}

.course-chapter-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  padding: 14px 16px;
  cursor: pointer;
  color: var(--text);
}

.course-chapter-head:hover { background: var(--surface-2); }

.course-chapter-num {
  flex: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-weight: 700;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
}

.course-chapter.open .course-chapter-num {
  background: var(--primary);
  color: #fff;
}

.course-chapter-title {
  flex: 1;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--primary-dark);
  line-height: 1.3;
}

.course-chapter-caret {
  flex: none;
  display: inline-flex;
  color: var(--muted);
  transition: transform 0.2s ease;
}

.course-chapter.open .course-chapter-caret {
  transform: rotate(180deg);
  color: var(--primary);
}

.course-chapter-body {
  max-height: 0;
  overflow: hidden;
  padding: 0 18px;
  transition: max-height 0.3s ease, padding 0.3s ease;
}

.course-chapter.open .course-chapter-body {
  max-height: none;
  padding: 4px 18px 18px;
  border-top: 1px solid var(--border);
}

.course-chapter-foot {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}

.course-nav-btn {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 48%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 8px 12px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.course-nav-btn:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.course-nav-btn.next { text-align: right; margin-left: auto; }

.course-nav-btn span {
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--primary);
}

.course-nav-btn em {
  font-style: normal;
  font-size: 0.82rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 860px) {
  .course-reader-grid { grid-template-columns: 1fr; }
  .course-toc { position: static; top: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .course-chapter-body,
  .course-chapter-caret { transition: none; }
}

.physics-exercise-card .exercise-num {
  max-width: 100%;
  white-space: normal;
}

.module-placeholder {
  min-height: 360px;
  display: grid;
  place-items: center;
  padding: 36px;
}

.placeholder-content {
  width: min(720px, 100%);
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 24px;
  padding: 36px;
  box-shadow: var(--shadow);
  text-align: center;
}

.placeholder-icon {
  width: 72px;
  height: 72px;
  margin: 0 auto 18px;
  border-radius: 24px;
  display: grid;
  place-items: center;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 2rem;
}

.placeholder-content h3 {
  margin: 0 0 10px;
  font-size: 1.45rem;
  color: var(--primary-dark);
}

.placeholder-content p {
  color: var(--muted);
  line-height: 1.7;
}

.placeholder-features {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}

.placeholder-features span {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 14px;
  color: var(--text);
  font-weight: 700;
  font-size: 0.86rem;
}

.institution-page {
  display: grid;
  gap: 22px;
}

.institutional-hero,
.institutional-quote,
.academic-start {
  border-color: rgba(30, 107, 71, 0.2);
}

.institution-cards .card,
.terms-grid article,
.contact-highlight {
  position: relative;
  overflow: hidden;
}

.card-kicker,
.terms-grid span {
  display: inline-flex;
  margin-bottom: 10px;
  border-radius: 999px;
  padding: 6px 10px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.contact-grid .contact-highlight {
  min-height: 190px;
  background: #ffffff;
}

.terms-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

.terms-grid article {
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.terms-grid h3 {
  margin: 0 0 10px;
  color: var(--text);
}

.terms-grid p {
  margin: 0;
  color: var(--muted);
  line-height: 1.7;
}

/* ── Pages institutionnelles (À propos, Règlement) : composants enrichis ── */
.institution-heading {
  margin: 14px 0 -6px;
  /* Titres de section des pages À propos / CGU : ils étaient à la taille
     exacte des h3 qu ils surplombent, donc indiscernables d eux. */
  font-size: 1.5rem;
  color: var(--primary-dark);
}

/* Pastille d'icône ronde (badge de section/carte) */
.page-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  margin-bottom: 12px;
  background: var(--primary);
  color: #fff;
}
.page-icon.soft {
  background: var(--primary-soft);
  color: var(--primary-dark);
}

.value-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.value-card h3 { margin: 6px 0 8px; }
.value-card p { margin: 0; color: var(--muted); line-height: 1.7; }

/* « Ce que vous trouverez » : lignes icône + texte */
.about-features .feature-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 16px;
  align-items: start;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow-sm);
}
.about-features .feature-row .page-icon { margin-bottom: 0; }
.about-features .feature-row h3 { margin: 2px 0 6px; font-size: 1.05rem; }
.about-features .feature-row p { margin: 0; color: var(--muted); line-height: 1.65; }

/* Règlement : engagements réciproques (2 colonnes) */
.reciprocal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
}
.reciprocal-col {
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: var(--shadow);
}
.check-list {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 12px;
}
.check-list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px;
  align-items: start;
  color: var(--text);
  line-height: 1.6;
}
.check-list li svg {
  color: var(--primary);
  margin-top: 3px;
  flex-shrink: 0;
}

/* ===================== Page de paiement premium ===================== */
.checkout-page {
  max-width: 1180px;
  margin: 0 auto;
}

.checkout-hero {
  text-align: center;
  padding: 8px 0 4px;
}

.checkout-hero h1 {
  margin: 6px auto 10px;
  max-width: 760px;
}

.checkout-hero .lead {
  margin: 0 auto;
  max-width: 560px;
}

.trust-badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 22px;
}

.trust-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 9px 16px;
  background: var(--surface);
  font-weight: 700;
  font-size: 0.88rem;
  color: var(--text);
  box-shadow: 0 4px 14px rgba(20, 60, 10, 0.05);
}

.tb-icon {
  display: inline-flex;
  color: var(--primary);
}

.pricing-section {
  margin-top: 40px;
}

.pricing-grid {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: 20px;
  align-items: stretch;
  max-width: 760px;
  margin: 0 auto;
}

.pricing-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px 24px;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.pricing-featured {
  border: 2px solid var(--primary);
  box-shadow: var(--shadow);
}

.pricing-ribbon {
  position: absolute;
  top: 16px;
  right: 16px;
  border-radius: var(--radius-sm);
  padding: 5px 12px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 0.74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.featured-ribbon {
  top: -13px;
  right: 50%;
  transform: translateX(50%);
  background: var(--primary);
  color: #fff;
}

.pricing-head h3 {
  margin: 0;
  font-size: 1.25rem;
  color: var(--primary-dark);
}

.pricing-featured .pricing-head h3 {
  margin-top: 8px;
}

.best-value-tag {
  display: inline-block;
  margin-top: 8px;
  border-radius: 999px;
  padding: 3px 10px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.pricing-tagline {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.pricing-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
  margin: 20px 0 4px;
}

.price-old {
  color: var(--muted);
  text-decoration: line-through;
  font-weight: 700;
  font-size: 0.95rem;
  order: -1;
  width: 100%;
}

.price-from {
  order: -1;
  width: 100%;
  color: var(--muted);
  font-weight: 700;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.pricing-breakdown {
  margin: 14px 0 0;
  text-align: center;
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 1.5;
}

.price-amount {
  font-size: 2.8rem;
  font-weight: 700;
  line-height: 1;
  color: var(--text);
}

.pricing-featured .price-amount {
  color: var(--primary-dark);
}

.price-currency {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--muted);
}

.price-context {
  margin: 0 0 18px;
  color: var(--muted);
  font-size: 0.85rem;
}

.pricing-benefits {
  list-style: none;
  padding: 0;
  margin: 0 0 22px;
  display: grid;
  gap: 11px;
  flex: 1;
}

.pricing-benefits li {
  position: relative;
  padding-left: 28px;
  color: var(--text);
  font-size: 0.92rem;
  line-height: 1.5;
}

.pricing-benefits li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 0.72rem;
  font-weight: 700;
}

.pricing-cta {
  width: 100%;
  justify-content: center;
  text-align: center;
  padding: 13px 18px;
  font-size: 0.98rem;
}

.btn.ghost {
  border: 1px solid var(--border);
  background: transparent;
  color: var(--primary-dark);
}

.btn.ghost:hover {
  background: var(--primary-soft);
}

.cta-featured {
  font-size: 1.05rem;
  padding: 15px 18px;
  box-shadow: var(--shadow);
}

.pricing-compare,
.pricing-saving {
  margin: 13px 0 0;
  text-align: center;
  font-size: 0.82rem;
}

.pricing-compare {
  color: var(--muted);
}

.pricing-saving {
  color: var(--primary-dark);
  font-weight: 700;
}

.semester-price-intro {
  margin: 0 0 10px;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--muted);
}

.semester-price-list {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: grid;
  gap: 8px;
}

.sem-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #fbfefb;
  transition: border-color 0.18s ease, background 0.18s ease;
}

.sem-row:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.sem-label {
  display: grid;
  gap: 1px;
  color: var(--text);
  font-weight: 700;
  font-size: 0.9rem;
}

.sem-label em {
  font-style: normal;
  font-weight: 700;
  color: var(--muted);
  font-size: 0.74rem;
}

.sem-prices {
  display: flex;
  align-items: baseline;
  gap: 8px;
  white-space: nowrap;
}

.sem-prices s {
  color: var(--muted);
  font-size: 0.82rem;
}

.sem-prices strong {
  color: var(--primary-dark);
  font-size: 1.1rem;
  font-weight: 700;
}

.anchor-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 30px;
  padding: 18px;
  border: 1px dashed var(--border);
  border-radius: 16px;
  background: #fbfefb;
}

.anchor-item {
  display: grid;
  justify-items: center;
  gap: 2px;
  text-align: center;
}

.anchor-item span {
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 700;
}

.anchor-item strong {
  font-size: 1.1rem;
  color: var(--text);
}

.anchor-item strong.strike {
  text-decoration: line-through;
  color: var(--muted);
}

.anchor-item em {
  font-style: normal;
  font-size: 0.74rem;
  font-weight: 700;
  color: var(--primary-dark);
}

.anchor-item.highlight strong,
.anchor-item.best strong {
  color: var(--primary-dark);
}

.anchor-item.best {
  background: var(--primary-soft);
  border-radius: 12px;
  padding: 8px 14px;
}

.anchor-arrow {
  color: var(--muted);
  font-weight: 700;
}

.friction-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 24px;
  margin-top: 24px;
}

.friction-row span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--primary-dark);
  font-weight: 600;
  font-size: 0.9rem;
}

.trust-section {
  margin-top: 56px;
  text-align: center;
}

.trust-section h2 {
  margin-bottom: 26px;
}

/* Quatre rubriques, quatre colonnes : jamais de carte orpheline sur une
   seconde ligne (auto-fit n'en plaçait que trois dans cette largeur). */
.trust-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

@media (max-width: 1180px) {
  .trust-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .trust-grid {
    grid-template-columns: 1fr;
  }
}

.trust-card {
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px 16px;
  background: var(--surface);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.trust-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 34px rgba(20, 60, 10, 0.1);
}

.trust-ico {
  display: inline-flex;
  color: var(--primary);
}

.trust-card h3 {
  margin: 12px 0 8px;
  font-size: 1.02rem;
  color: var(--primary-dark);
}

.trust-card p {
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.6;
}

@media (max-width: 940px) {
  .pricing-grid {
    grid-template-columns: 1fr;
  }
  .featured-ribbon {
    top: 16px;
    right: 16px;
    transform: none;
  }
}

.maintenance-status-card {
  display: flex;
  align-items: center;
  gap: 18px;
  border-left: 5px solid var(--primary);
  background: #ffffff;
}

.maintenance-status-icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 18px;
  background: var(--surface);
  font-size: 1.9rem;
  flex-shrink: 0;
  box-shadow: var(--shadow);
}

.maintenance-status-card h3 {
  margin: 0 0 6px;
  color: var(--primary-dark);
}

.maintenance-status-card p {
  margin: 0;
  color: var(--muted);
  line-height: 1.65;
}

.maintenance-section-title {
  margin-top: 0;
}

.maintenance-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
  margin-top: 16px;
}

.maintenance-item {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px;
  background: var(--surface);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.maintenance-item:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
}

.maintenance-item-num {
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-weight: 700;
  flex-shrink: 0;
}

.maintenance-item h3 {
  margin: 0 0 6px;
  font-size: 1.02rem;
  color: var(--text);
}

.maintenance-item p {
  margin: 0;
  color: var(--muted);
  line-height: 1.6;
  font-size: 0.9rem;
}

.admin-loading,
.admin-error,
.admin-empty {
  color: var(--muted);
  font-weight: 700;
}

.admin-error {
  color: var(--danger);
}

/* ── Tableau de bord (statistiques) ── */
.admin-stats-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}

.admin-stat {
  display: grid;
  gap: 4px;
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px 18px;
  background: var(--surface);
}

.admin-stat-value {
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1;
  color: var(--text);
}

.admin-stat-label {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.admin-stat.approved {
  border-color: rgba(30, 107, 71, 0.35);
  background: var(--primary-soft);
}
.admin-stat.approved .admin-stat-value { color: var(--primary-dark); }

.admin-stat.pending {
  border-color: #ffe2b8;
  background: #fff8ee;
}
.admin-stat.pending .admin-stat-value { color: var(--warning); }

.admin-stat.rejected {
  border-color: #ffd4d4;
  background: #fff1f1;
}
.admin-stat.rejected .admin-stat-value { color: var(--danger); }

/* ── Grille de cartes étudiants ── */
.admin-user-list {
  display: grid;
  gap: 8px;
  max-height: 640px;
  overflow-y: auto;
  padding-right: 4px;
}

.admin-user-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 12px 14px;
  background: var(--surface);
  text-align: left;
  transition: border-color 0.18s ease, background 0.18s ease, transform 0.18s ease;
}

.admin-user-item:hover {
  border-color: var(--primary);
  transform: translateY(-1px);
}

.admin-user-item.active {
  border-color: var(--primary);
  background: var(--primary-soft);
  box-shadow: var(--shadow);
}

.admin-avatar {
  display: inline-grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--surface-2);
  color: var(--primary-dark);
  font-weight: 700;
  font-size: 0.92rem;
  flex-shrink: 0;
}

.admin-avatar.large {
  width: 58px;
  height: 58px;
  font-size: 1.2rem;
}

.admin-avatar.approved {
  background: var(--primary-soft);
  color: var(--primary-dark);
}

.admin-avatar.rejected {
  background: #ffecec;
  color: var(--danger);
}

.admin-user-meta {
  display: grid;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.admin-user-meta strong {
  color: var(--text);
  font-size: 0.94rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.admin-user-meta span {
  color: var(--muted);
  font-size: 0.82rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.status-dot {
  width: 11px;
  height: 11px;
  border-radius: 999px;
  background: var(--warning);
  flex-shrink: 0;
}

.status-dot.approved {
  background: var(--primary);
}

.status-dot.rejected {
  background: var(--danger);
}

.admin-detail {
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--surface);
  padding: 22px;
  min-height: 420px;
}

.admin-detail-empty {
  display: grid;
  place-items: center;
  min-height: 360px;
  text-align: center;
  color: var(--muted);
}

.admin-full-toggle {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px 16px;
  background: #fbfefc;
  cursor: pointer;
  margin-bottom: 18px;
}

.admin-full-toggle input {
  width: 20px;
  height: 20px;
  accent-color: var(--primary);
}

.admin-full-toggle span {
  display: grid;
  gap: 2px;
}

.admin-full-toggle small {
  color: var(--muted);
}

.admin-access-body h4 {
  margin: 0 0 12px;
  color: var(--primary-dark);
}

/* Menu des semestres et modules du panneau admin.
   Les cases heritaient du `input { width: 100% }` global : chacune s'etirait sur
   la moitie de sa carte, poussait son libelle contre le bord droit et le cassait
   sur deux ou trois lignes. Elles sont dimensionnees ici, et le libelle prend le
   reste de la ligne — colonne de cases alignee, une ligne par module. */
.admin-access-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
  align-items: start;
  gap: 12px;
}

.admin-access-groups input[type="checkbox"] {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin: 0;
  padding: 0;
  border-radius: var(--radius-sm);
}

.admin-access-group {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 12px 14px 13px;
  background: var(--surface);
}

.admin-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  padding: 0 6px 9px;
  margin-bottom: 9px;
  border-bottom: 1px solid var(--border);
  color: var(--primary-dark);
  font-weight: 700;
  line-height: 1.3;
  cursor: pointer;
}

/* Base de 140px : un titre long (le parcours concours) garde une largeur
   lisible et renvoie la pastille << en preparation >> a la ligne suivante,
   au lieu d etre casse a un mot par ligne. */
.admin-group-head > span {
  flex: 1 1 140px;
  min-width: 0;
}

.admin-group-tag {
  flex: 0 0 auto;
  margin-left: auto;
  border-radius: 999px;
  padding: 2px 9px;
  background: #fff4e0;
  color: var(--warning);
  font-size: 0.72rem;
  font-style: normal;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.admin-group-empty {
  margin: 0;
  padding: 0 6px;
  color: var(--muted);
  font-size: 0.82rem;
  font-style: italic;
}

.admin-group-modules {
  display: grid;
  gap: 1px;
}

.admin-group-modules label {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 6px;
  border-radius: var(--radius-sm);
  color: #334a3f;
  font-weight: 600;
  font-size: 0.86rem;
  line-height: 1.3;
  cursor: pointer;
}

.admin-group-modules label > span {
  flex: 1 1 auto;
  min-width: 0;
}

.admin-group-modules label:hover {
  background: var(--primary-soft);
}

.admin-row-editor input[type="checkbox"] {
  accent-color: var(--primary);
}

.admin-row-editor.full-mode .admin-access-groups {
  opacity: 0.45;
  pointer-events: none;
}

.admin-detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}

/* Encaissement et journal — la trace d'une activation d'accès.
   Le virement se déclare hors plateforme ; ces champs notent ce qui a été reçu. */
.admin-paiement {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px;
  background: var(--surface);
  display: grid;
  gap: 12px;
}

.admin-paiement-intro {
  margin: 0;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.5;
}

.admin-paiement-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
}

.admin-paiement label,
.admin-paiement-note {
  display: grid;
  gap: 5px;
  color: #334a3f;
  font-weight: 700;
  font-size: 0.82rem;
}

.admin-paiement input,
.admin-paiement select {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 9px 11px;
  background: #fff;
  font: inherit;
  font-weight: 400;
  color: var(--text);
}

.admin-paiement input:focus,
.admin-paiement select:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

.admin-journal {
  border-top: 1px dashed var(--border);
  padding-top: 12px;
}

.admin-journal-title {
  margin: 0 0 8px;
  font-size: 0.9rem;
  color: var(--primary-dark);
}

.admin-journal-empty {
  margin: 0;
  color: var(--muted);
  font-size: 0.82rem;
  font-style: italic;
}

.admin-journal-list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.admin-journal-list li {
  display: grid;
  gap: 2px;
  border-left: 3px solid var(--border);
  padding-left: 10px;
  font-size: 0.82rem;
}

.admin-journal-date {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.admin-journal-action {
  font-weight: 700;
  color: var(--primary-dark);
}

.admin-journal-delta {
  color: var(--text);
}

.admin-journal-meta {
  color: var(--muted);
  font-size: 0.78rem;
}

@media (max-width: 940px) {
  .admin-workspace {
    grid-template-columns: 1fr;
  }

  .admin-user-list {
    max-height: 320px;
  }

  .admin-stats-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 760px) {
  .admin-panel-header {
    display: grid;
  }
}

@media (max-width: 640px) {
  .series-grid {
    grid-template-columns: 1fr 1fr;
  }

  .placeholder-content {
    padding: 24px;
  }

  .admin-stats-row {
    grid-template-columns: 1fr;
  }
}



/* ── Accessibilité : focus clavier ── */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.placeholder-icon svg {
  color: var(--primary);
}

/* Icône de chargement en rotation (écran « Chargement du module ») */
.placeholder-icon.loading svg {
  animation: bp-spin 0.9s linear infinite;
}

@keyframes bp-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .placeholder-icon.loading svg { animation: none; }
}

.placeholder-features span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}


/* ── Bandeau de vérification email ── */
.verify-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  border: 1px solid #ecd9a8;
  border-left: 4px solid var(--warning);
  border-radius: var(--radius-md);
  padding: 16px 20px;
  background: #fdf6e5;
}

.verify-banner-text strong {
  display: block;
  color: #6b4a0e;
}

.verify-banner-text p {
  margin: 4px 0 0;
  color: #7a5c22;
  font-size: 0.9rem;
}

.verify-banner .actions {
  margin: 0;
}

/* ── Bouton WhatsApp ── */
.btn.whatsapp-btn {
  background: #128c50;
}

.btn.whatsapp-btn:hover {
  background: #0d6e3f;
}

.btn.whatsapp-btn svg {
  flex: none;
}


/* ── Admin : liste dense en tableau ── */
.admin-table {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

.admin-table-head,
.admin-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 2.2fr) 150px 80px minmax(0, 1.3fr) 84px;
  gap: 10px;
  align-items: center;
  padding: 10px 16px;
}

.admin-row-num {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  font-weight: 600;
  font-size: 0.85rem;
  text-align: right;
}

.admin-table-head {
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.admin-row-wrap {
  border-bottom: 1px solid var(--border);
}

.admin-row-wrap:last-child {
  border-bottom: 0;
}

.admin-row-wrap.expanded {
  background: var(--primary-soft);
}

.admin-row-identity {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.admin-row-identity > div {
  min-width: 0;
}

.admin-row-identity strong {
  display: block;
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.admin-row-email {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 0.82rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.verified-tag,
.unverified-tag {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: none;
  font-style: normal;
  font-size: 0.72rem;
  font-weight: 600;
  border-radius: 999px;
  padding: 1px 8px;
}

.verified-tag {
  color: var(--primary-dark);
  background: var(--primary-soft);
}

.unverified-tag {
  color: var(--warning);
  background: #fdf0d5;
}

.admin-row-date,
.admin-row-access {
  color: var(--muted);
  font-size: 0.84rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.admin-row-manage {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 7px 12px;
  background: var(--surface);
  color: var(--primary-dark);
  font-weight: 600;
  font-size: 0.84rem;
}

.admin-row-manage:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.admin-row-editor {
  padding: 16px;
  border-top: 1px dashed var(--border);
  display: grid;
  gap: 14px;
}

.admin-row-editor.full-mode .admin-access-groups {
  opacity: 0.45;
  pointer-events: none;
}

@media (max-width: 940px) {
  .admin-table-head {
    display: none;
  }

  .admin-row {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 6px;
  }

  .admin-row-date,
  .admin-row-num {
    display: none;
  }
}

/* ============================================================
   QCM Physique — examens à choix multiples interactifs
   ============================================================ */
.qcm-exam {
  margin-top: 8px;
}

.qcm-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 20px;
  padding: 10px 14px;
  background: var(--primary-soft);
  border-radius: var(--radius-md);
  color: var(--primary-dark);
  font-size: 0.9rem;
}

.qcm-hint svg {
  flex: none;
}

.qcm-exercise {
  margin-bottom: 22px;
  padding: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.qcm-exercise-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}

.qcm-exercise-head h3 {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 1.15rem;
  color: var(--text);
}

.qcm-count {
  flex: none;
  font-size: 0.8rem;
  color: var(--muted);
}

.qcm-preamble {
  margin-bottom: 16px;
  padding-bottom: 14px;
  border-bottom: 1px dashed var(--border);
  font-size: 0.93rem;
  line-height: 1.7;
  color: var(--text);
}

.qcm-question {
  margin-top: 18px;
}

.qcm-prompt {
  margin-bottom: 10px;
  font-size: 0.96rem;
  font-weight: 600;
  line-height: 1.6;
  color: var(--text);
}

.qcm-qlabel {
  display: inline-block;
  margin-right: 4px;
  color: var(--primary);
  font-weight: 700;
}

.qcm-options {
  display: grid;
  gap: 8px;
}

.qcm-option {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 14px;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: 0.92rem;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.qcm-option:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.qcm-letter {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  background: var(--surface-2);
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--muted);
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}

.qcm-optext {
  flex: 1;
}

.qcm-mark {
  flex: none;
  width: 18px;
  text-align: center;
  font-weight: 700;
}

/* État sélectionné (avant vérification) */
.qcm-option.selected {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.qcm-option.selected .qcm-letter {
  border-color: var(--primary);
  background: var(--primary);
  color: #fff;
}

/* États après vérification */
.qcm-question.checked .qcm-option {
  cursor: default;
}

.qcm-question.checked .qcm-option:hover {
  border-color: var(--border);
  background: var(--surface);
}

.qcm-option.correct {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.qcm-option.correct .qcm-letter {
  border-color: var(--primary);
  background: var(--primary);
  color: #fff;
}

.qcm-option.correct:hover {
  border-color: var(--primary) !important;
  background: var(--primary-soft) !important;
}

.qcm-option.correct .qcm-mark::after {
  content: '\2713';
  color: var(--primary);
}

.qcm-option.wrong {
  border-color: var(--danger);
  background: #fbeaea;
}

.qcm-option.wrong .qcm-letter {
  border-color: var(--danger);
  background: var(--danger);
  color: #fff;
}

.qcm-option.wrong:hover {
  border-color: var(--danger) !important;
  background: #fbeaea !important;
}

.qcm-option.wrong .qcm-mark::after {
  content: '\2717';
  color: var(--danger);
}

.qcm-verdict {
  margin: 8px 0 0;
  font-size: 0.85rem;
  font-weight: 600;
}

.qcm-verdict.ok { color: var(--primary); }
.qcm-verdict.ko { color: var(--danger); }
.qcm-verdict.partial { color: var(--warning); }
.qcm-verdict.neutral { color: var(--muted); font-weight: 500; }

/* Explication propre à la question, révélée avec son verdict — permet de
   comprendre immédiatement une réponse sans aller chercher le corrigé
   détaillé en fin d'exercice. */
.qcm-explication {
  margin: 10px 0 0;
  padding: 12px 14px;
  background: var(--surface-2);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-md, 8px);
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--text);
}

.qcm-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.qcm-check-btn {
  padding: 9px 18px;
  background: var(--primary);
  border: none;
  border-radius: var(--radius-md);
  color: #fff;
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s;
}

.qcm-check-btn:hover {
  background: var(--primary-dark);
}

.qcm-check-btn:disabled {
  background: var(--surface-2);
  color: var(--muted);
  cursor: default;
}

.qcm-corr-toggle {
  padding: 9px 18px;
  background: transparent;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--primary);
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.qcm-corr-toggle:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.qcm-score {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text);
}

.qcm-correction {
  margin-top: 16px;
  padding: 20px;
  background: var(--surface-2);
  border-left: 4px solid var(--primary);
  border-radius: 0 10px 10px 0;
  font-size: 0.92rem;
  line-height: 1.75;
  color: var(--text);
}

@media (max-width: 640px) {
  .qcm-exercise {
    padding: 16px;
  }
  .qcm-option {
    padding: 10px 12px;
    font-size: 0.88rem;
  }
  .qcm-actions .qcm-check-btn,
  .qcm-actions .qcm-corr-toggle {
    flex: 1 1 auto;
  }
}

/* Physique 2 : module ouvert en aperçu sous un semestre en préparation */
.module-preview-tag {
  font-style: normal;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--primary, #1e6b47);
  background: rgba(30, 107, 71, 0.10);
  border-radius: var(--radius-sm, 4px);
  padding: 1px 6px;
  margin-left: 6px;
  vertical-align: middle;
}
.maintenance-item.available {
  border-color: rgba(30, 107, 71, 0.35);
}
.maintenance-item.available .maintenance-item-num {
  color: var(--primary, #1e6b47);
}
.btn.small {
  padding: 6px 14px;
  font-size: 0.85rem;
  margin-top: 10px;
}

/* Petit espace de paragraphe (remplace les doubles sauts de ligne) */
.md-break {
  display: block;
  height: 0.55em;
}

/* Séparateur de section (règle horizontale markdown ---) : trait discret */
.md-hr {
  border: 0;
  height: 1px;
  background: var(--border, #e2e8e5);
  margin: 1.4em 0;
}

/* Figures insérées dans les contenus : flottent à côté de l'exercice (comme
   sur une copie d'examen), le texte s'écoule à gauche. */
.md-img {
  float: right;
  max-width: min(320px, 42%);
  height: auto;
  margin: 2px 0 12px 20px;
  padding: 10px;
  background: #ffffff;
  border: 1px solid var(--border, #e2e8e5);
  border-radius: var(--radius-md, 8px);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,0.05));
}
/* Le conteneur d'énoncé contient le flottant (pas de débordement sur la carte) */
.maths-exercise-statement,
.qcm-preamble,
.qcm-prompt {
  display: flow-root;
}
@media (max-width: 640px) {
  .md-img {
    float: none;
    max-width: 100%;
    margin: 12px auto;
  }
}

/* =========================================================================
   Animations pédagogiques (animations.js) — préfixe `.anim-`
   ========================================================================= */
.anim-player {
  margin: 20px 0;
  padding: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius, 12px);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.05));
}

.anim-head { margin-bottom: 14px; }

.anim-title {
  font-family: var(--font-heading);
  font-size: 1.1rem;
  color: var(--primary-dark);
  margin: 0;
}

.anim-subtitle {
  margin: 4px 0 0;
  font-size: 0.88rem;
  color: var(--muted);
}

.anim-stage {
  background: #fbfdfc;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  padding: 8px;
  overflow-x: auto;
}

.anim-svg {
  display: block;
  width: 100%;
  min-width: 560px;
  height: auto;
}

/* ---- zones et structures ---- */
.anim-mito-outer {
  fill: #ffffff;
  stroke: var(--primary);
  stroke-width: 3;
}

.anim-zone-ims { fill: #eaf2f8; }
.anim-zone-matrice { fill: #edf5f0; }

.anim-zone-text {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  fill: var(--muted);
}

.anim-membrane-core { fill: #f4e9d8; stroke: none; }
.anim-lipid { fill: #d8c6a6; }

.anim-complex-body {
  fill: var(--primary);
  stroke: var(--primary-dark);
  stroke-width: 2;
}

.anim-complex-label {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 700;
  fill: #ffffff;
  text-anchor: middle;
}

/* Le complexe II ne pompe pas : teinte volontairement distincte, l'écart
   visuel porte l'information pédagogique. */
.anim-complex-nopump .anim-complex-body {
  fill: #7f9c8c;
  stroke: #5d7a6a;
}

.anim-carrier-body {
  fill: var(--accent);
  stroke: #21486a;
  stroke-width: 2;
}

.anim-carrier-label {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 700;
  fill: #ffffff;
  text-anchor: middle;
}

.anim-synthase-channel {
  fill: #b8873f;
  stroke: #8e6524;
  stroke-width: 2;
}

.anim-synthase-head {
  fill: #d79a3f;
  stroke: #8e6524;
  stroke-width: 2;
}

.anim-synthase-spoke {
  stroke: #8e6524;
  stroke-width: 2;
}

.anim-synthase-label {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  fill: var(--muted);
  text-anchor: middle;
}

.anim-spinning .anim-synthase-rotor {
  transform-box: fill-box;
  transform-origin: center;
  animation: anim-spin 2.8s linear infinite;
}

@keyframes anim-spin { to { transform: rotate(360deg); } }

/* ---- étiquettes de substrats ---- */
.anim-chip-body {
  fill: #ffffff;
  stroke: var(--border);
  stroke-width: 2;
}

.anim-chip-label {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  fill: var(--text);
  text-anchor: middle;
}

.anim-chip-nadh .anim-chip-body { stroke: var(--primary); }
.anim-chip-fadh .anim-chip-body { stroke: #7f9c8c; }
.anim-chip-o2 .anim-chip-body { stroke: var(--accent); }

/* ADP + Pi et ATP occupent la même place : l'un remplace l'autre. */
.anim-chip-atp { display: none; }
.anim-show-atp .anim-chip-adp { display: none; }
.anim-show-atp .anim-chip-atp { display: block; }
.anim-chip-atp .anim-chip-body { fill: var(--primary); stroke: var(--primary-dark); }
.anim-chip-atp .anim-chip-label { fill: #ffffff; }

.anim-gradient-box {
  fill: #ffffff;
  stroke: var(--accent);
  stroke-width: 2;
}

.anim-gradient-title {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  fill: var(--accent);
  text-anchor: middle;
}

.anim-gradient-value {
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 700;
  fill: var(--text);
  text-anchor: middle;
}

/* ---- particules ---- */
.anim-particle { pointer-events: none; }

.anim-electron {
  fill: #f0c33c;
  stroke: #a8781a;
  stroke-width: 1.5;
  animation: anim-travel linear infinite;
}

.anim-proton {
  fill: #d9534f;
  stroke: #9d3733;
  stroke-width: 1.5;
  animation: anim-travel linear infinite;
}

.anim-proton-pooled {
  animation: anim-pool-in 420ms ease-out both;
  transform-box: fill-box;
  transform-origin: center;
}

.anim-particle-static { animation: none; opacity: 0.9; }

@keyframes anim-travel {
  0%   { transform: translate(var(--x0), var(--y0)); opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { transform: translate(var(--x1), var(--y1)); opacity: 0; }
}

@keyframes anim-pool-in {
  from { opacity: 0; transform: scale(0.4); }
  to   { opacity: 1; transform: scale(1); }
}

/* ---- animation « transports membranaires » ---- */
.anim-prot-body {
  fill: var(--accent);
  stroke: #21486a;
  stroke-width: 2;
}

.anim-prot-pore { fill: #dceaf5; }
.anim-prot-site { fill: #dceaf5; stroke: #21486a; stroke-width: 1.5; }
.anim-prot-aqua { fill: #4a8ec2; }

/* Les transporteurs actifs se distinguent des passifs par la teinte : l'écart
   visuel porte la distinction pédagogique passif / actif. */
.anim-prot-active { fill: #b8552a; stroke: #8a3d1c; }
.anim-prot-active2 { fill: #d07a3f; stroke: #a1552a; }

.anim-prot-atp {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 700;
  fill: #8a3d1c;
  text-anchor: middle;
  opacity: 0;
  transition: opacity 240ms ease;
}

.anim-show-atp .anim-prot-atp { opacity: 1; }

.anim-station-label {
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 600;
  fill: var(--muted);
  text-anchor: middle;
}

.anim-station.anim-active .anim-station-label { fill: var(--primary-dark); font-weight: 700; }

.anim-solute-a { fill: #7d5ba6; stroke: #533a72; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-solute-b { fill: #2f8f7a; stroke: #1e6455; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-solute-c { fill: #f0c33c; stroke: #a8781a; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-solute-eau { fill: #4a8ec2; stroke: #21486a; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-solute-na { fill: #d9534f; stroke: #9d3733; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-solute-k { fill: #8e6524; stroke: #5d4118; stroke-width: 1.5; animation: anim-travel linear infinite; }

/* ---- animation « flux endomembranaires » ---- */
.anim-flux-noyau { fill: #cbd9e6; stroke: #21486a; stroke-width: 2.5; }
.anim-flux-noyau-in { fill: #e6eef5; stroke: #6d90ae; stroke-width: 1.5; }
.anim-flux-re { fill: none; stroke: var(--accent); stroke-width: 5; stroke-linecap: round; }
.anim-flux-ribo { fill: #21486a; }
.anim-flux-golgi { fill: none; stroke: var(--primary); stroke-width: 7; stroke-linecap: round; }
.anim-flux-vesicule { fill: #ffffff; stroke: var(--muted); stroke-width: 2.5; }
.anim-flux-lyso .anim-flux-vesicule { fill: #f3dcc8; stroke: #b8552a; }
.anim-flux-endo .anim-flux-vesicule { fill: #dceaf5; stroke: var(--accent); }

.anim-flux-label {
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 600;
  fill: var(--muted);
  text-anchor: middle;
}

.anim-flux-inner {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  fill: #21486a;
  text-anchor: middle;
}

.anim-flux-face {
  font-family: var(--font-body);
  font-size: 11.5px;
  font-style: italic;
  fill: var(--primary-dark);
  text-anchor: middle;
}

.anim-flux-part.anim-active .anim-flux-label { fill: var(--primary-dark); font-weight: 700; }

.anim-flux-bilan-val { font-size: 13.5px; }

/* Chaque flux a sa couleur : protéine sécrétée, hydrolase marquée au M6P,
   matériel entré par endocytose, et retour rétrograde. */
.anim-flux-arn { fill: #7d5ba6; stroke: #533a72; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-flux-prot { fill: #2f8f7a; stroke: #1e6455; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-flux-m6p { fill: #d9534f; stroke: #9d3733; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-flux-ext { fill: #4a8ec2; stroke: #21486a; stroke-width: 1.5; animation: anim-travel linear infinite; }
.anim-flux-retro { fill: #f0c33c; stroke: #a8781a; stroke-width: 1.5; animation: anim-travel linear infinite; }

/* ---- interaction ---- */
.anim-svg [data-info] { cursor: pointer; }

.anim-svg [data-info].anim-active .anim-flux-noyau,
.anim-svg [data-info].anim-active .anim-flux-vesicule {
  stroke: #b8552a;
  stroke-width: 3.5;
}

.anim-svg [data-info].anim-active .anim-flux-re,
.anim-svg [data-info].anim-active .anim-flux-golgi {
  stroke: #b8552a;
}

.anim-svg [data-info].anim-active .anim-prot-body {
  stroke: #b8552a;
  stroke-width: 3.5;
}

.anim-svg [data-info].anim-active .anim-prot-active,
.anim-svg [data-info].anim-active .anim-prot-active2 {
  stroke: var(--primary-dark);
  stroke-width: 3.5;
}

.anim-svg [data-info].anim-active .anim-complex-body,
.anim-svg [data-info].anim-active .anim-carrier-body,
.anim-svg [data-info].anim-active .anim-chip-body,
.anim-svg [data-info].anim-active .anim-gradient-box,
.anim-svg [data-info].anim-active .anim-synthase-channel,
.anim-svg [data-info].anim-active .anim-synthase-head,
.anim-svg [data-info].anim-active.anim-zone-ims,
.anim-svg [data-info].anim-active.anim-zone-matrice {
  stroke: #b8552a;
  stroke-width: 3.5;
}

.anim-svg [data-info].anim-active .anim-membrane-core { stroke: #b8552a; stroke-width: 3; }

.anim-svg [data-info].anim-selected .anim-complex-body,
.anim-svg [data-info].anim-selected .anim-carrier-body,
.anim-svg [data-info].anim-selected .anim-chip-body,
.anim-svg [data-info].anim-selected .anim-gradient-box,
.anim-svg [data-info].anim-selected .anim-synthase-head {
  stroke: var(--accent);
  stroke-width: 4;
}

/* ---- légende d'étape ---- */
.anim-caption {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin-top: 14px;
  padding: 14px 16px;
  background: var(--primary-soft);
  border-radius: var(--radius-md, 8px);
}

.anim-step-num {
  flex: 0 0 auto;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--primary-dark);
  background: #ffffff;
  border-radius: var(--radius-sm, 4px);
  padding: 4px 10px;
  white-space: nowrap;
}

.anim-step-text {
  margin: 0;
  font-size: 0.94rem;
  line-height: 1.55;
  color: var(--text);
}

/* ---- progression ---- */
.anim-progress { margin-top: 14px; }

.anim-progress-bar {
  height: 6px;
  background: var(--border);
  border-radius: 999px;
  overflow: hidden;
}

.anim-progress-fill {
  height: 100%;
  width: 0;
  background: var(--primary);
  border-radius: 999px;
  transition: width 320ms ease;
}

.anim-dots {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.anim-dot {
  width: 22px;
  height: 6px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--border);
  cursor: pointer;
  transition: background 200ms ease;
}

.anim-dot.done { background: #9dc3ad; }
.anim-dot.active { background: var(--primary); }

/* ---- commandes ---- */
.anim-controls {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  flex-wrap: wrap;
}

.anim-btn {
  font-family: var(--font-body);
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--primary-dark);
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  padding: 8px 16px;
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease;
}

.anim-btn:hover:not(:disabled) { background: var(--primary-soft); border-color: var(--primary); }
.anim-btn:disabled { opacity: 0.45; cursor: not-allowed; }

.anim-btn-primary {
  color: #ffffff;
  background: var(--primary);
  border-color: var(--primary);
}

.anim-btn-primary:hover:not(:disabled) { background: var(--primary-dark); border-color: var(--primary-dark); }
.anim-btn-ghost { color: var(--muted); }
.anim-btn-active { background: var(--primary-soft); border-color: var(--primary); }

/* ---- panneau d'explication ---- */
.anim-info {
  margin-top: 14px;
  padding: 14px 16px;
  min-height: 76px;
  background: #fbfdfc;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md, 8px);
}

.anim-info-hint {
  margin: 0;
  font-size: 0.88rem;
  font-style: italic;
  color: var(--muted);
}

.anim-info-title {
  font-family: var(--font-heading);
  font-size: 0.98rem;
  color: var(--primary-dark);
  margin: 0 0 6px;
}

.anim-info-text {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text);
}

.anim-info-note {
  margin: 8px 0 0;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--muted);
  padding-left: 10px;
  border-left: 2px solid var(--border);
}

.anim-missing {
  margin: 0;
  padding: 14px;
  font-size: 0.9rem;
  color: var(--muted);
  font-style: italic;
}

@media (max-width: 640px) {
  .anim-player { padding: 14px; }
  .anim-caption { flex-direction: column; gap: 8px; }
  .anim-controls .anim-btn { flex: 1 1 auto; }
}

@media (prefers-reduced-motion: reduce) {
  .anim-progress-fill { transition: none; }
  .anim-spinning .anim-synthase-rotor { animation: none; }
  .anim-proton-pooled { animation: none; }
}

/* ---- réglages interactifs (spec.tools) ---- */
.anim-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 22px;
  margin-top: 12px;
  padding: 12px 16px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
}

.anim-tool {
  flex: 1 1 200px;
  min-width: 168px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.anim-tool-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.anim-tool-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
}

.anim-tool-out {
  font-size: 0.84rem;
  font-weight: 700;
  color: var(--primary-dark);
  font-variant-numeric: tabular-nums;
}

.anim-tool-range {
  width: 100%;
  accent-color: var(--primary);
  cursor: pointer;
}

.anim-tool-choices { display: flex; flex-wrap: wrap; gap: 6px; }

.anim-tool-choice {
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
}

.anim-tool-choice.is-on {
  color: #ffffff;
  background: var(--primary);
  border-color: var(--primary);
}

/* =========================================================================
   Scènes de biostatistiques (S3) — préfixe `.anim-bs-`
   =========================================================================
   Ces scènes sont des figures de raisonnement : rien n'y est décoratif. Le
   vert forêt marque toujours l'événement ou le résultat étudié, le bleu
   ardoise ce qui conditionne, l'ocre ce qui trompe (faux positifs). Aucun
   dégradé, aucune ombre — mêmes règles que le reste du design system.
   ========================================================================= */
.anim-bs-svg { min-width: 680px; }
.anim-bs-svg text { font-family: var(--font-body); }
.anim-bs-still * { transition: none !important; }

.anim-bs-title { font-size: 16px; font-weight: 700; fill: var(--primary-dark); }
.anim-bs-head { font-size: 13.5px; font-weight: 700; fill: var(--text); }
.anim-bs-label { font-size: 12px; fill: var(--muted); }
.anim-bs-note { font-size: 13px; fill: var(--muted); font-style: italic; }
.anim-bs-value { font-size: 17px; font-weight: 700; fill: var(--primary-dark); }
.anim-bs-idx { font-size: 0.72em; }
.anim-bs-axis { stroke: var(--muted); stroke-width: 1.2; fill: none; }
.anim-bs-axis-label { font-size: 12px; fill: var(--muted); }

/* ---- dénombrement : jetons, cases et matrice des quatre cas ---- */
.anim-bs-chip-body { fill: #ffffff; stroke: var(--primary); stroke-width: 2; transition: fill 220ms ease, stroke 220ms ease; }
.anim-bs-chip-text { font-size: 15px; font-weight: 700; fill: var(--primary-dark); }
.anim-bs-chip.is-used .anim-bs-chip-body { fill: var(--surface-2); stroke: var(--border); }
.anim-bs-chip.is-used .anim-bs-chip-text { fill: var(--muted); }

.anim-bs-slot-body { fill: var(--primary-soft); stroke: var(--primary); stroke-width: 2; transition: fill 220ms ease, stroke 220ms ease; }
.anim-bs-slot-letter { font-size: 26px; font-weight: 700; fill: var(--primary-dark); }
.anim-bs-slot-note { font-size: 11.5px; fill: var(--muted); }
.anim-bs-slot.is-empty .anim-bs-slot-body { fill: #ffffff; stroke: var(--border); stroke-dasharray: 5 4; }
.anim-bs-slot.is-empty .anim-bs-slot-letter { fill: #c3cec7; }
.anim-bs-slots.is-set .anim-bs-slot-body { fill: #eaf1f7; stroke: var(--accent); }
.anim-bs-slots.is-set .anim-bs-slot-letter { fill: #21486a; }

.anim-bs-cell-body { fill: #ffffff; stroke: var(--border); stroke-width: 1.5; transition: fill 220ms ease, stroke 220ms ease; }
.anim-bs-cell-title { font-size: 13px; font-weight: 700; fill: var(--text); }
.anim-bs-cell-formula { font-size: 14px; fill: var(--primary-dark); }
.anim-bs-cell-ex { font-size: 13px; fill: var(--muted); }
.anim-bs-cell.anim-active .anim-bs-cell-body { fill: var(--primary-soft); stroke: var(--primary); stroke-width: 3; }
.anim-bs-cell.anim-active .anim-bs-cell-ex { fill: var(--primary-dark); font-weight: 600; }

.anim-bs-box-body { fill: #ffffff; stroke: var(--border); stroke-width: 1.5; transition: fill 220ms ease, stroke 220ms ease; }
.anim-bs-box-title { font-size: 12.5px; fill: var(--muted); }
.anim-bs-box-value { font-size: 14px; font-weight: 700; fill: var(--primary-dark); }
.anim-bs-box.anim-active .anim-bs-box-body { fill: #eaf1f7; stroke: var(--accent); stroke-width: 3; }

/* ---- tableau des deux dés ---- */
.anim-bs-sq-body { fill: #ffffff; stroke: var(--border); stroke-width: 1; transition: fill 200ms ease, stroke 200ms ease; }
.anim-bs-sq-text { font-size: 12.5px; fill: var(--muted); }
.anim-bs-sq.is-a .anim-bs-sq-body { fill: var(--primary-soft); stroke: var(--primary); stroke-width: 1.6; }
.anim-bs-sq.is-a .anim-bs-sq-text { fill: var(--primary-dark); font-weight: 700; }
.anim-bs-sq.is-b .anim-bs-sq-body { fill: #eaf1f7; stroke: var(--accent); stroke-width: 1.6; }
.anim-bs-sq.is-b .anim-bs-sq-text { fill: #21486a; font-weight: 700; }
.anim-bs-sq.is-ab .anim-bs-sq-body { fill: var(--primary); stroke: var(--primary-dark); stroke-width: 2; }
.anim-bs-sq.is-ab .anim-bs-sq-text { fill: #ffffff; font-weight: 700; }
.anim-bs-sq.is-c .anim-bs-sq-body { fill: #f6ede2; stroke: #b8552a; stroke-width: 1.6; }
.anim-bs-sq.is-c .anim-bs-sq-text { fill: #8a3d1c; font-weight: 700; }
.anim-bs-sq.is-dim { opacity: 0.3; }
.anim-bs-sq.is-part .anim-bs-sq-body { fill: #f2f7f4; }
.anim-bs-sq.is-part-alt .anim-bs-sq-body { fill: #ffffff; }

.anim-bs-panel-title { font-size: 15px; font-weight: 700; fill: var(--primary-dark); }
.anim-bs-panel-line { font-size: 13px; fill: var(--text); }
.anim-bs-panel-box-body { fill: var(--primary-soft); stroke: var(--primary); stroke-width: 1.5; }
.anim-bs-panel-formula { font-size: 14px; font-weight: 700; fill: var(--primary-dark); }

/* ---- arbre de dépistage (Bayes) ---- */
.anim-bs-edge { stroke: var(--border); stroke-width: 2; }
.anim-bs-edge-label { font-size: 12px; fill: var(--muted); }
.anim-bs-edge-label.anim-active { fill: var(--primary-dark); font-weight: 700; }
.anim-bs-node-body { fill: #ffffff; stroke: var(--border); stroke-width: 1.5; transition: stroke 220ms ease, stroke-width 220ms ease; }
.anim-bs-node-title { font-size: 12.5px; fill: var(--muted); }
.anim-bs-node-value { font-size: 15px; font-weight: 700; fill: var(--text); }
.anim-bs-node.is-malade .anim-bs-node-body { fill: #f7ece9; stroke: #c98a72; }
.anim-bs-node.is-sain .anim-bs-node-body { fill: #eef3f0; stroke: #b9cdc1; }
.anim-bs-node.is-vp .anim-bs-node-body { fill: var(--primary-soft); stroke: var(--primary); }
.anim-bs-node.is-fp .anim-bs-node-body { fill: #f7efe2; stroke: #c8862f; }
.anim-bs-node.anim-active .anim-bs-node-body { stroke-width: 3.5; }
.anim-bs-node.anim-active .anim-bs-node-value { fill: var(--primary-dark); }

.anim-bs-posbar { opacity: 0.3; transition: opacity 260ms ease; }
.anim-bs-show-bar .anim-bs-posbar { opacity: 1; }
.anim-bs-posbar-vp { fill: var(--primary); }
.anim-bs-posbar-fp { fill: #d99a4e; }
.anim-bs-posbar-frame { fill: none; stroke: var(--border); stroke-width: 1.5; }
.anim-bs-posbar-text { font-size: 12.5px; font-weight: 700; fill: #ffffff; }

/* ---- arbre de Bernoulli et histogramme binomial ---- */
.anim-bs-tree { opacity: 0.34; transition: opacity 260ms ease; }
.anim-bs-tree-on .anim-bs-tree { opacity: 1; }
.anim-bs-branch { stroke: var(--border); stroke-width: 2; transition: stroke 200ms ease, stroke-width 200ms ease; }
.anim-bs-branch.anim-active { stroke: var(--primary); stroke-width: 3.5; }
.anim-bs-tree-node { fill: #ffffff; stroke: var(--muted); stroke-width: 1.5; }
.anim-bs-branch-label { font-size: 12.5px; fill: var(--muted); }
.anim-bs-leaf-text { font-size: 13px; fill: var(--text); }
.anim-bs-leaf.anim-active .anim-bs-leaf-text { fill: var(--primary-dark); font-weight: 700; }
.anim-bs-bar { fill: #a9c9b8; transition: fill 200ms ease; }
.anim-bs-bar.is-mode { fill: var(--primary); }
.anim-bs-bar.anim-active { fill: var(--accent); }
.anim-bs-moment { font-size: 13px; fill: var(--muted); }
.anim-bs-moments-on .anim-bs-moment { fill: var(--primary-dark); font-weight: 700; }

/* ---- densités continues et loi normale ---- */
.anim-bs-curve { fill: none; stroke: var(--primary); stroke-width: 2.5; stroke-linejoin: round; }
.anim-bs-area { fill: rgba(30, 107, 71, 0.22); stroke: none; }
.anim-bs-cdf { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-dasharray: 5 4; }
.anim-bs-bound-line { stroke: var(--accent); stroke-width: 1.6; stroke-dasharray: 4 4; }
.anim-bs-bound-text { font-size: 12.5px; font-weight: 700; fill: #21486a; }
.anim-bs-band { stroke: none; }
.anim-bs-band.is-s1 { fill: rgba(30, 107, 71, 0.30); }
.anim-bs-band.is-s2 { fill: rgba(30, 107, 71, 0.17); }
.anim-bs-band.is-s3 { fill: rgba(30, 107, 71, 0.09); }
.anim-bs-band-label { font-size: 12.5px; font-weight: 600; fill: var(--primary-dark); }
.anim-bs-zaxis .anim-bs-axis { stroke: var(--accent); }
.anim-bs-zaxis .anim-bs-axis-label { fill: #21486a; }

@media (max-width: 640px) {
  .anim-tools { padding: 10px 12px; gap: 12px; }
  .anim-tool { flex: 1 1 100%; }
}

/* =========================================================================
   Cartes mentales (Biologie cellulaire, Géologie) — préfixe .cmap-
   =========================================================================
   Une carte = un chapitre. Le nœud central porte le schéma SVG, les branches
   reprennent la numérotation du polycopié. Les couleurs de branche viennent
   des données (une teinte par branche) ; tout le reste est aux tokens.
   ========================================================================= */
.cmap-choix {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
/* Sélecteur GROUPÉ — utilisé par Histologie – Embryologie, dont la collection
   de cartes porte DEUX matières aux logiques de lecture différentes
   (thématique d'un côté, chronologique de l'autre). Biologie cellulaire n'a
   qu'une matière et garde son `.cmap-choix` nu, sans groupe. */
.cmap-groupe + .cmap-groupe { margin-top: 4px; }
.cmap-groupe-titre {
  margin: 0 0 7px;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
}
.cmap-choix-btn {
  font: inherit;
  font-size: .88rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 14px;
  cursor: pointer;
}
.cmap-choix-btn.is-active {
  color: #fff;
  background: var(--primary);
  border-color: var(--primary);
}

.cmap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.cmap-head {
  padding: 18px 22px;
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
  justify-content: space-between;
}
.cmap-head h2 {
  font-size: 1.25rem;
  margin: 0;
}
.cmap-chapitre {
  font-size: .74rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin: 0 0 4px;
}
.cmap-lead {
  font-size: .9rem;
  color: var(--muted);
  margin: 6px 0 0;
  max-width: 62ch;
}
.cmap-freq {
  font-size: .78rem;
  font-weight: 600;
  color: var(--primary-dark);
  background: var(--primary-soft);
  border-radius: 999px;
  padding: 4px 12px;
  white-space: nowrap;
}

/* La scène défile dans son propre cadre : la page ne déborde jamais.
   `.content-area` est un élément de grille en `min-width: auto` : sans ce
   correctif il se dilate à la largeur minimale du SVG (660px) et fait déborder
   toute la page en mobile, au lieu de laisser la scène défiler. Le `:has()`
   cible uniquement les pages qui portent une carte — les autres modules
   gardent exactement le comportement qu'ils avaient. */
.content-area:has(.cmap-stage) { min-width: 0; }

.cmap-stage {
  padding: 8px 12px 4px;
  overflow-x: auto;
}
.cmap-svg {
  display: block;
  width: 100%;
  min-width: 660px;
  height: auto;
}

.cmap-node { cursor: pointer; }
.cmap-node .cmap-box { transition: filter .15s ease; }
.cmap-node:hover .cmap-box { filter: brightness(.97); }
.cmap-node:focus-visible { outline: none; }
.cmap-node:focus-visible .cmap-box,
.cmap-node.is-active .cmap-box { stroke-width: 3; }

.cmap-link { stroke: var(--border); stroke-width: 2; fill: none; }
.cmap-centre {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 700;
  fill: #fff;
}
.cmap-label {
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 700;
  fill: var(--text);
}
.cmap-num {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
}
.cmap-sub {
  font-family: var(--font-body);
  font-size: 12.5px;
  fill: var(--muted);
}
.cmap-badge {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
}
.cmap-mini {
  font-family: var(--font-body);
  font-size: 10.5px;
  fill: var(--muted);
}
.cmap-mini-i { font-style: italic; }
/* Valeur chiffrée mise en avant dans un schéma (échelles de résolution). */
.cmap-label-s {
  font-family: var(--font-heading);
  font-size: 14px;
  font-weight: 700;
  fill: var(--primary-dark);
}

.cmap-panel {
  border-top: 1px solid var(--border);
  padding: 22px;
  background: var(--surface-2);
}
.cmap-panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.cmap-panel-head h3 { font-size: 1.1rem; margin: 0; }
.cmap-chip {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  color: #fff;
  padding: 3px 9px;
  border-radius: var(--radius-sm);
}
.cmap-freq-line {
  font-size: .8rem;
  color: var(--muted);
  margin: 0;
}
.cmap-panel-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  margin-top: 14px;
}
.cmap-panel-body h4 {
  font-family: var(--font-body);
  font-size: .8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  margin: 0 0 8px;
}
.cmap-panel-body ul { margin: 0; padding-left: 18px; }
.cmap-panel-body li { margin-bottom: 7px; }
.cmap-panel-body li:last-child { margin-bottom: 0; }
.cmap-num-val {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--primary-dark);
}

.cmap-piege {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--danger);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  margin-bottom: 10px;
}
.cmap-piege:last-child { margin-bottom: 0; }
.cmap-piege p { margin: 0; font-size: .92rem; }
.cmap-src {
  display: block;
  margin-top: 6px;
  font-size: .78rem;
  color: var(--muted);
}
.cmap-vide { font-size: .9rem; color: var(--muted); margin: 0; }

/* Figure d'une branche — posée par Géologie, disponible à tout module qui en
   déclare une (`branche.figure`). Elle n'emprunte pas `.md-img` : celle-ci
   flotte à droite sur 320 px, ce qui, dans une colonne de panneau, réduirait
   la figure à une vignette collée au texte. Ici elle est en tête de colonne,
   pleine largeur, avec sa légende dessous. */
.cmap-figure { margin: 0 0 14px; }
.cmap-figure img {
  display: block;
  width: 100%;
  height: auto;
  padding: 8px;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}
.cmap-figure figcaption {
  font-size: .78rem;
  color: var(--muted);
  margin-top: 6px;
}

.cmap-foot {
  padding: 14px 22px;
  border-top: 1px solid var(--border);
  font-size: .8rem;
  color: var(--muted);
}

@media (max-width: 760px) {
  .cmap-panel-body { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .cmap-node .cmap-box { transition: none; }
}

/* =========================================================================
   Cours de Biologie cellulaire — préfixe .bc-cours-
   =========================================================================
   Le lecteur lui-même réutilise .course-reader / .course-toc / .course-chapter
   (partagés avec Maths et Physique) : seuls le sélecteur de chapitre, le
   bandeau de relecture et le traitement des figures sont propres au module.
   ========================================================================= */
.bc-cours-chapitres {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}
.bc-cours-chapitre {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font: inherit;
  font-size: .86rem;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 7px 13px;
  cursor: pointer;
  text-align: left;
}
.bc-cours-chapitre:hover { border-color: var(--primary); }
.bc-cours-chapitre.is-active {
  color: #fff;
  background: var(--primary);
  border-color: var(--primary);
}
.bc-cours-num {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: .82rem;
  opacity: .75;
}
.bc-cours-chapitre.is-active .bc-cours-num { opacity: .9; }
.bc-cours-titre { font-weight: 600; }

/* Bandeau des chapitres rédigés hors polycopié : le lecteur doit savoir
   d'où vient ce qu'il lit. Ne pas retirer sans validation du propriétaire. */
.bc-cours-avis {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--warning);
  border-radius: var(--radius-md);
  padding: 12px 15px;
  margin-bottom: 18px;
  font-size: .88rem;
  color: var(--muted);
}

.bc-cours-resume {
  margin: 0 0 4px;
  font-size: .92rem;
  color: var(--muted);
  max-width: 72ch;
}

/* Les figures du cours sont larges et porteuses d'information : le flottant
   320px de `.md-img` les rendrait illisibles. Pleine largeur, centrées —
   même traitement que `.bc-statement .md-img` pour les sujets d'examen. */
.bc-cours-content .md-img {
  float: none;
  display: block;
  max-width: 100%;
  margin: 18px auto 6px;
}
/* Les schémas du résumé (SVG vectoriels, ~500px de large) n'ont pas besoin de
   toute la largeur d'une colonne large : centrés, plafonnés, jamais démesurés. */
.maths-resume-content .md-img {
  float: none;
  display: block;
  max-width: min(560px, 100%);
  margin: 18px auto 6px;
}
/* La légende suit immédiatement la figure. Attention : `parseMarkdown` ne
   produit pas de <p> — il sépare les paragraphes par <span class="md-break">.
   La légende est donc le <em> qui suit ce séparateur, pas l'image elle-même. */
.bc-cours-content .md-img + .md-break + em {
  display: block;
  text-align: center;
  font-size: .84rem;
  color: var(--muted);
  margin: 0 auto 18px;
  max-width: 60ch;
}
.bc-cours-content h3 {
  font-size: 1.02rem;
  margin: 22px 0 8px;
  color: var(--primary-dark);
}
/* Encadré d'aparté. `parseMarkdown` ne gère PAS la syntaxe blockquote `>` :
   le cours emploie les marqueurs [[note]]…[[/note]] du projet, substitués par
   injectAnimationMounts() en `.bc-aside` — comme les corrigés d'examen. La
   règle existante étant scopée à `.maths-solution` et `.qcm-correction`, il
   faut la déclarer aussi pour le cours. */
.bc-cours-content .bc-aside {
  margin: 16px 0;
  padding: 12px 15px;
  background: var(--primary-soft);
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-md);
  font-size: .9rem;
  line-height: 1.55;
  color: var(--muted);
}

@media (max-width: 760px) {
  .bc-cours-chapitre { font-size: .8rem; padding: 6px 10px; }
}

/* Contention en largeur du lecteur de cours de Biologie cellulaire.
   Les chapitres contiennent des tableaux larges et de longs intitulés de
   navigation : leur largeur min-content remonte la chaîne des conteneurs
   (éléments de grille et de flex en `min-width: auto`) et fait déborder toute
   la page en mobile. Tout est scopé à `.bc-cours` — Maths et Physique, qui
   partagent le même lecteur, gardent exactement leur comportement. */
.content-area:has(.bc-cours) { min-width: 0; }
.bc-cours .course-reader-grid,
.bc-cours .course-chapters,
.bc-cours .course-chapter,
.bc-cours .course-chapter-body { min-width: 0; }

.bc-cours-table {
  overflow-x: auto;
  margin: 16px 0;
}
/* `display: block` est nécessaire, pas seulement `overflow-x: auto` sur
   l'enveloppe : un `<table>` reste en `table-layout: auto` par défaut, où un
   `width` (même 100 %) n'est qu'un PLANCHER — l'algorithme de colonnes peut le
   dépasser librement si le contenu des cellules le demande, et alors le
   tableau s'affiche à sa largeur intrinsèque quel que soit le défilement posé
   sur son enveloppe. Repéré sur la grille électrolytes/canaux ioniques de
   Physiologie animale (colonnes KaTeX insécables) : l'enveloppe rapportait
   fidèlement un `clientWidth` contenu, mais le tableau qu'elle contenait
   s'affichait tout de même à sa largeur pleine, et l'ancêtre remontait
   l'écart jusqu'à la page. */
.bc-cours-table table { margin: 0; display: block; width: 100%; }

/* Même contention pour un sujet de corpus (Examens/TD, `renderExamCorpus`) :
   un tableau à colonnes KaTeX insécables (grille électrolytes/canaux ioniques
   de Physiologie animale, 7 colonnes $t_1$…$t_7$) remonte la même chaîne de
   `min-width: auto` — `.maths-exam-detail` et ses descendants sont partagés
   par TOUS les modules à corpus (BC, Histologie, Chimie, TC, Géologie,
   Écologie, Microbiologie, Biochimie structurale), donc scopé large plutôt
   qu'au seul module qui l'a révélé. `overflow-x` sur `.math-table` et
   `.katex-display` (règles ci-dessus) ne suffit pas seul : sans `min-width: 0`
   sur la chaîne, c'est le CONTENEUR qui grandit avant que le défilement
   interne n'ait sa chance. */
.content-area:has(.maths-exam-detail) { min-width: 0; }
.maths-exam-detail,
.maths-exercises,
.maths-exercise,
.qcm-exam,
.qcm-exercise,
.qcm-questions,
.qcm-question { min-width: 0; }

/* Les boutons Précédent / Suivant portent le titre de la section voisine :
   ils doivent pouvoir passer à la ligne et tronquer, pas pousser la page. */
.bc-cours .course-chapter-foot { flex-wrap: wrap; gap: 8px; }
.bc-cours .course-nav-btn { min-width: 0; max-width: 100%; }
.bc-cours .course-nav-btn em {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ==========================================================================
   IMPRESSION — la feuille qui FABRIQUE le tirage
   (la seconde, en fin de fichier, NEUTRALISE l'impression du contenu payant)
   ==========================================================================

   POURQUOI ELLE EXISTE. Les résumés annoncent « à parcourir ou imprimer »
   depuis toujours, et aucune règle d'impression n'existait : un Ctrl+P tirait
   l'en-tête, la barre des semestres, les onglets, le pied de page et les fonds
   colorés de l'application. Les cartes mentales étaient pires — voir plus bas.

   CE QU'ELLE NE FAIT PAS. Elle ne touche à AUCUN rendu écran, et elle ne
   réécrit aucun contenu : même texte, même structure, mêmes images, mêmes
   couleurs. Elle retire le mobilier de l'application et rend le contenu
   imprimable, rien d'autre.

   LES COULEURS SONT DU CONTENU ICI, pas de la décoration : la couleur d'une
   branche relie sa boîte du schéma à son panneau de détail, la pastille du
   numéro et la barre de rappel se lisent l'une par l'autre. D'où
   `print-color-adjust: exact` — sans lui le navigateur tire les fonds en blanc
   « pour économiser l'encre » et la carte perd son système de repérage.

   LES CARTES S'IMPRIMENT EN PAYSAGE, et c'est une contrainte de lisibilité,
   pas un goût. Le schéma est un viewBox de 1040 unités dont les textes vont de
   10,5 px (`.cmap-mini`) à 16 px (`.cmap-label`). En A4 portrait, la largeur
   utile de 186 mm ramène le 10,5 px à 5,3 pt : illisible. En paysage, à
   245 mm, il remonte à 7 pt et le titre de branche à 10,7 pt. La largeur est
   plafonnée à 245 mm (et non à la pleine page) pour que le titre de la carte
   ET son schéma tiennent sur la MÊME feuille : 25 mm d'en-tête + 160 mm de
   schéma = 185 mm, sous les 190 mm utiles d'une A4 paysage.

   `.cmap-svg` porte `min-width: 660px` à l'écran, pour que la scène défile au
   lieu d'écraser le schéma sur mobile. En impression il n'y a pas de
   défilement : ce plancher ferait déborder la feuille, il est retiré.

   LES CONTENEURS À DÉFILEMENT SE ROUVRENT. `.bc-cours-table` et
   `.katex-display` sont des boîtes en `overflow-x: auto` : sur papier, ce qui
   dépasse n'est pas atteignable, il est COUPÉ. Ils repassent donc en
   `overflow: visible`, et `.bc-cours-table table` reprend `display: table`
   (il est en `display: block` à l'écran, sans quoi un `table-layout: auto`
   traite son `width` comme un plancher et ignore le défilement) pour que le
   tableau se replie à la largeur de la page.
   ========================================================================== */

@page {
  size: A4 portrait;
  margin: 14mm 12mm;
}

/* Page nommée pour les cartes mentales — voir la note sur la lisibilité. */
@page carte {
  size: A4 landscape;
  margin: 12mm;
}

@media print {

  /* Les couleurs portent l'information : ne pas les laisser tomber. */
  *, *::before, *::after {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  html, body {
    background: #fff;
    font-size: 11pt;
  }

  /* ---------------------------------------------------- mobilier à retirer */
  .site-header,
  .semester-sidebar,
  .site-footer,
  .mobile-toggle,
  .access-card,
  .logout-button,
  .td-tabs,
  .cmap-groupe,
  .cmap-choix,
  .course-chapter-foot {
    display: none !important;
  }

  /* Le panneau interactif d'une carte ne montre qu'UNE branche : sur papier
     il est remplacé par `.cmap-print`, qui les porte toutes. */
  .cmap-panel { display: none !important; }
  .cmap-print { display: block !important; }

  /* ------------------------------------------------------------- la page */
  .app-shell {
    display: block;
    padding: 0;
    margin: 0;
    gap: 0;
  }
  .content-area {
    width: auto;
    max-width: none;
    min-width: 0;
    padding: 0;
    margin: 0;
  }
  .section,
  .module-card,
  .stats-module {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: #fff;
    padding: 0;
    margin: 0;
  }

  h1 { font-size: 18pt; margin: 0 0 4pt; }
  h2 { font-size: 14pt; }
  h3 { font-size: 12pt; }
  .eyebrow { font-size: 9pt; }
  .lead { font-size: 10pt; }

  /* Un titre ne reste jamais seul en bas de feuille. */
  h1, h2, h3, h4 { break-after: avoid; page-break-after: avoid; }
  img, figure, table { break-inside: avoid; page-break-inside: avoid; }
  img { max-width: 100%; height: auto; }

  /* ------------------------------------------------- cartes mentales */
  .cmap {
    page: carte;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  /* L’en-tête reste SOLIDAIRE de son schéma (break-after: avoid) et se
     resserre : à sa taille d’écran, en-tête + schéma dépassaient les 186 mm
     utiles d’une A4 paysage et le schéma partait seul sur la feuille suivante,
     laissant une page presque blanche. */
  .cmap-head {
    padding: 0 0 4pt;
    border: 0;
    break-after: avoid;
    page-break-after: avoid;
  }
  .cmap-head h2 { font-size: 13pt; margin: 0; }
  .cmap-chapitre { font-size: 8pt; margin: 0 0 2pt; }
  .cmap-lead { font-size: 9pt; margin: 2pt 0 0; }
  .cmap-freq { font-size: 8.5pt; }
  .cmap-stage {
    padding: 0;
    overflow: visible;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .cmap-svg {
    min-width: 0;
    width: 100%;
    max-width: 240mm;
    height: auto;
    margin: 0 auto;
  }
  .cmap-node { cursor: auto; }

  /* Resserré pour que DEUX branches tiennent par feuille : à la densité de
     l’écran une seule y entrait, et les 63 branches du module partaient sur
     63 feuilles à moitié vides. */
  .cmap-print-branche {
    break-inside: avoid;
    page-break-inside: avoid;
    border-top: 1px solid #d6ddd6;
    padding: 6pt 0;
    font-size: 9pt;
  }
  .cmap-print .cmap-panel-head h3 { font-size: 10.5pt; }
  .cmap-print .cmap-panel-body { gap: 10pt; margin-top: 5pt; }
  .cmap-print .cmap-panel-body li { margin-bottom: 3pt; }
  .cmap-print .cmap-panel-body h4 { margin-bottom: 4pt; }
  .cmap-print .cmap-freq-line { font-size: 8pt; }
  .cmap-print .cmap-piege { margin-bottom: 5pt; }
  .cmap-print .cmap-piege p { font-size: 8.5pt; }
  .cmap-print .cmap-src { font-size: 7.5pt; }
  .cmap-print-branche:first-child { border-top: 0; }
  .cmap-print .cmap-panel-body {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14pt;
    margin-top: 8pt;
  }
  .cmap-foot {
    break-inside: avoid;
    page-break-inside: avoid;
    font-size: 8.5pt;
  }

  /* ------------------------------------------------------------ résumés */
  .maths-resume-sheet .maths-resume-chapter {
    padding: 10pt 0;
    break-inside: auto;
  }
  .maths-resume-intro { font-size: 9.5pt; }

  /* ------------------------------- boîtes à défilement : les rouvrir */
  .bc-cours-table,
  .math-table,
  .katex-display {
    overflow: visible !important;
  }
  .bc-cours-table table {
    display: table;
    width: 100%;
    table-layout: auto;
  }
  .bc-cours-table table,
  .maths-resume-sheet table {
    font-size: 9pt;
  }

  /* Les liens de la SPA sont des ancres internes : leur URL n'apprend rien
     au lecteur d'une feuille de papier, on ne l'imprime pas. */
  a[href]::after { content: none !important; }
}


/* ==========================================================================
   PROTECTION DU CONTENU PAYANT — sélection, copie, impression
   ==========================================================================

   CE QUE CE DISPOSITIF EST, ET CE QU'IL N'EST PAS. C'est une DISSUASION, pas
   une protection : le contenu d'un module ouvert est dans le navigateur de
   l'étudiant, et qui sait ouvrir les outils de développement l'en sortira. La
   seule chose qu'on puisse viser est de rendre la copie de masse — tout
   sélectionner, copier, coller ailleurs, ou imprimer en PDF — assez pénible
   pour qu'elle cesse d'être le geste par défaut. Ne pas surestimer ce que ces
   règles achètent, et ne pas les payer trop cher côté lecture.

   ELLE NE PORTE QUE SUR LA ROUTE `module`. Le marqueur `data-protege="1"` est
   posé sur `#app` par `renderRoute()`, et par elle seule. Le reste du site —
   accueil, tarifs, règlement, contact, coordonnées bancaires — reste
   sélectionnable : un visiteur doit pouvoir copier un RIB ou un numéro, et
   bloquer la page d'accueil n'aurait rien protégé du tout.

   L'IMPRESSION DU CONTENU PAYANT EST NEUTRALISÉE. « Imprimer en PDF » est le
   moyen le plus simple d'emporter un module entier, et il contournait tout le
   reste. La page imprimée porte donc un avis à la place du contenu. C'est
   cohérent avec la décision du 3 septembre 2026 sur les PDF imprimables : ils
   sont livrés au propriétaire dans un dossier, la plateforme n'en distribue
   aucun. Les intros de résumé, qui promettaient « à parcourir ou imprimer »,
   ont été corrigées le même jour — un site ne doit pas offrir ce qu'il refuse.

   CE BLOC NE GÊNE PAS LES GÉNÉRATEURS DE PDF. `gen-pdf-cartes.js` et
   `gen-pdf-resumes.js` fabriquent leurs propres pages avec un
   `<section class="content-area">` SANS `id="app"` : la règle d'impression,
   ancrée sur `#app[data-protege="1"]`, ne les atteint pas. Si l'on déplaçait un
   jour cette ancre vers `.content-area`, les deux générateurs sortiraient des
   PDF vides — et rien ne le dirait avant d'ouvrir le fichier.
   ========================================================================== */

#app[data-protege="1"],
#app[data-protege="1"] * {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Les champs de saisie d'un QCM restent utilisables : `user-select: none` sur un
   ancêtre les rendrait impossibles à corriger au clavier. */
#app[data-protege="1"] input,
#app[data-protege="1"] textarea {
  -webkit-user-select: text;
  user-select: text;
}

/* Une image glissée hors de la page est une copie comme une autre. On se garde
   de `pointer-events: none` : les figures des cours et les schémas de cartes
   mentales portent des interactions, et les éteindre casserait la lecture pour
   empêcher un geste que `-webkit-user-drag` suffit à bloquer. */
#app[data-protege="1"] img {
  -webkit-user-drag: none;
  user-drag: none;
}

/* L'avis n'existe qu'à l'impression : à l'écran il ne doit rien occuper. */
.print-avis { display: none; }

@media print {
  #app[data-protege="1"] { display: none !important; }

  .print-avis {
    display: block !important;
    padding: 2em 0;
    font-family: var(--font-body, inherit);
    font-size: 12pt;
    color: #000;
  }
}

/* L'avis d'évincement, sur la page de connexion : ce compte vient d'être
   réclamé sur un autre appareil. Il n'apparaît QUE là, et seulement après un
   évincement réel (`state.evince`) — un bandeau permanent ferait passer une
   règle pour une panne. Ton d'avertissement, pas d'erreur : l'étudiant n'a rien
   cassé, il doit juste se reconnecter. */
.auth-evincement {
  margin: 0 0 18px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--warning);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  color: var(--text);
  font-size: 0.94rem;
  line-height: 1.55;
}
/* ==========================================================================
   DÉMARCHE DE VERSEMENT — page Paiement, section « Comment payer »

   Portage de la palette bilingue du propriétaire. Le lecteur est un bachelier
   qui n'a jamais fait de virement : la section montre ce qu'il va voir (le
   reçu-témoin), écrit ce qu'il va dire (la bulle de guichet) et lui donne le
   chiffre exact à annoncer (le récapitulatif). Rien d'ornemental — chaque bloc
   répond à une question qu'il se poserait au comptoir.

   Bilinguisme : chaque ligne en darija porte `class="ar" lang="ar" dir="rtl"`.
   La direction se pose sur l'ÉLÉMENT, jamais sur la page — le site reste en
   français, et `unicode-bidi: isolate` empêche un mot latin enchâssé (le
   « versement » de la phrase du guichet) de désordonner ce qui l'entoure.
   ========================================================================== */

.ar {
  font-family: var(--font-ar);
  direction: rtl;
  unicode-bidi: isolate;
  font-weight: 500;
  line-height: 1.8;
  /* La ligne arabe se cale sur le bord GAUCHE, comme la ligne française
     qu'elle surmonte : la direction du TEXTE reste rtl (il se lit de droite
     à gauche), seul le bloc s'aligne. Laissée à droite, chaque étape faisait
     sauter l'œil d'un bord à l'autre, et le titre en darija se retrouvait à
     l'opposé de la pastille numérotée. */
  text-align: left;
}

/* Un mot latin au milieu d'une phrase arabe : il reprend la police du corps,
   sinon il sort en glyphes de secours au milieu de la bulle. */
.ar .lat,
.guichet-bulle .lat {
  font-family: var(--font-body);
  direction: ltr;
  unicode-bidi: isolate;
  font-weight: 700;
}

.versement {
  margin-top: 56px;
}

.versement-head {
  text-align: center;
  margin-bottom: 22px;
}

.versement-head h2 {
  margin: 4px 0 10px;
}

/* Le titre de section est en darija : Source Serif 4 ne couvre pas l'arabe,
   la règle globale `h1..h4` le mettrait donc en police de secours. */
.versement-head h2 .ar {
  font-size: 1.9rem;
  font-weight: 700;
}

.versement-head p {
  margin: 0 auto;
  max-width: 620px;
  color: var(--muted);
}

/* --- Récapitulatif : l'offre choisie et le montant exact ------------------ */

.versement-recap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 18px;
  align-items: end;
  margin: 0 auto 28px;
  max-width: 720px;
  padding: 16px 20px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.recap-field {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.recap-label {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.recap-label .ar {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.9rem;
}

.recap-value {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--text);
  overflow-wrap: anywhere;
}

.recap-field-montant .recap-value {
  color: var(--primary-dark);
  font-size: 1.55rem;
}

.recap-hint {
  grid-column: 1 / -1;
  margin: 4px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.84rem;
}

/* Le rang de semestre est devenu un bouton : il hérite sinon des marges et de
   la police du navigateur, et perd l'alignement de la liste des prix. */
.sem-row {
  width: 100%;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.sem-row.is-selected {
  border-color: var(--primary);
  background: var(--primary-soft);
  box-shadow: inset 3px 0 0 var(--primary);
}

/* --- Les quatre étapes ---------------------------------------------------- */

.versement-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 18px;
}

.versement-step {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: 16px;
  padding: 20px 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.versement-num {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 999px;
  background: var(--primary);
  color: #ffffff;
  font-weight: 700;
  font-size: 1rem;
}

.versement-body {
  min-width: 0;
}

.versement-body > h3 {
  display: grid;
  gap: 2px;
  margin: 4px 0 12px;
}

.versement-body > h3 .ar {
  font-size: 1.32rem;
  font-weight: 700;
  color: var(--text);
}

.versement-body > h3 em {
  font-family: var(--font-body);
  font-style: normal;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--muted);
}

/* Une note bilingue : la darija en tête, le français dessous, sans puce. */
.versement-note {
  display: grid;
  gap: 1px;
  margin: 0 0 14px;
}

.versement-note .ar {
  font-size: 1.02rem;
  color: var(--text);
}

.versement-note em {
  font-style: normal;
  font-size: 0.9rem;
  color: var(--muted);
  line-height: 1.6;
}

.versement-compte em {
  color: var(--accent);
}

/* --- Étape 1 : les deux comptes ------------------------------------------ */

.rib-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.rib-card {
  display: grid;
  gap: 10px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}

.rib-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--border);
}

.rib-head h4 {
  margin: 0;
  font-size: 1.02rem;
}

.rib-ico {
  display: grid;
  place-items: center;
  color: var(--primary);
}

.rib-field {
  display: grid;
  gap: 2px;
  margin: 0;
  min-width: 0;
}

.rib-key {
  display: flex;
  align-items: baseline;
  gap: 7px;
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.rib-key .ar {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.86rem;
}

/* Un numéro de compte se relit chiffre par chiffre au guichet : chasse fixe,
   chiffres tabulaires, et retour à la ligne autorisé plutôt qu'un débordement. */
.rib-number {
  font-family: 'Consolas', 'SFMono-Regular', 'Menlo', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--primary-dark);
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
}

.rib-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: 2px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--primary-dark);
  font-size: 0.84rem;
  font-weight: 700;
  transition: border-color 0.18s ease, background 0.18s ease;
}

.rib-copy:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.rib-copy.is-copied {
  border-color: var(--primary);
  background: var(--primary);
  color: #ffffff;
}

/* --- Étape 2 : l'agence et la phrase à dire ------------------------------ */

.versement-carry {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 16px;
  padding: 0;
}

.versement-carry li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}

.carry-ico {
  display: grid;
  place-items: center;
  color: var(--primary);
}

.carry-text {
  display: grid;
  gap: 0;
  font-size: 0.88rem;
  font-weight: 700;
}

.carry-text strong {
  color: var(--primary-dark);
}

.carry-text em {
  font-style: normal;
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--muted);
}

/* La bulle de guichet : c'est la pièce qui lève l'appréhension. Elle porte la
   phrase telle qu'elle se prononce, en grand, avec une pointe vers le bas pour
   se lire comme une parole et non comme un encadré de plus. */
.guichet {
  margin: 0 0 14px;
}

.guichet-intro {
  display: grid;
  gap: 1px;
  margin-bottom: 8px;
}

.guichet-intro .ar {
  font-size: 0.98rem;
  font-weight: 700;
  color: var(--primary-dark);
}

.guichet-intro em {
  font-style: normal;
  font-size: 0.86rem;
  color: var(--muted);
}

.guichet-bulle {
  position: relative;
  margin: 0 0 16px;
  padding: 16px 20px;
  border: 1px solid var(--primary);
  border-radius: var(--radius);
  background: var(--primary-soft);
  color: var(--text);
  font-family: var(--font-ar);
  font-size: 1.28rem;
  font-weight: 700;
  line-height: 1.9;
  direction: rtl;
  unicode-bidi: isolate;
  text-align: left;
}

.guichet-bulle::after {
  content: '';
  position: absolute;
  left: 32px;
  bottom: -9px;
  width: 15px;
  height: 15px;
  transform: rotate(45deg);
  border-right: 1px solid var(--primary);
  border-bottom: 1px solid var(--primary);
  background: var(--primary-soft);
}

.guichet-trad {
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
}

/* --- Étape 3 : le reçu-témoin -------------------------------------------- */

.recu-zone {
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}

/* Ce n'est pas un document, c'est un schéma : il porte son étiquette
   « Exemple », des valeurs manifestement fictives, et aucune identité de
   banque. Il n'existe que pour rendre les quatre lignes reconnaissables. */
.recu {
  margin: 0;
}

/* Le papier lui-même. La légende reste en dehors : enfermée dans le cadre,
   elle se lisait comme une ligne imprimée du reçu. */
.recu-papier {
  position: relative;
  padding: 30px 16px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  /* Teinte papier — le ticket est posé sur une carte blanche : en blanc pur,
     sa forme ne se détachait pas de son support. */
  background: #f8f8f6;
  box-shadow: var(--shadow-sm);
}


.recu-tag {
  position: absolute;
  top: 8px;
  left: 12px;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.recu-tag .ar {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8rem;
}

.recu-entete {
  display: grid;
  gap: 2px;
  padding-bottom: 9px;
  margin-bottom: 9px;
  border-bottom: 1px dashed var(--border);
  text-align: center;
}

.recu-entete strong {
  font-size: 0.8rem;
  letter-spacing: 0.09em;
}

.recu-entete span {
  color: var(--muted);
  font-size: 0.72rem;
}

.recu-lignes {
  display: grid;
  gap: 3px;
  margin: 0;
  font-family: 'Consolas', 'SFMono-Regular', 'Menlo', monospace;
  font-size: 0.76rem;
}

.recu-ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
}

.recu-ligne dt {
  color: var(--muted);
}

.recu-ligne dd {
  margin: 0;
  font-weight: 700;
  text-align: right;
  overflow-wrap: anywhere;
}

/* Les quatre lignes que la photo doit rendre lisibles. */
.recu-ligne.is-cle {
  background: var(--primary-soft);
  box-shadow: inset 2px 0 0 var(--primary);
}

.recu-ligne.is-cle dd {
  color: var(--primary-dark);
}

.recu figcaption {
  margin-top: 14px;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.55;
}

.recu-aside {
  min-width: 0;
}

.recu-check {
  list-style: none;
  display: grid;
  gap: 7px;
  margin: 0 0 16px;
  padding: 0;
}

.recu-check li {
  display: flex;
  align-items: baseline;
  gap: 9px;
  font-size: 0.9rem;
  font-weight: 700;
}

.recu-check svg {
  flex: none;
  color: var(--primary);
  transform: translateY(2px);
}

.recu-check em {
  font-style: normal;
  font-weight: 500;
  color: var(--muted);
}

/* Le numéro WhatsApp est une MENTION, pas une commande : le lien wa.me a été
   retiré volontairement en juillet 2026. Ni bordure ni fond de bouton — le
   design system interdit ce qui ressemble à un bouton sans en être un. */
.wa-numero {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--border);
}

.wa-ico {
  display: grid;
  place-items: center;
  color: var(--primary);
}

.wa-texte {
  display: grid;
  gap: 0;
  min-width: 0;
}

.wa-libelle {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 7px;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 700;
}

.wa-libelle em {
  font-weight: 500;
  font-size: 0.86rem;
}

.wa-texte strong {
  font-family: 'Consolas', 'SFMono-Regular', 'Menlo', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 1.02rem;
  color: var(--primary-dark);
  letter-spacing: 0.02em;
}

/* --- Solutions de repli et avertissements -------------------------------- */

.versement-plus {
  display: grid;
  gap: 18px;
  margin-top: 18px;
}

.versement-alt h3,
.versement-garde h3 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 12px;
}

.versement-alt h3 .ar,
.versement-garde h3 .ar {
  font-size: 1.14rem;
  font-weight: 700;
}

.versement-alt h3 em,
.versement-garde h3 em {
  font-family: var(--font-body);
  font-style: normal;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--muted);
}

.alt-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.alt-card {
  display: grid;
  gap: 7px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  background: var(--surface);
}

.alt-ico {
  color: var(--accent);
}

.alt-card h4 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin: 0;
  font-size: 0.98rem;
}

.alt-card h4 .ar {
  font-size: 0.94rem;
  font-weight: 500;
  color: var(--muted);
}

.alt-card p {
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
}

.versement-garde {
  padding: 18px 20px;
  border: 1px solid var(--danger);
  border-radius: var(--radius);
  background: #fdf6f6;
}

.versement-garde .garde-ico {
  display: grid;
  place-items: center;
  color: var(--danger);
  transform: translateY(3px);
}

.versement-garde ul {
  list-style: none;
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
}

.versement-garde li {
  display: grid;
  gap: 1px;
  padding-left: 13px;
  border-left: 2px solid var(--danger);
}

.versement-garde li .ar {
  font-size: 1rem;
  color: var(--text);
}

.versement-garde li em {
  font-style: normal;
  font-size: 0.87rem;
  color: var(--muted);
  line-height: 1.55;
}

/* --- Replis étroits ------------------------------------------------------ */

@media (max-width: 860px) {
  .rib-grid,
  .alt-grid {
    grid-template-columns: 1fr;
  }
  .recu-zone {
    grid-template-columns: 1fr;
  }
  .recu {
    max-width: 320px;
  }
}

@media (max-width: 620px) {
  .versement-recap {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .versement-step {
    grid-template-columns: 1fr;
    gap: 10px;
    padding: 18px 16px;
  }
  .versement-head h2 .ar {
    font-size: 1.6rem;
  }
  .guichet-bulle {
    font-size: 1.12rem;
    padding: 14px 16px;
  }
}
