/* bundle.css — WRITTEN by bin/build_css.py from main.css and its partials: do not edit it,
   edit the partials, then run  python bin/build_css.py  (release plan PERF-6). */
@import url('../../vendor/fonts/fonts.css');

/* ---- variables.css ---- */
/* ==========================================================================
   CommeUnJeu Design Tokens
   All colors, spacing, typography, and breakpoints in one place.
   ========================================================================== */

:root {
  /* --- Brand --- */
  --cuj-primary: #4650DD;
  --cuj-primary-light: #6b73e8;
  --cuj-primary-dark: #3540b0;
  --cuj-primary-bg: #eef0ff;

  /* --- Semantic colors --- */
  --cuj-success: #4CAF50;
  --cuj-success-bg: #e8f5e9;
  --cuj-warning: #FF9800;
  --cuj-warning-bg: #fff3e0;
  --cuj-danger: #F44336;
  --cuj-danger-bg: #ffebee;
  --cuj-info: #1266F1;
  --cuj-info-bg: #e3f2fd;

  /* --- Math content colors (matching mobile app) --- */
  --cuj-definition: #F93154;
  --cuj-definition-bg: rgba(249, 49, 84, 0.06);
  --cuj-theorem: #1266F1;
  --cuj-theorem-bg: rgba(18, 102, 241, 0.06);
  --cuj-example-border: #9e9e9e;
  --cuj-example-bg: #fafafa;
  --cuj-remark: #FF9800;
  --cuj-remark-bg: #fff8e1;

  /* --- Mastery score states (shared with mobile) --- */
  --cuj-score-good: #4CAF50;
  --cuj-score-good-bg: #e8f5e9;
  --cuj-score-middle: #FF9800;
  --cuj-score-middle-bg: #fff3e0;
  --cuj-score-bad: #F44336;
  --cuj-score-bad-bg: #ffebee;
  --cuj-score-notdone: #9E9E9E;
  --cuj-score-notdone-bg: #f5f5f5;

  /* --- Neutrals --- */
  --cuj-white: #ffffff;
  --cuj-paper: #FAF8F3;              /* warm off-white, Codex background */
  --cuj-paper-shade: #F5F2EA;        /* slightly darker paper for cards */
  --cuj-gray-50: #fafafa;
  --cuj-gray-100: #f5f7fa;
  --cuj-gray-200: #e9ecef;
  --cuj-gray-300: #dee2e6;
  --cuj-gray-400: #ced4da;
  --cuj-gray-500: #adb5bd;
  --cuj-gray-600: #6c757d;
  --cuj-gray-700: #495057;           /* WCAG AA safe on paper */
  --cuj-gray-800: #343a40;
  --cuj-gray-900: #212529;
  --cuj-ink: #1a1a1a;                /* near-black for display headings */
  --cuj-black: #000000;

  /* --- Typography --- */
  --cuj-font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --cuj-font-display: 'Newsreader', 'Georgia', 'Times New Roman', serif;
  --cuj-font-mono: 'Source Code Pro', 'Courier New', monospace;

  /* --- Reading scale (controls body text density — set server-side per user) --- */
  --cuj-reading-scale: 1.0;  /* 0.9 compact | 1.0 normal | 1.15 generous */
  --cuj-font-size-xs: 0.75rem;   /* 12px */
  --cuj-font-size-sm: 0.8125rem; /* 13px */
  --cuj-font-size-base: 0.9rem;  /* ~14.4px */
  --cuj-font-size-md: 1rem;      /* 16px */
  --cuj-font-size-lg: 1.125rem;  /* 18px */
  --cuj-font-size-xl: 1.25rem;   /* 20px */
  --cuj-font-size-2xl: 1.5rem;   /* 24px */
  --cuj-font-size-3xl: 1.875rem; /* 30px */
  --cuj-line-height: 1.5;
  --cuj-line-height-tight: 1.25;

  /* --- Spacing scale (4px base) --- */
  --cuj-space-0: 0;
  --cuj-space-1: 0.25rem;  /* 4px */
  --cuj-space-2: 0.5rem;   /* 8px */
  --cuj-space-3: 0.75rem;  /* 12px */
  --cuj-space-4: 1rem;     /* 16px */
  --cuj-space-5: 1.5rem;   /* 24px */
  --cuj-space-6: 2rem;     /* 32px */
  --cuj-space-8: 3rem;     /* 48px */

  /* --- Border radius --- */
  --cuj-radius-sm: 4px;
  --cuj-radius-md: 8px;
  --cuj-radius-lg: 12px;
  --cuj-radius-xl: 16px;
  --cuj-radius-pill: 50px;
  --cuj-radius-round: 50%;

  /* --- Shadows --- */
  --cuj-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --cuj-shadow-md: 0 2px 4px rgba(0, 0, 0, 0.08);
  --cuj-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.1);

  /* --- Breakpoints (for reference — used in @media queries) --- */
  /* sm: 576px, md: 768px, lg: 992px, xl: 1200px */

  /* --- Navbar --- */
  --cuj-navbar-height: 56px;

  /* --- Transitions --- */
  --cuj-transition-fast: 150ms ease;
  --cuj-transition-base: 250ms ease;
}

/* ---- reset.css ---- */
/* ==========================================================================
   Minimal reset — box-sizing, margin, font defaults.
   Replaces Bootstrap's reboot.css (~300 lines) with ~30 lines.
   ========================================================================== */

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

body {
  margin: 0;
  font-family: var(--cuj-font-family);
  font-size: var(--cuj-font-size-base);
  font-weight: 400;
  line-height: var(--cuj-line-height);
  color: var(--cuj-gray-800);
  background-color: var(--cuj-white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4, h5, h6 {
  margin-top: 0;
  margin-bottom: 0.5rem;
  font-weight: 600;
  line-height: var(--cuj-line-height-tight);
}

p { margin-top: 0; margin-bottom: 0.75rem; }

a { color: var(--cuj-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

img, svg { vertical-align: middle; }

table { border-collapse: collapse; }

fieldset { min-width: 0; padding: 0; margin: 0; border: 0; }

button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

ul, ol { padding-left: 1.5rem; }

hr { border: 0; border-top: 1px solid var(--cuj-gray-300); margin: 1rem 0; }

/* Preserve hidden attribute */
[hidden] { display: none !important; }

/* ---- typography.css ---- */
/* ==========================================================================
   Typography — Source Sans Pro + heading scale
   ========================================================================== */

/* --- Google Fonts — Source Sans Pro (body) + Newsreader (display serif) --- */
/* The two families, fetched once from Google by bin/fetch_vendor_assets.py and served from
   here: no page tells Google of a visit for a font (LEG-4). */

/* --- Display text (Newsreader) — for chapter titles, section heads, pull-quotes --- */
.font-display {
  font-family: var(--cuj-font-display);
  font-optical-sizing: auto;
  letter-spacing: -0.01em;
}

/* --- Heading scale --- */
h1 { font-size: var(--cuj-font-size-3xl); }
h2 { font-size: var(--cuj-font-size-2xl); }
h3 { font-size: var(--cuj-font-size-xl); }
h4 { font-size: var(--cuj-font-size-lg); }
h5 { font-size: var(--cuj-font-size-md); }
h6 { font-size: var(--cuj-font-size-base); }

/* --- Body text helpers --- */
.lead { font-size: var(--cuj-font-size-lg); font-weight: 300; }
.small, small { font-size: var(--cuj-font-size-sm); }
.text-uppercase { text-transform: uppercase; }
.font-weight-bold, .fw-bold { font-weight: 700; }
.fw-semibold { font-weight: 600; }

/* --- Math content text classes (from NodeTreeHtml) --- */
.consign { font-weight: bold; font-size: var(--cuj-font-size-base); }
.impo { font-weight: bold; }
.textit { font-style: italic; }
.scriptsize { font-size: 10px; }

/* --- Color classes used in math content --- */
.redcommeunjeu { color: var(--cuj-definition); }
.bluecommeunjeu { color: var(--cuj-theorem); }
.olivecommeunjeu { color: #808000; }
.yellowommeunjeu { color: #9E9125; }  /* legacy typo — kept for compat; same as below */
.yellowcommeunjeu { color: #9E9125; } /* 3.2:1 on white: AA for LARGE text only (was #FFEB3B, 1.2:1).
                                          Its one use is the .cuj-verdict line below — do not reuse it
                                          for normal-size text. No yellow reaches 4.5:1 on white. */

/* The verdict of an answered exercise (« Good » / « Great effort! » / « Incorrect »):
   bold at 20px is WCAG "large text", whose threshold (3:1) the yellow above and the
   red (#F93154, 3.75:1) can meet. */
.cuj-verdict {
  font-size: var(--cuj-font-size-xl);
  font-weight: 700;
}
.defi { color: var(--cuj-definition); font-weight: bold; }
.propri { color: var(--cuj-theorem); font-weight: bold; }
.funky { color: #808000; font-weight: bold; }

/* --- Responsive images --- */
.my-img {
  max-width: 100%;
  height: auto;
}

/* ---- layout.css ---- */
/* ==========================================================================
   Layout — navbar, containers, page structure.
   Replaces Bootstrap's navbar + container + flex utilities.
   ========================================================================== */

/* --- Containers --- */
.container {
  width: 100%;
  max-width: 1140px;
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--cuj-space-4);
  padding-right: var(--cuj-space-4);
}

.container-fluid {
  width: 100%;
  padding-left: var(--cuj-space-4);
  padding-right: var(--cuj-space-4);
}

@media (min-width: 992px) {
  .px-lg-2 { padding-left: 0.5rem !important; padding-right: 0.5rem !important; }
  .px-lg-4 { padding-left: 1.5rem !important; padding-right: 1.5rem !important; }
}

@media (min-width: 1200px) {
  .px-xl-3 { padding-left: 1rem !important; padding-right: 1rem !important; }
  .px-xl-5 { padding-left: 3rem !important; padding-right: 3rem !important; }
}

/* --- Navbar --- */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1030;
  display: flex;
  align-items: center;
  padding: 0 var(--cuj-space-4);
  min-height: var(--cuj-navbar-height);
  background-color: var(--cuj-white);
  box-shadow: var(--cuj-shadow-md);
}

.nav-item { display: inline-block; }

/* The menu is a main action: 44 px targets (founder's rule, 2026-09-24; they were 38). */
.navbar .nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--cuj-space-2) var(--cuj-space-3);
  color: var(--cuj-gray-700);
  font-weight: 600;
  font-size: var(--cuj-font-size-base);
  transition: color var(--cuj-transition-fast);
}

/* The list on the right kept the browser's top margin (the template only removes the bottom
   one): « Se connecter · S'inscrire » sat 8 px below « Cours ». */
.navbar > ul { margin-top: 0; }

.navbar .nav-link:hover,
.navbar .nav-link.active {
  color: var(--cuj-primary);
  text-decoration: none;
}

/* Header wrapper — semantic, no special styling beyond what navbar provides */
.header { display: block; }

/* Sidebar (present in template but currently unused) */
.sidebar { display: none; }

/* --- Page structure ---
   Unified paper background across the whole app (navbar + page) so content
   and chrome share the same canvas. Pages that need a different color can
   opt in with their own wrapper (e.g. .practice-page, .home-page). */
body { background-color: var(--cuj-paper); }
.page-holder {
  min-height: 100vh;
  background-color: var(--cuj-paper);
}
/* Override Bootstrap-era utilities we no longer want — utilities.css makes .bg-gray-100
   !important, which painted a grey panel under the old pages (the user journey, 2026-09-23) */
.page-holder.bg-gray-100 { background-color: var(--cuj-paper) !important; }

/* The base template wraps page_content in a flex row.
   Ensure every page wrapper fills the available horizontal space so
   their internal `justify-content:center` actually centers horizontally. */
.page-holder,              /* the old wrapper of 25 templates: without it, the invalid-activation page sat on the left */
.auth-page,
.status-page,
.settings-page,
.home-page,
.practice-page,
.codex-page {
  flex: 1 1 auto;
  min-width: 0;
}

/* Navbar blends with the paper and loses its Bootstrap-era drop shadow,
   replaced by a subtle bottom rule for separation. */
.cuj-navbar {
  background-color: var(--cuj-paper) !important;
  box-shadow: none !important;
  border-bottom: 1px solid var(--cuj-gray-200);
}

/* Replacement for the d-flex align-items-stretch wrapper in base.html */
.page-wrapper {
  display: flex;
  align-items: stretch;
}

.page-content {
  flex-grow: 1;
  min-width: 0; /* prevent flex overflow */
}

/* --- Fixed-top clearance --- */
.navbar-clearance {
  padding-top: var(--cuj-navbar-height);
}

/* --- Footer --- */
.site-footer {
  padding: var(--cuj-space-4) 0;
  margin-top: var(--cuj-space-5);
  text-align: center;
  color: var(--cuj-gray-500);
  font-size: var(--cuj-font-size-sm);
}

.site-footer a {
  color: var(--cuj-gray-600);
  margin: 0 var(--cuj-space-2);
}

.site-footer a:hover { color: var(--cuj-primary); }

/* With viewport-fit=cover (base.html) the page reaches under the notch and the home bar, in
   Safari tabs and in the installed app alike; these insets keep the content clear. env() is 0
   where there is nothing to avoid. */
body {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
  padding-bottom: env(safe-area-inset-bottom);
}
.navbar.fixed-top {                     /* fixed to the viewport, and .fixed-top (utilities.css) sets left/right too: 0,2,0 wins */
  left: env(safe-area-inset-left);
  right: env(safe-area-inset-right);
}

/* ---- components.css ---- */
/* ==========================================================================
   Components — cards, buttons, alerts, breadcrumbs, badges, forms,
   tables, dropdowns, collapse.
   Replaces ~50 Bootstrap component classes with ~180 lines.
   ========================================================================== */

/* --- Cards --- */
.card {
  background: var(--cuj-white);
  border: 1px solid var(--cuj-gray-200);
  border-radius: var(--cuj-radius-md);
  margin-bottom: var(--cuj-space-4);
}

.card-header {
  padding: var(--cuj-space-3) var(--cuj-space-4);
  border-bottom: 1px solid var(--cuj-gray-200);
  font-weight: 600;
}

.card-body {
  padding: var(--cuj-space-4);
}

.card-text { /* no special styling — just a semantic wrapper */ }

.card-title {
  margin-bottom: var(--cuj-space-3);
  font-weight: 600;
}

.card-footer {
  padding: var(--cuj-space-3) var(--cuj-space-4);
  border-top: 1px solid var(--cuj-gray-200);
}

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.375rem 0.75rem;
  font-size: var(--cuj-font-size-base);
  font-weight: 600;
  line-height: 1.5;
  border: 1px solid transparent;
  border-radius: var(--cuj-radius-sm);
  cursor: pointer;
  transition: all var(--cuj-transition-fast);
  text-decoration: none;
  white-space: nowrap;
}

.btn:hover { text-decoration: none; }
.btn:disabled, .btn.disabled { opacity: 0.65; pointer-events: none; }

.btn-primary {
  background-color: var(--cuj-primary);
  color: var(--cuj-white);
  border-color: var(--cuj-primary);
}
.btn-primary:hover { background-color: var(--cuj-primary-dark); border-color: var(--cuj-primary-dark); }

.btn-secondary {
  background-color: var(--cuj-gray-600);
  color: var(--cuj-white);
  border-color: var(--cuj-gray-600);
}

.btn-danger {
  background-color: var(--cuj-danger);
  color: var(--cuj-white);
  border-color: var(--cuj-danger);
}

.btn-success {
  background-color: var(--cuj-success);
  color: var(--cuj-white);
  border-color: var(--cuj-success);
}

/* Outlined variants */
.btn-outline-primary {
  background-color: transparent;
  color: var(--cuj-primary);
  border-color: var(--cuj-primary);
}
.btn-outline-primary:hover { background-color: var(--cuj-primary); color: var(--cuj-white); }

.btn-outline-secondary {
  background-color: transparent;
  color: var(--cuj-gray-600);
  border-color: var(--cuj-gray-400);
}
.btn-outline-secondary:hover { background-color: var(--cuj-gray-200); }

.btn-outline-danger {
  background-color: transparent;
  color: var(--cuj-danger);
  border-color: var(--cuj-danger);
}
.btn-outline-danger:hover { background-color: var(--cuj-danger); color: var(--cuj-white); }

.btn-outline-warning {
  background-color: transparent;
  color: #995B00; /* darkened for AA text contrast (was var(--cuj-warning) #FF9800, 2.2:1) */
  border-color: var(--cuj-warning);
}

.btn-sm { padding: 0.25rem 0.5rem; font-size: var(--cuj-font-size-sm); }

/* Composed button pattern used across the codebase: */
.btn.border-primary { border-color: var(--cuj-primary); }
.btn.bg-white { background-color: var(--cuj-white); }
.btn.text-primary { color: var(--cuj-primary); }

/* --- Alerts --- */
.alert {
  padding: var(--cuj-space-3) var(--cuj-space-4);
  border: 1px solid transparent;
  border-radius: var(--cuj-radius-md);
  margin-bottom: var(--cuj-space-4);
}

.alert-success { background-color: var(--cuj-success-bg); border-color: var(--cuj-success); color: #155724; }
.alert-danger { background-color: var(--cuj-danger-bg); border-color: var(--cuj-danger); color: #721c24; }
.alert-light { background-color: var(--cuj-gray-50); border-color: var(--cuj-gray-300); color: var(--cuj-gray-700); }

/* --- Breadcrumbs --- */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  padding: 0;
  margin-bottom: var(--cuj-space-2);
  list-style: none;
}

.breadcrumb-item + .breadcrumb-item::before {
  content: "/";
  padding: 0 var(--cuj-space-2);
  color: var(--cuj-gray-400);
}

.breadcrumb-item a { color: var(--cuj-gray-600); }
.breadcrumb-item a:hover { color: var(--cuj-primary); }
.breadcrumb-item.active { color: var(--cuj-gray-500); }

/* --- Dropdown --- */
.dropdown { position: relative; display: inline-block; }

.dropdown-menu {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 1050;
  min-width: 160px;
  padding: var(--cuj-space-2) 0;
  background-color: var(--cuj-white);
  border: 1px solid var(--cuj-gray-200);
  border-radius: var(--cuj-radius-md);
  box-shadow: var(--cuj-shadow-lg);
  display: none; /* toggled by JS */
}

.dropdown-menu.show { display: block; }

.dropdown-header {
  padding: var(--cuj-space-2) var(--cuj-space-4);
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-gray-600);
}

.dropdown-item {
  display: block;
  padding: var(--cuj-space-2) var(--cuj-space-4);
  color: var(--cuj-gray-800);
  text-decoration: none;
}
.dropdown-item:hover { background-color: var(--cuj-gray-100); text-decoration: none; }

.dropdown-divider {
  height: 0;
  margin: var(--cuj-space-2) 0;
  border-top: 1px solid var(--cuj-gray-200);
}

/* --- Collapse --- */
.collapse { display: none; }
.collapse.show { display: block; }

/* --- Forms (checkbox/radio for MCQ) --- */
.form-check {
  display: block;
  padding-left: 1.5em;
  margin-bottom: var(--cuj-space-2);
}

.form-check-input {
  width: 1em;
  height: 1em;
  margin-left: -1.5em;
  margin-top: 0.25em;
  vertical-align: top;
}

.form-check-label {
  display: inline-block;
  cursor: pointer;
}

/* --- Tables --- */
.table { width: 100%; border-collapse: collapse; }
.table td, .table th { padding: var(--cuj-space-2); }

.table-bordered, .table-bordered2 {
  width: auto;
  border: 1px solid var(--cuj-gray-800);
}

.table-bordered td, .table-bordered th,
.table-bordered2 td, .table-bordered2 th {
  border: 1px solid var(--cuj-gray-800);
  padding: var(--cuj-space-2);
}

.table-bordered2 td, .table-bordered2 th { padding: var(--cuj-space-1); }

.table-inline-borderless {
  width: auto;
  border-collapse: separate;
  border-spacing: 0 var(--cuj-space-1);
}

.table-inline-borderless td, .table-inline-borderless th {
  border: none;
  padding: var(--cuj-space-1) var(--cuj-space-2);
}

/* --- Legal pages (mentions légales, confidentialité, CGU/CGV) -----------------
   One narrow column of running text, the site's paper aesthetic, tables that stay
   readable on a phone. Added 2026-09-22 with the rewritten legal texts (LEG-1/2/3). */
.legal-page {
  max-width: 46rem;
  margin: 0 auto;
  /* The navbar is fixed-top: clear its height, or the h1 sits behind it. */
  padding: calc(var(--cuj-navbar-height) + var(--cuj-space-5)) var(--cuj-space-4) var(--cuj-space-8);
  color: var(--cuj-ink);
}
.legal-page h1 {
  font-family: var(--cuj-font-display);
  font-size: 1.9rem;
  font-weight: 500;
  margin: 0 0 4px;
}
.legal-page h2 {
  font-family: var(--cuj-font-display);
  font-size: 1.25rem;
  font-weight: 500;
  margin: var(--cuj-space-6) 0 var(--cuj-space-2);
  padding-top: var(--cuj-space-3);
  border-top: 1px solid var(--cuj-gray-200);
}
.legal-page h3 { font-family: var(--cuj-font-display); font-size: 1.05rem; font-weight: 600; margin: var(--cuj-space-4) 0 var(--cuj-space-1); }
.legal-page p, .legal-page li { line-height: 1.7; }
.legal-page ul { padding-left: 1.3rem; }
.legal-page li { margin-bottom: var(--cuj-space-2); }
.legal-date { color: var(--cuj-gray-600); font-style: italic; margin-bottom: var(--cuj-space-5); }
.legal-table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--cuj-space-3) 0 var(--cuj-space-4);
  font-size: 0.92rem;
}
.legal-table th, .legal-table td {
  border: 1px solid var(--cuj-gray-200);
  padding: 8px 10px;
  text-align: left;
  vertical-align: top;
}
.legal-table th { background: var(--cuj-paper-shade, #f7f5f0); font-weight: 600; }
@media (max-width: 640px) {
  .legal-table, .legal-table tbody, .legal-table tr, .legal-table td { display: block; }
  /* Each row becomes a card; the column headings would become a meaningless first card,
     and every cell reads on its own without them. */
  .legal-table tr:first-child { display: none; }
  .legal-table tr { margin-bottom: var(--cuj-space-3); border: 1px solid var(--cuj-gray-200); }
  .legal-table td { border: none; border-bottom: 1px solid var(--cuj-gray-100); }
  .legal-table td:first-child { font-weight: 600; }
  .legal-table td:last-child { border-bottom: none; color: var(--cuj-gray-600); }
}

/* --- Footer (LEG-8, UX-9) ---------------------------------------------------------
   Replaced the March placeholder (dark blue, English on every page, marked TEMPORARY). */
.cuj-footer {
  margin-top: var(--cuj-space-8);
  padding: var(--cuj-space-5) var(--cuj-space-4);
  border-top: 1px solid var(--cuj-gray-200);
  background: var(--cuj-paper-shade, #f7f5f0);
}
.cuj-footer-inner {
  max-width: 60rem;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
  justify-content: center;
  font-family: var(--cuj-font-display);
  font-size: 0.85rem;
  color: var(--cuj-gray-600);
}
/* 24 px tall at least, like every target of the site (founder's rule, 2026-09-24): they were 19. */
.cuj-footer-inner a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  color: var(--cuj-gray-700);
  text-decoration: none;
}
.cuj-footer-inner a:hover { color: var(--cuj-primary); text-decoration: underline; }
.cuj-footer-copy { width: 100%; text-align: center; color: var(--cuj-gray-500); }
@media (max-width: 480px) { .cuj-footer-inner { font-size: 0.8rem; } }
/* The trademark / non-affiliation note under a page that names the IB (LEG-7). */
.legal-note {
  max-width: 46rem; margin: var(--cuj-space-6) auto 0; padding: 0 var(--cuj-space-4);
  font-size: 0.82rem; line-height: 1.55; color: var(--cuj-gray-600);
}

/* --------------------------------------------------------------------------
   A video is a card until it is played (LEG-4, UX-10)

   Every YouTube video was an eager iframe, 560 px wide whatever the screen, that
   contacted youtube.com — and set its cookies — before anyone pressed play. The
   card requests nothing from Google: its image, fetched once at deploy by
   bin/fetch_video_thumbnails.py, is served from this site (without one, the
   gradient below shows); practice.js builds the iframe on click, on
   youtube-nocookie.com. 16/9 whatever the width, so a phone gets the whole frame.
   -------------------------------------------------------------------------- */

.cuj-video {
  position: relative;
  width: 100%;
  max-width: 560px;
  aspect-ratio: 16 / 9;
  margin: 12px auto;
  border-radius: 10px;
  overflow: hidden;
  background: linear-gradient(135deg, #10203a, #1d4ed8);
}

/* The video's image lies under the button, which darkens it a little so the white
   label and the play circle read on any picture. */
.cuj-video-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cuj-video.has-thumb .cuj-video-play { background: rgba(0, 0, 0, 0.28); }

.cuj-video.has-thumb .cuj-video-play:hover,
.cuj-video.has-thumb .cuj-video-play:focus-visible { background: rgba(0, 0, 0, 0.12); }

.cuj-video.has-thumb .cuj-video-icon { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4); }

.cuj-video-play {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px;
  border: 0;
  background: transparent;
  color: #fff;
  cursor: pointer;
  font: inherit;
}

.cuj-video-play:hover .cuj-video-icon,
.cuj-video-play:focus-visible .cuj-video-icon { transform: scale(1.08); }

.cuj-video-play:focus-visible { outline: 3px solid #fff; outline-offset: -6px; }

.cuj-video-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;                              /* a thumb, not a mouse */
  height: 64px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: #1d4ed8;
  font-size: 26px;
  padding-left: 4px;                        /* the triangle sits visually centred */
  transition: transform 0.15s ease;
}

.cuj-video-title {
  font-size: 0.95rem;
  font-weight: 600;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

/* Play refused — no jeton left, or a visitor's tries used up (cours/video_access.py):
   the reason over the bottom of the card, with the way out. */
.cuj-video-refusal {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px 14px;
  background: rgba(12, 18, 32, 0.9);
  color: #fff;
  font-size: 0.9rem;
  line-height: 1.4;
  text-align: center;
}

.cuj-video-refusal:empty { display: none; }

.cuj-video-refusal a { color: #fff; font-weight: 600; text-decoration: underline; }

.cuj-video[aria-busy="true"] .cuj-video-play { cursor: progress; }

.cuj-video[aria-busy="true"] .cuj-video-icon { opacity: 0.6; }

.cuj-video.playing iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* --------------------------------------------------------------------------
   Wide content scrolls inside its box (UX-10)

   A long displayed formula or a wide table used to widen the whole page on a
   phone and make it scroll sideways, text included.
   -------------------------------------------------------------------------- */

mjx-container[display="true"] {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}

/* The frame stays on the cells, centred as \begin{center} puts it: a block spreads its
   border over the whole card, the cells left on the left (2026-10-26). */
.card-body table {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  overflow-x: auto;
}

/* A long INLINE formula (headless pass, QA-2): MathJax 3 cannot wrap it, so base.html marks
   the ones wider than their block, and only those scroll sideways in their own box. */
mjx-container.cuj-math-wide {
  display: inline-block;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  vertical-align: middle;
  -webkit-overflow-scrolling: touch;
}

/* « Signaler une erreur » at the foot of every block (CNT-6): a quiet footnote — with a
   target of 24 px, not the 19 of its text; the margin gives back what the box took. */
.cuj-report {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  margin-top: 4px;
  font-size: 0.78rem;
  color: var(--cuj-gray-500, #6b7280);
  text-decoration: none;
  opacity: 0.75;
}

.cuj-report::before { content: "\2709\00a0"; }
.cuj-report:hover, .cuj-report:focus-visible { opacity: 1; text-decoration: underline; }

/* Skip link (UX-13): off-screen until a keyboard user tabs to it, then above
   the fixed navbar (z-index 1030) so it's never hidden behind it. */
.cuj-skip-link {
  position: absolute;
  top: -1000px;
  left: 0;
  z-index: 1100;
  padding: var(--cuj-space-3) var(--cuj-space-4);
  background: var(--cuj-primary);
  color: #fff;
  border-radius: 0 0 var(--cuj-radius-md) 0;
  text-decoration: none;
}

.cuj-skip-link:focus {
  top: 0;
}

/* The skip link's target is a landmark, not a control: no ring around the whole page. */
#main-content:focus {
  outline: none;
}

/* ---- diaporama.css ---- */
/* ==========================================================================
   Diaporama — guided "worked-example" walkthrough.

   Reframed from a bordered box (which nested awkwardly inside parent cards and
   clashed with the warm paper via cold indigo dots) into a FRAMED FIGURE: the
   step sits openly on the page, separated from a slim caption bar (prev ·
   counter · next) by a single hairline, with a reading-progress line beneath.
   Tonal ink-on-paper — harmonises with --cuj-paper, scales to any step count,
   and never reads as a box-in-a-box.

   Colour is intentionally tonal. To add a warm pop, set --diapo-accent on
   .diapo-widget to a hue (e.g. a muted ochre #B8862B, or var(--cuj-primary)).

   Markup: NodeTreeHtml DIAPORAMA branch. Behaviour: initDiaporamas() in base.html.
   ========================================================================== */

.diapo-widget {
  --diapo-ink: var(--cuj-ink);
  --diapo-accent: var(--cuj-ink);          /* tonal; swap to a hue for a pop */
  --diapo-line: rgba(26, 26, 26, 0.12);
  --diapo-line-soft: rgba(26, 26, 26, 0.06);
  max-width: 32rem;
  margin: var(--cuj-space-5) auto;
}

/* --- Figure: one step at a time, no container box --- */
.diapo-steps {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--cuj-space-3) var(--cuj-space-2) var(--cuj-space-5);
  text-align: center;
}
.diapo-steps ul { list-style: none; margin: 0; padding: 0; width: 100%; }
.diapo-steps img { max-width: 100%; height: auto; }   /* keep wide figures in-column */

.diapo-step { display: none; }
/* No-JS / pre-init fallback: the first step is always visible. */
.diapo-widget:not(.diapo-ready) .diapo-step:first-child { display: block; }
.diapo-widget.diapo-ready .diapo-step.is-active {
  display: block;
  animation: diapoFadeIn var(--cuj-transition-base) ease;
}
@keyframes diapoFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* --- Caption bar: prev · counter · next, framed by one hairline --- */
.diapo-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cuj-space-3);
  padding: var(--cuj-space-2) var(--cuj-space-1);
  border-top: 1px solid var(--diapo-line);
}

.diapo-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: none;
  border-radius: var(--cuj-radius-round);
  background: transparent;
  color: var(--diapo-ink);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  transition: background var(--cuj-transition-fast),
              opacity var(--cuj-transition-fast),
              transform var(--cuj-transition-fast);
}
.diapo-btn:hover:not(:disabled)  { background: var(--diapo-line-soft); }
.diapo-btn:active:not(:disabled) { transform: scale(0.9); }
.diapo-btn:disabled              { opacity: 0.22; cursor: default; }

/* Counter — serif, editorial; current step emphasised, total muted. */
.diapo-counter {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-lg);
  letter-spacing: 0.04em;
  color: var(--cuj-gray-500);
  user-select: none;
  white-space: nowrap;
}
.diapo-counter .diapo-cur { color: var(--diapo-accent); font-weight: 600; }

/* --- Reading-progress line (click to seek) --- */
.diapo-progress {
  position: relative;
  height: 2px;
  border-radius: 2px;
  background: var(--diapo-line-soft);
  overflow: hidden;
  cursor: pointer;
}
.diapo-progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background: var(--diapo-accent);
  border-radius: inherit;
  transition: width var(--cuj-transition-base) ease;
}

/* ---- utilities.css ---- */
/* ==========================================================================
   Utility classes — spacing, text, background, border, display, flex.
   Replaces Bootstrap's utility layer with only the classes actually used.
   ========================================================================== */

/* --- Spacing (margin & padding) ---
   Bootstrap uses m/p + t/b/s/e/x/y + 0-5. We only define used ones. */

/* Margin */
.m-0 { margin: 0 !important; }
.mt-2 { margin-top: 0.5rem !important; }
.mt-3 { margin-top: 1rem !important; }
.mt-4 { margin-top: 1.5rem !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-2 { margin-bottom: 0.5rem !important; }
.mb-3 { margin-bottom: 1rem !important; }
.mb-4 { margin-bottom: 1rem !important; }
.ms-2 { margin-left: 0.5rem !important; }
.ms-auto { margin-left: auto !important; }
.mx-2 { margin-left: 0.5rem !important; margin-right: 0.5rem !important; }
.me-4 { margin-right: 1.5rem !important; }

/* Padding */
.p-1 { padding: 0.25rem !important; }
.p-4 { padding: 1.5rem !important; }
.p-5 { padding: 3rem !important; }
.pt-1 { padding-top: 0.25rem !important; }
.pt-2 { padding-top: 0.5rem !important; }
.pt-3 { padding-top: 1rem !important; }
.pt-5 { padding-top: 3rem !important; }
.pb-3 { padding-bottom: 1rem !important; }
.px-4 { padding-left: 1.5rem !important; padding-right: 1.5rem !important; }
.py-0 { padding-top: 0 !important; padding-bottom: 0 !important; }
.py-3 { padding-top: 1rem !important; padding-bottom: 1rem !important; }
.py-5 { padding-top: 3rem !important; padding-bottom: 3rem !important; }
.pe-0 { padding-right: 0 !important; }

/* --- Display --- */
.d-none { display: none !important; }
.d-block { display: block !important; }
.d-flex { display: flex !important; }
.d-inline { display: inline !important; }
.d-inline-block { display: inline-block !important; }

/* --- Flexbox --- */
.flex-grow-1 { flex-grow: 1 !important; }
.flex-wrap { flex-wrap: wrap !important; }
.flex-nowrap { flex-wrap: nowrap !important; }
.align-items-center { align-items: center !important; }
.align-items-stretch { align-items: stretch !important; }
.align-items-start { align-items: flex-start !important; }
.justify-content-center { justify-content: center !important; }
.justify-content-between { justify-content: space-between !important; }

/* --- Text --- */
.text-center { text-align: center !important; }
.text-left { text-align: left !important; }
.text-muted { color: var(--cuj-gray-500) !important; }
.text-primary { color: var(--cuj-primary) !important; }
.text-gray-700 { color: var(--cuj-gray-700) !important; }

/* --- Background --- */
.bg-white { background-color: var(--cuj-white) !important; }
.bg-gray-100 { background-color: var(--cuj-gray-100) !important; }
.bg-danger { background-color: var(--cuj-danger) !important; }

/* --- Border --- */
.border { border: 1px solid var(--cuj-gray-300) !important; }
.border-primary { border-color: var(--cuj-primary) !important; }

/* --- Shadow --- */
.shadow { box-shadow: var(--cuj-shadow-md) !important; }
.shadow-sm { box-shadow: var(--cuj-shadow-sm) !important; }

/* --- Position --- */
.fixed-top { position: fixed; top: 0; left: 0; right: 0; z-index: 1030; }
.sticky-top { position: sticky; top: 0; z-index: 1020; }

/* --- Width --- */
.w-100 { width: 100% !important; }

/* --- Simple column (used with d-flex for centering) --- */
.col { flex: 1; }

/* --- List --- */
.list-unstyled { padding-left: 0; list-style: none; }

/* --- Link color variants (from Bubbly theme, used in exercise links) --- */
.link-success { color: var(--cuj-success) !important; }
.link-warning { color: #995B00 !important; } /* darkened for AA text contrast (was var(--cuj-warning) #FF9800, 2.2:1) */
.link-primary { color: var(--cuj-primary) !important; }
.link-danger { color: var(--cuj-danger) !important; }
.text-base { color: var(--cuj-gray-800); }

/* --- Misc --- */
.avatar {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--cuj-radius-round);
}

/* ---- cover.css ---- */
/* ==========================================================================
   Cover — curriculum tile grid (horizontal scroll rows).
   Migrated from base.html inline <style>.
   ========================================================================== */

.cover-container {
  height: 220px;
  overflow-x: scroll;
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  scrollbar-width: thin;
}

.cover-container::-webkit-scrollbar { height: 10px; }
.cover-container::-webkit-scrollbar-thumb { background: #bbb; border-radius: 5px; }
.cover-container::-webkit-scrollbar-track { background: #f0f0f0; }

.cover-item {
  position: relative;
  flex: 0 0 auto;
  margin: var(--cuj-space-2);
  box-shadow: var(--cuj-shadow-sm);
  border-top-right-radius: var(--cuj-radius-sm);
  width: 130px;
  height: 180px;
  background-position: top left;
  background-repeat: no-repeat;
  transition: transform var(--cuj-transition-base);
}

.cover-item a {
  text-decoration: none;
  color: var(--cuj-gray-800);
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  position: absolute;
  top: 0;
  left: 0;
}

.cover-item img {
  width: 126px;
  height: auto;
}

.cover-item p {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: var(--cuj-space-1);
  margin: 0;
  background: rgba(255, 255, 255, 0.9);
  font-size: var(--cuj-font-size-xs);
  font-weight: 600;
  text-align: center;
  line-height: 1.2;
  overflow: hidden;
}

.title-large { font-size: var(--cuj-font-size-xs); }
.title-small { font-size: 8px; }

.cover-item:hover { transform: translateY(-5px); }

/* --- Score state borders --- */
.cover-item.good { border: 2px solid var(--cuj-score-good); }
.cover-item.middle { border: 2px solid var(--cuj-score-middle); }
.cover-item.bad { border: 2px solid var(--cuj-score-bad); }
.cover-item.notdone { border: 1px solid var(--cuj-gray-300); }

/* ---- chapter.css ---- */
/* ==========================================================================
   Chapter page — competence rows, section headers, bloc styling,
   status squares, tooltips. Matching mobile app design.
   ========================================================================== */

/* --- Status squares (exercise buttons in chapter/block view) --- */
button.status-square {
  width: 40px;
  height: 40px;
  border: none;
  border-radius: var(--cuj-radius-sm);
  color: var(--cuj-white);
  font-weight: 700;
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
  position: relative;
  display: inline-block;
  margin: 2px;
  transition: transform var(--cuj-transition-fast);
}

button.status-square:hover { transform: translateY(-2px); }

button.good { background: var(--cuj-score-good); }
button.middle { background: var(--cuj-score-middle); }
button.bad { background: var(--cuj-score-bad); }
button.notdone { background: var(--cuj-primary); }

/* --- Custom tooltip (CSS-only, not Bootstrap) --- */
.tooltip-text {
  visibility: hidden;
  position: absolute;
  z-index: 100000;
  background-color: var(--cuj-gray-800);
  color: var(--cuj-white);
  text-align: center;
  padding: var(--cuj-space-1) var(--cuj-space-2);
  border-radius: var(--cuj-radius-sm);
  font-size: 10px;
  width: 60px;
  bottom: 110%;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
  transition: opacity var(--cuj-transition-fast);
}

.tooltip-text::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: var(--cuj-gray-800) transparent transparent transparent;
}

button.status-square:hover .tooltip-text {
  visibility: visible;
  opacity: 1;
}

/* --- Exit button (fixed bottom-right) --- */
.button-bottom-right {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 1000;
  padding: var(--cuj-space-2) var(--cuj-space-4);
  background-color: var(--cuj-primary);
  color: var(--cuj-white);
  border: none;
  border-radius: var(--cuj-radius-pill);
  font-size: var(--cuj-font-size-base);
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--cuj-shadow-lg);
  transition: all var(--cuj-transition-fast);
}

.button-bottom-right:hover {
  background-color: var(--cuj-primary-dark);
  transform: translateY(-2px);
}

/* --- Flex centering pattern (used in block/quiz views) --- */
.flex-container-center {
  display: flex;
  justify-content: center;
}

/* --- Btn-container (for MCQ buttons) --- */
.btn-container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cuj-space-2);
  justify-content: center;
}

/* Previous / next chapter (headless pass, QA-2, 2026-09-24): a long title in a row that could not
   wrap made the page 370 px wide on a 360 px phone. The row wraps, the titles too, and the
   buttons are tall enough to tap. */
.chapter-prevnext {
  flex-wrap: wrap;
  gap: var(--cuj-space-2, 8px);
}
.chapter-prevnext .btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  max-width: 100%;
  white-space: normal;
}
.chapter-prevnext .btn[rel="next"] {
  margin-left: auto;
  text-align: right;
}

/* ---- codex.css ---- */
/* ==========================================================================
   Le Codex — editorial chapter layout.
   Desktop: Spine (left) · Content (center) · Marginalia (right)
   Mobile:  Content only, with sticky TOC chip
   ========================================================================== */

/* --- The outer shell — paper background, body text scale --- */
.codex-page {
  background: var(--cuj-paper);
  min-height: calc(100vh - var(--cuj-navbar-height));
  padding-top: var(--cuj-space-5);
  padding-bottom: var(--cuj-space-8);
  font-size: calc(var(--cuj-font-size-md) * var(--cuj-reading-scale));
  line-height: calc(var(--cuj-line-height) * var(--cuj-reading-scale));
  color: var(--cuj-gray-800);
}

/* --- Two-column grid (desktop ≥992px): Spine (with downloads) + Content --- */
.codex-grid {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: var(--cuj-space-5);
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0 var(--cuj-space-4);
  box-sizing: border-box;
}

/* --- Single column (mobile <992px): content only --- */
@media (max-width: 991.98px) {
  .codex-grid {
    grid-template-columns: 1fr;
    padding: 0 var(--cuj-space-4);
    max-width: 100%;
  }
  .codex-spine-desktop { display: none; }
}

/* ==========================================================================
   SPINE — left rail with vertical path of blocks
   ========================================================================== */

.codex-spine-desktop {
  position: sticky;
  top: calc(var(--cuj-navbar-height) + var(--cuj-space-5));
  align-self: start;
  max-height: calc(100vh - var(--cuj-navbar-height) - var(--cuj-space-5));
  overflow-y: auto;
  padding: var(--cuj-space-3) 0;
  font-size: var(--cuj-font-size-sm);
  scrollbar-width: thin;
  scrollbar-color: var(--cuj-gray-300) transparent;
}
.codex-spine-desktop::-webkit-scrollbar { width: 6px; }
.codex-spine-desktop::-webkit-scrollbar-track { background: transparent; }
.codex-spine-desktop::-webkit-scrollbar-thumb {
  background: var(--cuj-gray-300);
  border-radius: 3px;
}
.codex-spine-desktop::-webkit-scrollbar-thumb:hover { background: var(--cuj-gray-500); }

.codex-spine-label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-700);
  margin-bottom: var(--cuj-space-3);
  padding-left: var(--cuj-space-3);
}

.codex-spine-path {
  position: relative;
}

/* --- Section group (header + nested skills) --- */
.codex-spine-section {
  position: relative;
  padding: var(--cuj-space-2) 0 var(--cuj-space-2) var(--cuj-space-3);
  border-left: 2px solid var(--cuj-gray-200);
  margin-bottom: var(--cuj-space-1);
  transition: border-color var(--cuj-transition-fast);
}
.codex-spine-section.current {
  border-left-color: var(--cuj-primary);
  background: linear-gradient(to right, rgba(70,80,221,0.04), transparent);
}

/* --- Section header (topic title, not a mastery row) --- */
/* The rail's links: 24 px at least, like every target (a one-line title made them 21-22). */
.codex-spine-section-head {
  display: flex;
  align-items: baseline;
  gap: var(--cuj-space-2);
  min-height: 24px;
  padding: 2px 0;
  color: var(--cuj-ink);
  text-decoration: none;
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  line-height: 1.3;
}
.codex-spine-section-head:hover {
  text-decoration: none;
  color: var(--cuj-primary);
}

.codex-spine-num {
  display: inline-block;
  min-width: 22px;
  font-style: italic;
  font-variant-numeric: tabular-nums;
  font-size: var(--cuj-font-size-xs);
  /* Match the title next to it — no primary-color highlight since the
     current-section chip already carries that signal. */
  color: inherit;
  letter-spacing: 0.02em;
}

.codex-spine-title {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* --- Nested skills list --- */
.codex-spine-skills {
  list-style: none;
  margin: var(--cuj-space-1) 0 0;
  padding: 0 0 0 var(--cuj-space-1);
}

.codex-spine-skill {
  margin: 0;
}
.codex-spine-skill a {
  display: flex;
  align-items: center;
  gap: var(--cuj-space-2);
  min-height: 24px;
  padding: 3px var(--cuj-space-2) 3px 0;
  color: var(--cuj-gray-600);
  text-decoration: none;
  font-size: var(--cuj-font-size-xs);
  line-height: 1.35;
  border-radius: var(--cuj-radius-sm);
  transition: color var(--cuj-transition-fast), background var(--cuj-transition-fast);
}
.codex-spine-skill a:hover {
  color: var(--cuj-ink);
  text-decoration: none;
  background: var(--cuj-paper-shade);
}

.codex-spine-skill-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--cuj-paper);
  border: 1.5px solid var(--cuj-gray-400);
  transition: all var(--cuj-transition-fast);
}
.codex-spine-skill.good   .codex-spine-skill-dot { background: var(--cuj-score-good);   border-color: var(--cuj-score-good); }
.codex-spine-skill.middle .codex-spine-skill-dot { background: var(--cuj-score-middle); border-color: var(--cuj-score-middle); }
.codex-spine-skill.bad    .codex-spine-skill-dot { background: var(--cuj-score-bad);    border-color: var(--cuj-score-bad); }
.codex-spine-skill.quiz   .codex-spine-skill-dot {
  border-radius: 2px;
  transform: rotate(45deg);
  background: var(--cuj-primary);
  border-color: var(--cuj-primary);
}

.codex-spine-skill-title {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* Current skill — filled dot with ring */
.codex-spine-skill.current a {
  color: var(--cuj-ink);
  font-weight: 600;
}
.codex-spine-skill.current .codex-spine-skill-dot {
  box-shadow: 0 0 0 3px rgba(70, 80, 221, 0.18);
  border-color: var(--cuj-primary);
}

/* --- Tone down default Bootstrap-ish card backgrounds inside Codex content.
   The NodeTree default renderer emits <div class="card"> for TEXT/OPENING_PROBLEM
   and answer-reveal wrappers; on paper they read as harsh white boxes.
   Keep the structural role (padding, separation) but remove the bright fill. ---  */
.codex-content .card,
.codex-content .card-body {
  background: transparent;
  border: none;
  box-shadow: none;
  padding: 0;
  margin: 0;
}
/* Outer TEXT/OPENING_PROBLEM bloc (the top block in your screenshot) — give
   it a subtle left rule like a margin note, not a filled card. */
.codex-content > .card,
.codex-content > div > .card {
  border-left: 2px solid var(--cuj-gray-300);
  padding: var(--cuj-space-2) 0 var(--cuj-space-2) var(--cuj-space-4);
  margin-bottom: var(--cuj-space-4);
}
/* Answer reveal wrapper — soft paper-shade fill so it clearly belongs to the example */
.codex-bloc .collapse .card {
  background: var(--cuj-paper-shade);
  border-radius: var(--cuj-radius-md);
  padding: var(--cuj-space-3) var(--cuj-space-4);
  margin-top: var(--cuj-space-2);
}

/* --- Answer toggle: replace the bordered pill with a hypertext link + chevron.
   The NodeTree renderer emits <a class="btn border-primary text-primary"
   data-toggle="collapse" …>Answer</a>. Inside the Codex, we strip button chrome.
   28 px tall: the 4 px margins it had above and below became target (it was 20 px, under
   the 24 px every target of the site gets — founder's rule, 2026-09-24), in the same room. */
.codex-content a[data-toggle="collapse"].btn,
.codex-bloc a[data-toggle="collapse"].btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 28px;
  padding: 0;
  margin: 0;
  background: transparent !important;
  border: none !important;
  color: var(--cuj-primary) !important;
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-weight: 500;
  font-size: var(--cuj-font-size-sm);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--cuj-transition-fast);
}
.codex-content a[data-toggle="collapse"].btn:hover,
.codex-bloc a[data-toggle="collapse"].btn:hover {
  color: var(--cuj-primary-dark);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Chevron that rotates when the disclosure is open (via aria-expanded) */
.codex-content a[data-toggle="collapse"].btn::before,
.codex-bloc a[data-toggle="collapse"].btn::before {
  content: "›";
  display: inline-block;
  font-style: normal;
  font-weight: 700;
  font-size: 1.1em;
  line-height: 1;
  transition: transform var(--cuj-transition-fast);
}
.codex-content a[data-toggle="collapse"].btn[aria-expanded="true"]::before,
.codex-bloc a[data-toggle="collapse"].btn[aria-expanded="true"]::before {
  transform: rotate(90deg);
}

/* ==========================================================================
   MOBILE SPINE — sticky chip with bottom sheet TOC
   ========================================================================== */

.codex-spine-mobile {
  display: none;
}

@media (max-width: 991.98px) {
  .codex-spine-mobile {
    display: flex;
    position: sticky;
    top: var(--cuj-navbar-height);
    z-index: 900;
    align-items: center;
    gap: var(--cuj-space-2);
    margin: 0 calc(-1 * var(--cuj-space-4)) var(--cuj-space-4);
    padding: 1px var(--cuj-space-4);          /* the chip's own box is 44 px: the bar keeps its height */
    background: var(--cuj-paper);
    border-bottom: 1px solid var(--cuj-gray-200);
    font-size: var(--cuj-font-size-sm);
    color: var(--cuj-gray-700);
  }

  /* A 44 px target (founder's rule, 2026-09-24: 44 px for the main actions) in a bar that
     stays on the screen: the box you tap is 44 px, the pill you see (::before) keeps its 30. */
  .codex-spine-chip {
    position: relative;
    isolation: isolate;
    display: inline-flex;
    align-items: center;
    gap: var(--cuj-space-2);
    min-height: 44px;
    padding: 0 var(--cuj-space-3);
    background: transparent;
    border: 0;
    font-weight: 600;
    cursor: pointer;
    color: var(--cuj-ink);
  }
  .codex-spine-chip::before {
    content: "";
    position: absolute;
    inset: 7px 0;
    z-index: -1;
    background: var(--cuj-white);
    border: 1px solid var(--cuj-gray-300);
    border-radius: var(--cuj-radius-pill);
  }
  .codex-spine-chip:focus-visible { outline: none; }
  .codex-spine-chip:focus-visible::before { outline: 2px solid var(--cuj-primary); outline-offset: 2px; }

  .codex-spine-progress-bar {
    flex: 1;
    height: 6px;
    background: var(--cuj-gray-200);
    border-radius: 3px;
    overflow: hidden;
  }
  .codex-spine-progress-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--cuj-primary), var(--cuj-primary-light));
    transition: width var(--cuj-transition-base);
  }
}

/* Bottom sheet TOC (mobile) */
.codex-toc-sheet {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 2000;
  background: var(--cuj-paper);
  border-radius: var(--cuj-radius-xl) var(--cuj-radius-xl) 0 0;
  box-shadow: 0 -8px 32px rgba(0,0,0,0.15);
  max-height: 70vh;
  overflow-y: auto;
  padding: var(--cuj-space-4);
  padding-bottom: calc(var(--cuj-space-4) + env(safe-area-inset-bottom));
}
.codex-toc-sheet.open { display: block; }

.codex-toc-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1999;
  background: rgba(0,0,0,0.4);
}
.codex-toc-backdrop.open { display: block; }

/* ==========================================================================
   CHAPTER HERO
   ========================================================================== */

.codex-hero {
  margin-bottom: var(--cuj-space-6);
  padding-bottom: var(--cuj-space-5);
  border-bottom: 1px solid var(--cuj-gray-300);
}

.codex-hero-eyebrow {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--cuj-gray-700);
  margin-bottom: var(--cuj-space-2);
}

.codex-hero-title {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: clamp(2rem, 4vw + 0.5rem, 3.25rem);
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: var(--cuj-ink);
  margin: 0 0 var(--cuj-space-3);
}

.codex-hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cuj-space-4);
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-gray-700);
  margin-bottom: var(--cuj-space-4);
}

.codex-hero-meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
}
.codex-hero-meta-item a {             /* the prerequisites: 24 px targets, not 20 */
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

.codex-hero-summary {
  font-family: var(--cuj-font-display);
  font-weight: 400;
  font-size: var(--cuj-font-size-lg);
  line-height: 1.5;
  color: var(--cuj-gray-800);
  max-width: none;
  margin: 0 0 var(--cuj-space-5);
}

.codex-hero-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  padding: var(--cuj-space-3) var(--cuj-space-5);
  background: var(--cuj-primary);
  color: var(--cuj-white) !important;
  text-decoration: none !important;
  border-radius: var(--cuj-radius-pill);
  font-weight: 600;
  font-size: var(--cuj-font-size-md);
  transition: all var(--cuj-transition-fast);
  box-shadow: 0 2px 8px rgba(70, 80, 221, 0.25);
}
.codex-hero-cta:hover {
  background: var(--cuj-primary-dark);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(70, 80, 221, 0.35);
}

.codex-hero-cta-arrow {
  font-family: var(--cuj-font-display);
  font-size: 1.2em;
}

/* ==========================================================================
   CONTENT COLUMN — editorial flow
   ========================================================================== */

.codex-content {
  max-width: none;
  min-width: 0;
}

.codex-content p {
  margin: 0 0 var(--cuj-space-4);
}

.codex-content > p:first-of-type::first-letter {
  /* Drop cap on the first paragraph only */
  font-family: var(--cuj-font-display);
  font-size: 3.5em;
  float: left;
  line-height: 0.85;
  padding: 0.1em 0.1em 0 0;
  color: var(--cuj-primary);
  font-weight: 500;
}

/* --- Section structure --- */
.codex-section {
  margin: var(--cuj-space-6) 0 var(--cuj-space-5);
  scroll-margin-top: calc(var(--cuj-navbar-height) + var(--cuj-space-4));
}

.codex-section-heading {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-2xl);
  line-height: 1.2;
  color: var(--cuj-ink);
  margin-bottom: var(--cuj-space-4);
  padding-bottom: var(--cuj-space-2);
  border-bottom: 2px solid var(--cuj-gray-300);
}

.codex-section-roman {
  font-family: var(--cuj-font-display);
  color: var(--cuj-ink);
  font-weight: 500;
  margin-right: var(--cuj-space-2);
}

/* --- Subsection (one level deeper: § I.1, I.2 …) --- */
.codex-subsection {
  margin: var(--cuj-space-5) 0 var(--cuj-space-4);
  scroll-margin-top: calc(var(--cuj-navbar-height) + var(--cuj-space-4));
}

.codex-subsection-heading {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-xl);
  line-height: 1.25;
  color: var(--cuj-ink);
  margin-bottom: var(--cuj-space-3);
  padding-bottom: var(--cuj-space-1);
  border-bottom: 1px solid var(--cuj-gray-200);
}

.codex-subsection-roman {
  font-family: var(--cuj-font-display);
  color: var(--cuj-ink);
  font-weight: 500;
  font-size: 0.9em;
  margin-right: var(--cuj-space-2);
}

/* --- Spine: subsection level (visually nested between section header and skills) --- */
.codex-spine-subsection {
  margin-top: var(--cuj-space-1);
  padding: 2px 0 2px var(--cuj-space-3);
  border-left: 1px dashed var(--cuj-gray-300);
  margin-left: var(--cuj-space-1);
}

.codex-spine-subsection-head {
  display: flex;
  align-items: baseline;
  gap: var(--cuj-space-2);
  padding: 2px 0;
  color: var(--cuj-gray-800);
  text-decoration: none;
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-size: calc(var(--cuj-font-size-sm) * 0.95);
  font-weight: 500;
  line-height: 1.3;
}
.codex-spine-subsection-head:hover {
  text-decoration: none;
  color: var(--cuj-primary);
}

/* --- Math scroll wrapper (prevents wide equations breaking the column) --- */
.math-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  max-width: 100%;
  margin: var(--cuj-space-3) 0;
  padding: var(--cuj-space-1) 0;
}

/* ==========================================================================
   CONTENT BLOCS — editorial cards with pattern + color dual encoding
   ========================================================================== */

.codex-bloc {
  margin: var(--cuj-space-4) 0;
  padding: var(--cuj-space-3) var(--cuj-space-4);
  background: var(--cuj-white);
  border-left: 4px solid var(--cuj-gray-400);
  border-radius: 0 var(--cuj-radius-md) var(--cuj-radius-md) 0;
  box-shadow: var(--cuj-shadow-sm);
}

.codex-bloc-label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--cuj-space-2);
}

/* Bloc-label glyphs removed — the label word ("DEFINITION", "THEOREM"…)
   already carries the meaning; the § / λ / › / ✻ glyphs were visual
   noise. The border style (solid / double / dashed / dotted) is the
   remaining type signal. */

/* --- Definition — red, solid border --- */
.codex-bloc.definition {
  background: var(--cuj-definition-bg);
  border-left-style: solid;
  border-left-color: var(--cuj-definition);
}
.codex-bloc.definition .codex-bloc-label { color: var(--cuj-definition); }

/* --- Theorem / Proposition — blue, double border --- */
.codex-bloc.theorem {
  background: var(--cuj-theorem-bg);
  border-left-style: double;
  border-left-width: 6px;
  border-left-color: var(--cuj-theorem);
  padding-left: calc(var(--cuj-space-4) - 2px);
}
.codex-bloc.theorem .codex-bloc-label { color: var(--cuj-theorem); }

/* --- Example — grey, dashed border --- */
.codex-bloc.example {
  background: var(--cuj-paper-shade);
  border-left-style: dashed;
  border-left-color: var(--cuj-gray-500);
}
.codex-bloc.example .codex-bloc-label { color: var(--cuj-gray-700); }

/* --- Remark — orange, dotted border --- */
.codex-bloc.remark {
  background: var(--cuj-remark-bg);
  border-left-style: dotted;
  border-left-width: 5px;
  border-left-color: var(--cuj-remark);
}
.codex-bloc.remark .codex-bloc-label { color: #e65100; }  /* darker orange for AA */

/* --- Inline "Practice this" callout (legacy) --- */
.codex-practice-callout {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  padding: var(--cuj-space-2) var(--cuj-space-4);
  margin: var(--cuj-space-3) 0;
  background: var(--cuj-primary-bg);
  color: var(--cuj-primary) !important;
  text-decoration: none !important;
  border-radius: var(--cuj-radius-md);
  font-weight: 600;
  font-size: var(--cuj-font-size-sm);
  transition: all var(--cuj-transition-fast);
}
.codex-practice-callout:hover {
  background: var(--cuj-primary);
  color: var(--cuj-white) !important;
}

/* --- Skills strip (competence rows inside a section) --- */
.codex-skills-label {
  margin: var(--cuj-space-5) 0 var(--cuj-space-2);
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-700);
}
.codex-skill-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--cuj-space-4);
  border-top: 1px solid var(--cuj-gray-200);
}
.codex-skill-row {
  display: flex;
  align-items: center;
  gap: var(--cuj-space-3);
  padding: var(--cuj-space-3) 0;
  border-bottom: 1px solid var(--cuj-gray-200);
}
.codex-skill-dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--cuj-gray-300);
  box-shadow: 0 0 0 3px var(--cuj-paper), 0 0 0 4px var(--cuj-gray-300);
}
.codex-skill-row.good     .codex-skill-dot { background: var(--cuj-success); box-shadow: 0 0 0 3px var(--cuj-paper), 0 0 0 4px var(--cuj-success); }
.codex-skill-row.middle   .codex-skill-dot { background: var(--cuj-warning); box-shadow: 0 0 0 3px var(--cuj-paper), 0 0 0 4px var(--cuj-warning); }
.codex-skill-row.bad      .codex-skill-dot { background: var(--cuj-danger);  box-shadow: 0 0 0 3px var(--cuj-paper), 0 0 0 4px var(--cuj-danger); }
.codex-skill-row.quiz     .codex-skill-dot { background: var(--cuj-primary); box-shadow: 0 0 0 3px var(--cuj-paper), 0 0 0 4px var(--cuj-primary); }
.codex-skill-title {
  flex: 1;
  font-weight: 500;
  color: var(--cuj-ink);
}
.codex-stars {                        /* le niveau d'une marche : ★ à ★★★, ★★★★ au concours */
  margin-left: var(--cuj-space-2);
  color: var(--cuj-primary);
  font-size: var(--cuj-font-size-sm);
  letter-spacing: 0.05em;
  white-space: nowrap;
}
.codex-skill-cta {                    /* the main action of a chapter: 44 px (it was 37) */
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  min-height: 44px;
  padding: 0.375rem 0.875rem;
  background: transparent;
  color: var(--cuj-primary);
  border: 1px solid var(--cuj-primary);
  border-radius: var(--cuj-radius-pill, 999px);
  font-weight: 600;
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
  text-decoration: none;
  transition: all var(--cuj-transition-fast);
  white-space: nowrap;
}
.codex-skill-cta:hover {
  background: var(--cuj-primary);
  color: var(--cuj-white);
}
@media (max-width: 640px) {
  .codex-skill-row { flex-wrap: wrap; }
  .codex-skill-title { flex-basis: 100%; }
}

/* ==========================================================================
   MARGINALIA — right column with auxiliary info
   ========================================================================== */

.codex-marginalia {
  position: sticky;
  top: calc(var(--cuj-navbar-height) + var(--cuj-space-5));
  align-self: start;
  max-height: calc(100vh - var(--cuj-navbar-height) - var(--cuj-space-5));
  overflow-y: auto;
  font-size: var(--cuj-font-size-sm);
}

.codex-margin-card {
  background: transparent;
  border: none;
  border-left: 2px solid var(--cuj-gray-300);
  border-radius: 0;
  padding: 0 0 0 var(--cuj-space-3);
  margin-bottom: var(--cuj-space-4);
}

.codex-margin-title {
  font-family: var(--cuj-font-display);
  font-weight: 600;
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-700);
  margin-bottom: var(--cuj-space-2);
  padding-bottom: var(--cuj-space-2);
  border-bottom: 1px solid var(--cuj-gray-200);
}

.codex-margin-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.codex-margin-list li {
  padding: var(--cuj-space-1) 0;
}
.codex-margin-list a {
  color: var(--cuj-gray-800);
  text-decoration: none;
}
.codex-margin-list a:hover {
  color: var(--cuj-primary);
  text-decoration: underline;
}

/* PDF downloads, on the hero's meta line */
.codex-hero-pdf {
  min-height: 24px;                   /* a target of 24 px, as the prerequisites */
  color: var(--cuj-gray-800);
  text-decoration: none;
  transition: color var(--cuj-transition-fast);
}
.codex-hero-pdf:hover {
  color: var(--cuj-primary);
  text-decoration: underline;
}
.codex-hero-pdf-tag {
  flex: none;
  font-family: var(--cuj-font-display);
  color: var(--cuj-definition);
  font-weight: 700;
  font-size: 10px;
  padding: 1px 4px;
  background: var(--cuj-definition-bg);
  border-radius: 3px;
}

/* ==========================================================================
   PREV / NEXT FOOTER — chapter pagination
   ========================================================================== */

.codex-paginate {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--cuj-space-3);
  margin-top: var(--cuj-space-8);
  padding-top: var(--cuj-space-5);
  border-top: 1px solid var(--cuj-gray-300);
}

.codex-paginate-link {
  display: flex;
  flex-direction: column;
  gap: var(--cuj-space-1);
  padding: var(--cuj-space-3) var(--cuj-space-4);
  background: var(--cuj-white);
  border: 1px solid var(--cuj-gray-200);
  border-radius: var(--cuj-radius-md);
  color: var(--cuj-ink) !important;
  text-decoration: none !important;
  flex: 1;
  max-width: 45%;
  transition: all var(--cuj-transition-fast);
}
.codex-paginate-link:hover {
  border-color: var(--cuj-primary);
  transform: translateY(-1px);
}

.codex-paginate-link.next { text-align: right; }

.codex-paginate-dir {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-600);
}

.codex-paginate-title {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-md);
  line-height: 1.2;
}

/* ==========================================================================
   LITE FALLBACK — for exercise-only chapters (no lesson flow)
   ========================================================================== */

.codex-lite .codex-spine-desktop,
.codex-lite .codex-marginalia { display: none; }

.codex-lite .codex-grid {
  grid-template-columns: minmax(0, 1fr);
  max-width: 900px;
}

.codex-lite .codex-exercise-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--cuj-space-3);
  margin-top: var(--cuj-space-5);
}

.codex-lite .codex-exercise-card {
  padding: var(--cuj-space-4);
  background: var(--cuj-white);
  border: 1px solid var(--cuj-gray-200);
  border-radius: var(--cuj-radius-md);
  text-decoration: none;
  color: var(--cuj-ink);
  text-align: center;
  transition: all var(--cuj-transition-fast);
}
.codex-lite .codex-exercise-card:hover {
  transform: translateY(-2px);
  border-color: var(--cuj-primary);
}

/* ==========================================================================
   RAPPEL — recap sections (structure field review=1).
   Prerequisite material retold inside the chapter's story. The heading keeps
   its roman numeral (the narrative spine stays whole); the body folds under a
   small-caps « Rappel » cartouche in the tradition of classic French
   schoolbooks (petit-texte under a double rule). Closed by default: the year
   view stays slim, the story keeps every step, the prerequisite is one tap
   away. Print reveals everything.
   ========================================================================== */

.codex-recap {
  margin: calc(-1 * var(--cuj-space-2)) 0 var(--cuj-space-4);
}

.codex-recap-summary {
  display: flex;
  align-items: baseline;
  gap: var(--cuj-space-2);
  cursor: pointer;
  list-style: none;               /* hide the default triangle everywhere */
  padding: var(--cuj-space-1) 0;
  -webkit-user-select: none;
  user-select: none;
}
.codex-recap-summary::-webkit-details-marker { display: none; }

/* The cartouche: small caps between two thin rules — the Lebossé « RAPPEL » */
.codex-recap-cartouche {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cuj-gray-700);
  border-top: 1px solid var(--cuj-gray-500);
  border-bottom: 1px solid var(--cuj-gray-500);
  padding: 1px var(--cuj-space-2);
  white-space: nowrap;
}

.codex-recap-hint {
  font-size: var(--cuj-font-size-sm);
  font-style: italic;
  color: var(--cuj-gray-600);
}

.codex-recap-chevron {
  margin-left: auto;
  color: var(--cuj-gray-600);
  transition: transform 0.18s ease;
  font-style: normal;
}
.codex-recap[open] > .codex-recap-summary .codex-recap-chevron {
  transform: rotate(90deg);
}
.codex-recap-summary:hover .codex-recap-cartouche {
  color: var(--cuj-primary);
  border-color: var(--cuj-primary);
}

/* Open state: petit-texte register — slightly reduced, ruled on the left,
   so even unfolded the recap reads as a different voice than the year's new
   material. The rule uses a soft crease shadow to sit "into" the paper. */
.codex-recap-body {
  font-size: 0.925em;
  color: var(--cuj-gray-700);
  border-left: 2px solid var(--cuj-gray-300);
  padding-left: var(--cuj-space-3);
  margin-top: var(--cuj-space-2);
  box-shadow: inset 6px 0 8px -8px rgba(26, 26, 26, 0.18);
}

/* Dim the recap headings a touch so the year's new sections carry the page */
.codex-section-recap > .codex-section-heading,
.codex-subsection-recap > .codex-subsection-heading {
  color: var(--cuj-gray-700);
  border-bottom-style: dashed;
}

/* Spine + mobile TOC: recap rows step back */
.codex-spine-section.recap > .codex-spine-section-head .codex-spine-title {
  color: var(--cuj-gray-600);
  font-style: italic;
}
.codex-spine-section.recap > .codex-spine-section-head .codex-spine-title::after {
  content: " · rappel";
  font-size: 0.85em;
  letter-spacing: 0.05em;
}

/* Print: paper shows the whole story — folds forced open, cartouche kept */
@media print {
  .codex-recap { display: block; }
  .codex-recap > .codex-recap-body { display: block !important; }
  .codex-recap-chevron, .codex-recap-hint { display: none; }
}

/* --- review=2 « Pour aller plus loin » — the fold's other register.
   Same mechanics as « Rappel », different promise: this is content BEYOND the
   year, not before it. The cartouche borrows the accent colour so the two
   registers are told apart at a glance (founder, 2026-07-30). --- */
.codex-recap.codex-beyond > .codex-recap-summary .codex-recap-cartouche {
  color: var(--cuj-primary);
  border-color: var(--cuj-primary);
  letter-spacing: 0.1em;
}
.codex-recap.codex-beyond > .codex-recap-body {
  border-left-color: var(--cuj-primary);
  box-shadow: inset 6px 0 8px -8px rgba(70, 80, 221, 0.22);
}

/* Spine / mobile TOC: an extension row is marked « au-delà », not « rappel » —
   the two registers must never borrow each other's word. */
.codex-spine-section.beyond > .codex-spine-section-head .codex-spine-title {
  color: var(--cuj-gray-600);
  font-style: italic;
}
.codex-spine-section.beyond > .codex-spine-section-head .codex-spine-title::after {
  content: " · au-del\00E0";
  font-size: 0.85em;
  letter-spacing: 0.05em;
}

/* ==========================================================================
   Le contrôle du chapitre — une FEUILLE, pas une carte.

   Le produit est crème, arrondi, et son indigo veut dire « s'entraîner ». Un
   contrôle n'est rien de tout cela : c'est un sujet imprimé, posé sur la table.
   D'où le blanc plus froid que la page, les angles droits, le filet d'un
   cheveu, et l'absence d'ombre portée — un document ne flotte pas.

   Le rouge est celui du stylo du professeur, et il ne sert qu'au BARÈME. La
   note, elle, s'affiche à l'encre : elle est attribuée par une IA, et le rouge
   lui prêterait une autorité qu'elle n'a pas.
   ========================================================================== */
.codex-eval {
  --eval-sheet: #FFFFFF;
  --eval-rule: #C9C6BE;
  --eval-points: #8A1C1C;
  --eval-quiet: #6B6660;

  background: var(--eval-sheet);
  border: 1px solid var(--eval-rule);
  border-radius: 0;
  box-shadow: none;
  padding: 1.75rem 1.5rem 1.25rem;
  margin: 3rem 0 1rem;
}
.codex-eval-title {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-2xl);
  line-height: 1.2;
  color: var(--cuj-ink);
  margin: 0 0 0.5rem;
}
.codex-eval-lede {
  font-size: var(--cuj-font-size-base);
  color: var(--cuj-gray-700);
  margin: 0 0 0.25rem;
  max-width: 62ch;
}
.codex-eval-promise {
  font-size: var(--cuj-font-size-sm);
  color: var(--eval-quiet);
  margin: 0.75rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--eval-rule);
  max-width: 62ch;
}

/* Les exercices. La LIGNE ENTIÈRE est le contrôle : pas de bouton bordé — le
   produit en a déjà un, en pastille indigo, et un carré d'encre à côté n'en était
   qu'une version moins bonne, sur une cible minuscule. Le numéro vient du ::marker
   de la liste ordonnée : l'écrire une seconde fois à la main donnait « 1. 1 » dès
   que la feuille de styles manquait. */
.codex-eval-list {
  list-style: decimal;
  margin: 1.25rem 0 0;
  padding: 0 0 0 1.9rem;
  border-top: 1px solid var(--eval-rule);
}
.codex-eval-list > li::marker {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-lg);
  color: var(--cuj-ink);
}
.codex-eval-row { border-bottom: 1px solid var(--eval-rule); }
.codex-eval-form { margin: 0; }
.codex-eval-open {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 0.75rem;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0.85rem 0.5rem 0.85rem 0.25rem;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.codex-eval-open:hover { background: #FBFAF7; }
.codex-eval-open:hover .codex-eval-name {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.codex-eval-open:focus-visible { outline: 2px solid var(--cuj-ink); outline-offset: -2px; }
.codex-eval-name {
  font-size: var(--cuj-font-size-md);
  color: var(--cuj-ink);
  min-width: 0;
}
/* « (4 points) » : la parenthèse et le rouge du sujet imprimé. Une fois corrigé,
   « 3 / 4 » à l'encre, sans parenthèse — la marge du professeur. Deux formes qu'un
   élève français distingue depuis le collège, sans qu'on ait à les étiqueter. */
.codex-eval-score {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-base);
  color: var(--eval-points);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.codex-eval-row.graded .codex-eval-score { color: var(--cuj-ink); }
.codex-eval-chevron {
  color: var(--eval-quiet);
  font-size: var(--cuj-font-size-lg);
  line-height: 1;
}
.codex-eval-open:hover .codex-eval-chevron { color: var(--cuj-ink); }
/* Le verbe de l'action n'est lu que par les lecteurs d'écran : à l'œil, c'est la
   ligne elle-même qui invite ; à l'oreille, il faut dire « Composer ». */
.codex-eval-action {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.codex-eval-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding-top: 0.9rem;
  font-size: var(--cuj-font-size-base);
  color: var(--eval-quiet);
}
.codex-eval-total {
  font-family: var(--cuj-font-display);
  color: var(--cuj-ink);
  font-variant-numeric: tabular-nums;
}
.codex-eval-origin {
  font-size: var(--cuj-font-size-xs);
  color: var(--eval-quiet);
  margin: 0.35rem 0 0;
}

/* L'entrée de navigation : pas de chiffre romain, puisque le contrôle n'est pas
   une étape de la progression — mais il reste atteignable sans tout dérouler. */
.codex-spine-eval > .codex-spine-section-head {
  border-top: 1px solid var(--eval-rule);
  margin-top: 0.5rem;
  padding-top: 0.6rem;
}
.codex-spine-eval .codex-spine-title { color: var(--cuj-ink); }

/* Téléphone : l'ordre de lecture devient rang+objet, puis ce que ça vaut, puis
   l'action — jamais trois colonnes qui se disputent 320 px. */
@media (max-width: 560px) {
  .codex-eval { padding: 1.25rem 1rem 1rem; }
  .codex-eval-list { padding-left: 1.5rem; }
  .codex-eval-open {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 0.35rem;
  }
  .codex-eval-name    { grid-column: 1; grid-row: 1; }
  .codex-eval-chevron { grid-column: 2; grid-row: 1; }
  .codex-eval-score   { grid-column: 1; grid-row: 2; }
}

/* ---- block.css ---- */
/* ==========================================================================
   Block / exercise flow — feedback banner, nav dots, submit bar, summary.
   Placeholder for Phase 2 redesign (matching mobile block screen).
   Currently empty — will be populated during Phase 2 implementation.
   ========================================================================== */

/* Phase 2 will add:
   - .feedback-banner (.good, .middle, .bad)
   - .exercise-nav-dots
   - .exercise-nav-dot (.current, .correct, .incorrect, .unanswered)
   - .submit-bar
   - .summary-screen
   - .explanation-card
   - .ai-feedback-card
*/

/* ---- calculators.css ---- */
/* ==========================================================================
   Calculators — numeric pad, fraction input, MathQuill, expression editor.
   Migrated from base.html inline <style>.
   ========================================================================== */

/* --- Calculator buttons (basic/fraction calculators) --- */
.button_calculator {
  width: 40px;
  height: 30px;
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
}

/* --- MathQuill field styling --- */
.math-input {
  border: 1px solid var(--cuj-gray-400);
  padding: 5px;
  display: inline-block;
  min-width: 160px;
  min-height: 40px;
  font-size: 20px;
}

.hidden-input { display: none; }

/* --- Fraction display --- */
.fraction-container {
  display: inline-block;
  text-align: center;
  vertical-align: middle;
}

.numerator, .denominator {
  display: block;
  text-align: center;
}

.fraction-line {
  display: block;
  border-top: 2px solid var(--cuj-gray-900);
  margin: 5px 0;
  width: 80%;
  margin-left: auto;
  margin-right: auto;
}

/* --- MathJax overline hack --- */
.overline-css {
  border-top: 1px solid black;
  display: inline-block;
  padding-top: 2px;
}

/* --- My table (for structured exercises) --- */
.my-table {
  width: 50%;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  border-collapse: collapse;
}

/* --------------------------------------------------------------------------
   On a phone (UX-10)

   Keys were 30 px high where a thumb needs 44 to 48, and an input under 16 px
   makes iOS zoom the whole page in when it is focused — and not out again.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  .table-bordered2 button,
  .button_calculator {
    min-height: 48px;
    min-width: 48px;
    font-size: 1.1rem;
  }

  .table-bordered2 input,
  .math-input,
  input[type="text"],
  input[type="number"],
  textarea {
    font-size: 16px;
  }
}

/* A field inside MathJax's math would inherit its glyph-less MJXZERO font (reset.css): Safari showed specks instead of the digits typed (UX-13). */
mjx-container input {
  font-family: var(--cuj-font-family);
}

/* ---- keypad.css ---- */
/* ==========================================================================
   The answer keypad (cours/keypad.py, js/keypad.js, js/keypad_rules.js; 2026-10-26)

   One panel at the bottom of the screen for every typed answer, in place of the keypad
   each field drew under itself and that pushed the page down. It covers the end of the
   page without moving it: while it is open the page keeps room for it below (--cuj-kp-h).
   A widget moved to it (<body data-keypad~="num">) hides its old keypad here: a setting
   switches it back, nothing in the exercise HTML cached for everyone changes.
   ========================================================================== */

/* --- The old keypads of the widgets moved to the panel -------------------------------- */

/* !important: the old keypad's JS shows its rows by an inline style (show_calculators in
   base.html), and the fragments carry an inline display:inline-table. */
/* The rows of keys; the field's own row, the first one, has no id. */
body[data-keypad~="num"] table[data-cuj-keypad="num"] tr[id] { display: none !important; }
/* A fraction's keypads are keys only, beside its boxes. */
body[data-keypad~="frac"] table[data-cuj-keypad="frac"] { display: none !important; }
/* The expression field's: its MathQuill box sits in the first row, without an id. */
body[data-keypad~="expr"] table[data-cuj-keypad="expr"] tr[id] { display: none !important; }
/* A formula's (CalInMath*.html): the formula, with its fields, in the first row. */
body[data-keypad~="inmath"] table[data-cuj-keypad="inmath"] tr[id] { display: none !important; }

/* The field's own frame was a table cell's border round the input's: one frame now. */
body[data-keypad~="num"] table[data-cuj-keypad="num"],
body[data-keypad~="num"] table[data-cuj-keypad="num"] th {
  border: 0;
  padding: 0;
  background: none;
}

/* --- The answer box, the same for every widget moved to the panel ---------------------- */

body[data-keypad~="num"] input[data-cuj-field^="num"],
body[data-keypad~="frac"] input[data-cuj-field^="frac"] {
  box-sizing: border-box;
  min-height: 44px;
  min-width: 4.5em;
  padding: 4px 10px;
  border: 1.5px solid var(--cuj-gray-600);
  border-radius: var(--cuj-radius-md);
  background: var(--cuj-white);
  color: var(--cuj-ink);
  font-family: var(--cuj-font-family);
  font-size: 1.2rem;                       /* above 16 px: iOS does not zoom on focus */
  line-height: 1.2;
  vertical-align: middle;
}
body[data-keypad~="frac"] input[data-cuj-field^="frac"] { min-width: 3.2em; }
body[data-keypad~="num"] input[data-cuj-field^="num"]:focus,
body[data-keypad~="frac"] input[data-cuj-field^="frac"]:focus,
input[data-cuj-active] {
  border-color: var(--cuj-primary);
  box-shadow: 0 0 0 4px rgba(70, 80, 221, 0.18);
}
/* A real ring for the keyboard (UX-13), which forced-colors mode keeps; the halo alone it drops. */
body[data-keypad~="num"] input[data-cuj-field^="num"]:focus-visible,
body[data-keypad~="frac"] input[data-cuj-field^="frac"]:focus-visible {
  outline: 2px solid var(--cuj-primary-dark);
  outline-offset: 2px;
}

/* A field inside a formula: the input MathJax makes (base.html's \input), the same frame; its
   size stays the macro's, its font calculators.css's (mjx-container input, UX-13). */
body[data-keypad~="inmath"] mjx-container input[data-cuj-field^="inmath"] {
  box-sizing: border-box;
  padding: 0 4px;
  border: 1.5px solid var(--cuj-gray-600);
  border-radius: var(--cuj-radius-sm);
  background: var(--cuj-white);
  color: var(--cuj-ink);
  text-align: center;
}
body[data-keypad~="inmath"] mjx-container input[data-cuj-field^="inmath"]:focus,
body[data-keypad~="inmath"] mjx-container input[data-cuj-field^="inmath"][data-cuj-active] {
  border-color: var(--cuj-primary);
  box-shadow: 0 0 0 3px rgba(70, 80, 221, 0.18);
}
body[data-keypad~="inmath"] mjx-container input[data-cuj-field^="inmath"]:focus-visible {
  outline: 2px solid var(--cuj-primary-dark);
  outline-offset: 1px;
}

/* The expression field: MathQuill's box, the same frame. MathQuill keeps the focus on a
   hidden textarea and marks its box .mq-focused: the ring goes there. */
body[data-keypad~="expr"] [data-cuj-field="expr"] {
  box-sizing: border-box;
  min-height: 48px;
  min-width: 9em;
  padding: 4px 10px;
  border: 1.5px solid var(--cuj-gray-600);
  border-radius: var(--cuj-radius-md);
  background: var(--cuj-white);
  font-size: 1.35rem;
  vertical-align: middle;
}
body[data-keypad~="expr"] [data-cuj-field="expr"].mq-focused,
body[data-keypad~="expr"] [data-cuj-field="expr"][data-cuj-active] {
  border-color: var(--cuj-primary);
  box-shadow: 0 0 0 4px rgba(70, 80, 221, 0.18);
}
body[data-keypad~="expr"] [data-cuj-field="expr"].mq-focused {
  outline: 2px solid var(--cuj-primary-dark);
  outline-offset: 2px;
}

/* --- The panel ------------------------------------------------------------------------- */

body.cuj-kp-open { padding-bottom: var(--cuj-kp-h, 0px); }

.cuj-kp {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1040;                           /* above the navbar (1030), below the lesson drawer (1050) and the slate (2000) */
  box-sizing: border-box;
  max-width: 720px;
  margin: 0 auto;
  padding: 0 8px calc(8px + env(safe-area-inset-bottom));
  background: var(--cuj-paper-shade);
  border: 1px solid var(--cuj-gray-300);
  border-bottom: 0;
  border-radius: var(--cuj-radius-xl) var(--cuj-radius-xl) 0 0;
  box-shadow: 0 -10px 28px rgba(26, 26, 26, 0.10);
  font-family: var(--cuj-font-family);
  color: var(--cuj-ink);
  animation: cuj-kp-in 0.18s ease-out;
}
.cuj-kp[hidden] { display: none; }

@keyframes cuj-kp-in {
  from { transform: translateY(24px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .cuj-kp { animation: none; }
}

.cuj-kp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
  padding: 2px 0 2px 6px;
}
.cuj-kp-title {
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  color: var(--cuj-gray-700);
}
.cuj-kp-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--cuj-ink);
  cursor: pointer;
}

.cuj-kp-grid {
  display: grid;
  grid-template-columns: repeat(var(--cuj-kp-cols, 4), minmax(0, 1fr));
  gap: 6px;
}
.cuj-kp-key {
  height: 56px;
  padding: 0;
  border: 1px solid var(--cuj-gray-300);
  border-radius: var(--cuj-radius-md);
  background: var(--cuj-white);
  box-shadow: 0 1px 0 var(--cuj-gray-400);
  color: var(--cuj-ink);
  font: 600 1.5rem/1 var(--cuj-font-family);
  cursor: pointer;
  touch-action: manipulation;              /* no double-tap zoom on a fast thumb */
  -webkit-tap-highlight-color: transparent; /* the key's own :active look instead of a blue flash */
  -webkit-user-select: none;
  user-select: none;
}
.cuj-kp-key:active { transform: translateY(1px); box-shadow: none; background: var(--cuj-gray-100); }
.cuj-kp-key.is-op { color: var(--cuj-primary-dark); font-weight: 400; font-size: 1.7rem; }
.cuj-kp-key.is-act,
.cuj-kp-key.is-word { background: var(--cuj-gray-200); }
.cuj-kp-key.is-word { font-size: 1rem; line-height: 1.15; }    /* « Dénominateur ↓ »: a word, not a sign */
/* The expression field's: the letters and the maths, tinted, as in the textbook. */
.cuj-kp-key.is-var,
.cuj-kp-key.is-math,
.cuj-kp-key.is-fn {
  background: var(--cuj-primary-bg);
  border-color: #d3d8fa;
  color: var(--cuj-primary-dark);
}
.cuj-kp-key.is-var { font-family: var(--cuj-font-display); font-style: italic; font-weight: 500; }
.cuj-kp-key.is-fn { font-family: var(--cuj-font-display); font-weight: 500; font-size: 1.05rem; }
.cuj-kp-grid.is-dense .cuj-kp-key { height: 48px; font-size: 1.3rem; }
.cuj-kp-grid.is-dense .cuj-kp-key.is-fn,
.cuj-kp-grid.is-dense .cuj-kp-key.is-word { font-size: 0.95rem; }
.cuj-kp-frac {                                   /* the fraction key: two boxes and a bar */
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.cuj-kp-frac i { width: 10px; height: 10px; border: 1.6px solid currentColor; border-radius: 2px; }
.cuj-kp-frac b { width: 18px; height: 1.8px; background: currentColor; }

.cuj-kp-tabs { display: flex; gap: 6px; }
.cuj-kp-tab {
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: var(--cuj-radius-pill);
  background: transparent;
  color: var(--cuj-gray-700);
  font: 600 0.95rem var(--cuj-font-family);
  cursor: pointer;
}
.cuj-kp-tab[aria-pressed="true"] {
  background: var(--cuj-white);
  border-color: var(--cuj-gray-300);
  color: var(--cuj-ink);
}
.cuj-kp-tab:focus-visible { outline: 3px solid var(--cuj-primary-dark); outline-offset: 2px; }

.cuj-kp-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px 2px;
}
.cuj-kp-skip {
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  background: transparent;
  color: var(--cuj-primary);
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-size: 1rem;
  cursor: pointer;
}
.cuj-kp-main {
  margin-left: auto;
  min-height: 48px;
  padding: 0 26px;
  border: 0;
  border-radius: var(--cuj-radius-pill);
  background: var(--cuj-primary);
  color: var(--cuj-white);
  font-family: var(--cuj-font-display);
  font-weight: 600;
  font-size: 1.1rem;
  cursor: pointer;
}
.cuj-kp-main:hover { background: var(--cuj-primary-dark); }
.cuj-kp-close:focus-visible,
.cuj-kp-key:focus-visible,
.cuj-kp-skip:focus-visible,
.cuj-kp-main:focus-visible {
  outline: 3px solid var(--cuj-primary-dark);
  outline-offset: 2px;
}

/* A phone held sideways: smaller keys, so that the field keeps some of the screen. */
@media (max-height: 520px) {
  .cuj-kp-head { min-height: 36px; }
  .cuj-kp-close { width: 36px; height: 36px; }
  .cuj-kp-key,
  .cuj-kp-grid.is-dense .cuj-kp-key { height: 36px; font-size: 1.15rem; }
  .cuj-kp-foot { padding-top: 6px; }
  .cuj-kp-main,
  .cuj-kp-skip { min-height: 40px; }
}

/* « Clavier ouvert », for a screen reader only: the panel sits at the end of the page. */
.cuj-kp-status {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- practice.css ---- */
/* ==========================================================================
   Practice (Compétence) panel — the /block/ screen.
   Focused single-exercise flow with progress strip, lesson drawer, and
   Flow A/B nudge. Shares the Codex paper aesthetic.
   ========================================================================== */

.practice-page {
  background: var(--cuj-paper);
  min-height: calc(100vh - var(--cuj-navbar-height));
  padding: var(--cuj-space-5) var(--cuj-space-4) var(--cuj-space-8);
  max-width: 860px;
  margin: 0 auto;
  color: var(--cuj-gray-800);
  font-size: calc(var(--cuj-font-size-md) * var(--cuj-reading-scale));
  line-height: calc(var(--cuj-line-height) * var(--cuj-reading-scale));
}

/* --- Breadcrumb bar --- */
.practice-breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cuj-space-2);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-600);
  margin-bottom: var(--cuj-space-5);
  padding-bottom: var(--cuj-space-3);
  border-bottom: 1px solid var(--cuj-gray-200);
}
.practice-breadcrumb-back {
  color: var(--cuj-gray-700);
  text-decoration: none;
  font-weight: 600;
}
.practice-breadcrumb-back:hover {
  text-decoration: underline;
  color: var(--cuj-primary);
}
.practice-breadcrumb-sep { color: var(--cuj-gray-400); }
.practice-breadcrumb-chapter { color: var(--cuj-gray-700); }
.practice-breadcrumb-skill { color: var(--cuj-ink); font-weight: 600; }

/* --- Flow B nudge card — quiet editorial treatment:
   paperShade bg + 1px gray rail. Inner primary-colored icon + italic link
   carry the semantic signal without a loud wash. */
.practice-nudge {
  display: flex;
  align-items: flex-start;
  gap: var(--cuj-space-3);
  padding: var(--cuj-space-4);
  margin-bottom: var(--cuj-space-5);
  background: var(--cuj-paper-shade);
  border-left: 1px solid var(--cuj-gray-300);
  border-radius: var(--cuj-radius-md);
}
.practice-nudge-icon {
  font-size: 28px;
  line-height: 1;
  flex: none;
  color: var(--cuj-primary);
}
.practice-nudge-body { flex: 1; min-width: 0; }
.practice-nudge-title {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-lg);
  font-weight: 600;
  color: var(--cuj-ink);
  margin-bottom: var(--cuj-space-1);
}
.practice-nudge-text {
  margin: 0 0 var(--cuj-space-3);
  color: var(--cuj-gray-700);
}
.practice-nudge-cta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0.5rem 1.125rem;
  background: transparent;
  color: var(--cuj-primary);
  border: 1.5px solid var(--cuj-primary);
  border-radius: var(--cuj-radius-pill, 999px);
  text-decoration: none;
  font-weight: 600;
  font-size: var(--cuj-font-size-sm);
  margin-right: var(--cuj-space-3);
}
.practice-nudge-cta:hover {
  background: rgba(70, 80, 221, 0.08);
  color: var(--cuj-primary);
  text-decoration: none;
}
.practice-nudge-dismiss {
  background: none;
  border: none;
  color: var(--cuj-gray-700);
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
  padding: 0;
}
.practice-nudge-dismiss:hover { color: var(--cuj-primary); text-decoration: underline; }

/* --- Skill title --- */
.practice-title {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-3xl);
  line-height: 1.15;
  color: var(--cuj-ink);
  margin: 0 0 var(--cuj-space-5);
}

/* --- Progress strip --- */
.practice-progress {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cuj-space-3);
  margin-bottom: var(--cuj-space-5);
  padding: var(--cuj-space-3) 0;
  border-top: 1px solid var(--cuj-gray-200);
  border-bottom: 1px solid var(--cuj-gray-200);
}
.practice-progress-label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-700);
  font-weight: 600;
}
.practice-progress-dots {
  display: flex;
  gap: var(--cuj-space-2);
  flex: 1;
  flex-wrap: wrap;
}
.practice-progress-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--cuj-paper);
  border: 2px solid var(--cuj-gray-300);
  color: var(--cuj-gray-600);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  cursor: pointer;
  transition: all var(--cuj-transition-fast);
  padding: 0;
}
.practice-progress-dot:hover {
  transform: scale(1.1);
  border-color: var(--cuj-primary);
}
/* Mastery state drives the dot's background + number color. */
.practice-progress-dot.good    { background: var(--cuj-score-good);   border-color: var(--cuj-score-good);   color: var(--cuj-white); }
.practice-progress-dot.middle  { background: var(--cuj-score-middle); border-color: var(--cuj-score-middle); color: var(--cuj-white); }
.practice-progress-dot.bad     { background: var(--cuj-score-bad);    border-color: var(--cuj-score-bad);    color: var(--cuj-white); }
/* Not-yet-attempted — defensive fallback for missing class. */
.practice-progress-dot.notdone,
.practice-progress-dot:not(.good):not(.middle):not(.bad) {
  background: var(--cuj-paper);
  border-color: var(--cuj-gray-300);
  color: var(--cuj-gray-700);
}

/* "Current" is an ADDITIVE state — it only swaps the border to primary +
   adds a subtle halo, leaving the mastery fill intact. A dot the student
   just succeeded on (.good) + is currently showing (.current) reads as:
   green fill (success) + blue border (you're here). Both signals stack. */
.practice-progress-dot.current {
  border-color: var(--cuj-primary);
  box-shadow: 0 0 0 3px rgba(70, 80, 221, 0.15);
}
/* When the current dot is also "not done", the number would be gray-700
   on paper — fine, but we bump it to primary so the halo + number color
   agree visually. */
.practice-progress-dot.current.notdone,
.practice-progress-dot.current:not(.good):not(.middle):not(.bad) {
  color: var(--cuj-primary);
}
.practice-progress-count {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-gray-700);
  font-variant-numeric: tabular-nums;
}

/* --- Exercise carousel (only .current visible) --- */
.practice-carousel {
  position: relative;
  margin-bottom: var(--cuj-space-5);
}
.practice-exercise {
  display: none;
  padding: var(--cuj-space-4) 0;
}
.practice-exercise.current { display: block; }

.practice-exercise-label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-700);
  font-weight: 600;
  margin-bottom: var(--cuj-space-3);
}
/* --- Verdict banner (post-submission) --- */
.practice-verdict {
  display: inline-block;
  padding: var(--cuj-space-2) var(--cuj-space-3);
  border-radius: var(--cuj-radius-sm);
  font-weight: 600;
  margin-bottom: var(--cuj-space-3);
}
.practice-verdict.good    { background: var(--cuj-success-bg); color: #166534; }
.practice-verdict.middle  { background: var(--cuj-warning-bg, #fff4e5); color: #92400e; }
.practice-verdict.bad     { background: var(--cuj-danger-bg);  color: #991b1b; }
.practice-verdict.score   { background: var(--cuj-primary-bg); color: var(--cuj-primary-dark); }

/* --- Exercise form / actions --- */
.practice-exercise-form { margin: 0; }

.practice-actions {
  display: flex;
  align-items: center;
  gap: var(--cuj-space-3);
  flex-wrap: wrap;
  margin-top: var(--cuj-space-4);
  padding-top: var(--cuj-space-3);
  border-top: 1px solid var(--cuj-gray-200);
}
.practice-submit {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  padding: 0.55rem 1.5rem;
  background: transparent;
  color: var(--cuj-primary);
  border: 1.5px solid var(--cuj-primary);
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-weight: 600;
  font-size: var(--cuj-font-size-base);
  cursor: pointer;
  transition: background var(--cuj-transition-fast), transform var(--cuj-transition-fast);
}
.practice-submit:hover {
  background: rgba(70, 80, 221, 0.08);
  color: var(--cuj-primary);
}
.practice-arrow { transition: transform var(--cuj-transition-fast); }
.practice-submit:hover .practice-arrow { transform: translateX(2px); }

.practice-action-link {
  background: none;
  border: none;
  color: var(--cuj-primary);
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-weight: 500;
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
  text-decoration: none;
  padding: 0;
}
.practice-action-link:hover { text-decoration: underline; color: var(--cuj-primary-dark); }

/* --- Prev/Next bottom nav --- */
.practice-nav {
  display: flex;
  justify-content: space-between;
  gap: var(--cuj-space-3);
  margin-top: var(--cuj-space-5);
  padding-top: var(--cuj-space-4);
  border-top: 1px solid var(--cuj-gray-200);
}
.practice-nav-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-1);
  padding: 0.5rem 1rem;
  background: transparent;
  border: 1px solid var(--cuj-gray-400);
  border-radius: var(--cuj-radius-pill, 999px);
  color: var(--cuj-gray-800);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  font-weight: 500;
  cursor: pointer;
  transition: all var(--cuj-transition-fast);
}
.practice-nav-btn:hover {
  border-color: var(--cuj-primary);
  color: var(--cuj-primary);
}
.practice-nav-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* --- Lesson drawer (right side-sheet on desktop, bottom sheet on mobile) --- */
.practice-lesson-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 520px;
  max-width: 90vw;
  background: var(--cuj-paper);
  border-left: 1px solid var(--cuj-gray-200);
  box-shadow: -4px 0 24px rgba(0, 0, 0, 0.08);
  z-index: 1051;
  transform: translateX(100%);
  transition: transform 0.25s cubic-bezier(0.32, 0.72, 0, 1);
  display: flex;
  flex-direction: column;
}
.practice-lesson-drawer.open { transform: translateX(0); }

.practice-lesson-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--cuj-space-3) var(--cuj-space-4);
  border-bottom: 1px solid var(--cuj-gray-200);
  background: var(--cuj-paper-shade);
}
.practice-lesson-drawer-title {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-700);
  font-weight: 600;
}
.practice-lesson-drawer-close {
  background: none;
  border: none;
  font-size: 24px;
  color: var(--cuj-gray-700);
  cursor: pointer;
  line-height: 1;
  padding: 0 var(--cuj-space-2);
}
.practice-lesson-drawer-close:hover { color: var(--cuj-ink); }

.practice-lesson-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--cuj-space-4);
}

.practice-lesson-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  z-index: 1050;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.practice-lesson-drawer-backdrop.open {
  opacity: 1;
  pointer-events: auto;
}

@media (max-width: 640px) {
  .practice-lesson-drawer {
    top: auto;
    right: 0;
    left: 0;
    bottom: 0;
    width: 100%;
    max-width: 100%;
    height: 85vh;
    border-left: none;
    border-top: 1px solid var(--cuj-gray-200);
    border-radius: var(--cuj-radius-lg, 12px) var(--cuj-radius-lg, 12px) 0 0;
    transform: translateY(100%);
  }
  .practice-lesson-drawer.open { transform: translateY(0); }
}

/* --- The unit is finished: the verdict on the competence (the chapter page's rule), in the
   row under the answer just corrected, where « Exercice suivant » was — or above the
   exercises when the pupil comes back to a finished unit (founder, 2026-10-25: pinned to
   the bottom of the screen, it came after the whole correction). --- */
.practice-complete {
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  gap: var(--cuj-space-2) var(--cuj-space-3);
  padding: var(--cuj-space-3) var(--cuj-space-4);
  background: var(--cuj-success-bg);
  border-left: 3px solid var(--cuj-score-good);
  border-radius: var(--cuj-radius-md);
}
.practice-complete.is-partial {
  background: var(--cuj-paper);
  border-left-color: var(--cuj-primary);
}
.practice-complete-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--cuj-score-good);
  color: var(--cuj-white);
  font-size: 18px;
  line-height: 1;
}
.practice-complete-title {
  flex: 1 1 auto;
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-lg);
  font-weight: 600;
  color: #166534;
}
.practice-complete.is-partial .practice-complete-title { color: var(--cuj-ink); }

/* --------------------------------------------------------------------------
   Once the exercise is corrected (UX-6)

   Every clickable thing — the submit button, "Passer", "Révéler la leçon" — was
   rendered in the unanswered branch only, so a corrected exercise ended in a dead
   end: the pupil had to find the carousel arrows at the bottom of the page.
   -------------------------------------------------------------------------- */

.practice-after {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 18px 0 6px;
}

.practice-after-next {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 20px;
  min-height: 44px;                       /* a thumb, not a mouse (UX-10) */
  border: 0;
  border-radius: 999px;
  background: var(--cuj-primary, #1d4ed8);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}

.practice-after-next:hover { filter: brightness(1.08); }
a.practice-after-next, a.practice-after-next:hover { color: #fff; text-decoration: none; }  /* « Retour au chapitre » */
.practice-after-retry { margin: 0; }

/* Waiting for the correction: AI grading of a photo takes 10 to 60 s, and silence
   is what made pupils tap a second time — at 10 jetons a tap. */
.practice-spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  vertical-align: -2px;
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-top-color: #fff;
  border-radius: 50%;
  animation: practice-spin 0.7s linear infinite;
}

@keyframes practice-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .practice-spinner { animation-duration: 2.4s; }
}

.practice-submit[disabled], .quiz-submit[disabled] { opacity: 0.72; cursor: progress; }

/* Not enough jetons — said here, so the answer stays where it was typed. */
.practice-jetons-note {
  margin: 12px 0;
  padding: 10px 14px;
  border-left: 3px solid #d97706;
  background: #fffbeb;
  border-radius: 4px;
  color: #7c2d12;
}

.practice-jetons-note a { color: #7c2d12; font-weight: 600; }

/* The grader's note on an ordinary answer (an answer we could not read said only
   « Faux » before). */
.cuj-answer-note { margin: 6px 0; text-align: left; }

/* A written answer the server refused (unreadable, or more than four pages): said above
   the exercise, which is shown again, ready for another try (spec §5.5). */
.cuj-upload-refused {
  margin: var(--cuj-space-2) 0 var(--cuj-space-3);
  padding: var(--cuj-space-2) var(--cuj-space-3);
  border-left: 3px solid var(--cuj-danger);
  background: rgba(220, 53, 69, 0.06);
  color: var(--cuj-ink);
  font-weight: 600;
}

/* The slate (« ardoise »): the full-screen frame practice.js opens over the exercise. */
.cuj-slate-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: var(--cuj-paper);
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
.cuj-slate-frame { display: block; width: 100%; height: 100%; border: 0; }

/* Until the slate says it listens: a ring above the frame (the fixed overlay is its
   positioning context), gone once it is ready; the overlay closes with a note after 20 s. */
.cuj-slate-loading {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.cuj-slate-loading::before {
  content: "";
  box-sizing: border-box;
  width: 44px;
  height: 44px;
  border: 4px solid var(--cuj-gray-300);
  border-top-color: var(--cuj-primary);
  border-radius: 50%;
  animation: cuj-slate-spin 0.9s linear infinite;
}

@keyframes cuj-slate-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .cuj-slate-loading::before { animation: none; }          /* the ring stays, still */
}

/* The pages of a written answer on the correction page (MetaTextHtmlFeedBackUser). */
figure.written-page { display: inline-block; max-width: 100%; margin: var(--cuj-space-2); vertical-align: top; }
figure.written-page img {
  max-width: 100%;
  height: auto;
  border: 1px solid var(--cuj-gray-300);
  border-radius: var(--cuj-radius-md);
}
figure.written-page figcaption { text-align: center; font-size: var(--cuj-font-size-sm); color: var(--cuj-gray-600); }

/* --- One copy for a part of a paper devoir (cours/unit_copy.py) ----------------
   The same sheet as the chapter's « Contrôle » (codex.css, .codex-eval): white, square,
   ruled, the points in the corrector's red. The one figure of its own: each page sent is
   a small exam sheet, red margin line and folio, in the order it will be read. */
.cuj-copy-unit {
  --copy-sheet: #FFFFFF;
  --copy-rule: #C9C6BE;
  --copy-points: #8A1C1C;
  --copy-quiet: #6B6660;
  --copy-margin: #D9534F;
}
.cuj-copy-exercise { margin: var(--cuj-space-6) 0; }
.cuj-copy-exercise ol ol { list-style-type: lower-alpha; }       /* 3.b, as on the paper devoir */
.cuj-copy-exercise ol ol ol { list-style-type: lower-roman; }
.cuj-copy-exercise-title { font-family: var(--cuj-font-display); font-size: var(--cuj-font-size-xl); }

.cuj-copy,
.cuj-copy-result {
  background: var(--copy-sheet);
  border: 1px solid var(--copy-rule);
  border-radius: 0;
  padding: 1.5rem 1.5rem 1.25rem;
  margin: 2.5rem 0 1rem;
}
.cuj-copy-title { font-family: var(--cuj-font-display); font-size: var(--cuj-font-size-2xl); margin: 0 0 var(--cuj-space-2); }
.cuj-copy-lede, .cuj-copy-replaces, .cuj-copy-by { color: var(--copy-quiet); margin: 0 0 var(--cuj-space-3); }
.cuj-copy-replaces { color: var(--copy-points); }

.cuj-copy-pages {
  list-style: none;
  padding: 0;
  margin: var(--cuj-space-4) 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: var(--cuj-space-4);
}
.cuj-copy-page { display: flex; flex-direction: column; gap: var(--cuj-space-2); }
.cuj-copy-sheet {
  position: relative;
  aspect-ratio: 3 / 4;
  background: var(--copy-sheet);
  border: 1px solid var(--copy-rule);
  overflow: hidden;
}
.cuj-copy-sheet::before {                                         /* the red margin of a French copy */
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 14%;
  border-left: 1px solid var(--copy-margin);
  opacity: 0.55;
  z-index: 1;
}
.cuj-copy-sheet img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cuj-copy-folio {
  position: absolute;
  right: 0.35rem; bottom: 0.25rem;
  z-index: 2;
  background: var(--copy-sheet);
  padding: 0 0.3rem;
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
}
.cuj-copy-tools { display: flex; gap: var(--cuj-space-1); justify-content: center; }
.cuj-copy-tools button {
  min-width: 2.25rem; min-height: 2.25rem;
  border: 1px solid var(--copy-rule);
  background: var(--copy-sheet);
  border-radius: var(--cuj-radius-sm);
  cursor: pointer;
}
.cuj-copy-tools button:disabled { opacity: 0.35; cursor: default; }
.cuj-copy-tools button:focus-visible,
.cuj-copy-btn:focus-visible { outline: 2px solid var(--cuj-primary); outline-offset: 2px; }
.cuj-copy-btn:has(input:focus-visible) { outline: 2px solid var(--cuj-primary); outline-offset: 2px; }

.cuj-copy-add { display: flex; flex-wrap: wrap; gap: var(--cuj-space-3); margin: var(--cuj-space-3) 0; }
.cuj-copy-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem;
  padding: 0 1.1rem;
  border: 1px solid var(--cuj-primary);
  border-radius: var(--cuj-radius-pill);
  background: var(--cuj-primary);
  color: #fff;
  font: inherit;
  cursor: pointer;
}
.cuj-copy-btn--ghost { background: var(--copy-sheet); color: var(--cuj-primary); }
.cuj-copy-btn[hidden] { display: none; }
.cuj-copy-native {                                                /* the gallery input, reached through its label */
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.cuj-copy-fallback { display: block; margin: var(--cuj-space-3) 0; }
.cuj-copy-fallback[hidden] { display: none; }
.cuj-copy-status { color: var(--copy-quiet); margin: 0 0 var(--cuj-space-2); min-height: 1em; }
.cuj-copy-error { color: var(--cuj-danger); margin: var(--cuj-space-2) 0; }
.cuj-copy-error[hidden] { display: none; }

.cuj-copy-cam {
  position: fixed; inset: 0; z-index: 1050;
  display: flex; align-items: center; justify-content: center;
  background: rgba(20, 20, 20, 0.72);
  padding: var(--cuj-space-4);
}
.cuj-copy-cam[hidden] { display: none; }
.cuj-copy-cam-card { background: var(--copy-sheet); padding: var(--cuj-space-4); max-width: 34rem; width: 100%; }
.cuj-copy-cam-title { font-family: var(--cuj-font-display); font-size: var(--cuj-font-size-xl); margin: 0 0 var(--cuj-space-3); }
.cuj-copy-cam-stage video,
.cuj-copy-cam-stage canvas { width: 100%; max-height: 60vh; object-fit: contain; background: #000; display: block; }
.cuj-copy-cam-buttons { display: flex; flex-wrap: wrap; gap: var(--cuj-space-2); margin-top: var(--cuj-space-3); }

.cuj-copy-total { font-size: var(--cuj-font-size-lg); margin: 0 0 var(--cuj-space-3); }
.cuj-copy-total strong { color: var(--copy-points); font-family: var(--cuj-font-display); }
.cuj-copy-overall { margin: 0 0 var(--cuj-space-4); }
.cuj-copy-sent { margin: 0 0 var(--cuj-space-4); }
.cuj-copy-marks { width: 100%; border-collapse: collapse; margin: 0 0 var(--cuj-space-3); }
.cuj-copy-marks th,
.cuj-copy-marks td { text-align: left; vertical-align: top; padding: 0.6rem 0.5rem; border-top: 1px solid var(--copy-rule); }
.cuj-copy-marks thead th { border-top: 0; color: var(--copy-quiet); font-weight: 600; }
.cuj-copy-marks tbody th { font-family: var(--cuj-font-display); white-space: nowrap; }
.cuj-copy-points { color: var(--copy-points); font-family: var(--cuj-font-display); white-space: nowrap; }
.cuj-copy-again { margin: var(--cuj-space-4) 0; }
.cuj-copy-back { margin: 0 0 var(--cuj-space-6); }

@media (max-width: 576px) {
  .cuj-copy, .cuj-copy-result { padding: 1.25rem 1rem 1rem; }
  .cuj-copy-marks thead { display: none; }
  .cuj-copy-marks tr { display: grid; grid-template-columns: auto 1fr; border-top: 1px solid var(--copy-rule); }
  .cuj-copy-marks th, .cuj-copy-marks td { border-top: 0; }
  .cuj-copy-marks td:last-child { grid-column: 1 / -1; }
}

/* ---- home.css ---- */
/* ==========================================================================
   Homepage — authenticated dashboard (.home-auth) and anonymous browse
   (.home-anon). Shares the Codex paper aesthetic.
   ========================================================================== */

.home-page {
  background: var(--cuj-paper);
  min-height: calc(100vh - var(--cuj-navbar-height));
  padding: var(--cuj-space-5) 0 var(--cuj-space-8);
  color: var(--cuj-gray-800);
  font-size: calc(var(--cuj-font-size-md) * var(--cuj-reading-scale));
  line-height: calc(var(--cuj-line-height) * var(--cuj-reading-scale));
}

.home-page > * { padding-left: var(--cuj-space-4); padding-right: var(--cuj-space-4); max-width: 1400px; margin-left: auto; margin-right: auto; box-sizing: border-box; }
.home-page > .home-signup-bar {
  max-width: 100%;
  margin: 0;
  /* keep its own internal padding — only widen it to edge-to-edge */
}
/* When the sign-up bar is the first child, pull it flush against the navbar
   above (cancels the .home-page top padding). */
.home-page > .home-signup-bar:first-child {
  margin-top: calc(-1 * var(--cuj-space-5));
}

/* ==========================================================================
   AUTHENTICATED DASHBOARD
   ========================================================================== */

/* --- Hero "Current chapter" — editorial card, parity with the mobile app.
   Whole card is a single anchor. Cover on the left with paperShade backdrop,
   title on the right, subtle chevron at the far right. The 3px primary rail
   is the only "this is important" signal. */
.home-hero {
  display: grid;
  grid-template-columns: 220px 1fr auto;
  gap: 0;
  align-items: stretch;
  margin-bottom: var(--cuj-space-6);
  background: var(--cuj-paper);
  border: 1px solid var(--cuj-gray-200);
  border-left: 3px solid var(--cuj-primary);
  border-radius: var(--cuj-radius-md);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: border-color var(--cuj-transition-fast);
}
.home-hero:hover {
  border-color: var(--cuj-gray-300);
  border-left-color: var(--cuj-primary);
  text-decoration: none;
  color: inherit;
}
/* The class the pupil chose, under the hero: « Sixième · Éducation nationale · Changer ». */
.home-class-line {
  margin: calc(-1 * var(--cuj-space-4)) 0 var(--cuj-space-6);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-gray-600);
  text-align: right;
}
.home-class-line a { color: var(--cuj-primary); }
.home-hero-cover-wrap {
  background: var(--cuj-paper-shade);
  padding: var(--cuj-space-3);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 140px;
}
.home-hero-cover {
  max-width: 100%;
  max-height: 140px;
  object-fit: contain;
}
.home-hero-body {
  padding: var(--cuj-space-5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.home-hero-label {
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-primary);
  margin: 0 0 var(--cuj-space-2);
}
.home-hero-title {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-3xl);
  font-weight: 500;
  line-height: 1.15;
  color: var(--cuj-ink);
  margin: 0;
}
.home-hero-chevron {
  display: flex;
  align-items: center;
  padding: 0 var(--cuj-space-4);
  color: var(--cuj-gray-400);
  font-size: var(--cuj-font-size-xl);
  transition: transform var(--cuj-transition-fast), color var(--cuj-transition-fast);
}
.home-hero:hover .home-hero-chevron {
  transform: translateX(3px);
  color: var(--cuj-primary);
}

/* --- Row generic (Recommandé / Révision / Grade anon) --- */
.home-row, .home-grade-row {
  margin-bottom: var(--cuj-space-6);
}
.home-row-label, .home-section-heading {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-700);
  font-weight: 600;
  margin: 0 0 var(--cuj-space-3);
}
.home-row-count {
  font-weight: 400;
  color: var(--cuj-gray-500);
  text-transform: none;
  letter-spacing: 0;
}
.home-row-scroll {
  display: flex;
  gap: var(--cuj-space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--cuj-space-2);
  scrollbar-width: thin;
  scrollbar-color: var(--cuj-gray-300) transparent;
}
.home-row-scroll > * { scroll-snap-align: start; flex: none; }

/* --- Skill card (in Recommandé / Révision rows) ---
   Native <button> element: kill UA appearance so our styles reliably apply. */
.home-skill-form { margin: 0; flex: none; }
.home-skill-card {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: inherit;
  display: flex;
  flex-direction: column;
  width: 200px;
  /* no fixed min-height — let the card size to its content so meta sits
     right under the title, no empty gap for short skill titles */
  text-align: left;
  background: var(--cuj-white) !important;
  border: 1px solid var(--cuj-gray-200);
  border-radius: var(--cuj-radius-md);
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  transition: transform var(--cuj-transition-fast), box-shadow var(--cuj-transition-fast), border-color var(--cuj-transition-fast);
}
.home-skill-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
  border-color: var(--cuj-primary);
}
.home-skill-cover {
  width: 100%;
  height: 120px;
  background-color: var(--cuj-paper-shade);
  background-position: center;
  background-size: contain;         /* keep full logo visible, don't crop */
  background-repeat: no-repeat;
  border-bottom: 1px solid var(--cuj-gray-200);
  flex: none;
}
.home-skill-cover.placeholder { background-color: var(--cuj-paper-shade); }

.home-skill-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 10px 10px;
  flex: 1;
  min-width: 0;
  background: var(--cuj-white);
  color: var(--cuj-ink);
}
.home-skill-chapter {
  font-family: var(--cuj-font-display);
  font-size: 11px;
  color: var(--cuj-gray-600);
  font-style: italic;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.2;
}
.home-skill-title {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-family: var(--cuj-font-display);
  font-weight: 600;
  color: var(--cuj-ink);
  line-height: 1.25;
  font-size: 13px;
  overflow: hidden;
}
.home-skill-title > span:last-child {
  flex: 1;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.home-skill-dot {
  flex: none;
  margin-top: 5px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cuj-paper);
  border: 1.5px solid var(--cuj-gray-400);
}
.home-skill-card.good   .home-skill-dot { background: var(--cuj-score-good);   border-color: var(--cuj-score-good); }
.home-skill-card.middle .home-skill-dot { background: var(--cuj-score-middle); border-color: var(--cuj-score-middle); }
.home-skill-card.bad    .home-skill-dot { background: var(--cuj-score-bad);    border-color: var(--cuj-score-bad); }
.home-skill-card.quiz   .home-skill-dot { background: var(--cuj-primary);      border-color: var(--cuj-primary); border-radius: 2px; transform: rotate(45deg); }
.home-skill-meta {
  padding-top: 4px;
  font-size: 11px;
  color: var(--cuj-gray-700);
  line-height: 1.2;
}
.home-skill-cta {
  color: var(--cuj-primary);
  font-weight: 600;
}
.home-skill-empty {
  padding: var(--cuj-space-3) var(--cuj-space-4);
  color: var(--cuj-gray-600);
  font-style: italic;
  background: var(--cuj-paper-shade);
  border-radius: var(--cuj-radius-sm);
  width: 100%;
}

/* --- Chapter grid (authenticated) --- */
.home-chapter-grid { margin-bottom: var(--cuj-space-6); }
.home-chapter-grid-inner {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--cuj-space-4);
}

.home-chapter-card {
  position: relative;
  display: block;
  background: var(--cuj-white);
  border: 1px solid var(--cuj-gray-200);
  border-radius: var(--cuj-radius-md);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform var(--cuj-transition-fast), box-shadow var(--cuj-transition-fast);
}
/* Inside a horizontal scroll row (anonymous Netflix layout), pin card width
   so tiles don't auto-shrink to content; flex: none so they keep their size. */
.home-row-scroll .home-chapter-card {
  width: 240px;
  flex: none;
}
.home-chapter-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
  border-color: var(--cuj-primary);
  text-decoration: none;
}
/* Mastery-colored card borders (only applied when the student has real
   progress). .in-progress was dropped — the home hero is the single
   source of truth for "current chapter". */
.home-chapter-card.good        { border-color: var(--cuj-score-good); }
.home-chapter-card.middle      { border-color: var(--cuj-score-middle); }
.home-chapter-card.bad         { border-color: var(--cuj-score-bad); }

.home-chapter-cover {
  width: 100%;
  height: 280px;
  object-fit: contain;       /* full logo visible, no crop */
  background: var(--cuj-paper-shade);
  padding: 16px;
  box-sizing: border-box;
  display: block;
}
.home-chapter-cover-placeholder {
  height: 280px;
  background: var(--cuj-paper-shade);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--cuj-font-display);
  font-size: 40px;
  font-style: italic;
  color: var(--cuj-gray-400);
}
.home-chapter-title {
  padding: var(--cuj-space-3) var(--cuj-space-3) 4px;
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-ink);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Mastery stats — "40% · 4/10" line under the title */
.home-chapter-meta {
  padding: 0 var(--cuj-space-3) var(--cuj-space-3);
  font-family: var(--cuj-font-display);
  font-size: 11px;
  color: var(--cuj-gray-600);
  font-variant-numeric: tabular-nums;
}

/* Mastery progress bar — sits as its own row between the cover and the
   title so it can't be clipped by image padding / object-fit boxing. */
.home-chapter-cover-wrap {
  position: relative;
  display: block;
}
.home-chapter-progress {
  display: block;
  height: 6px;
  width: 100%;
  background: var(--cuj-gray-200);
  overflow: hidden;
  border-bottom: 1px solid var(--cuj-gray-200);
}
.home-chapter-progress::after {
  content: "";
  display: block;
  height: 100%;
  width: var(--progress, 0%);
  background: var(--cuj-primary);
  transition: width var(--cuj-transition-fast);
}
.home-chapter-progress.good::after   { background: var(--cuj-score-good); }
.home-chapter-progress.middle::after { background: var(--cuj-score-middle); }
.home-chapter-progress.bad::after    { background: var(--cuj-score-bad); }
.home-chapter-ribbon {
  position: absolute;
  top: var(--cuj-space-2);
  left: var(--cuj-space-2);
  padding: 2px 10px;
  background: var(--cuj-paper);
  color: var(--cuj-primary);
  border: 1px solid var(--cuj-primary);
  font-size: 10px;
  font-family: var(--cuj-font-display);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-radius: var(--cuj-radius-pill, 999px);
  z-index: 2;
}
.home-chapter-ribbon.mastered {
  background: var(--cuj-paper);
  color: var(--cuj-score-good);
  border-color: var(--cuj-score-good);
}

/* ==========================================================================
   ANONYMOUS NETFLIX LAYOUT
   ========================================================================== */

/* Sign-up bar — the whole bar is an anchor. Paper-shade backdrop, 3px
   primary left rail as the only visual signal. No filled button — the
   italic "S'inscrire →" text at the right carries the CTA. */
.home-signup-bar {                   /* « S'inscrire gratuitement » — a main action: 44 px (37 on a wide screen) */
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--cuj-space-3);
  min-height: 44px;
  padding: var(--cuj-space-2) var(--cuj-space-4);
  background: var(--cuj-paper-shade);
  color: var(--cuj-gray-800);
  border-bottom: 1px solid var(--cuj-gray-200);
  border-left: 3px solid var(--cuj-primary);
  font-size: var(--cuj-font-size-sm);
  text-decoration: none;
  transition: background var(--cuj-transition-fast);
}
.home-signup-bar:hover {
  background: var(--cuj-paper);
  text-decoration: none;
  color: var(--cuj-gray-800);
}
.home-signup-bar-brand {
  font-family: var(--cuj-font-display);
  color: var(--cuj-gray-700);
}
.home-signup-bar-cta {
  font-family: var(--cuj-font-display);
  font-style: italic;
  color: var(--cuj-primary);
  font-weight: 600;
  white-space: nowrap;
  transition: transform var(--cuj-transition-fast);
}
.home-signup-bar:hover .home-signup-bar-cta {
  transform: translateX(2px);
}

.home-pitch {
  padding-top: var(--cuj-space-6);
  padding-bottom: var(--cuj-space-5);
  text-align: center;
  border-bottom: 1px solid var(--cuj-gray-200);
  margin-bottom: var(--cuj-space-5);
}
.home-pitch-title {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-4xl, 2.5rem);
  font-weight: 500;
  line-height: 1.1;
  color: var(--cuj-ink);
  margin: 0 0 var(--cuj-space-3);
}
.home-pitch-body {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-lg);
  color: var(--cuj-gray-700);
  max-width: 48ch;
  margin: 0 auto;
}

.home-chips {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--cuj-space-2);
  row-gap: 0;                        /* the chips' 44 px boxes already space the rows */
  justify-content: center;
  margin-bottom: var(--cuj-space-6);
  position: sticky;
  top: var(--cuj-navbar-height);
  background: var(--cuj-paper);
  padding: 7px var(--cuj-space-4);   /* + the 5 px of the chips' boxes: the pills sit 12 px in */
  z-index: 980;
  border-bottom: 1px solid var(--cuj-gray-200);
}
/* A class is the main action of the home page: a 44 px target (founder's rule, 2026-09-24).
   The box you tap is 44 px, the pill you see (::before) keeps its 34 — the bar stays on the
   screen, it must not grow. */
.home-grade-chip {
  position: relative;
  isolation: isolate;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1rem;
  color: var(--cuj-gray-800);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--cuj-transition-fast);
}
.home-grade-chip::before {
  content: "";
  position: absolute;
  inset: 5px 0;
  z-index: -1;
  background: transparent;
  border: 1px solid var(--cuj-gray-300);
  border-radius: var(--cuj-radius-pill, 999px);
  transition: all var(--cuj-transition-fast);
}
.home-grade-chip:hover {
  color: var(--cuj-primary);
  text-decoration: none;
}
.home-grade-chip:hover::before {
  background: var(--cuj-paper-shade);
  border-color: var(--cuj-primary);
}
.home-grade-chip.active {
  /* Outlined active state — matches the mobile chip-picker pattern in
     Settings. Filled primary was too loud against the paper aesthetic. */
  color: var(--cuj-primary);
  font-weight: 600;
}
.home-grade-chip.active::before {
  background: rgba(70, 80, 221, 0.08);
  border: 1.5px solid var(--cuj-primary);
}
.home-grade-chip:focus-visible { outline: none; }
.home-grade-chip:focus-visible::before { outline: 2px solid var(--cuj-primary); outline-offset: 2px; }

/* Under 992 px the classes wrapped into 7 to 17 rows, and that block stays on the screen:
   on a phone it covered 723 px of 800 — the page behind it could not be read (2026-09-24).
   One row that scrolls sideways instead; home.js keeps the current class in view. */
@media (max-width: 991.98px) {
  .home-chips {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .home-chips::-webkit-scrollbar { display: none; }
}

/* Clear the menu and the bar of classes, whatever its height (home.js measures it). */
.home-grade-row {
  scroll-margin-top: calc(var(--cuj-navbar-height) + var(--home-chips-height, 100px) + var(--cuj-space-3));
}

/* Bottom signup block — match the top sign-up bar's restraint: paper
   backdrop, 3px primary rail, outlined CTA with primary text. */
.home-signup-final {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--cuj-space-3);
  padding: var(--cuj-space-5);
  margin-top: var(--cuj-space-6);
  background: var(--cuj-paper-shade);
  border-left: 3px solid var(--cuj-primary);
  border-radius: var(--cuj-radius-md);
}
.home-signup-final-body {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-lg);
  color: var(--cuj-ink);
}
.home-signup-final-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  min-height: 44px;                  /* a main action (it was 42) */
  padding: 0.5rem 1.25rem;
  background: transparent;
  color: var(--cuj-primary);
  border: 1.5px solid var(--cuj-primary);
  border-radius: var(--cuj-radius-pill, 999px);
  text-decoration: none;
  font-family: var(--cuj-font-display);
  font-weight: 600;
  transition: background var(--cuj-transition-fast), transform var(--cuj-transition-fast);
}
.home-signup-final-cta:hover {
  background: rgba(70, 80, 221, 0.08);
  color: var(--cuj-primary);
  text-decoration: none;
  transform: translateX(2px);
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 991.98px) {
  .home-hero {
    grid-template-columns: 160px 1fr auto;
  }
  .home-hero-cover-wrap { min-height: 110px; }
  .home-hero-cover { max-height: 110px; }
  .home-hero-body { padding: var(--cuj-space-4); }
}

@media (max-width: 640px) {
  .home-pitch-title { font-size: var(--cuj-font-size-2xl); }
  .home-chapter-grid-inner { grid-template-columns: 1fr; }
  .home-hero {
    grid-template-columns: 120px 1fr auto;
  }
  .home-hero-cover-wrap { min-height: 96px; padding: var(--cuj-space-2); }
  .home-hero-cover { max-height: 96px; }
  .home-hero-body { padding: var(--cuj-space-3) var(--cuj-space-4); }
  .home-hero-title { font-size: var(--cuj-font-size-xl); }
  .home-hero-chevron { padding: 0 var(--cuj-space-3); font-size: var(--cuj-font-size-lg); }
}

/* --------------------------------------------------------------------------
   The install banner (docs/superpowers/specs/2026-10-01-pwa-design.md §3.4)

   Hidden by default on every device; pwa.js (pwa_rules.js) adds .is-shown on a
   touch device that can install the site and has not closed the banner before.
   Until 2026-10-01 this invited a phone to the separate Flutter app and the Play
   Store (UX-2, decision D-3) — now the site itself is the app.
   -------------------------------------------------------------------------- */

.home-app-banner {
  display: none;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin: 0 0 14px;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--cuj-paper-shade, #f7f5f0);
  border: 1px solid var(--cuj-gray-200, #e5e7eb);
  font-size: 0.92rem;
}

.home-app-banner-text { flex: 1 1 100%; color: var(--cuj-gray-700, #374151); }

.home-app-banner-link {
  min-height: 44px;                       /* a thumb, not a mouse */
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  border-radius: 999px;
  background: var(--cuj-primary, #1d4ed8);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
}

.home-app-banner.is-shown { display: flex; }        /* pwa.js decides (pwa_rules.js) */

.home-app-banner-link { border: 0; cursor: pointer; font: inherit; }

.home-app-banner-close {
  min-width: 44px;                        /* a thumb, not a mouse */
  min-height: 44px;
  margin-left: auto;
  border: 0;
  background: transparent;
  color: var(--cuj-gray-700, #374151);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

/* ---- auth.css ---- */
/* ==========================================================================
   Auth & status pages (Pattern A: centered form · Pattern B: status card)
   Shared editorial look: paper bg, Newsreader display, thin inputs.
   Used by login / register / password-reset flows + activation status pages.
   ========================================================================== */

/* --- Pattern A: centered form page --- */

.auth-page {
  min-height: calc(100vh - var(--cuj-navbar-height));
  background: var(--cuj-paper);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: calc(var(--cuj-navbar-height) + var(--cuj-space-5)) var(--cuj-space-4) var(--cuj-space-8);
  width: 100%;
}

.auth-card {
  width: 100%;
  max-width: 420px;
  text-align: left;
  color: var(--cuj-ink);
}

.auth-title {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-3xl);
  line-height: 1.1;
  margin: 0 0 var(--cuj-space-3);
  color: var(--cuj-ink);
}

.auth-subtitle {
  font-family: var(--cuj-font-display);
  color: var(--cuj-gray-700);
  margin: 0 0 var(--cuj-space-5);
  font-size: var(--cuj-font-size-md);
}

.auth-form { margin: 0; }

.auth-field {
  display: flex;
  flex-direction: column;
  margin-bottom: var(--cuj-space-4);
}
.auth-field label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-700);
  margin-bottom: 4px;
}
.auth-field input,
.auth-field select,
.auth-field textarea {
  min-height: 44px;                  /* a main action of the page (it was 41) */
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--cuj-gray-400);
  padding: 8px 2px;
  font-size: var(--cuj-font-size-md);
  color: var(--cuj-ink);
  font-family: inherit;
  transition: border-color var(--cuj-transition-fast);
  outline: none;
}
.auth-field input:focus,
.auth-field select:focus,
.auth-field textarea:focus {
  border-bottom-color: var(--cuj-primary);
}
/* A 1px border-colour change alone is too faint to see (UX-13) — a keyboard user
   also gets a real ring. :focus-visible (not :focus) so a mouse click still gets
   just the quiet border tint above. */
.auth-field input:focus-visible,
.auth-field select:focus-visible,
.auth-field textarea:focus-visible {
  outline: 2px solid var(--cuj-primary);
  outline-offset: 2px;
}
.auth-field .helptext,
.auth-field .form-text {
  font-size: var(--cuj-font-size-xs);
  color: var(--cuj-gray-600);
  margin-top: 4px;
}
.auth-field .errorlist,
.auth-field .invalid-feedback {
  list-style: none;
  padding: 0;
  margin: 4px 0 0;
  color: var(--cuj-danger);
  font-size: var(--cuj-font-size-xs);
}

/* crispy-forms output wrapped in .auth-form — apply the same look */
.auth-form div[class*="field"],
.auth-form .form-group { margin-bottom: var(--cuj-space-4); }
.auth-form label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-700);
  margin-bottom: 4px;
  display: block;
}
.auth-form input[type="text"],
.auth-form input[type="email"],
.auth-form input[type="password"],
.auth-form select {
  width: 100%;
  min-height: 44px;                  /* a main action of the page (it was 41) */
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--cuj-gray-400);
  border-radius: 0;
  padding: 8px 2px;
  font-size: var(--cuj-font-size-md);
  color: var(--cuj-ink);
  font-family: inherit;
  outline: none;
  box-shadow: none;
  transition: border-color var(--cuj-transition-fast);
}
.auth-form input:focus,
.auth-form select:focus {
  border-bottom-color: var(--cuj-primary);
  background: transparent;
  color: var(--cuj-ink);
}
.auth-form input:focus-visible,
.auth-form select:focus-visible {
  outline: 2px solid var(--cuj-primary);
  outline-offset: 2px;
}
.auth-form .asteriskField { color: var(--cuj-danger); margin-left: 2px; }

.auth-submit {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  padding: 0.75rem 1.5rem;
  background: var(--cuj-primary);
  color: var(--cuj-white);
  border: none;
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-weight: 600;
  font-size: var(--cuj-font-size-md);
  cursor: pointer;
  transition: background var(--cuj-transition-fast);
  margin-top: var(--cuj-space-3);
}
.auth-submit:hover { background: var(--cuj-primary-dark); }
.auth-arrow { transition: transform var(--cuj-transition-fast); }
.auth-submit:hover .auth-arrow { transform: translateX(2px); }

.auth-divider {
  display: flex;
  align-items: center;
  gap: var(--cuj-space-3);
  color: var(--cuj-gray-500);
  font-style: italic;
  font-family: var(--cuj-font-display);
  margin: var(--cuj-space-5) 0;
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--cuj-gray-300);
}

.auth-social-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--cuj-space-2);
  width: 100%;
  padding: 0.625rem 1rem;
  background: var(--cuj-white);
  color: var(--cuj-ink);
  border: 1px solid var(--cuj-gray-300);
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-md);
  cursor: pointer;
  text-decoration: none;
  transition: border-color var(--cuj-transition-fast);
}
.auth-social-btn:hover {
  border-color: var(--cuj-primary);
  color: var(--cuj-ink);
  text-decoration: none;
}

.auth-secondary {
  margin-top: var(--cuj-space-5);
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-gray-700);
}
.auth-secondary a {
  color: var(--cuj-primary);
  text-decoration: none;
  font-weight: 600;
}
.auth-secondary a:hover { text-decoration: underline; }

.auth-messages {
  background: var(--cuj-danger-bg);
  border-left: 3px solid var(--cuj-danger);
  padding: var(--cuj-space-2) var(--cuj-space-3);
  border-radius: var(--cuj-radius-sm);
  list-style: none;
  margin: 0 0 var(--cuj-space-4);
  font-size: var(--cuj-font-size-sm);
  color: #991b1b;
}

/* Register wizard: 3-step progress dots */
.auth-steps {
  display: flex;
  gap: var(--cuj-space-2);
  align-items: center;
  margin-bottom: var(--cuj-space-5);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-600);
}
.auth-step-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--cuj-paper);
  border: 1.5px solid var(--cuj-gray-400);
}
.auth-step-dot.done { background: var(--cuj-primary); border-color: var(--cuj-primary); }
.auth-step-dot.current {
  background: var(--cuj-primary);
  border-color: var(--cuj-primary);
  box-shadow: 0 0 0 3px rgba(70, 80, 221, 0.18);
}

/* ==========================================================================
   Pattern B — centered status card (activation, password, upload success)
   ========================================================================== */

.status-page {
  min-height: calc(100vh - var(--cuj-navbar-height));
  background: var(--cuj-paper);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: calc(var(--cuj-navbar-height) + var(--cuj-space-5)) var(--cuj-space-4) var(--cuj-space-8);
  width: 100%;
}
.status-card {
  width: 100%;
  max-width: 480px;
  text-align: center;
  color: var(--cuj-ink);
}
.status-glyph {
  font-size: 64px;
  line-height: 1;
  margin-bottom: var(--cuj-space-4);
  color: var(--cuj-primary);
}
.status-glyph.good   { color: var(--cuj-score-good); }
.status-glyph.bad    { color: var(--cuj-score-bad); }
.status-glyph.middle { color: #995B00; } /* darkened for AA text contrast (was var(--cuj-score-middle) #FF9800, 2.2:1) */

.status-title {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-2xl);
  line-height: 1.15;
  margin: 0 0 var(--cuj-space-3);
  color: var(--cuj-ink);
}
.status-body {
  font-family: var(--cuj-font-display);
  color: var(--cuj-gray-700);
  font-size: var(--cuj-font-size-md);
  line-height: 1.5;
  margin: 0 0 var(--cuj-space-5);
}
.status-body strong { color: var(--cuj-ink); }
.status-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  padding: 0.75rem 1.5rem;
  background: var(--cuj-primary);
  color: var(--cuj-white);
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-weight: 600;
  font-size: var(--cuj-font-size-md);
  text-decoration: none;
  border: none;
  cursor: pointer;
}
.status-cta:hover { background: var(--cuj-primary-dark); color: var(--cuj-white); text-decoration: none; }
.status-cta.danger { background: var(--cuj-danger); }
.status-cta.danger:hover { background: #991b1b; }
.status-secondary {
  margin-top: var(--cuj-space-4);
  font-size: var(--cuj-font-size-sm);
}
.status-secondary a { color: var(--cuj-primary); font-style: italic; text-decoration: none; }
.status-secondary a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   The wall an anonymous visitor meets on « Pratiquer » (UX-5)

   It was one bare sentence on an empty page, under a navbar whose three links
   rendered as nothing — the first page a parent sent by a friend would see.
   -------------------------------------------------------------------------- */

.login-wall {
  max-width: 620px;
  margin: 0 auto;
  padding: 32px 16px 48px;
  text-align: center;
}

.login-wall-title {
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  font-weight: 700;
  margin-bottom: 16px;
  color: var(--cuj-text, #10203a);
}

.login-wall-pitch { font-size: 1.05rem; line-height: 1.6; margin-bottom: 12px; }

.login-wall-free {
  font-size: 0.97rem;
  line-height: 1.55;
  color: var(--cuj-text-muted, #52627a);
  margin-bottom: 26px;
}

.login-wall-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-bottom: 22px;
}

.login-wall-primary, .login-wall-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;                        /* a thumb, not a mouse */
  padding: 12px 24px;
  border-radius: 999px;
  font-weight: 600;
  text-decoration: none;
}

.login-wall-primary {
  background: var(--cuj-primary, #1d4ed8);
  color: #fff;
}

.login-wall-primary:hover { filter: brightness(1.08); color: #fff; text-decoration: none; }

.login-wall-secondary {
  background: transparent;
  color: var(--cuj-primary, #1d4ed8);
  border: 1px solid currentColor;
}

.login-wall-secondary:hover { background: rgba(29, 78, 216, 0.07); text-decoration: none; }

.login-wall-back a { color: var(--cuj-text-muted, #52627a); font-size: 0.95rem; }

@media (max-width: 420px) {
  .login-wall-actions { flex-direction: column; align-items: stretch; }
}

/* « Continuer avec Google »: a plain link to Google's own page (web/google_oauth.py), no popup. */
.auth-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 10px 16px;
  border: 1px solid #dadce0;
  border-radius: 999px;
  background: #fff;
  color: #3c4043;
  font-weight: 500;
  text-decoration: none;
}
.auth-google:hover { background: #f8f9fa; color: #3c4043; text-decoration: none; }
.auth-google:focus-visible { outline: 3px solid var(--cuj-primary, #4650DD); outline-offset: 2px; }

/* ---- settings.css ---- */
/* ==========================================================================
   Settings page (Pattern C) — sidebar nav + main pane with section cards.
   Chip pickers, inline-edit rows, danger zone.
   ========================================================================== */

.settings-page {
  flex: 1 1 auto;
  min-width: 0;          /* a flex item of base.html's row: its content must not widen the page */
  min-height: calc(100vh - var(--cuj-navbar-height));
  background: var(--cuj-paper);
  padding: var(--cuj-space-5) var(--cuj-space-4) var(--cuj-space-8);
}

.settings-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: var(--cuj-space-6);
  max-width: 1100px;
  margin: 0 auto;
}

.settings-header {
  grid-column: 1 / -1;
  margin-bottom: var(--cuj-space-4);
}
.settings-header h1 {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-3xl);
  margin: 0 0 var(--cuj-space-1);
  color: var(--cuj-ink);
}
.settings-header p {
  font-family: var(--cuj-font-display);
  color: var(--cuj-gray-700);
  margin: 0;
}

/* --- Sidebar nav --- */
.settings-sidebar {
  position: sticky;
  top: calc(var(--cuj-navbar-height) + var(--cuj-space-5));
  align-self: start;
  max-height: calc(100vh - var(--cuj-navbar-height) - var(--cuj-space-5));
  overflow-y: auto;
}
.settings-sidebar nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.settings-sidebar a {
  display: block;
  padding: 8px 12px;
  color: var(--cuj-gray-700);
  text-decoration: none;
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  border-left: 2px solid transparent;
  transition: all var(--cuj-transition-fast);
}
.settings-sidebar a:hover {
  color: var(--cuj-primary);
  background: var(--cuj-paper-shade);
  text-decoration: none;
}
.settings-sidebar a.current {
  color: var(--cuj-primary);
  border-left-color: var(--cuj-primary);
  background: rgba(70, 80, 221, 0.04);
  font-weight: 600;
}

/* --- Main pane --- */
.settings-main { min-width: 0; }

.settings-section {
  margin-bottom: var(--cuj-space-6);
  scroll-margin-top: calc(var(--cuj-navbar-height) + var(--cuj-space-4));
}
.settings-section-title {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-700);
  font-weight: 600;
  margin: 0 0 var(--cuj-space-3);
  padding-bottom: var(--cuj-space-2);
  border-bottom: 1px solid var(--cuj-gray-200);
}

/* --- Row (label + value + optional action) --- */
.settings-row {
  display: grid;
  grid-template-columns: 180px 1fr auto;
  align-items: center;
  gap: var(--cuj-space-3);
  padding: var(--cuj-space-3) 0;
  border-bottom: 1px solid var(--cuj-gray-200);
}
.settings-row:last-child { border-bottom: none; }
.settings-row-label {
  font-family: var(--cuj-font-display);
  color: var(--cuj-gray-700);
  font-size: var(--cuj-font-size-sm);
}
.settings-row-value {
  font-family: var(--cuj-font-display);
  color: var(--cuj-ink);
  font-size: var(--cuj-font-size-md);
  overflow: hidden;
  text-overflow: ellipsis;
}
.settings-row-value.muted { color: var(--cuj-gray-500); font-style: italic; }

.settings-row-action,
.settings-row-action button,
.settings-row-action a {
  background: none;
  border: none;
  color: var(--cuj-primary);
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
  padding: 0;
  text-decoration: none;
}
.settings-row-action button:hover,
.settings-row-action a:hover { text-decoration: underline; color: var(--cuj-primary-dark); }

/* --- Chip picker (multi-buttons inline) --- */
.settings-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--cuj-space-2);
}
.settings-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  background: transparent;
  color: var(--cuj-gray-800);
  border: 1px solid var(--cuj-gray-300);
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
  text-decoration: none;
  transition: all var(--cuj-transition-fast);
}
.settings-chip:hover {
  border-color: var(--cuj-primary);
  color: var(--cuj-primary);
  text-decoration: none;
}
.settings-chip.active {
  background: var(--cuj-primary);
  color: var(--cuj-white);
  border-color: var(--cuj-primary);
}
.settings-chip-form { margin: 0; display: inline-flex; }

/* --- Enrolled grade cards (a student may have multiple curricula) --- */
.settings-enrolled {
  display: flex;
  flex-direction: column;
  gap: var(--cuj-space-2);
  margin-top: var(--cuj-space-2);
}
.settings-enrolled-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--cuj-space-3);
  padding: 10px 14px;
  background: var(--cuj-white);
  border: 1px solid var(--cuj-gray-200);
  border-radius: var(--cuj-radius-md);
}
.settings-enrolled-label {
  font-family: var(--cuj-font-display);
  color: var(--cuj-ink);
  font-size: var(--cuj-font-size-sm);
}
.settings-enrolled-remove {
  background: none;
  border: none;
  color: var(--cuj-danger);
  font-family: var(--cuj-font-display);
  font-style: italic;
  font-size: var(--cuj-font-size-xs);
  cursor: pointer;
  padding: 0;
}
.settings-enrolled-remove:hover { text-decoration: underline; }

.settings-add-grade {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 8px 14px;
  background: transparent;
  color: var(--cuj-primary);
  border: 1px dashed var(--cuj-primary);
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
  margin-top: var(--cuj-space-2);
}
.settings-add-grade:hover {
  background: var(--cuj-primary);
  color: var(--cuj-white);
}

/* --- Danger zone --- */
.settings-section.danger .settings-section-title { color: var(--cuj-danger); }
.settings-section.danger .settings-row { border-bottom: 1px solid var(--cuj-danger-bg); }
.settings-row-action.danger,
.settings-row-action.danger button,
.settings-row-action.danger a { color: var(--cuj-danger); }
.settings-row-action.danger button:hover,
.settings-row-action.danger a:hover { color: #991b1b; }

/* --- Inline wizard (Add grade / Change language path reuses grade wizard) --- */
.settings-wizard-overlay {
  background: var(--cuj-paper-shade);
  border-radius: var(--cuj-radius-md);
  padding: var(--cuj-space-4);
  margin-top: var(--cuj-space-3);
}

/* --- Responsive --- */
@media (max-width: 768px) {
  .settings-layout {
    /* minmax(0, …): a plain 1fr never shrinks below its content — the row of section links
       widened the whole page to 413 px on a 375 px phone (2026-09-29). */
    grid-template-columns: minmax(0, 1fr);
    gap: var(--cuj-space-3);
  }
  .settings-sidebar {
    position: static;
    max-height: none;
    overflow: visible;
  }
  .settings-sidebar nav {
    flex-direction: row;
    overflow-x: auto;
    padding-bottom: var(--cuj-space-2);
    border-bottom: 1px solid var(--cuj-gray-200);
  }
  .settings-sidebar a {
    flex: none;
    border-left: none;
    border-bottom: 2px solid transparent;
    white-space: nowrap;
  }
  .settings-sidebar a.current {
    border-left: none;
    border-bottom-color: var(--cuj-primary);
    background: transparent;
  }
  .settings-row {
    grid-template-columns: 1fr;
    gap: 4px;
    align-items: flex-start;
  }
  .settings-row-label { font-weight: 600; }
  .settings-row-action { justify-self: flex-start; }
}

/* ---- quiz.css ---- */
/* ==========================================================================
   Quiz screen — amber-accented exam panel. Distinct from the purple Practice
   screen so students know "this is graded territory". All questions visible
   at once, single submit at the bottom, result screen after submission.
   ========================================================================== */

.quiz-page {
  background: var(--cuj-paper);
  min-height: calc(100vh - var(--cuj-navbar-height));
  padding: calc(var(--cuj-navbar-height) + var(--cuj-space-5)) var(--cuj-space-4) var(--cuj-space-8);
  max-width: 860px;
  margin: 0 auto;
  color: var(--cuj-gray-800);
  --quiz-accent: var(--cuj-score-middle, #FF9800);
  --quiz-accent-dark: #b26a00;
  --quiz-accent-bg: var(--cuj-score-middle-bg, #fff4e5);
}

/* --- Breadcrumb --- */
.quiz-breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--cuj-space-2);
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cuj-gray-600);
  margin-bottom: var(--cuj-space-5);
  padding-bottom: var(--cuj-space-3);
  border-bottom: 1px solid var(--cuj-gray-200);
}
.quiz-breadcrumb-back {
  color: var(--quiz-accent);
  text-decoration: none;
  font-weight: 600;
}
.quiz-breadcrumb-back:hover { text-decoration: underline; color: var(--quiz-accent-dark); }
.quiz-breadcrumb-sep    { color: var(--cuj-gray-400); }
.quiz-breadcrumb-chapter { color: var(--cuj-gray-700); }
.quiz-breadcrumb-tag {
  color: var(--cuj-white);
  background: var(--quiz-accent);
  padding: 1px 8px;
  border-radius: var(--cuj-radius-pill, 999px);
  font-weight: 700;
  letter-spacing: 0.08em;
}

/* --- Title --- */
.quiz-title {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: var(--cuj-font-size-3xl);
  line-height: 1.1;
  color: var(--cuj-ink);
  margin: 0 0 var(--cuj-space-5);
}

/* --- Form & question cards --- */
.quiz-form { margin: 0; }

.quiz-question {
  padding: var(--cuj-space-4) 0;
  border-bottom: 1px solid var(--cuj-gray-200);
}
.quiz-question:first-of-type { border-top: 1px solid var(--cuj-gray-200); }

.quiz-question-head {
  display: flex;
  align-items: center;
  gap: var(--cuj-space-3);
  margin-bottom: var(--cuj-space-3);
}
.quiz-question-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--cuj-paper-shade);
  border: 2px solid var(--cuj-gray-300);
  color: var(--cuj-gray-700);
  font-family: var(--cuj-font-display);
  font-weight: 700;
  font-size: var(--cuj-font-size-sm);
}
.quiz-question-label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-700);
  font-weight: 600;
}
.quiz-question-status {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  padding: 2px 10px;
  border-radius: var(--cuj-radius-pill, 999px);
  margin-left: auto;
}
.quiz-question-status.good   { background: var(--cuj-success-bg); color: #166534; }
.quiz-question-status.middle { background: var(--cuj-warning-bg, #fff4e5); color: var(--quiz-accent-dark); }
.quiz-question-status.bad    { background: var(--cuj-danger-bg);  color: #991b1b; }

/* After submission — colored left rule for each question */
.quiz-question.good { border-left: 3px solid var(--cuj-score-good); padding-left: var(--cuj-space-3); }
.quiz-question.middle { border-left: 3px solid var(--cuj-score-middle); padding-left: var(--cuj-space-3); }
.quiz-question.bad  { border-left: 3px solid var(--cuj-score-bad);  padding-left: var(--cuj-space-3); }

/* --- Submit / actions --- */
.quiz-actions {
  display: flex;
  align-items: center;
  gap: var(--cuj-space-3);
  flex-wrap: wrap;
  margin-top: var(--cuj-space-5);
  padding-top: var(--cuj-space-5);
  border-top: 1px solid var(--cuj-gray-200);
  justify-content: center;
}
.quiz-submit {
  display: inline-flex;
  align-items: center;
  gap: var(--cuj-space-2);
  padding: 0.75rem 1.75rem;
  background: var(--quiz-accent);
  color: var(--cuj-white);
  border: none;
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-weight: 600;
  font-size: var(--cuj-font-size-lg);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--cuj-transition-fast);
}
.quiz-submit:hover { background: var(--quiz-accent-dark); color: var(--cuj-white); text-decoration: none; }
.quiz-arrow { transition: transform var(--cuj-transition-fast); }
.quiz-submit:hover .quiz-arrow { transform: translateX(2px); }
/* The price, on its own line above the button (1 jeton an answered question,
   cours/quiz_price.py). A subscriber pays nothing, so reads nothing. */
.quiz-price {
  flex-basis: 100%;
  margin: 0;
  text-align: center;
  color: var(--cuj-gray-600);
  font-size: var(--cuj-font-size-sm);
}
body[data-premium="1"] .quiz-price { display: none; }

.quiz-retry {
  background: transparent;
  color: var(--quiz-accent-dark);
  border: 1px solid var(--quiz-accent);
  padding: 0.625rem 1.25rem;
  border-radius: var(--cuj-radius-pill, 999px);
  font-family: var(--cuj-font-display);
  font-weight: 600;
  font-size: var(--cuj-font-size-sm);
  cursor: pointer;
}
.quiz-retry:hover { background: var(--quiz-accent-bg); }

/* --- Result screen --- */
.quiz-result {
  text-align: center;
  padding: var(--cuj-space-6) var(--cuj-space-4);
  margin-bottom: var(--cuj-space-5);
  background: var(--quiz-accent-bg);
  border-left: 4px solid var(--quiz-accent);
  border-radius: var(--cuj-radius-md);
}
.quiz-result-glyph {
  font-size: 40px;
  color: var(--quiz-accent);
  line-height: 1;
  margin-bottom: var(--cuj-space-2);
}
.quiz-result-title {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--quiz-accent-dark);
  font-weight: 600;
  margin-bottom: var(--cuj-space-1);
}
.quiz-result-score {
  font-family: var(--cuj-font-display);
  font-weight: 500;
  font-size: 3rem;
  line-height: 1;
  color: var(--cuj-ink);
}
.quiz-result-pct {
  font-family: var(--cuj-font-display);
  color: var(--quiz-accent-dark);
  font-size: var(--cuj-font-size-md);
  font-weight: 600;
  margin-top: var(--cuj-space-1);
}

.quiz-review-label {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--cuj-gray-700);
  font-weight: 600;
  margin: 0 0 var(--cuj-space-3);
  padding-bottom: var(--cuj-space-2);
  border-bottom: 1px solid var(--cuj-gray-200);
}

/* --- "Added to Révision" block (mastery-guard explanation) --- */
.quiz-revision-added {
  margin-bottom: var(--cuj-space-5);
  padding: var(--cuj-space-4);
  background: var(--cuj-paper-shade);
  border-left: 3px solid var(--quiz-accent);
  border-radius: var(--cuj-radius-md);
}
.quiz-revision-added-head {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  font-weight: 600;
  color: var(--quiz-accent-dark);
  margin-bottom: var(--cuj-space-2);
}
.quiz-revision-added-body {
  font-family: var(--cuj-font-display);
  font-size: var(--cuj-font-size-sm);
  color: var(--cuj-gray-700);
  line-height: 1.45;
  margin: 0 0 var(--cuj-space-2);
}
.quiz-revision-added-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.quiz-revision-added-list li {
  padding: 4px 0;
  font-family: var(--cuj-font-display);
  color: var(--cuj-ink);
  font-size: var(--cuj-font-size-sm);
}
.quiz-revision-added-list li::before {
  content: "\2022";
  color: var(--quiz-accent);
  margin-right: 10px;
  font-weight: 700;
}

/* ---- offer.css ---- */
/* ==========================================================================
   The offer page, /abonnement/ (redesigned 2026-09-23)

   What each thing costs, in each plan, read across ONE table: the free plan counts
   in jetons, Premium counts nothing. The Premium column is the page's single strong
   colour; everything else is paper, ink and the table's rules. The two declarations
   of the checkout get a full reading line of their own.

   The page is a flex item of #main-content (base.html, a flex row): it must grow in
   it. Shrunk to its content, it used to sit on the left of a wide screen.
   ========================================================================== */

.offer-page {
  --offer-rule: #ddd6c7;               /* the table's rules, a shade of the paper */
  --offer-band: #eef0ff;               /* the Premium column below its head */
  flex: 1 1 auto;
  min-width: 0;
  /* the navbar is fixed over the top of the page */
  padding: calc(var(--cuj-navbar-height) + var(--cuj-space-6)) var(--cuj-space-4) 5rem;
  color: var(--cuj-gray-800);
  font-family: var(--cuj-font-family);
}

.offer-wrap {
  max-width: 52rem;
  margin: 0 auto;
}

.offer-page h1::before,
.offer-page h2::before { content: none; }

.offer-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---- Heading ------------------------------------------------------------ */

.offer-head {
  text-align: center;
  margin: 0 0 var(--cuj-space-6);
}

.offer-head h1 {
  margin: 0 0 var(--cuj-space-3);
  font-family: var(--cuj-font-display);
  font-size: clamp(2rem, 1.35rem + 2.4vw, 3rem);
  font-weight: 500;
  line-height: 1.1;
  color: var(--cuj-ink);
}

.offer-head p {
  max-width: 34rem;
  margin: 0 auto;
  font-size: 1.125rem;
  line-height: 1.5;
  color: var(--cuj-gray-700);
}

/* ---- Where you stand: short of jetons, subscribed, a notice ------------- */

.offer-message {
  max-width: 40rem;
  margin: 0 auto var(--cuj-space-6);
  padding: var(--cuj-space-3) var(--cuj-space-5);
  border: 1px solid var(--offer-rule);
  border-radius: var(--cuj-radius-md);
  background: var(--cuj-paper-shade);
  text-align: center;
  font-size: 1rem;
  line-height: 1.5;
}

.offer-message p { margin: 0; }
.offer-message p + p { margin-top: var(--cuj-space-1); }
.offer-message a { color: inherit; font-weight: 600; text-decoration: underline; }

.offer-message--short {                 /* a pupil sent here by a priced action */
  border-color: #f0c36d;
  background: #fff7e6;
  color: #6b4500;
}

.offer-message--active {
  border-color: #9ccfa0;
  background: #edf7ee;
  color: #1f5a25;
}

/* ---- The table ------------------------------------------------------------ */

.offer-table {
  width: 100%;
  border-collapse: separate;            /* rounded corners on the Premium band */
  border-spacing: 0;
  font-size: 1.0625rem;
  font-variant-numeric: lining-nums tabular-nums;
}

.offer-table th,
.offer-table td {
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--offer-rule);
  vertical-align: middle;
}

.offer-table col.offer-col-action { width: 46%; }
.offer-table col.offer-col-plan { width: 27%; }

.offer-table tbody th,
.offer-table tfoot th {
  text-align: left;
  font-weight: 400;
  color: var(--cuj-ink);
}

.offer-table td {
  text-align: center;
  white-space: nowrap;
}

.offer-action-note {                    /* « la première fois » */
  display: block;
  font-size: 0.875rem;
  color: var(--cuj-gray-700);
}

/* the head of each plan: its name, its price, what the price covers */
.offer-table thead th {
  padding-top: var(--cuj-space-5);
  padding-bottom: var(--cuj-space-4);
  border-bottom: 2px solid var(--cuj-ink);
  text-align: center;
  vertical-align: top;           /* both plans' names and prices on the same lines */
  font-weight: 400;
}

.offer-table thead td { border-bottom: 2px solid var(--cuj-ink); }

.offer-plan-name {
  display: block;
  font-family: var(--cuj-font-display);
  font-size: 1.5rem;
  line-height: 1.2;
  color: var(--cuj-ink);
}

.offer-price {
  display: block;
  margin: var(--cuj-space-1) 0 0;
  font-family: var(--cuj-font-display);
  font-size: 2.5rem;
  line-height: 1.1;
  color: var(--cuj-ink);
}

.offer-price-note {
  display: block;
  margin-top: var(--cuj-space-1);
  font-size: 0.9375rem;
  color: var(--cuj-gray-700);
}

.offer-yours {                          /* the plan this account is on */
  display: block;
  margin-top: var(--cuj-space-2);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--cuj-primary-dark);
}

/* the Premium column: a solid head, then a band down to the last row */
.offer-table .offer-premium {
  background: var(--offer-band);
  border-bottom-color: #d5d9fb;
  color: var(--cuj-primary-dark);
  font-weight: 600;
}

.offer-table thead th.offer-premium {
  border-radius: var(--cuj-radius-lg) var(--cuj-radius-lg) 0 0;
  border-bottom-color: var(--cuj-primary);
  background: var(--cuj-primary);
  font-weight: 400;
}

.offer-table thead th.offer-premium .offer-plan-name,
.offer-table thead th.offer-premium .offer-price { color: #fff; }
.offer-table thead th.offer-premium .offer-price-note,
.offer-table thead th.offer-premium .offer-yours { color: #e4e7ff; }

.offer-table tfoot .offer-premium {
  border-bottom: 0;
  border-radius: 0 0 var(--cuj-radius-lg) var(--cuj-radius-lg);
}

.offer-table tfoot th,
.offer-table tfoot td { border-bottom: 0; }

/* A jeton, drawn as one: a round token with its value, and the ridge of its rim. */
.jeton {
  display: inline-grid;
  place-items: center;
  min-width: 1.9em;
  height: 1.9em;
  margin-right: 0.35em;
  padding: 0 0.3em;
  border: 2px solid var(--cuj-primary);
  border-radius: 999px;
  background: #fff;
  box-shadow: inset 0 0 0 2px #fff, inset 0 0 0 3px rgba(70, 80, 221, 0.3);
  color: var(--cuj-primary-dark);
  font-size: 0.85em;
  font-weight: 700;
  line-height: 1;
  vertical-align: middle;
}

.offer-footnote {
  margin: var(--cuj-space-4) 0 0;
  text-align: center;
  font-size: 0.9375rem;
  color: var(--cuj-gray-700);
}

/* ---- Subscribing ---------------------------------------------------------- */

.offer-join {
  max-width: 40rem;
  margin: var(--cuj-space-8) auto 0;
  padding: var(--cuj-space-6);
  border: 1px solid var(--offer-rule);
  border-radius: var(--cuj-radius-lg);
  background: var(--cuj-white);
}

.offer-join--visitor {                  /* a button and a line: no panel needed */
  max-width: 28rem;
  padding: 0;
  border: 0;
  background: none;
}

.offer-join h2 {
  margin: 0 0 var(--cuj-space-5);
  font-family: var(--cuj-font-display);
  font-size: 1.5rem;
  font-weight: 500;
  text-align: center;
  color: var(--cuj-ink);
}

.offer-check {
  display: grid;
  grid-template-columns: 1.25rem 1fr;   /* the box, then ONE text block beside it */
  gap: var(--cuj-space-3);
  align-items: start;
  margin: 0 0 var(--cuj-space-4);
  font-size: 1rem;
  line-height: 1.55;
  cursor: pointer;
}

.offer-check input {
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.15rem 0 0;
  accent-color: var(--cuj-primary);
}

.offer-check a { color: var(--cuj-primary-dark); font-weight: 600; }

.offer-check-error {
  margin: 0 0 var(--cuj-space-4);
  font-weight: 600;
  color: #b42318;
}

.offer-cta {
  display: block;
  width: 100%;
  margin-top: var(--cuj-space-5);
  padding: 1rem 1.25rem;
  border: 0;
  border-radius: var(--cuj-radius-md);
  background: var(--cuj-primary);
  color: #fff;
  font: 700 1.0625rem/1.2 var(--cuj-font-family);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.offer-join--visitor .offer-cta { margin-top: 0; }

.offer-cta:hover,
.offer-cta:focus-visible {
  background: var(--cuj-primary-dark);
  color: #fff;
  text-decoration: none;
}

.offer-cta:focus-visible { outline: 3px solid var(--cuj-ink); outline-offset: 3px; }

.offer-join-note {
  margin: var(--cuj-space-3) 0 0;
  text-align: center;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--cuj-gray-700);
}

.offer-join-note a { color: var(--cuj-primary-dark); font-weight: 600; }

/* ---- A phone ------------------------------------------------------------- */

@media (max-width: 600px) {
  .offer-page { padding: calc(var(--cuj-navbar-height) + var(--cuj-space-4)) var(--cuj-space-3) 4rem; }
  .offer-table { font-size: 0.9375rem; }
  .offer-table th,
  .offer-table td { padding: 0.75rem 0.45rem; }
  .offer-table td { white-space: normal; }
  .offer-table col.offer-col-action { width: 40%; }
  .offer-table col.offer-col-plan { width: 30%; }
  .offer-plan-name { font-size: 1.125rem; }
  .offer-price { font-size: 1.75rem; }
  .offer-table td .jeton {            /* a narrow column: the jeton above its word */
    display: grid;
    width: max-content;
    margin: 0 auto 0.3rem;
  }
  .offer-join { padding: var(--cuj-space-5) var(--cuj-space-4); }
}
