/* ============================================================
   Parcours RGPD — feuille de style
   ============================================================ */

:root {
  --bg: #f5f7fb;
  --bg-soft: #eef1f8;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --border: #e3e8f0;
  --text: #101828;
  --text-soft: #5a6a85;
  --text-mute: #8a97ab;

  --brand: #4f46e5;
  --brand-2: #7c3aed;
  --brand-soft: #eef2ff;
  --teal: #0d9488;
  --ok: #12b76a;
  --ok-soft: #e7f8ef;
  --warn: #f79009;
  --warn-soft: #fff5e6;
  --danger: #e11d48;
  --danger-soft: #ffeaef;
  --info: #0ea5e9;
  --info-soft: #e8f6fe;

  --accent: var(--brand);

  --radius: 16px;
  --radius-sm: 10px;
  --radius-lg: 26px;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .05), 0 1px 3px rgba(16, 24, 40, .06);
  --shadow: 0 4px 12px rgba(16, 24, 40, .07), 0 12px 28px rgba(16, 24, 40, .06);
  --shadow-lg: 0 18px 50px rgba(16, 24, 40, .14);
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}

html[data-theme='dark'] {
  --bg: #0c1020;
  --bg-soft: #121729;
  --surface: #161c31;
  --surface-2: #1c2338;
  --border: #2a3350;
  --text: #eef2fb;
  --text-soft: #a8b4cd;
  --text-mute: #7d8aa6;
  --brand: #8b8cff;
  --brand-2: #b78bff;
  --brand-soft: #232a49;
  --ok-soft: #12301f;
  --warn-soft: #33260f;
  --danger-soft: #3a1220;
  --info-soft: #0f2a3d;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow: 0 6px 22px rgba(0, 0, 0, .45);
  --shadow-lg: 0 22px 60px rgba(0, 0, 0, .6);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
  /* Pas de surlignement bleu au double-clic ou au glissé : l'interface est
     faite de zones cliquables, la sélection de texte n'y a pas d'usage. */
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  /* Supprime aussi le flash bleu au toucher sur mobile. */
  -webkit-tap-highlight-color: transparent;
}

/* Les champs de saisie doivent évidemment rester sélectionnables. */
input, textarea, select, [contenteditable] {
  -webkit-user-select: text;
  -moz-user-select: text;
  user-select: text;
}

h1, h2, h3, h4 { line-height: 1.22; margin: 0 0 .5em; font-weight: 700; letter-spacing: -.02em; }
p { margin: 0 0 1em; }
a { color: var(--brand); }
button { font-family: inherit; }

::selection { background: color-mix(in srgb, var(--brand) 25%, transparent); }

/* L'attribut `hidden` doit cacher, quoi qu'en dise la feuille de style.
   La règle par défaut du navigateur — [hidden] { display: none } — a la
   spécificité la plus faible qui soit : n'importe quelle classe qui pose un
   `display` la bat. Un `.btn` masqué par `element.hidden = true` restait donc
   affiché, ce qui est exactement le contraire de ce que le code demandait. */
[hidden] { display: none !important; }

/* ─────────────── Boutons ─────────────── */
/* ── Boutons ────────────────────────────────────────────────────────────────
   Un seul principe partout : la couleur vit dans le trait et le texte, jamais
   en aplat. Au survol, un voile très léger de cette même couleur et un contour
   plus affirmé — assez pour signaler, trop discret pour crier.
   --ton est la couleur du bouton ; --ton-texte en est une version assourdie,
   mêlée à la couleur du texte, qui évite l'effet fluorescent des teintes pures.
   Les variantes ne redéfinissent que --ton. */
.btn {
  --ton: var(--brand);
  --ton-texte: color-mix(in srgb, var(--ton) 70%, var(--text));
  display: inline-flex; align-items: center; justify-content: center; gap: .55em;
  padding: .72em 1.35em; border-radius: 999px;
  font-weight: 600; font-size: .95rem; cursor: pointer;
  background: transparent; color: var(--ton-texte);
  border: 1.5px solid color-mix(in srgb, var(--ton) 34%, var(--border));
  text-decoration: none; /* un <a> stylé en bouton ne doit pas être souligné */
  transition: background .16s, border-color .16s, color .16s, opacity .16s;
}
.btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--ton) 9%, transparent);
  border-color: color-mix(in srgb, var(--ton) 62%, var(--border));
}
.btn:active:not(:disabled) { background: color-mix(in srgb, var(--ton) 17%, transparent); }
.btn:disabled { opacity: .45; cursor: not-allowed; }

/* Variantes : seule la teinte change. */
.btn.ok { --ton: var(--ok); }
.btn.warn { --ton: var(--warn); }
.btn.danger { --ton: var(--danger); }
/* Anneau de focus visible au clavier : nécessaire dès lors qu'il n'y a plus
   d'ombre pour marquer l'état actif. */
.btn:focus-visible, .iconbtn:focus-visible, .opt:focus-visible,
.sort-cat:focus-visible, .match-item:focus-visible, .theme-switch:focus-visible,
.pending-chip:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px;
}
/* Bouton secondaire : exactement le même comportement, dans une teinte neutre.
   C'est la couleur qui porte la hiérarchie, pas une différence de mécanique. */
.btn.ghost { --ton: var(--text-mute); color: var(--text-soft); border-color: var(--border); }
.btn.ghost:hover:not(:disabled) { border-color: color-mix(in srgb, var(--text-mute) 65%, var(--border)); }
.btn.ghost.warn-ghost { --ton: var(--warn); }
.btn.ghost.ok-ghost { --ton: var(--ok); }



.btn.lg { padding: .95em 2em; font-size: 1.05rem; }
.btn.sm { padding: .45em .95em; font-size: .84rem; }
.btn.ghost.danger-ghost { --ton: var(--danger); padding: .45em .7em; }

/* ─────────────── Écran d'authentification ─────────────── */
.auth {
  min-height: 100vh; display: grid; grid-template-columns: 1.05fr .95fr;
}
.auth__brand {
  position: relative; overflow: hidden; color: #fff;
  background: linear-gradient(140deg, #4f46e5 0%, #7c3aed 45%, #0d9488 120%);
  display: flex; flex-direction: column; justify-content: center; padding: 4rem 4.5rem;
}
.auth__brand::before, .auth__brand::after {
  content: ''; position: absolute; border-radius: 50%; opacity: .18;
  background: radial-gradient(circle at 30% 30%, #fff, transparent 65%);
}
.auth__brand::before { width: 520px; height: 520px; top: -160px; right: -140px; animation: float 16s ease-in-out infinite; }
.auth__brand::after { width: 380px; height: 380px; bottom: -120px; left: -100px; animation: float 20s ease-in-out infinite reverse; }
@keyframes float { 50% { transform: translate(26px, -30px) scale(1.06); } }

.auth__logo { display: flex; align-items: center; gap: .75rem; font-weight: 800; font-size: 1.15rem; letter-spacing: -.01em; margin-bottom: 3rem; position: relative; }
/* Le logo est posé sur une pastille blanche : ses roses et ses bleus se
   perdraient sur le dégradé violet du panneau de gauche. */
.auth__logo .mark {
  width: 46px; height: 46px; border-radius: 14px; display: grid; place-items: center; padding: 5px;
  background: #fff; box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
}
.auth__brand h1 { font-size: clamp(2rem, 3.4vw, 3rem); position: relative; margin-bottom: .35em; }
.auth__brand p { font-size: 1.08rem; opacity: .92; max-width: 30ch; position: relative; }
.auth__features { list-style: none; padding: 0; margin: 2.5rem 0 0; display: grid; gap: 1rem; position: relative; }
.auth__features li { display: flex; align-items: flex-start; gap: .85rem; font-size: .98rem; opacity: .95; }
.auth__features .ico {
  flex: none; width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center;
  background: rgba(255, 255, 255, .16); border: 1px solid rgba(255, 255, 255, .2);
}

.auth__panel { display: grid; place-items: center; padding: 2.5rem; background: var(--bg); }
.auth__card h2 { font-size: 1.5rem; }
.auth__card .auth__intro { color: var(--text-soft); font-size: .94rem; }

/* Sur iOS, 100vh dépasse la zone réellement visible (barres du navigateur) :
   le bas de la page s'y retrouve tronqué. 100svh vise la plus petite hauteur
   possible, donc toujours visible. */
@supports (min-height: 100svh) {
  .auth { min-height: 100svh; }
}
.auth__card { width: min(430px, 100%); }
.auth__tabs { display: flex; gap: .3rem; background: var(--bg-soft); padding: .3rem; border-radius: 999px; margin-bottom: 1.8rem; }
.auth__tabs button {
  flex: 1; padding: .65em 1em; border: 0; background: transparent; border-radius: 999px;
  font-weight: 600; color: var(--text-soft); cursor: pointer; transition: .2s;
}
.auth__tabs button.on { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }

.field { margin-bottom: 1.05rem; }
.field label { display: block; font-size: .85rem; font-weight: 600; color: var(--text-soft); margin-bottom: .4rem; }
.field input, .field select, .field textarea {
  width: 100%; padding: .8em 1em; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--text); font-size: .98rem; font-family: inherit; transition: .18s;
}
.field input:focus, .field select:focus {
  outline: none; border-color: var(--brand); box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 14%, transparent);
}
.field .hint { font-size: .78rem; color: var(--text-mute); margin-top: .35rem; }

.alert { padding: .8em 1em; border-radius: var(--radius-sm); font-size: .9rem; margin-bottom: 1rem; display: flex; gap: .6em; align-items: flex-start; }
.alert.err { background: var(--danger-soft); color: var(--danger); }
.alert.ok { background: var(--ok-soft); color: var(--ok); }
.alert.info-note {
  background: var(--info-soft); color: color-mix(in srgb, var(--info) 78%, var(--text));
  font-size: .84rem; align-items: flex-start; margin: .2rem 0 1rem;
}

.alert.ok-note {
  background: var(--ok-soft); color: color-mix(in srgb, var(--ok) 82%, var(--text));
  font-size: .84rem; margin: .2rem 0 1rem;
}
.alert.warn-note {
  background: var(--warn-soft); color: color-mix(in srgb, var(--warn) 82%, var(--text));
  font-size: .84rem; margin: .2rem 0 1rem;
}
.alert.warn-note b, .alert.ok-note b { color: inherit; }

/* Écran de confirmation de la dernière question d'une évaluation. */
.quiz-recap {
  border: 1px solid color-mix(in srgb, var(--ok) 35%, var(--border));
  background: color-mix(in srgb, var(--ok) 7%, var(--surface));
  border-radius: var(--radius); padding: 1.1rem 1.2rem; margin-top: 1.2rem;
}
.quiz-recap__titre {
  font-size: .74rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-mute); margin-bottom: .6rem;
}
.quiz-recap__ligne { display: flex; align-items: flex-start; gap: .6rem; padding: .25rem 0; font-size: .96rem; }
.quiz-recap__ligne .ok { color: var(--ok); font-weight: 700; flex: 0 0 auto; }
.quiz-recap__aide { font-size: .85rem; color: var(--text-mute); margin: .9rem 0 0; }

/* Fin d'un exercice : le moteur vide sa zone, il faut donc dire ce qui a été
   fait et où se trouve la suite. Le bouton de validation se signale, car il
   tombe souvent sous la ligne de flottaison d'un écran de portable. */
.game-fini {
  display: flex; flex-direction: column; gap: .2rem; text-align: center;
  padding: 1.2rem; border-radius: var(--radius);
  background: color-mix(in srgb, var(--ok) 9%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ok) 32%, var(--border));
}
.game-fini b { font-size: 1.05rem; color: var(--ok); }
.game-fini span { font-size: .88rem; color: var(--text-soft); }

.step-nav--pret .btn.lg {
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 55%, transparent);
  animation: pretPulse 1.6s ease-out 3;
}
@keyframes pretPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 45%, transparent); }
  70%  { box-shadow: 0 0 0 14px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) { .step-nav--pret .btn.lg { animation: none; } }

/* ═══════════════ Cyber Escape Game ═══════════════ */
.esc-entete {
  display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap;
  padding: .9rem 1.2rem; margin-bottom: 1.4rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  position: sticky; top: .6rem; z-index: 5; box-shadow: var(--shadow-sm);
}
.esc-entete__titre b { display: block; font-size: .96rem; }
.esc-entete__titre span { font-size: .78rem; color: var(--text-mute); }
.esc-entete__droite { margin-left: auto; display: flex; align-items: center; gap: .9rem; }

.esc-jauge { display: flex; gap: .3rem; }
.esc-plot {
  width: 1.7rem; height: 1.7rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .74rem; font-weight: 700;
  background: var(--bg-soft); color: var(--text-mute); border: 1px solid var(--border);
}
.esc-plot.faite { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.esc-plot.active { background: var(--brand); color: #fff; border-color: var(--brand); }

.esc-coffre { display: flex; gap: .25rem; }
.esc-case {
  width: 1.5rem; height: 1.9rem; border-radius: 5px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'DejaVu Sans Mono', monospace; font-weight: 700; font-size: .9rem;
  background: var(--bg-soft); color: var(--text-mute); border: 1px dashed var(--border);
}
.esc-case.on { background: color-mix(in srgb, var(--brand) 12%, transparent); color: var(--brand); border: 1px solid var(--brand); }
.esc-chrono {
  font-family: 'DejaVu Sans Mono', monospace; font-size: 1.05rem; font-weight: 700;
  color: var(--text); padding: .2rem .6rem; border-radius: 7px; background: var(--bg-soft);
}

/* ── Intro, salles, résolution ── */
.esc-intro, .esc-final, .esc-fin, .esc-resolu {
  text-align: center; max-width: 640px; margin: 0 auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 2.4rem 2rem;
}
.esc-intro__ico, .esc-final__ico, .esc-fin__ico { font-size: 3rem; }
.esc-intro h2, .esc-final h2, .esc-fin h2 { margin: .6rem 0 1rem; font-size: 1.5rem; }
.esc-intro p, .esc-final p, .esc-fin p { color: var(--text-soft); line-height: 1.65; }
.esc-mission {
  margin: 1.4rem 0 .4rem; font-size: .8rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--brand);
}
.esc-actions { display: flex; gap: .7rem; justify-content: center; margin-top: 1.4rem; flex-wrap: wrap; }

.esc-salle { --ton: var(--brand); }
.esc-salle.ton-danger { --ton: var(--danger); }
.esc-salle.ton-warn { --ton: var(--warn); }
.esc-salle.ton-info { --ton: var(--info); }
.esc-salle.ton-ok { --ton: var(--ok); }
.esc-salle__tete { display: flex; gap: 1rem; align-items: flex-start; margin-bottom: 1rem; }
.esc-salle__ico {
  flex: 0 0 auto; width: 3rem; height: 3rem; border-radius: var(--radius-sm); font-size: 1.5rem;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--ton) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ton) 28%, var(--border));
}
.esc-salle__kicker { font-size: .74rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ton); }
.esc-salle__tete h2 { margin: .1rem 0 .1rem; font-size: 1.4rem; }
.esc-salle__ss { font-size: .9rem; color: var(--text-soft); }
.esc-brief {
  background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--ton);
  border-radius: var(--radius-sm); padding: 1rem 1.1rem; color: var(--text-soft); line-height: 1.65;
  margin-bottom: 1.4rem;
}
.esc-consigne {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  font-weight: 600; margin-bottom: .8rem; flex-wrap: wrap;
}
.esc-compteur {
  font-family: 'DejaVu Sans Mono', monospace; font-weight: 700; color: var(--ton, var(--brand));
  background: color-mix(in srgb, var(--ton, var(--brand)) 11%, transparent);
  padding: .15rem .6rem; border-radius: 99px; font-size: .88rem;
}
.esc-aide { font-size: .85rem; color: var(--text-mute); margin: 0 0 1rem; }

.esc-resolu__chiffre {
  width: 4rem; height: 4rem; margin: 0 auto 1rem; border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center;
  font-family: 'DejaVu Sans Mono', monospace; font-size: 2rem; font-weight: 800;
  color: #fff; background: var(--ok);
}
.esc-resolu b { font-size: 1.15rem; }
.esc-resolu__code { font-size: .9rem; color: var(--text-mute); }

/* ── Message piégé ── */
.esc-mail { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); overflow: hidden; }
.esc-mail__head { padding: 1rem 1.2rem; background: var(--surface-2); border-bottom: 1px solid var(--border); font-size: .9rem; }
.esc-mail__head > div { display: flex; gap: .6rem; padding: .18rem 0; }
.esc-mail__head .lbl { flex: 0 0 3.4rem; color: var(--text-mute); font-size: .8rem; }
.esc-mail__corps { padding: 1.4rem 1.4rem 1.2rem; font-size: .94rem; line-height: 1.75; color: var(--text-soft); }
.esc-mail__par { margin: 0 0 .95rem; }
.esc-mail__par:last-child { margin-bottom: 0; }
/* La signature se détache, comme sur le papier. */
.esc-mail__par:last-child:not(:only-child) { margin-top: .3rem; }
.esc-frag { cursor: pointer; border-radius: 3px; padding: 0 1px; transition: background .12s; }
.esc-frag:hover { background: color-mix(in srgb, var(--brand) 13%, transparent); }
.esc-frag.trouve {
  background: color-mix(in srgb, var(--ok) 20%, transparent); color: var(--ok);
  font-weight: 600; cursor: default;
}
.esc-frag.ecarte { opacity: .45; cursor: default; }
.esc-mail__corps { word-spacing: .02em; }

/* ── Trouvailles et explications ── */
.esc-detail { display: flex; flex-direction: column; gap: .6rem; margin-top: 1.2rem; }
.esc-trouvaille {
  padding: .8rem 1rem; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--ok) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ok) 28%, var(--border));
  animation: escApparait .25s ease-out;
}
.esc-trouvaille.mauvaise {
  background: color-mix(in srgb, var(--danger) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--danger) 28%, var(--border));
}
.esc-trouvaille b { display: block; font-size: .93rem; margin-bottom: .2rem; }
.esc-trouvaille p { margin: 0; font-size: .88rem; color: var(--text-soft); line-height: 1.6; }
@keyframes escApparait { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* ── Cartes de réponse ── */
.esc-cartes { display: grid; gap: .55rem; }
.esc-carte {
  display: flex; align-items: center; gap: .8rem; text-align: left; width: 100%;
  padding: .85rem 1rem; border-radius: var(--radius-sm); font-family: inherit; font-size: .94rem;
  background: var(--surface); border: 1px solid var(--border); color: var(--text); cursor: pointer;
  transition: border-color .15s, background .15s;
}
.esc-carte:hover:not(.placee):not(.ecartee) { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 5%, var(--surface)); }
.esc-carte.choisie { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 11%, var(--surface)); font-weight: 600; }
.esc-carte.placee { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 11%, var(--surface)); cursor: default; }
.esc-carte.ecartee { border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); opacity: .5; cursor: default; text-decoration: line-through; }
.esc-carte__rang {
  flex: 0 0 auto; width: 1.6rem; height: 1.6rem; border-radius: 50%; background: var(--ok); color: #fff;
  display: inline-flex; align-items: center; justify-content: center; font-size: .78rem; font-weight: 700;
}
.esc-carte__txt { flex: 1; }

/* ── Tri ── */
.esc-tri__item {
  text-align: center; font-size: 1.02rem; font-weight: 600; padding: 1.6rem 1.2rem;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: .9rem;
}
.esc-tri__cats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: .6rem; }
.esc-cat {
  display: flex; flex-direction: column; align-items: center; gap: .3rem; padding: 1rem .8rem;
  border-radius: var(--radius-sm); font-family: inherit; font-size: .88rem; font-weight: 600; cursor: pointer;
  background: color-mix(in srgb, var(--cat) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--cat) 32%, var(--border)); color: var(--cat);
}
.esc-cat:hover { background: color-mix(in srgb, var(--cat) 18%, var(--surface)); }
.esc-cat .ico { font-size: 1.3rem; }

/* ── Conversation piégée ──
   Le fil s'allonge à chaque tour et les messages précédents restent lisibles :
   la fraude au virement tient à l'enchaînement, qu'on doit pouvoir relire. */
.esc-fil { display: flex; flex-direction: column; gap: .8rem; margin-bottom: 1.2rem; }
.esc-bulle {
  border: 1px solid var(--border); border-left: 4px solid var(--warn);
  border-radius: var(--radius); background: var(--surface); padding: .9rem 1.1rem; max-width: 88%;
}
.esc-bulle__de { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .5rem; }
.esc-bulle__de b { font-size: .93rem; }
.esc-bulle__de span { font-size: .8rem; color: var(--text-soft); }
.esc-bulle__objet {
  font-size: .82rem; color: var(--text-soft); margin-bottom: .5rem;
  padding-bottom: .5rem; border-bottom: 1px dashed var(--border);
}
.esc-bulle p { margin: 0 0 .5rem; font-size: .92rem; line-height: 1.65; white-space: pre-line; }
.esc-bulle p:last-child { margin-bottom: 0; }
/* Vos réponses : alignées à droite, dans le vert de ce qui est acquis. */
.esc-bulle--moi {
  align-self: flex-end; border-left: 1px solid var(--border); border-right: 4px solid var(--ok);
  background: color-mix(in srgb, var(--ok) 7%, var(--surface));
}

/* ── La fiche de registre ──
   Une ligne par rubrique : l'intitulé à gauche, les mentions possibles à
   droite. Une fois tranchée, la rubrique se fige — on ne revient pas sur un
   registre qu'on vient de remplir. */
.esc-fiche__tete {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .9rem 1.1rem; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: color-mix(in srgb, var(--brand) 9%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--brand) 26%, var(--border)); border-bottom: 0;
}
.esc-fiche__tete b { font-size: 1rem; }
.esc-fiche__tete span { font-size: .8rem; color: var(--text-soft); }
.esc-fiche {
  border: 1px solid var(--border); border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  overflow: hidden; margin-bottom: 1.2rem;
}
.esc-fiche__ligne {
  display: flex; gap: 1rem; align-items: flex-start; flex-wrap: wrap;
  padding: .8rem 1.1rem; border-bottom: 1px solid var(--border); background: var(--surface);
}
.esc-fiche__ligne:last-child { border-bottom: 0; }
.esc-fiche__ligne.remplie { background: color-mix(in srgb, var(--ok) 8%, var(--surface)); }
.esc-fiche__lbl {
  flex: 0 0 9rem; font-size: .74rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-mute); padding-top: .45rem;
}
.esc-fiche__valeur { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.esc-fiche__ok { font-size: .93rem; font-weight: 600; color: var(--ok); padding: .35rem 0; }
.esc-chip {
  padding: .4rem .8rem; border-radius: 999px; cursor: pointer; text-align: left;
  font-family: inherit; font-size: .86rem; color: var(--text);
  background: var(--surface-2); border: 1px solid var(--border);
  transition: border-color .16s, background .16s;
}
.esc-chip:hover:not(.ecartee) { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); }
.esc-chip.ecartee { opacity: .45; text-decoration: line-through; cursor: default; border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); }

/* ── L'arbre de décision ──
   Le chemin parcouru reste affiché : c'est lui qu'il faut retenir, pas la
   conclusion seule. Le filet vertical relie les marches franchies. */
.esc-arbre { position: relative; margin-bottom: 1.2rem; padding-left: .2rem; }
.esc-arbre__noeud {
  position: relative; display: flex; gap: .9rem; align-items: flex-start;
  padding: .9rem 1.1rem .9rem .9rem; margin-bottom: .5rem;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--border); border-radius: var(--radius-sm);
}
.esc-arbre__noeud.franchi { border-left-color: var(--ok); }
.esc-arbre__rang {
  flex: none; width: 1.6rem; height: 1.6rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem; font-weight: 700; color: #fff; background: var(--brand);
}
.esc-arbre__noeud.franchi .esc-arbre__rang { background: var(--ok); }
.esc-arbre__noeud b { font-size: .97rem; }
.esc-arbre__noeud p { margin: .25rem 0 0; font-size: .89rem; color: var(--text-soft); line-height: 1.6; }
.esc-arbre__reponse {
  display: flex; gap: .45rem; align-items: baseline; margin-top: .55rem;
  padding-top: .55rem; border-top: 1px dashed var(--border); font-size: .9rem; color: var(--ok);
}
.esc-arbre__fin {
  padding: 1rem 1.2rem; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--ok) 9%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ok) 32%, var(--border)); border-left: 3px solid var(--ok);
}
.esc-arbre__fin b { display: block; font-size: 1rem; margin-bottom: .25rem; }
.esc-arbre__fin p { margin: 0; font-size: .92rem; line-height: 1.65; color: var(--text-soft); }

@media (max-width: 640px) {
  .esc-fiche__lbl { flex: 1 0 100%; padding-top: 0; }
}

/* ── Écran de rançon ──
   Volontairement laid : terminal noir, texte sans accents, fautes de casse.
   C'est à cela que ressemblent ces messages, et le reconnaître fait partie de
   ce qu'on apprend ici. La couleur ne suit pas le thème — un écran de rançon
   n'a pas de mode clair. */
.esc-rancon {
  border-radius: var(--radius); overflow: hidden; margin-bottom: 1.2rem;
  border: 1px solid #3a0d16; background: #0b0b0f;
}
.esc-rancon__tete {
  display: flex; align-items: center; gap: .7rem; padding: .8rem 1.1rem;
  background: #7a0b1e; color: #ffe8ec; font-weight: 700; letter-spacing: .04em;
}
.esc-rancon__tete .ico { font-size: 1.2rem; }
.esc-rancon__note {
  margin: 0; padding: 1.2rem; overflow-x: auto;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: .84rem; line-height: 1.75; color: #d8dbe0; white-space: pre-wrap;
}
.esc-rancon__phrase {
  text-align: center; font-size: 1.05rem; font-weight: 600; font-style: italic;
  padding: 1.5rem 1.2rem; margin-bottom: .9rem;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
}
.esc-rancon__choix { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; }
/* Le verdict est rappelé sur chaque ligne du récapitulatif : sans lui, on
   relit une explication sans savoir de quel côté elle penchait. */
.esc-verdict {
  display: inline-block; margin-bottom: .35rem; padding: .1rem .5rem; border-radius: 999px;
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  background: var(--surface-2); color: var(--text-soft); border: 1px solid var(--border);
}

/* ── Saisie du code ── */
.esc-saisies { display: flex; gap: .5rem; justify-content: center; margin: 1.6rem 0 .6rem; }
.esc-saisie {
  width: 3rem; height: 3.6rem; text-align: center; font-size: 1.5rem; font-weight: 800;
  font-family: 'DejaVu Sans Mono', monospace;
  border-radius: var(--radius-sm); border: 1.5px solid var(--border); background: var(--surface); color: var(--text);
}
.esc-saisie:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent); }

/* ── Bilan final ── */
.esc-bilan { display: flex; gap: 1.6rem; justify-content: center; flex-wrap: wrap; margin: 1.6rem 0; }
.esc-bilan div { display: flex; flex-direction: column; }
.esc-bilan b { font-size: 1.6rem; color: var(--brand); }
.esc-bilan span { font-size: .76rem; color: var(--text-mute); }
.esc-fin__soustitre { font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-mute); margin: 1.6rem 0 .9rem; }
.esc-reflexes { display: grid; grid-template-columns: repeat(2, 1fr); gap: .7rem; }
.esc-reflexe {
  padding: 1rem .7rem; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border);
}
.esc-reflexe .ico { font-size: 1.5rem; display: block; }
.esc-reflexe b { display: block; font-size: .82rem; letter-spacing: .04em; margin: .3rem 0 .2rem; }
.esc-reflexe span { font-size: .78rem; color: var(--text-mute); line-height: 1.45; }

/* ═══════════════ Le bureau des erreurs ═══════════════
   La scène est une image ; les zones cliquables sont des rectangles SVG posés
   par-dessus, en coordonnées de l'image. Aucune n'est visible au repos : la
   salle consiste à regarder, pas à repérer ce qui brille. */
.bureau {
  max-width: 920px; margin: 0 auto;
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden; background: var(--surface-2);
}
/* Une image matricielle ne suit pas le thème. Plutôt que d'en produire deux,
   on l'assombrit légèrement : le contraste du texte de la page reste maître. */
html[data-theme='dark'] .bureau { filter: brightness(.86) saturate(.94); }

.bureau-svg { display: block; width: 100%; height: auto; }
.bureau-svg image { pointer-events: none; }

.bureau-zone {
  fill: transparent; stroke: transparent; stroke-width: 5;
  cursor: pointer; transition: fill .15s, stroke .15s;
}
.bureau-zone:hover { fill: color-mix(in srgb, #ffffff 20%, transparent); stroke: rgba(255,255,255,.6); }
.bureau-zone:focus-visible { outline: none; stroke: var(--brand); stroke-width: 6; }
.bureau-zone.trouvee {
  fill: color-mix(in srgb, #12b76a 28%, transparent);
  stroke: #12b76a; cursor: default; pointer-events: none;
}

@media (max-width: 700px) {
  .esc-entete { position: static; }
  .esc-saisie { width: 2.4rem; height: 3rem; font-size: 1.2rem; }
}

/* ─────────────── Familles de parcours ───────────────
   Deux familles ont chacune leur « Niveau 1 » : le regroupement porte la
   distinction, sans quoi deux entrées homonymes se côtoieraient. */
.familles { display: grid; gap: 1.1rem; margin-bottom: 1.6rem; }
.famille__titre {
  font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-mute); margin-bottom: .5rem;
}
.famille .niveaux { margin-bottom: 0; }

/* ─────────────── Modules complémentaires ───────────────
   Une grille de cartes, pas un chemin : les modules se prennent dans
   n'importe quel ordre. La teinte reprend celle du module à l'écran comme
   sur son attestation. */
.mod-intro { color: var(--text-soft); font-size: .9rem; margin: -.4rem 0 1.1rem; }
.mod-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(285px, 1fr)); gap: .9rem; margin-bottom: 2.4rem; }

.mod-carte {
  --ton: var(--brand);
  display: flex; align-items: flex-start; gap: .85rem; text-align: left;
  padding: 1rem 1.05rem; border-radius: var(--radius); font-family: inherit;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid color-mix(in srgb, var(--ton) 55%, var(--border));
  cursor: pointer; transition: border-color .18s, box-shadow .18s, transform .18s;
}
.mod-carte.ton-danger { --ton: var(--danger); }
.mod-carte.ton-warn   { --ton: var(--warn); }
.mod-carte.ton-info   { --ton: var(--info); }
.mod-carte.ton-teal   { --ton: var(--teal); }
.mod-carte:hover:not(.verrouille) {
  border-color: color-mix(in srgb, var(--ton) 45%, var(--border));
  border-left-color: var(--ton);
  box-shadow: var(--shadow); transform: translateY(-2px);
}
.mod-carte.verrouille { cursor: default; opacity: .55; border-left-color: var(--border); }
.mod-carte.reussi { border-left-color: var(--ok); }

.mod-ico {
  flex: 0 0 auto; width: 2.4rem; height: 2.4rem; border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center; font-size: 1.25rem;
  background: color-mix(in srgb, var(--ton) 11%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ton) 24%, var(--border));
}
.mod-txt { flex: 1; min-width: 0; display: block; }
.mod-txt b { display: block; font-size: 1rem; color: var(--text); line-height: 1.25; }
.mod-ss { display: block; font-size: .82rem; color: var(--text-soft); margin-top: .1rem; }
.mod-etat { display: block; font-size: .75rem; font-weight: 600; color: var(--ton); margin-top: .45rem; }
.mod-carte.verrouille .mod-etat { color: var(--text-mute); }
.mod-carte.reussi .mod-etat { color: var(--ok); }

/* Dérogations par module, dans la fiche d'un participant. */
/* ── Fiche d'un participant ──
   La fiche sert à décider : on y lit un état, on y ouvre ou on y referme un
   accès. Le détail chapitre par chapitre y tenait douze grandes lignes pour
   dire « 0/12 » — il est devenu une barre et une rangée de pastilles. */
.modal__body h4 {
  font-size: .78rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-mute); margin: 1.7rem 0 .8rem;
  padding-bottom: .45rem; border-bottom: 1px solid var(--border);
}
.modal__body h4:first-of-type { margin-top: 1.3rem; }

.fp-resume {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.3rem;
  font-size: .86rem; color: var(--text-soft);
}
.fp-resume b { color: var(--text); font-size: 1rem; }

.fp-niveau { margin-bottom: 1.1rem; }
.fp-niveau__tete { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; margin-bottom: .4rem; }
.fp-niveau__tete b { font-size: .92rem; }
.fp-niveau__tete span { font-size: .8rem; color: var(--text-mute); }
.fp-niveau .mini-bar { display: block; width: 100%; margin-bottom: .5rem; }

.fp-chips { display: flex; flex-wrap: wrap; gap: .3rem; }
.fp-chip {
  min-width: 1.65rem; height: 1.65rem; padding: 0 .35rem; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .74rem; font-weight: 600; cursor: default;
  background: var(--bg-soft); border: 1px solid var(--border); color: var(--text-mute);
}
.fp-chip.on { background: color-mix(in srgb, var(--ok) 16%, transparent); border-color: color-mix(in srgb, var(--ok) 45%, transparent); color: var(--ok); }
.fp-chip.partiel { background: color-mix(in srgb, var(--warn) 14%, transparent); border-color: color-mix(in srgb, var(--warn) 42%, transparent); color: var(--warn); }
.fp-chip--mod { min-width: 1.85rem; height: 1.85rem; font-size: .95rem; }
.fp-chip--mod:not(.on):not(.partiel) { filter: grayscale(1); opacity: .45; }

.fp-bascule {
  display: flex; align-items: center; gap: .6rem; padding: .5rem .55rem;
  border-radius: var(--radius-sm); cursor: pointer;
}
.fp-bascule { border: 1px solid var(--border); margin-bottom: .9rem; }
.fp-bascule:hover { background: var(--surface-2); }
.fp-bascule input { width: 1rem; height: 1rem; accent-color: var(--brand); cursor: pointer; flex: 0 0 auto; }
.fp-bascule .ico { font-size: 1rem; flex: 0 0 auto; }
.fp-bascule .nom { display: block; }
.fp-bascule .nom b { display: block; font-size: .9rem; }
.fp-bascule .nom small { display: block; font-size: .76rem; color: var(--text-mute); margin-top: .1rem; }

.fp-aide { font-size: .8rem; color: var(--text-mute); line-height: 1.5; margin: 0 0 .5rem; }

.fp-evals { display: flex; flex-direction: column; gap: .1rem; }
.fp-eval {
  display: flex; align-items: baseline; gap: .6rem; padding: .5rem .2rem;
  border-bottom: 1px solid var(--border); font-size: .86rem;
}
.fp-eval:last-child { border-bottom: 0; }
.fp-eval .st { flex: 0 0 auto; }
.fp-eval .quoi { flex: 1; min-width: 0; color: var(--text); }
.fp-eval b { color: var(--text); }
.fp-eval .quand { font-size: .78rem; color: var(--text-mute); }
.fp-vide { color: var(--text-mute); font-size: .88rem; }

/* Le contenu peut dépasser : la barre reste discrète, comme dans le tableau. */
.modal { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
.modal::-webkit-scrollbar { width: 8px; }
.modal::-webkit-scrollbar-track { background: transparent; }
.modal::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }
.modal::-webkit-scrollbar-thumb:hover { background: var(--text-mute); }

/* ─────────────── Réglages de l'organisme ───────────────
   Formulaire long et rarement ouvert : on privilégie la lisibilité de chaque
   champ à la densité. Deux colonnes seulement sur grand écran. */
.rg-form { max-width: 780px; }
.rg-groupe { margin-bottom: 2rem; }
.rg-groupe h3 {
  font-size: .82rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-mute); margin: 0 0 1rem;
  padding-bottom: .5rem; border-bottom: 1px solid var(--border);
}
.rg-champs { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.4rem; }
.rg-champs .field { margin-bottom: 1.3rem; }
.rg-champs .hint { font-size: .78rem; color: var(--text-mute); margin-top: .35rem; line-height: 1.45; }
.rg-champs textarea { resize: vertical; min-height: 2.6em; }

/* Une mention imposée par la loi et laissée vide doit se voir dès le
   formulaire, pas seulement sur la page publique. */
.rg-tag {
  margin-left: .5em; padding: .05em .55em; border-radius: 999px;
  font-size: .66rem; font-weight: 600; letter-spacing: .02em; text-transform: none;
  color: var(--text-mute); background: var(--bg-soft); border: 1px solid var(--border);
}
.rg-tag--manque {
  color: var(--warn); background: var(--warn-soft);
  border: 1px dashed color-mix(in srgb, var(--warn) 45%, transparent);
}

.rg-ecarts { list-style: none; margin: .2rem 0 0; padding: 0; font-size: .82rem; }
.rg-ecarts li { padding: .15rem 0; }
.rg-ecarts i { font-style: normal; padding: 0 .35em; border-radius: 4px; background: color-mix(in srgb, var(--warn) 14%, transparent); }

.rg-actions { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: .4rem; }
.rg-maj { font-size: .78rem; color: var(--text-mute); margin-top: 1.2rem; }

@media (max-width: 700px) {
  .rg-champs { grid-template-columns: 1fr; }
}

/* ─────────────── Shell applicatif ─────────────── */
.topbar {
  /* Fond opaque plutôt que translucide + flou : le flou était recalculé à
     chaque défilement, sur toutes les pages. */
  position: sticky; top: 0; z-index: 40; background: var(--surface);
  border-bottom: 1px solid var(--border);
}
/* La barre occupe toute la largeur, mais son contenu de GAUCHE reste aligné
   sur la colonne de contenu : le retrait à gauche vaut exactement la marge de
   centrage d'un bloc de 1180 px, et le bloc de droite se cale contre le bord
   de la page.
   Le calcul porte sur `50%` de la barre — la largeur réellement disponible —
   et non sur `100vw`, qui compte la barre de défilement et décalerait le logo
   de quelques pixels par rapport au contenu situé dessous. */
.topbar__in {
  max-width: none; margin: 0;
  /* 590px = la moitié des 1180px de `main`, et 1.4rem son retrait interne :
     le logo tombe ainsi sur le bord du TEXTE de la page, pas sur celui de sa
     boîte. Vingt-deux pixels d'écart se voient, sur une verticale aussi longue. */
  padding: .7rem 1.4rem .7rem max(1.4rem, calc(50% - 590px + 1.4rem));
  display: flex; align-items: center; gap: 1.2rem; min-width: 0;
}
.topbar__logo {
  display: flex; align-items: center; gap: .6rem; font-weight: 800; cursor: pointer;
  letter-spacing: -.02em; min-width: 0;
}
.topbar__logo .brand-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar__logo .mark {
  width: 36px; height: 36px; display: grid; place-items: center; flex: none;
}

/* Le logo garde ses couleurs propres : pas de fond ni de teinte appliquée. */
.logo-img { display: block; width: 100%; height: 100%; object-fit: contain; }
/* L'intitulé de la section, à la place des six boutons d'autrefois. */
.topbar__ou {
  margin-left: .9rem; padding-left: .9rem; border-left: 1px solid var(--border);
  font-size: .88rem; font-weight: 600; color: var(--text-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.topbar__spacer { flex: 1 1 0; min-width: 0; }

.xpchip {
  display: flex; align-items: center; gap: .6rem; padding: .35rem .8rem .35rem .45rem;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px; flex: none;
}
.xpchip .lvl {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; color: #fff; font-size: .8rem; font-weight: 700;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
}
.xpchip .bar { width: 96px; height: 6px; border-radius: 99px; background: var(--border); overflow: hidden; }
.xpchip .bar i { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--brand), var(--teal)); transition: width .6s cubic-bezier(.2,.8,.2,1); }
.xpchip .val { font-size: .78rem; font-weight: 700; color: var(--text-soft); white-space: nowrap; }

.iconbtn {
  width: 38px; height: 38px; border-radius: 50%; border: 1.5px solid var(--border); background: transparent;
  cursor: pointer; display: grid; place-items: center; font-size: 1rem; color: var(--text-soft);
  transition: background .16s, border-color .16s, color .16s; flex: none;
}
.iconbtn:hover {
  background: color-mix(in srgb, var(--brand) 9%, transparent);
  color: color-mix(in srgb, var(--brand) 70%, var(--text));
  border-color: color-mix(in srgb, var(--brand) 62%, var(--border));
}

/* ── Sélecteur bascule jour / nuit ── */
.theme-switch {
  position: relative; flex: none; width: 64px; height: 32px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface-2); padding: 0;
  display: flex; align-items: center; justify-content: space-around;
}
.theme-switch .ico { position: relative; z-index: 1; font-size: .8rem; line-height: 1; transition: opacity .2s, transform .2s; }
.theme-switch .knob {
  position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: 50%; z-index: 0;
  background: var(--surface); box-shadow: var(--shadow-sm);
  transition: transform .3s cubic-bezier(.3, 1.5, .5, 1);
}
html[data-theme='dark'] .theme-switch .knob { transform: translateX(34px); }
html[data-theme='light'] .theme-switch .moon,
html[data-theme='dark'] .theme-switch .sun { opacity: .3; transform: scale(.85); }
.theme-switch:hover { border-color: color-mix(in srgb, var(--brand) 45%, var(--border)); }

/* Pastille du compte : le nom en toutes lettres, et un chevron qui annonce le
   menu. Volontairement plus discrète que la pastille d'XP voisine — l'une est
   un état qu'on regarde, l'autre une commande qu'on ouvre. Les deux au même
   niveau de contraste feraient une barre à deux titres concurrents. */
.compte-chip {
  display: flex; align-items: center; gap: .45rem; flex: none;
  max-width: 15rem; height: 38px; padding: 0 .55rem 0 .8rem;
  border-radius: 999px; cursor: pointer; font-family: inherit;
  font-size: .86rem; font-weight: 700; color: var(--text-soft);
  background: transparent; border: 1px solid transparent; transition: .15s;
}
.compte-chip .nom, .compte-chip .prenom {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
/* Le prénom seul est le repli des écrans étroits : masqué par défaut. */
.compte-chip .prenom { display: none; }
.compte-chip .chevron {
  flex: none; width: .5em; height: .5em; margin-bottom: .2em;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); opacity: .55;
}
.compte-chip:hover, .compte-chip:focus-visible {
  background: var(--surface-2); border-color: var(--border); color: var(--text);
}
.compte-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* position: fixed — la barre haute est collante, le menu doit rester ancré à
   l'écran. Son décalage exact est calculé à l'ouverture depuis l'avatar, la
   hauteur de la barre variant selon la largeur d'écran. */
.menu {
  position: fixed; right: 1.4rem; top: 62px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-lg); min-width: 230px; padding: .45rem; z-index: 60;
  animation: pop .16s ease-out;
  max-height: calc(100vh - 76px); overflow-y: auto;
}
.menu .who { padding: .7rem .8rem; border-bottom: 1px solid var(--border); margin-bottom: .3rem; }
.menu .who b { display: block; font-size: .93rem; }
.menu .who span { font-size: .8rem; color: var(--text-mute); word-break: break-all; }
.menu button {
  width: 100%; text-align: left; border: 0; background: transparent; padding: .6em .8em; border-radius: 8px;
  cursor: pointer; color: var(--text); font-size: .9rem; display: flex; gap: .6em; align-items: center;
}
.menu button:hover { background: var(--surface-2); }
@keyframes pop { from { opacity: 0; transform: translateY(-6px) scale(.98); } }

main { max-width: 1180px; margin: 0 auto; padding: 2.2rem 1.4rem 5rem; }
/* Le suivi des participants compte huit colonnes : la mesure de lecture confortable
   d'un texte ne lui convient pas. Sur grand écran, il prend la place disponible
   plutôt que d'imposer un défilement horizontal. */
main.large { max-width: 1500px; }

/* ─────────────── Accueil / carte du parcours ─────────────── */
.hero-home {
  position: relative; overflow: hidden; border-radius: var(--radius-lg); padding: 2.4rem 2.6rem;
  background: linear-gradient(135deg, #4f46e5, #7c3aed 55%, #0d9488); color: #fff; margin-bottom: 2.2rem;
  box-shadow: var(--shadow);
}
.hero-home::after {
  content: ''; position: absolute; width: 420px; height: 420px; border-radius: 50%; right: -120px; top: -180px;
  background: radial-gradient(circle, rgba(255,255,255,.22), transparent 68%);
}
.hero-home h1 { font-size: clamp(1.6rem, 3vw, 2.3rem); margin-bottom: .3em; position: relative; }
.hero-home p { opacity: .93; max-width: 56ch; position: relative; margin-bottom: 1.4rem; }
.hero-home .row { display: flex; flex-wrap: wrap; gap: 2rem; position: relative; align-items: center; }
.hero-home .hero-text { flex: 1; min-width: 260px; }
.hero-home .hero-actions { display: flex; gap: .7rem; flex-wrap: wrap; }
/* Sur le dégradé, même principe en blanc : contour et texte blancs, voile
   blanc très léger au survol. */
.hero-home .btn {
  background: transparent; color: #fff;
  border: 1.5px solid rgba(255, 255, 255, .55);
}
.hero-home .btn:hover:not(:disabled) { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .9); color: #fff; }
.hero-home .btn:active:not(:disabled) { background: rgba(255, 255, 255, .26); }
.hero-home .btn:focus-visible { outline-color: #fff; }

.ring { --p: 0; width: 104px; height: 104px; flex: none; position: relative; display: grid; place-items: center; }
.ring::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(#fff calc(var(--p) * 1%), rgba(255,255,255,.22) 0);
  mask: radial-gradient(farthest-side, transparent calc(100% - 9px), #000 calc(100% - 8px));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 9px), #000 calc(100% - 8px));
  transition: background .8s cubic-bezier(.2,.8,.2,1);
}
.ring b { font-size: 1.5rem; font-weight: 800; }
.ring small { display: block; font-size: .68rem; opacity: .85; text-align: center; margin-top: -4px; }

.section-title { display: flex; align-items: baseline; gap: .8rem; margin: 2.4rem 0 1.1rem; }
.section-title h2 { font-size: 1.28rem; margin: 0; }
.section-title span { font-size: .87rem; color: var(--text-mute); }

.path { display: grid; gap: 1rem; }
.node {
  display: flex; gap: 1.2rem; align-items: center; background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1.1rem 1.3rem; cursor: pointer; position: relative;
  transition: background .2s, border-color .2s, box-shadow .22s;
}
/* Au survol : un voile de la couleur du chapitre envahit la carte, la bordure
   se teinte, l'icône s'intensifie et le titre prend la couleur. Quatre signaux
   discrets qui, ensemble, se remarquent nettement — sans aucun aplat. */
.node:hover:not(.locked) {
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  box-shadow: var(--shadow);
}
.node:hover:not(.locked) .node__badge {
  background: color-mix(in srgb, var(--accent) 24%, var(--surface));
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}
.node:hover:not(.locked) .node__body h3 { color: color-mix(in srgb, var(--accent) 55%, var(--text)); }
.node__badge, .node__body h3 { transition: background .2s, border-color .2s, color .2s; }
.node.locked { opacity: .55; cursor: not-allowed; }
.node__badge {
  flex: none; width: 58px; height: 58px; border-radius: 18px; display: grid; place-items: center; font-size: 1.6rem;
  background: color-mix(in srgb, var(--accent) 14%, var(--surface)); border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  position: relative;
}
.node__num {
  position: absolute; top: -7px; left: -7px; width: 24px; height: 24px; border-radius: 50%; font-size: .72rem;
  display: grid; place-items: center; color: #fff; font-weight: 700; background: var(--accent); border: 2px solid var(--surface);
}
.node__body { flex: 1; min-width: 0; }
.node__body h3 { font-size: 1.05rem; margin: 0 0 .15em; }
.node__body p { margin: 0; font-size: .88rem; color: var(--text-soft); }
.node__meta { display: flex; gap: .8rem; margin-top: .45rem; font-size: .78rem; color: var(--text-mute); flex-wrap: wrap; }
.node__state { flex: none; font-size: 1.5rem; }
.node.done { border-color: color-mix(in srgb, var(--ok) 40%, var(--border)); }
.node.done .node__badge { background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.node.current { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }

.pill {
  display: inline-flex; align-items: center; gap: .35em; padding: .2em .65em;
  border-radius: 999px; font-size: .74rem; font-weight: 700;
  /* Sur une seule ligne : une pastille coupée en deux déséquilibre la hauteur
     des lignes du tableau. */
  white-space: nowrap;
}
.pill.ok { background: var(--ok-soft); color: var(--ok); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.info { background: var(--info-soft); color: var(--info); }
.pill.brand { background: var(--brand-soft); color: var(--brand); }

/* ── Sélecteur de niveau ── */
.niveaux { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: .8rem; margin-bottom: 1.8rem; }
.niveau {
  display: flex; align-items: center; gap: .9rem; text-align: left; width: 100%;
  padding: 1rem 1.2rem; border-radius: var(--radius); cursor: pointer; font-family: inherit;
  background: transparent; border: 1.5px solid var(--border); color: var(--text);
  transition: background .16s, border-color .16s;
}
.niveau:hover:not(:disabled) {
  background: color-mix(in srgb, var(--brand) 8%, transparent);
  border-color: color-mix(in srgb, var(--brand) 55%, var(--border));
}
/* Le niveau consulté se distingue par un contour affirmé, pas par un aplat. */
.niveau.on {
  border-color: color-mix(in srgb, var(--brand) 70%, var(--border));
  background: color-mix(in srgb, var(--brand) 6%, transparent);
}
.niveau.verrouille { opacity: .6; cursor: not-allowed; }
.niveau .niv-icone { font-size: 1.5rem; flex: none; }
.niveau .niv-texte { flex: 1; min-width: 0; display: block; }
.niveau .niv-texte b { display: block; font-size: .96rem; margin-bottom: .1rem; }
.niveau .niv-texte span { font-size: .8rem; color: var(--text-mute); }

/* ── La médaille d'un parcours validé ──
   Posée sur le coin de la carte, à côté du bouton et non dedans : la carte est
   elle-même un bouton, et l'imbrication rendrait le clavier inopérant.
   Elle mène à l'attestation ; le lien du bas de page reste en place. */
.carte-medaillee { position: relative; display: flex; }
.carte-medaillee > .niveau,
.carte-medaillee > .mod-carte { flex: 1; padding-right: 3.1rem; }
.medaille {
  position: absolute; top: .55rem; right: .55rem;
  display: flex; align-items: center; justify-content: center;
  width: 2.1rem; height: 2.1rem; padding: 0; line-height: 1; font-size: 1.15rem;
  border-radius: 50%; cursor: pointer;
  background: transparent; border: 1px solid transparent;
  transition: background .16s, border-color .16s, transform .16s;
}
.medaille:hover {
  background: color-mix(in srgb, var(--ok) 16%, var(--surface));
  border-color: color-mix(in srgb, var(--ok) 45%, var(--border));
  transform: scale(1.1);
}
.medaille:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* La carte de niveau est centrée verticalement : la médaille l'accompagne. */
.carte-medaillee > .niveau ~ .medaille { top: 50%; right: .7rem; transform: translateY(-50%); }
.carte-medaillee > .niveau ~ .medaille:hover { transform: translateY(-50%) scale(1.1); }

/* ── Sources d'un écran ── */
.sources {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .9rem;
  margin-top: 1.2rem; padding-top: .9rem; border-top: 1px solid var(--border);
  font-size: .82rem;
}
.sources .src-titre { color: var(--text-mute); font-weight: 700; }
.sources a {
  color: var(--text-soft); text-decoration: none;
  border-bottom: 1px dashed color-mix(in srgb, var(--brand) 45%, transparent);
}
.sources a:hover { color: var(--brand); border-bottom-color: var(--brand); }
.sources a::after { content: ' ↗'; font-size: .85em; opacity: .7; }

/* ── Progression par niveau dans le tableau d'administration ── */
/* ── Tableau d'administration : une colonne par objet de progression ──
   Chaque cellule tient sur UNE ligne. La pastille porte à la fois la valeur et
   l'avancement — son fond se remplit à proportion —, là où une barre séparée
   doublait la largeur pour dire la même chose. */
.data--admin th { white-space: nowrap; }
.data--admin td { vertical-align: middle; }
/* L'alignement vaut pour l'intitulé comme pour la cellule : appliqué à la
   seule cellule, le titre restait collé à gauche d'une colonne centrée. */
.data--admin th.c-num, .c-num { text-align: center; white-space: nowrap; }
.data--admin th.c-droite { text-align: right; }
.c-vide { color: var(--text-mute); font-size: .82rem; }
.c-date { font-size: .8rem; color: var(--text-mute); white-space: nowrap; }
.c-eval { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.c-eval b { font-size: .95rem; }
.c-eval .c-vide { font-size: .74rem; }

.prog-chip {
  --p: 0%;
  display: inline-block; padding: .22rem .55rem; border-radius: 999px;
  font-size: .8rem; font-weight: 600; color: var(--text); white-space: nowrap;
  border: 1px solid var(--border);
  /* Le remplissage EST la barre de progression : dégradé net, arrêté au ratio. */
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--brand) 26%, var(--surface)) var(--p),
    var(--surface-2) var(--p));
}
.prog-chip.plein {
  border-color: color-mix(in srgb, var(--ok) 45%, var(--border));
  background: color-mix(in srgb, var(--ok) 16%, var(--surface));
  color: var(--ok);
}
.prog-jeux { display: inline-flex; gap: .3rem; }
.prog-jeux .prog-chip { background: var(--surface-2); }

/* Onze colonnes ne tiennent pas sur un écran de portable étroit. Plutôt qu'une
   barre de défilement horizontale — que la lecture ligne à ligne rend pénible —
   les colonnes les moins critiques s'effacent : elles restent dans la fiche du
   compte et dans l'export. L'ordre d'effacement suit l'usage réel. */
@media (max-width: 1360px) {
  .data--admin th, .data--admin td { padding-left: .55rem; padding-right: .55rem; }
  .data--admin { font-size: .9rem; }
}
@media (max-width: 1220px) {                    /* la dernière activité s'en va */
  .data--admin th:nth-child(10), .data--admin td:nth-child(10) { display: none; }
}
@media (max-width: 1060px) {                    /* puis la structure */
  .data--admin th:nth-child(3), .data--admin td:nth-child(3) { display: none; }
}
@media (max-width: 1000px) {                    /* enfin, on resserre tout */
  .data--admin { font-size: .84rem; }
  .data--admin th, .data--admin td { padding: .55rem .4rem; }
  .data--admin td:first-child div { font-size: .74rem; }
  .prog-chip { padding: .2rem .4rem; font-size: .76rem; }
}
.niv-tag {
  font-size: .64rem; font-weight: 800; color: var(--text-mute);
  border: 1px solid var(--border); border-radius: 5px; padding: 0 .25rem;
}

/* Carte finale : questionnaire */
.finale {
  margin-top: 1rem; border-radius: var(--radius); padding: 1.6rem 1.8rem; border: 1px dashed var(--border);
  background: linear-gradient(135deg, var(--surface), var(--surface-2)); display: flex; gap: 1.4rem; align-items: center; flex-wrap: wrap;
}
.finale.ready { border: 1px solid transparent; background: linear-gradient(135deg, #101828, #2b1c5a); color: #fff; box-shadow: var(--shadow); }
.finale.ready p { color: rgba(255,255,255,.85); }
.finale .em { font-size: 2.6rem; }
.finale h3 { margin: 0 0 .2em; }
.finale p { margin: 0; font-size: .9rem; color: var(--text-soft); }
.finale .grow { flex: 1; min-width: 220px; }

/* Badges */
.badges { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: .9rem; }
.badge {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.1rem .9rem;
  text-align: center; transition: .2s;
}
.badge .em { font-size: 2rem; display: block; filter: grayscale(1); opacity: .35; transition: .3s; }
.badge b { display: block; font-size: .85rem; margin-top: .35rem; }
.badge small { font-size: .74rem; color: var(--text-mute); display: block; margin-top: .2rem; line-height: 1.35; }
.badge.on { border-color: color-mix(in srgb, var(--warn) 45%, var(--border)); background: linear-gradient(180deg, var(--warn-soft), var(--surface)); }
.badge.on .em { filter: none; opacity: 1; animation: badgePop .5s cubic-bezier(.2,1.4,.4,1); }
@keyframes badgePop { 0% { transform: scale(.4) rotate(-16deg); } 60% { transform: scale(1.18) rotate(6deg); } }

/* ─────────────── Chapitre ─────────────── */
.chapter-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.4rem; }
.chapter-head .back { flex: none; }
.chapter-head .info { flex: 1; min-width: 0; }
.chapter-head .info b { font-size: .78rem; text-transform: uppercase; letter-spacing: .09em; color: var(--accent); }
.chapter-head .info h2 { margin: .1rem 0 0; font-size: 1.2rem; }

.steps-bar { display: flex; gap: 6px; margin-bottom: 1.8rem; }
.steps-bar i {
  height: 5px; flex: 1; border-radius: 99px; background: var(--border); transition: background .35s, transform .35s;
}
.steps-bar i.done { background: color-mix(in srgb, var(--accent) 55%, var(--border)); }
.steps-bar i.on { background: var(--accent); transform: scaleY(1.7); }

.step { animation: stepIn .42s cubic-bezier(.2,.8,.2,1); }
@keyframes stepIn { from { opacity: 0; transform: translateY(16px); } }

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 2.2rem 2.4rem; box-shadow: var(--shadow-sm);
}
.card h2 { font-size: 1.55rem; }
.card h3 { font-size: 1.15rem; }
.card .intro { color: var(--text-soft); font-size: 1rem; }

.step-hero { text-align: center; padding: 3.2rem 2.4rem; }
.step-hero .kicker { font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); font-weight: 700; }
.step-hero .em { font-size: 3.6rem; display: block; margin-bottom: .6rem; animation: bob 3s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(-9px); } }
.step-hero h2 { font-size: clamp(1.5rem, 3.2vw, 2.1rem); margin: .3em 0 .45em; }
.step-hero p { font-size: 1.06rem; color: var(--text-soft); max-width: 60ch; margin: 0 auto; }

/* Cartes en grille */
.grid-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; margin-top: 1.4rem; }
.mini {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.3rem;
  transition: transform .2s, box-shadow .2s;
}
/* Ces cartes ne sont pas cliquables : aucun effet de survol, pour ne pas
   suggérer une interaction qui n'existe pas. */
.grid-cards.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cards.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mini .em { font-size: 1.7rem; display: block; margin-bottom: .5rem; }
.mini b { display: block; margin-bottom: .3rem; font-size: 1rem; }
.mini p { margin: 0 0 .6rem; font-size: .9rem; color: var(--text-soft); }
.mini p:last-child { margin-bottom: 0; }
.mini .src {
  margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--border);
  font-size: .78rem; color: var(--text-mute);
}

/* Définition */
.defbox {
  border-left: 4px solid var(--accent); background: color-mix(in srgb, var(--accent) 6%, var(--surface-2));
  border-radius: 0 var(--radius) var(--radius) 0; padding: 1.5rem 1.7rem; margin-top: 1.2rem;
}
.defbox .term { font-size: 1.25rem; font-weight: 700; }
.defbox .src { font-size: .78rem; color: var(--text-mute); margin-bottom: .8rem; }
.defbox .txt { font-size: 1.02rem; }
.chips { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1rem; }
.chips span {
  background: var(--surface); border: 1px solid var(--border); padding: .32em .8em; border-radius: 999px; font-size: .84rem; color: var(--text-soft);
}

/* Callout */
.callout { border-radius: var(--radius); padding: 1.4rem 1.6rem; display: flex; gap: 1rem; margin-top: 1.2rem; }
.callout .em { font-size: 1.5rem; flex: none; }
.callout b { display: block; margin-bottom: .3rem; }
.callout p { margin: 0; font-size: .96rem; }
.callout.info { background: var(--info-soft); color: color-mix(in srgb, var(--info) 75%, var(--text)); }
.callout.warn { background: var(--warn-soft); color: color-mix(in srgb, var(--warn) 78%, var(--text)); }
.callout.danger { background: var(--danger-soft); color: color-mix(in srgb, var(--danger) 78%, var(--text)); }
.callout.ok { background: var(--ok-soft); color: color-mix(in srgb, var(--ok) 78%, var(--text)); }
/* Un encadré peut porter deux paragraphes : le second énonce souvent la règle
   à retenir, il ne doit pas se coller au premier. */
.callout p + p { margin-top: .7em; }

/* Timeline */
.timeline { position: relative; margin-top: 1.6rem; padding-left: 2.2rem; }
.timeline::before { content: ''; position: absolute; left: 9px; top: 8px; bottom: 8px; width: 2px; background: var(--border); }
.tl-item { position: relative; padding-bottom: 1.7rem; }
.tl-item::before {
  content: ''; position: absolute; left: -2.2rem; top: 5px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--border);
}
.tl-item.hl::before { border-color: var(--accent); box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 15%, transparent); }
.tl-item .date { font-size: .78rem; font-weight: 800; color: var(--accent); letter-spacing: .04em; }
.tl-item b { display: block; margin: .1rem 0 .25rem; }
.tl-item p { margin: 0; font-size: .93rem; color: var(--text-soft); }

/* Pyramide */
.pyramid { display: grid; gap: .8rem; margin-top: 1.4rem; }
.pyr-level {
  border-radius: var(--radius); padding: 1.2rem 1.4rem; border: 1px solid var(--border); background: var(--surface-2);
  display: flex; gap: 1rem; align-items: flex-start; transition: transform .2s;
  border-left: 5px solid var(--lvl);
}

.pyr-level .em { font-size: 1.6rem; flex: none; }
.pyr-level b { display: block; color: var(--lvl); margin-bottom: .25rem; }
.pyr-level p { margin: 0; font-size: .92rem; color: var(--text-soft); }

/* Split 2 colonnes */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1.4rem; }
.split .col { border-radius: var(--radius); padding: 1.4rem 1.5rem; border: 1px solid var(--border); background: var(--surface-2); }
.split .col .em { font-size: 1.7rem; display: block; margin-bottom: .5rem; }
.split .col b { display: block; font-size: 1.05rem; margin-bottom: .5rem; }
.split .col p { font-size: .93rem; color: var(--text-soft); margin: 0; white-space: pre-line; }
.split .col ul { margin: .3rem 0 0; padding-left: 1.1rem; font-size: .92rem; color: var(--text-soft); }
.split .col ul li { margin-bottom: .45rem; }
.split .col.danger { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 22%, transparent); }
.split .col.ok { background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 22%, transparent); }
.split .col.warn { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 22%, transparent); }

/* Listes à puces enrichies */
.blist { display: grid; gap: .8rem; margin-top: 1.4rem; }
.blist .row { display: flex; gap: 1rem; padding: 1rem 1.2rem; border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--border); }
.blist .row .n {
  flex: none; width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; font-size: .95rem;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); font-weight: 700;
}
.blist .row b { display: block; margin-bottom: .15rem; }
.blist .row p { margin: 0; font-size: .92rem; color: var(--text-soft); }

/* Grille 6 bases légales */
.grid6 { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: .9rem; margin-top: 1.4rem; }
.grid6 .cell {
  border: 1px solid var(--border); border-radius: var(--radius); padding: 1.2rem; background: var(--surface-2);
  transition: .2s; position: relative; overflow: hidden;
}
.grid6 .cell::before {
  content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%);
  opacity: 0; transition: .25s;
}

.grid6 .cell:hover::before { opacity: 1; }
.grid6 .em { font-size: 1.5rem; display: block; margin-bottom: .4rem; position: relative; }
.grid6 b { display: block; margin-bottom: .25rem; position: relative; }
.grid6 p { margin: 0; font-size: .88rem; color: var(--text-soft); position: relative; }

/* Checklist */
.checklist { display: grid; gap: .6rem; margin-top: 1.4rem; }
.checklist .item {
  display: flex; gap: .9rem; align-items: flex-start; padding: .95rem 1.2rem; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border); cursor: pointer; transition: .18s;
}
.checklist .item:hover { border-color: color-mix(in srgb, var(--accent) 35%, var(--border)); }
.checklist .item .box {
  flex: none; width: 22px; height: 22px; border-radius: 7px; border: 2px solid var(--border); display: grid; place-items: center;
  font-size: .8rem; color: transparent; transition: .18s; margin-top: 1px;
}
.checklist .item.on { background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.checklist .item.on .box { background: var(--ok); border-color: var(--ok); color: #fff; }
.checklist .item span { font-size: .95rem; }

/* Stats */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1rem; margin-top: 1.4rem; }
.stat { text-align: center; padding: 1.4rem 1rem; border-radius: var(--radius); background: var(--surface-2); border: 1px solid var(--border); }
.stat b { display: block; font-size: 2.2rem; font-weight: 800; letter-spacing: -.03em; color: var(--accent); }
.stat span { font-size: .84rem; color: var(--text-soft); }

/* Outro */
.outro { text-align: center; padding: 3rem 2.4rem; }
.outro .em { font-size: 4rem; display: block; animation: bob 3s ease-in-out infinite; }
.outro .mail {
  display: inline-block; margin-top: 1rem; padding: .6em 1.3em; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand); font-weight: 600; text-decoration: none;
}

/* Navigation de chapitre */
.step-nav { display: flex; gap: .8rem; align-items: center; margin-top: 1.6rem; }
.step-nav .grow { flex: 1; }
.step-count { font-size: .84rem; color: var(--text-mute); font-weight: 600; }

/* ─────────────── Loupe / mots-clés ─────────────── */
.kw {
  display: inline; cursor: pointer; font-weight: 600; color: var(--accent);
  border-bottom: 1.5px dashed color-mix(in srgb, var(--accent) 55%, transparent);
  padding: 0 .1em; border-radius: 3px; transition: background .18s;
  position: relative;
}
.kw::after { content: '\00a0🔍'; font-size: .78em; opacity: .75; }
.kw:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.kw.seen { color: var(--text-soft); border-bottom-color: var(--border); }
.kw.seen::after { opacity: .4; }

.overlay {
  /* Pas de backdrop-filter : flouter toute la page sous la modale coûtait des
     images à 158 ms. Un voile un peu plus dense produit le même effet de mise
     en retrait, sans recalcul du fond à chaque image. */
  position: fixed; inset: 0; background: rgba(10, 14, 30, .64);
  display: grid; place-items: center; z-index: 100; padding: 1.4rem; animation: fade .18s;
  /* minmax(0, …) empêche la colonne d'être dimensionnée sur le contenu :
     sans cela le pourcentage de largeur de la modale peut déborder. */
  grid-template-columns: minmax(0, 1fr);
}
@keyframes fade { from { opacity: 0; } }
.modal {
  background: var(--surface); border-radius: var(--radius-lg);
  width: min(560px, 100%); max-width: 100%; justify-self: center;
  max-height: 86vh; overflow: auto; overflow-wrap: break-word;
  box-shadow: var(--shadow-lg); animation: modalIn .28s cubic-bezier(.2,.9,.3,1.1); position: relative;
}
@keyframes modalIn { from { opacity: 0; transform: translateY(24px) scale(.96); } }
.modal__head {
  padding: 1.6rem 1.8rem 1.2rem; background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 14%, var(--surface)), var(--surface));
  border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 2;
}
/* Le z-index n'est pas décoratif : sans lui, tout contenu du corps portant un
   `filter` ou une `opacity` — qui créent un contexte d'empilement — se peint
   au-dessus du bandeau collant, parce qu'il le suit dans le document. C'est ce
   qui faisait passer les pastilles de modules à travers le nom. */
.modal__head .lens { font-size: 1.7rem; }
/* Sans pictogramme, l'en-tête n'a plus besoin de la hauteur qu'il réservait. */
.modal__head--compact { padding-top: 1.15rem; padding-bottom: 1rem; }
.modal__head--compact h3 { margin-top: 0; }
.modal__head h3 { margin: .3rem 0 .1rem; font-size: 1.35rem; }
.modal__head .sub { font-size: .82rem; color: var(--text-mute); }
.modal__body { padding: 1.4rem 1.8rem 1.8rem; }
.modal__body p { font-size: .98rem; }
.modal__body ul { padding-left: 1.1rem; margin: .8rem 0 0; }
.modal__body li { font-size: .93rem; color: var(--text-soft); margin-bottom: .55rem; }
/* La croix suit le défilement, elle ne s'en va pas avec lui.
   En « absolute », elle était positionnée par rapport au contenu de la modale
   — qui est le conteneur qui défile — et disparaissait vers le haut dès qu'on
   descendait, alors que l'en-tête, lui, restait collé. En « sticky » elle reste
   à sa place. La marge basse négative annule la hauteur qu'elle occuperait
   dans le flux : l'en-tête démarre toujours au bord supérieur. */
.modal__close {
  position: sticky; top: 1rem; z-index: 3;
  display: block; margin: 1rem 1rem -3rem auto;
  width: 32px; height: 32px; border-radius: 50%; border: 0;
  background: var(--surface-2); cursor: pointer; font-size: 1rem; color: var(--text-soft);
}
.modal__close:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.modal__close:hover { background: var(--border); }
.modal .srcline { margin-top: 1.1rem; padding-top: .9rem; border-top: 1px solid var(--border); font-size: .8rem; color: var(--text-mute); }

/* ─────────────── Mini-jeux ─────────────── */
.game { border: 2px solid color-mix(in srgb, var(--accent) 25%, var(--border)); border-radius: var(--radius-lg); padding: 2rem 2.2rem; background: var(--surface); }
.game__head { display: flex; align-items: center; gap: .8rem; margin-bottom: .4rem; }
.game__head .em { font-size: 1.5rem; }
.game__head h3 { margin: 0; font-size: 1.25rem; }
.game__head .score { margin-left: auto; font-weight: 800; color: var(--accent); font-size: .95rem; }
.game .intro { color: var(--text-soft); font-size: .94rem; margin-bottom: 1.4rem; }

/* Vrai / faux */
.tf-card {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.8rem;
  text-align: center; font-size: 1.12rem; font-weight: 600; margin-bottom: 1.2rem; min-height: 110px;
  display: grid; place-items: center; animation: stepIn .3s;
}
.tf-actions { display: flex; gap: 1rem; justify-content: center; }
.tf-actions .btn { min-width: 140px; }
/* Vrai / Faux : mêmes teintes que Valider / Refuser, même comportement. */
.tf-actions .btn.vrai { --ton: var(--ok); }
.tf-actions .btn.faux { --ton: var(--danger); }
/* Réponse retenue : le même repère que pour un choix unique. Sans lui, revenir
   en arrière sur une question vrai/faux ne montrait pas ce qu'on avait coché —
   « soft » se distinguait à peine de l'état non choisi. */
.tf-actions .btn.sel {
  background: color-mix(in srgb, var(--ton) 13%, var(--surface));
  border-color: var(--ton);
  box-shadow: inset 0 0 0 1px var(--ton);
  font-weight: 700;
}

.feedback { border-radius: var(--radius); padding: 1.1rem 1.3rem; margin-top: 1.2rem; animation: stepIn .3s; font-size: .94rem; }
.feedback.good { background: var(--ok-soft); color: color-mix(in srgb, var(--ok) 80%, var(--text)); }
.feedback.bad { background: var(--danger-soft); color: color-mix(in srgb, var(--danger) 80%, var(--text)); }
.feedback b { display: block; margin-bottom: .25rem; }

/* QCM */
.opt {
  display: flex; gap: .85rem; align-items: flex-start; width: 100%; text-align: left; padding: 1rem 1.2rem; margin-bottom: .6rem;
  border-radius: var(--radius-sm); border: 1.5px solid var(--border); background: var(--surface-2); cursor: pointer;
  font-size: .96rem; color: var(--text); transition: .16s; font-family: inherit;
}
.opt:hover:not(:disabled) { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 6%, var(--surface-2)); }
.opt .let {
  flex: none; width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; font-weight: 700; font-size: .82rem;
  background: var(--surface); border: 1px solid var(--border);
}
.opt.good { background: var(--ok-soft); border-color: var(--ok); }
.opt.good .let { background: var(--ok); color: #fff; border-color: var(--ok); }
.opt.bad { background: var(--danger-soft); border-color: var(--danger); }
.opt.bad .let { background: var(--danger); color: #fff; border-color: var(--danger); }
.opt.sel { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--surface-2)); }
.opt.sel .let { background: var(--accent); color: #fff; border-color: var(--accent); }
.opt:disabled { cursor: default; }

/* Tri (sort) */
.sort-item {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-sm); padding: 1rem 1.3rem;
  font-weight: 600; text-align: center; margin-bottom: 1.2rem; box-shadow: var(--shadow-sm); animation: stepIn .28s;
}
.sort-cats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: .8rem; }
/* Bordure pleine, et non en pointillés : ce sont des boutons à cliquer,
   pas des zones de dépôt — le pointillé suggérait un glisser-déposer. */
.sort-cat {
  border: 2px solid color-mix(in srgb, var(--c) 45%, var(--border)); border-radius: var(--radius); padding: 1.2rem .9rem;
  text-align: center; cursor: pointer; background: color-mix(in srgb, var(--c) 7%, var(--surface-2)); transition: .18s;
  font-family: inherit; color: var(--text); width: 100%; box-shadow: var(--shadow-sm);
}
.sort-cat:hover:not(:disabled) {
  background: color-mix(in srgb, var(--c) 15%, var(--surface-2));
  border-color: color-mix(in srgb, var(--c) 75%, var(--border));
}
.sort-cat .em { font-size: 1.5rem; display: block; margin-bottom: .3rem; }
.sort-cat b { font-size: .88rem; color: var(--c); }
.sort-cat:disabled { opacity: .5; cursor: default; }

/* Association (match) */
.match-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.match-col { display: grid; gap: .55rem; align-content: start; }
.match-col h4 { font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-mute); margin: 0 0 .2rem; }
.match-item {
  padding: .85rem 1rem; border-radius: var(--radius-sm); border: 1.5px solid var(--border); background: var(--surface-2);
  cursor: pointer; font-size: .9rem; text-align: left; transition: .16s; font-family: inherit; color: var(--text);
}
.match-item:hover:not(:disabled) { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface-2)); }
.match-item.sel { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--surface-2)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent); }
.match-item.paired { opacity: .45; cursor: default; border-style: dashed; }
.match-item.flash-good { border-color: var(--ok); background: var(--ok-soft); }
.match-item.flash-bad { border-color: var(--danger); background: var(--danger-soft); animation: shake .35s; }
@keyframes shake { 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }

/* Remise en ordre */
.order-list { display: grid; gap: .6rem; }
.order-item {
  display: flex; align-items: center; gap: .9rem; padding: .95rem 1.1rem; border-radius: var(--radius-sm);
  border: 1.5px solid var(--border); background: var(--surface-2); cursor: grab; font-size: .94rem;
}
.order-item.dragging { opacity: .4; }
.order-item .handle { color: var(--text-mute); font-size: 1.1rem; cursor: grab; }
.order-item .arrows { margin-left: auto; display: flex; gap: .25rem; }
.order-item .arrows button {
  width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface);
  cursor: pointer; color: var(--text-soft); font-size: .8rem;
}
.order-item .arrows button:hover { background: var(--brand-soft); color: var(--brand); }
.order-item.good { border-color: var(--ok); background: var(--ok-soft); }
.order-item.bad { border-color: var(--danger); background: var(--danger-soft); }

/* Phishing */
.mailbox { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface-2); }
.mailbox__head { padding: 1rem 1.3rem; border-bottom: 1px solid var(--border); background: var(--surface); font-size: .88rem; }
.mailbox__head .line { display: flex; gap: .5rem; margin-bottom: .3rem; }
.mailbox__head .line .lbl { color: var(--text-mute); min-width: 62px; }
.mailbox__head .subject { font-weight: 700; font-size: 1rem; margin-top: .5rem; }
.mailbox__body { padding: 1.4rem 1.3rem; font-size: .95rem; white-space: pre-wrap; line-height: 1.7; }
.clue {
  cursor: pointer; border-radius: 4px; padding: .05em .25em; background: color-mix(in srgb, var(--warn) 12%, transparent);
  border-bottom: 2px dotted color-mix(in srgb, var(--text-mute) 60%, transparent); transition: .16s;
}
.clue:hover { background: color-mix(in srgb, var(--warn) 25%, transparent); }
.clue.found { background: var(--ok-soft); border-bottom-color: var(--ok); color: color-mix(in srgb, var(--ok) 75%, var(--text)); font-weight: 600; }
.clue.miss { background: var(--danger-soft); }
.clue-list { margin-top: 1.2rem; display: grid; gap: .5rem; }
.clue-list .found-item {
  padding: .8rem 1rem; border-radius: var(--radius-sm); background: var(--ok-soft); font-size: .89rem;
  color: color-mix(in srgb, var(--ok) 80%, var(--text)); animation: stepIn .3s;
}
.clue-counter { text-align: center; font-weight: 700; color: var(--accent); margin: 1rem 0 0; }

/* Testeur de mot de passe */
.pw-box { margin-top: 1.4rem; }
.pw-box input {
  width: 100%; padding: 1em 1.2em; border-radius: var(--radius-sm); border: 1.5px solid var(--border);
  background: var(--surface); color: var(--text); font-size: 1.05rem; font-family: ui-monospace, monospace;
}
.pw-box input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 14%, transparent); }
.pw-meter { height: 9px; border-radius: 99px; background: var(--border); margin: .9rem 0 .6rem; overflow: hidden; }
.pw-meter i { display: block; height: 100%; width: 0; border-radius: 99px; transition: width .35s, background .35s; }
.pw-verdict { font-weight: 700; font-size: .95rem; margin-bottom: .8rem; }
/* Champ mot de passe avec bouton afficher/masquer */
.pw-input { position: relative; }
.pw-input input { padding-right: 3rem; }
.pw-eye {
  position: absolute; right: .5rem; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; border: 0; background: transparent; cursor: pointer;
  border-radius: 8px; font-size: 1rem; line-height: 1;
}
.pw-eye:hover { background: var(--surface-2); }

.pw-rules { display: grid; gap: .4rem; }
.pw-rules.pw-rules--hidden { display: none; }
.pw-rules div { font-size: .88rem; color: var(--text-mute); display: flex; gap: .5rem; align-items: center; }
.pw-rules div.on { color: var(--ok); }

/* Résultat de mini-jeu */
.game-done {
  text-align: center; padding: 1.8rem; border-radius: var(--radius); margin-top: 1.4rem;
  background: linear-gradient(135deg, var(--brand-soft), var(--surface-2)); animation: stepIn .4s;
}
.game-done .em { font-size: 2.6rem; display: block; }
.game-done b { display: block; font-size: 1.15rem; margin: .4rem 0 .2rem; }
.game-done p { margin: 0; font-size: .9rem; color: var(--text-soft); }

/* ─────────────── Questionnaire final ─────────────── */
.quiz-shell { max-width: 800px; margin: 0 auto; }
.quiz-top { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.4rem; }
.quiz-top .prog { flex: 1; height: 8px; border-radius: 99px; background: var(--border); overflow: hidden; }
.quiz-top .prog i { display: block; height: 100%; background: linear-gradient(90deg, var(--brand), var(--teal)); transition: width .4s; }
.quiz-top .cnt { font-size: .85rem; font-weight: 700; color: var(--text-soft); white-space: nowrap; }
.quiz-q { font-size: 1.22rem; font-weight: 600; margin: .3rem 0 1.4rem; }
.quiz-theme { font-size: .74rem; text-transform: uppercase; letter-spacing: .09em; font-weight: 800; color: var(--accent); }
.quiz-multi-hint { font-size: .82rem; color: var(--text-mute); margin-bottom: .8rem; }

.score-hero { text-align: center; padding: 3rem 2rem 2.4rem; }
.big-ring { --p: 0; --col: var(--brand); width: 180px; height: 180px; margin: 0 auto 1.4rem; position: relative; display: grid; place-items: center; }
.big-ring::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(var(--col) calc(var(--p) * 1%), var(--border) 0);
  mask: radial-gradient(farthest-side, transparent calc(100% - 15px), #000 calc(100% - 14px));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 15px), #000 calc(100% - 14px));
  transition: background 1.2s cubic-bezier(.2,.8,.2,1);
}
.big-ring > div { text-align: center; }
.big-ring b { display: block; font-size: 2.8rem; font-weight: 800; letter-spacing: -.04em; line-height: 1.1; }
.big-ring small { display: block; font-size: .8rem; color: var(--text-mute); }

.theme-bars { display: grid; gap: .8rem; margin-top: 1.4rem; }
.theme-bar { display: flex; align-items: center; gap: 1rem; }
.theme-bar .nm { width: 150px; font-size: .88rem; font-weight: 600; flex: none; }
.theme-bar .tr { flex: 1; height: 10px; border-radius: 99px; background: var(--border); overflow: hidden; }
.theme-bar .tr i { display: block; height: 100%; border-radius: 99px; transition: width .8s; }
.theme-bar .vl { font-size: .82rem; color: var(--text-mute); width: 46px; text-align: right; flex: none; }

.review-item { border: 1px solid var(--border); border-radius: var(--radius); padding: 1.2rem 1.4rem; margin-bottom: .8rem; }
.review-item.ko { border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); background: color-mix(in srgb, var(--danger) 3%, var(--surface)); }
.review-item .qh { display: flex; gap: .7rem; align-items: flex-start; margin-bottom: .7rem; }
.review-item .qh .st { font-size: 1.1rem; }
.review-item .qh b { font-size: .98rem; font-weight: 600; }
.review-item .ans { font-size: .88rem; display: grid; gap: .3rem; margin-bottom: .6rem; }
.review-item .ans .lbl { color: var(--text-mute); }
.review-item .ans .good { color: var(--ok); font-weight: 600; }
.review-item .ans .bad { color: var(--danger); font-weight: 600; }
.review-item .why { font-size: .88rem; color: var(--text-soft); background: var(--surface-2); border-radius: var(--radius-sm); padding: .7rem .9rem; }

/* ═══════════════ Attestation ═══════════════
   Un document, pas un écran : fond blanc, tout centré, et AUCUN cadre — ni
   bordure d'ensemble, ni filet, ni pastille cerclée. Ce qui structure la page
   est l'espacement et la hiérarchie typographique, comme sur un vrai document.
   Les couleurs sont écrites en dur : une attestation imprimée ne suit pas le
   thème de qui la consulte, et doit rester lisible en noir et blanc. */
.cert {
  --or: #4f46e5;                      /* couleur du parcours, RGPD par défaut */
  max-width: 760px; margin: 0 auto;
  background: #fff; color: #101828; text-align: center;
  padding: 3rem 3rem 2.6rem;
  border-radius: 4px; box-shadow: var(--shadow);

  /* Une page, pas un bloc qui s'arrête où le contenu s'arrête. La hauteur
     minimale est celle d'un A4 à cette largeur ; l'espace en trop se répartit
     entre les blocs au lieu de s'accumuler en bas. Une attestation sans module
     et une attestation qui en porte huit occupent ainsi la même page, l'une
     aérée, l'autre dense. */
  min-height: 1074px;                 /* 760 px × √2 */
  display: flex; flex-direction: column; justify-content: space-between;
  gap: 1.4rem;
}
/* Sur un écran étroit, forcer la proportion créerait un vide absurde : le
   document reprend sa hauteur naturelle. « screen » est indispensable — une
   page A4 mesure environ 740 px de large, elle tomberait sinon dans cette
   règle et l'attestation imprimée cesserait de se répartir. */
@media screen and (max-width: 820px) {
  .cert { min-height: 0; display: block; }
  .cert-bloc + .cert-bloc, .cert .meta, .cert-modules, .cert-pied { margin-top: 2rem; }
}
/* Chaque bloc reste solidaire : l'espace se glisse entre eux, jamais dedans. */
.cert-bloc { flex: none; }
.cert--cyber { --or: #0b7285; }

/* ── En-tête : logo et émetteur, centrés ── */
.cert-head { display: flex; flex-direction: column; align-items: center; gap: .5rem; flex: none; }
.cert-logo { width: 52px; height: 52px; object-fit: contain; }
.cert-head__txt { display: flex; flex-direction: column; line-height: 1.35; }
.cert-head__txt b { font-size: 1rem; color: #101828; letter-spacing: .01em; }
.cert-head__txt span { font-size: .78rem; color: #6b7688; }

/* ── Titre ── */
.cert-eyebrow {
  font-size: .74rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: #8a93a6;
}
.cert h2 {
  font-size: 2.5rem; line-height: 1.1; margin: .35rem 0 .4rem;
  letter-spacing: -.01em; color: var(--or);
}
.cert .sub { color: #5a6a85; font-size: .9rem; }
/* Le niveau, sans pastille cerclée : la couleur et la graisse suffisent. */
.cert .cert-niveau {
  display: block; margin-top: 1rem; color: var(--or);
  font-size: .82rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}

/* ── Le corps de l'attestation ── */
.cert-formule { font-size: .88rem; color: #6b7688; font-style: italic; }
.cert .who {
  font-size: 1.75rem; font-weight: 800; margin: .35rem 0 .2rem; color: #101828;
  letter-spacing: -.01em;
}
.cert-structure { font-size: .92rem; color: #5a6a85; }
.cert-corps { max-width: 46ch; margin: 1.1rem auto 0; font-size: .95rem; line-height: 1.7; color: #3d4759; }

.cert .meta { display: flex; justify-content: center; gap: 3rem; flex-wrap: wrap; flex: none; }
.cert .meta div b { display: block; font-size: 1.25rem; color: var(--or); }
.cert .meta div span { font-size: .74rem; color: #6b7688; text-transform: uppercase; letter-spacing: .06em; }

/* ── Modules complémentaires ──
   Des lignes, pas des encadrés : le point coloré tient lieu de puce. */
.cert-modules { flex: none; }
.cert-modules__titre {
  font-size: .74rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: #8a93a6; margin-bottom: .7rem;
}
.cert-modules ul { list-style: none; margin: 0 auto; padding: 0; display: grid; gap: .28rem; max-width: 40rem; }
.cert-modules li {
  display: flex; align-items: baseline; gap: .45rem; flex-wrap: wrap;
  font-size: .85rem; color: #3d4759; text-align: left;
}
.cert-modules li::before {
  content: ''; flex: none; width: 5px; height: 5px; border-radius: 50%;
  background: var(--or); transform: translateY(-2px);
}
.cert-modules li b { font-weight: 700; }
.cert-modules li .ss { color: #6b7688; flex: 1; min-width: 0; }
.cert-modules li .sc { margin-left: auto; white-space: nowrap; color: var(--or); font-weight: 700; font-size: .79rem; }

/* ── Pied : la référence, centrée ── */
.cert-pied { display: flex; flex-direction: column; align-items: center; gap: .12rem; flex: none; }
.cert-pied .lbl { font-size: .68rem; text-transform: uppercase; letter-spacing: .12em; color: #8a93a6; }
.cert-pied .val.mono {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: .84rem; font-weight: 600; color: #101828; letter-spacing: .04em;
}

/* ═══════════════ Une fiche réflexe à l'écran ═══════════════
   Même contenu que le PDF, mise en page de l'application. La couleur vient de
   la famille, par --ton, comme sur les cartes. */
.fiche-page {
  --ton: var(--brand);
  background: var(--surface); border: 1px solid var(--border);
  border-top: 4px solid var(--ton); border-radius: var(--radius); padding: 1.8rem 2rem 1.6rem;
}
.fiche-page.ton-danger { --ton: var(--danger); }
.fiche-page.ton-teal   { --ton: var(--teal); }

.fp-tete { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1.2rem; }
.fp-ico {
  flex: 0 0 auto; width: 3rem; height: 3rem; border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center; font-size: 1.5rem;
  background: color-mix(in srgb, var(--ton) 11%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ton) 24%, var(--border));
}
.fp-titre { flex: 1; min-width: 0; }
.fp-kicker {
  font-size: .72rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ton); margin-bottom: .2rem;
}
.fp-titre h2 { font-size: 1.5rem; margin: 0; line-height: 1.2; letter-spacing: -.01em; }
.fp-ss { font-size: .92rem; color: var(--text-soft); margin-top: .15rem; }
.fp-pdf { flex: 0 0 auto; white-space: nowrap; }
.fp-resume {
  font-style: italic; color: var(--text-soft); font-size: .95rem; line-height: 1.65;
  padding-bottom: 1.2rem; margin: 0 0 1.4rem; border-bottom: 1px solid var(--border);
}

.fb { margin-bottom: 1.6rem; }
.fb h3 {
  font-size: .74rem; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
  color: var(--text-mute); margin: 0 0 .7rem;
  padding-bottom: .4rem; border-bottom: 1px solid var(--border);
}
.fb p { margin: .15rem 0 0; font-size: .92rem; line-height: 1.65; color: var(--text-soft); }
.fb li { font-size: .93rem; line-height: 1.6; }

/* Le bandeau d'urgence : la première chose lue. */
.fb-urgence {
  display: flex; gap: .8rem; align-items: flex-start; margin-bottom: 1.6rem;
  padding: .9rem 1.1rem; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--danger) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--danger) 30%, var(--border));
  border-left: 3px solid var(--danger);
}
.fb-urgence__ico {
  flex: none; width: 1.4rem; height: 1.4rem; border-radius: 50%; background: var(--danger);
  color: #fff; font-weight: 800; font-size: .85rem; display: flex; align-items: center; justify-content: center;
}
.fb-urgence p { margin: 0; color: var(--text); font-weight: 500; }

.fb-cles { margin: 0; padding: 0; list-style: none; counter-reset: cle; display: grid; gap: .6rem; }
.fb-cles li {
  counter-increment: cle; display: flex; gap: .7rem; align-items: flex-start;
  padding-bottom: .6rem; border-bottom: 1px dashed var(--border);
}
.fb-cles li:last-child { border-bottom: 0; padding-bottom: 0; }
.fb-cles li::before {
  content: counter(cle); flex: none; width: 1.5rem; height: 1.5rem; border-radius: 50%;
  background: var(--ton); color: #fff; font-size: .76rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}

.fb-puces, .fb-interdits { margin: 0; padding: 0; list-style: none; display: grid; gap: .45rem; }
.fb-puces li, .fb-interdits li { display: flex; gap: .6rem; align-items: flex-start; }
.fb-puces li::before { content: '•'; color: var(--ton); font-weight: 800; flex: none; }
.fb-interdits li::before { content: '✕'; color: var(--danger); font-weight: 700; font-size: .85rem; flex: none; }

.fb-etapes { display: grid; gap: .1rem; }
.fb-etape {
  display: flex; gap: 1rem; align-items: flex-start;
  padding: .7rem 0; border-bottom: 1px solid var(--border);
}
.fb-etape:last-child { border-bottom: 0; }
.fb-etape__quand {
  flex: 0 0 7rem; font-size: .7rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ton); padding-top: .15rem;
}
.fb-etape b { font-size: .95rem; }

.fb-tableau { overflow-x: auto; }
.fb-tableau table { width: 100%; border-collapse: collapse; font-size: .89rem; }
.fb-tableau th {
  text-align: left; font-size: .7rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-mute); padding: 0 .8rem .5rem 0; border-bottom: 1px solid var(--border);
}
.fb-tableau td { padding: .55rem .8rem .55rem 0; border-bottom: 1px solid var(--border); vertical-align: top; color: var(--text-soft); }
.fb-tableau td:first-child { color: var(--text); font-weight: 600; white-space: nowrap; }

.fb-encart {
  --e: var(--info);
  margin: 0 0 1.6rem; padding: .9rem 1.1rem; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--e) 7%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--e) 26%, var(--border));
  border-left: 3px solid var(--e);
}
.fb-encart.ton-danger { --e: var(--danger); }
.fb-encart.ton-warn   { --e: var(--warn); }
.fb-encart.ton-ok     { --e: var(--ok); }
.fb-encart > b { display: block; font-size: .93rem; margin-bottom: .25rem; }

.fb-contacts { display: grid; gap: .4rem; }
.fb-contacts > div {
  display: flex; flex-wrap: wrap; gap: .3rem 1rem; align-items: baseline;
  padding: .55rem .9rem; border-radius: var(--radius-sm); background: var(--surface-2);
}
.fb-contacts .lbl { flex: 0 0 15rem; font-size: .78rem; color: var(--text-mute); }
.fb-contacts a { color: var(--ton); }

.fb-sources { margin: 0; padding: 0; list-style: none; display: grid; gap: .55rem; }
.fb-sources b { display: block; font-size: .9rem; }
.fb-url { font-size: .84rem; color: var(--ton); word-break: break-all; }

.fp-pied {
  margin: 1.8rem 0 0; padding-top: 1rem; border-top: 1px solid var(--border);
  font-size: .76rem; color: var(--text-mute); text-align: center;
}

/* Les autres fiches de la même famille, pour ne pas repasser par la liste. */
.fp-suite { margin-top: 1.8rem; }
.fp-suite > span {
  display: block; font-size: .74rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-mute); margin-bottom: .7rem;
}
.fp-liens { display: flex; flex-wrap: wrap; gap: .5rem; }
.fp-lien {
  --ton: var(--brand);
  display: inline-flex; align-items: center; gap: .45rem; text-decoration: none;
  padding: .45rem .85rem; border-radius: 999px; font-size: .85rem; color: var(--text);
  background: var(--surface); border: 1px solid var(--border);
  transition: border-color .16s, background .16s;
}
.fp-lien.ton-danger { --ton: var(--danger); }
.fp-lien.ton-teal   { --ton: var(--teal); }
.fp-lien:hover { border-color: var(--ton); background: color-mix(in srgb, var(--ton) 8%, var(--surface)); }

@media (max-width: 700px) {
  .fiche-page { padding: 1.3rem 1.1rem; }
  /* Le bouton PDF passe sous le titre : coincé à côté, il réduisait celui-ci
     à une colonne de trois mots. */
  .fp-tete { flex-wrap: wrap; }
  .fp-titre { flex: 1 1 calc(100% - 4rem); }
  .fp-pdf { order: 3; margin-left: auto; }
  .fp-etape { flex-direction: column; }
  .fb-etape { flex-direction: column; gap: .2rem; }
  .fb-etape__quand { flex: none; }
  .fb-contacts .lbl { flex: 1 0 100%; }
}

/* Les escape games dans la fiche d'un compte : deux lignes, à côté des
   modules, parce que c'est là qu'on les cherche. */
.fp-jeux { display: grid; gap: .4rem; margin-top: .5rem; }
.fp-jeu {
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem .8rem; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border); opacity: .6;
}
.fp-jeu.joue { opacity: 1; border-color: color-mix(in srgb, var(--ok) 35%, var(--border)); background: color-mix(in srgb, var(--ok) 7%, var(--surface)); }
.fp-jeu .ico { font-size: 1.1rem; flex: none; }
.fp-jeu > div { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.fp-jeu b { font-size: .88rem; }
.fp-jeu > div span { font-size: .78rem; color: var(--text-mute); }
.fp-jeu__score { flex: none; font-size: .88rem; font-weight: 700; color: var(--ok); }

/* ═══════════════════ Le hub ═══════════════════
   L'accueil ne présente plus que les sections. Le bandeau de reprise passe
   avant les cartes : le geste le plus fréquent ne doit pas coûter un clic de
   plus que les autres. */
.hub-tete { margin-bottom: 1.4rem; }
.hub-tete h1 { font-size: 1.7rem; margin: 0 0 .2rem; letter-spacing: -.02em; }
.hub-tete p { margin: 0; color: var(--text-soft); font-size: .95rem; }

.hub-reprise {
  display: flex; align-items: center; gap: 1rem; text-decoration: none;
  padding: 1rem 1.2rem; margin-bottom: 1.6rem; border-radius: var(--radius);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--brand) 12%, var(--surface)),
    color-mix(in srgb, var(--brand2) 10%, var(--surface)));
  border: 1px solid color-mix(in srgb, var(--brand) 32%, var(--border));
  transition: border-color .16s, transform .16s, box-shadow .16s;
}
.hub-reprise:hover { border-color: var(--brand); transform: translateY(-1px); box-shadow: var(--shadow); }
.hub-reprise__ico {
  flex: none; width: 2.4rem; height: 2.4rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
  background: var(--brand); color: #fff;
}
.hub-reprise__txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hub-reprise__txt b { font-size: 1rem; color: var(--text); }
.hub-reprise__txt span {
  font-size: .86rem; color: var(--text-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hub-reprise__fleche { flex: none; color: var(--brand); font-size: 1.2rem; }

/* Trois colonnes, donc deux rangées de trois : le nombre de colonnes est fixé
   plutôt que déduit d'une largeur minimale. Avec « auto-fill », six cartes se
   répartissaient en quatre puis deux — une grille bancale, alors que 3 × 2 se
   lit d'un coup d'œil. */
.hub-grille {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1rem; margin-bottom: 2.4rem;
}
@media (max-width: 940px) { .hub-grille { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .hub-grille { grid-template-columns: 1fr; } }
.hub-carte {
  --ton: var(--brand);
  display: flex; flex-direction: column; gap: .25rem; text-decoration: none;
  padding: 1.2rem 1.2rem 1.1rem; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--border);
  border-top: 3px solid color-mix(in srgb, var(--ton) 60%, var(--border));
  transition: border-color .18s, box-shadow .18s, transform .18s;
}
.hub-carte.ton-brand  { --ton: var(--brand); }
.hub-carte.ton-brand2 { --ton: var(--brand-2); }
.hub-carte.ton-teal   { --ton: var(--teal); }
.hub-carte.ton-danger { --ton: var(--danger); }
.hub-carte.ton-warn   { --ton: var(--warn); }
.hub-carte.ton-info   { --ton: var(--info); }
.hub-carte:not(.verrouille):hover {
  border-color: color-mix(in srgb, var(--ton) 50%, var(--border));
  border-top-color: var(--ton);
  box-shadow: var(--shadow); transform: translateY(-2px);
}
.hub-carte.verrouille { opacity: .58; }
.hub-carte__haut { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
.hub-carte__ico {
  width: 2.8rem; height: 2.8rem; border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center; font-size: 1.4rem;
  background: color-mix(in srgb, var(--ton) 11%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ton) 24%, var(--border));
}
.hub-carte__ok { font-size: 1.1rem; }
.hub-carte > b { font-size: 1.05rem; color: var(--text); line-height: 1.25; }
.hub-carte__ss { font-size: .84rem; color: var(--text-soft); }
.hub-carte__jauge {
  height: 5px; border-radius: 999px; margin-top: .7rem;
  background: color-mix(in srgb, var(--ton) 16%, var(--surface-2)); overflow: hidden;
}
.hub-carte__jauge i { display: block; height: 100%; background: var(--ton); transition: width .4s; }
.hub-carte__etat { margin-top: .5rem; font-size: .78rem; font-weight: 600; color: var(--ton); }

/* Sur téléphone, six cartes en pleine largeur font beaucoup à faire défiler :
   elles se compactent plutôt que de s'empiler à la même hauteur qu'au bureau. */
@media (max-width: 560px) {
  .hub-carte { padding: .9rem 1rem; }
  .hub-carte__ico { width: 2.2rem; height: 2.2rem; font-size: 1.1rem; }
  .hub-carte__haut { margin-bottom: .3rem; }
  .hub-carte > b { font-size: .98rem; }
  .hub-tete h1 { font-size: 1.45rem; }
}

/* Fil d'Ariane des pages de section : le retour au hub, et où l'on est. */
.fil { display: flex; align-items: center; gap: .6rem; margin-bottom: 1.2rem; font-size: .85rem; }
.fil a { color: var(--text-mute); text-decoration: none; }
.fil a:hover { color: var(--brand); }
.fil span { color: var(--text-soft); font-weight: 600; }
.fil span::before { content: '/'; margin-right: .6rem; color: var(--text-mute); font-weight: 400; }

/* Retour à la vue quittée. Poussé à droite : le fil d'Ariane dit la place dans
   l'arborescence, ce bouton dit d'où l'on vient — deux gestes distincts. */
.retour-prec {
  margin-left: auto; padding: .35rem .8rem; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: .82rem; font-weight: 600; color: var(--brand);
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--brand) 30%, var(--border));
  white-space: nowrap; max-width: 22rem; overflow: hidden; text-overflow: ellipsis;
  transition: background .16s, border-color .16s;
}
.retour-prec:hover { background: color-mix(in srgb, var(--brand) 15%, var(--surface)); border-color: var(--brand); }
.savoir-onglets .retour-prec { align-self: center; }
@media (max-width: 560px) { .retour-prec { max-width: 11rem; } }

/* ═══════════════ Ressources ═══════════════
   Glossaire et ressources partagent une carte au hub : une barre d'onglets
   les sépare ici, plutôt que deux entrées concurrentes dans la navigation. */
.savoir-onglets { display: flex; gap: .4rem; margin-bottom: 1.4rem; }
.savoir-onglet {
  padding: .5rem 1rem; border-radius: 999px; text-decoration: none;
  font-size: .88rem; font-weight: 600; color: var(--text-soft);
  background: var(--surface); border: 1px solid var(--border);
  transition: border-color .16s, background .16s, color .16s;
}
.savoir-onglet:hover { border-color: var(--brand); color: var(--text); }
.savoir-onglet.on {
  background: color-mix(in srgb, var(--brand) 12%, var(--surface));
  border-color: color-mix(in srgb, var(--brand) 55%, var(--border));
  color: var(--brand);
}

.res-barre { margin-bottom: 1.6rem; }
.res-recherche {
  width: 100%; padding: .85em 1em; border-radius: 999px; font-size: .96rem;
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
}
.res-recherche:focus { outline: none; border-color: var(--brand); }

.res-liste { display: grid; gap: .7rem; }
/* Sections rétractables. <details> porte l'état ; on n'habille que l'apparence.
   Fermées par défaut, les dix thèmes tiennent sur un écran : la page devient
   un sommaire d'où l'on ouvre ce dont on a besoin. */
.res-groupe {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); overflow: hidden;
}
.res-groupe[open] { border-color: color-mix(in srgb, var(--brand) 32%, var(--border)); }
.res-groupe__tete {
  display: flex; align-items: flex-start; gap: .8rem; cursor: pointer;
  padding: .9rem 1.1rem; list-style: none; user-select: none;
}
.res-groupe__tete::-webkit-details-marker { display: none; }
.res-groupe__tete:hover { background: var(--surface-2); }
.res-groupe[open] .res-groupe__tete { border-bottom: 1px solid var(--border); }
.res-chevron {
  flex: none; color: var(--text-mute); font-size: 1.1rem; line-height: 1;
  transition: transform .2s; align-self: center;
}
.res-groupe[open] .res-chevron { transform: rotate(180deg); }
.res-groupe > ul { padding: .9rem 1.1rem 1.1rem; }
.res-groupe__tete .ico { font-size: 1.3rem; flex: none; }
.res-groupe__tete > div { flex: 1; min-width: 0; }
.res-groupe__tete h3 { margin: 0; font-size: 1.05rem; }
.res-groupe__tete p { margin: .1rem 0 0; font-size: .85rem; color: var(--text-soft); }
.res-compte {
  flex: none; padding: .15rem .55rem; border-radius: 999px;
  font-size: .78rem; font-weight: 700; color: var(--text-mute);
  background: var(--surface-2); border: 1px solid var(--border);
}

.res-items { list-style: none; margin: 0; display: grid; gap: .7rem; }
.res-items li {
  padding: .7rem .9rem; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border);
  transition: border-color .16s;
}
.res-items li:hover { border-color: color-mix(in srgb, var(--brand) 40%, var(--border)); }
.res-lien { display: block; text-decoration: none; }
.res-lien b { display: block; font-size: .93rem; color: var(--text); line-height: 1.35; }
.res-url { display: block; font-size: .78rem; color: var(--info); word-break: break-all; margin-top: .1rem; }

.res-meta { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem; align-items: center; }
.res-emetteur {
  font-size: .7rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-mute); padding-right: .3rem;
}
/* D'où la référence est citée : cliquable, elle y ramène. */
.res-cite {
  font-size: .74rem; text-decoration: none; color: var(--text-soft);
  padding: .12rem .5rem; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.res-cite:hover { border-color: var(--brand); color: var(--brand); }
.res-vide { color: var(--text-mute); text-align: center; padding: 2rem 0; }

/* ─────────────── Glossaire ─────────────── */
.gl-search { position: relative; margin-bottom: 1.4rem; }
.gl-search input { width: 100%; padding: .9em 1em .9em 2.8em; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text); font-size: .98rem; }
.gl-search input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 14%, transparent); }
.gl-search .ico { position: absolute; left: 1.1em; top: 50%; transform: translateY(-50%); color: var(--text-mute); }
.gl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; }
.gl-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.3rem 1.4rem; cursor: pointer; transition: .2s; }
.gl-card:hover { border-color: color-mix(in srgb, var(--brand) 50%, var(--border)); box-shadow: var(--shadow-sm); }
.gl-card b { display: block; font-size: 1.02rem; margin-bottom: .2rem; }
.gl-card .sub { font-size: .76rem; color: var(--text-mute); margin-bottom: .5rem; }
.gl-card p { margin: 0; font-size: .88rem; color: var(--text-soft); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* ─────────────── Admin ─────────────── */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
/* Le défilement reste possible sur fenêtre étroite, mais sa barre n'a pas à
   s'imposer : elle apparaît discrète, et seulement quand elle est nécessaire. */
.table-wrap { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
.table-wrap::-webkit-scrollbar { height: 8px; }
.table-wrap::-webkit-scrollbar-track { background: transparent; }
.table-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }
.table-wrap::-webkit-scrollbar-thumb:hover { background: var(--text-mute); }
table.data { width: 100%; border-collapse: collapse; font-size: .89rem; min-width: 860px; }
table.data th {
  text-align: left; padding: .9rem 1rem; font-size: .74rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-mute); border-bottom: 1px solid var(--border); background: var(--surface-2); white-space: nowrap;
}
table.data td { padding: .85rem .8rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.data th:first-child, table.data td:first-child { padding-left: 1rem; }
table.data th:last-child, table.data td:last-child { padding-right: 1rem; }
table.data tr:last-child td { border-bottom: 0; }
table.data tr:hover td { background: var(--surface-2); }
/* Colonne d'actions : boutons carrés de gabarit strictement identique, sur une
   seule ligne. Icône seule et infobulle : avec des libellés, quatre boutons
   s'empilaient sur quatre lignes et faisaient exploser la hauteur des lignes. */
.cell-actions { white-space: nowrap; width: 1%; }
.row-actions { display: flex; gap: .35rem; justify-content: flex-end; flex-wrap: nowrap; }
.act {
  flex: none; width: 32px; height: 32px; padding: 0; border-radius: 9px;
  border: 1.5px solid var(--border); background: transparent;
  cursor: pointer; font-size: .92rem; line-height: 1;
  display: grid; place-items: center; font-family: inherit; color: var(--text-soft);
  transition: background .16s, border-color .16s, color .16s;
}
.act { --ton: var(--brand); }
.act.ok-ghost { --ton: var(--ok); }
.act.warn-ghost { --ton: var(--warn); }
.act.danger-ghost { --ton: var(--danger); }
/* Bascule fermée : la commande reste lisible mais s'efface, pour qu'un coup
   d'œil au tableau distingue les comptes concernés des autres. */
.act.act-off { opacity: .38; }
.act.act-off:hover { opacity: 1; }
.act:hover {
  background: color-mix(in srgb, var(--ton) 10%, transparent);
  border-color: color-mix(in srgb, var(--ton) 62%, var(--border));
}
.act:active { background: color-mix(in srgb, var(--ton) 18%, transparent); }
.act:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.mini-bar { width: 84px; height: 7px; border-radius: 99px; background: var(--border); overflow: hidden; display: inline-block; vertical-align: middle; margin-right: .5rem; }
.mini-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--brand), var(--teal)); }

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; margin-bottom: 1.6rem; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.3rem 1.4rem; }
.kpi.kpi-alert { border-color: color-mix(in srgb, var(--warn) 50%, var(--border)); background: var(--warn-soft); }
.kpi.kpi-alert b { color: var(--warn); }

/* ── File d'attente des demandes de compte ── */
.queue { display: grid; gap: .7rem; margin-bottom: 1.6rem; }
.queue-item {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  background: var(--surface); border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--border));
  border-left: 4px solid var(--warn); border-radius: var(--radius); padding: 1rem 1.2rem;
}
.queue-who { flex: 1; min-width: 200px; }
.queue-who b { display: block; font-size: 1rem; }
.queue-meta { font-size: .82rem; color: var(--text-mute); }
.queue-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

table.data tr.row-muted td { background: var(--surface-2); }
table.data tr.row-muted td:first-child b { color: var(--text-soft); }

/* ── Pastille-compteur des demandes en attente ── */
.topbar__right { display: flex; align-items: center; gap: .55rem; flex: none; }

.pending-chip {
  display: flex; align-items: center; gap: .3rem; flex: none;
  height: 36px; padding: 0 .7rem 0 .55rem; border-radius: 999px; cursor: pointer;
  background: transparent; border: 1.5px solid color-mix(in srgb, var(--warn) 55%, transparent);
  color: color-mix(in srgb, var(--warn) 85%, var(--text));
  font-family: inherit; font-weight: 800;
  transition: background .16s, border-color .16s, color .16s;
  animation: pcPop .4s cubic-bezier(.2, 1.5, .4, 1);
}
.pending-chip:hover {
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border-color: color-mix(in srgb, var(--warn) 75%, var(--border));
}
.pending-chip .pc-ico { font-size: .95rem; line-height: 1; animation: pcRing 3.5s ease-in-out infinite; transform-origin: 50% 10%; }
.pending-chip .pc-n { font-size: .88rem; font-variant-numeric: tabular-nums; }
@keyframes pcPop { from { opacity: 0; transform: scale(.7); } }
/* Sonnerie discrète, très espacée : signaler sans harceler. */
@keyframes pcRing {
  0%, 88%, 100% { transform: rotate(0); }
  90% { transform: rotate(11deg); }
  92% { transform: rotate(-9deg); }
  94% { transform: rotate(7deg); }
  96% { transform: rotate(-5deg); }
}
@media (prefers-reduced-motion: reduce) {
  .pending-chip, .pending-chip .pc-ico { animation: none; }
}
@media (max-width: 600px) {
  .pending-chip { height: 32px; padding: 0 .55rem 0 .45rem; }
  .pending-chip .pc-n { font-size: .82rem; }
}


.kpi b { display: block; font-size: 2rem; font-weight: 800; letter-spacing: -.03em; }
/* text-wrap: balance répartit les lignes plutôt que de laisser « %) » seul
   en bas — le libellé le plus long tient sur deux lignes équilibrées. */
.kpi span { font-size: .82rem; color: var(--text-mute); text-wrap: balance; }

/* ─────────────── Divers ─────────────── */
.toast-wrap { position: fixed; bottom: 1.6rem; left: 50%; transform: translateX(-50%); z-index: 200; display: grid; gap: .6rem; }
.toast {
  background: var(--text); color: var(--bg); padding: .85em 1.4em; border-radius: 999px; font-size: .92rem; font-weight: 600;
  box-shadow: var(--shadow-lg); animation: toastIn .3s cubic-bezier(.2,1.2,.3,1); display: flex; gap: .6em; align-items: center;
}
@keyframes toastIn { from { opacity: 0; transform: translateY(20px) scale(.9); } }
.toast.badge-toast { background: linear-gradient(135deg, #f79009, #e11d48); color: #fff; }

/* ── Guide visuel d'installation (iOS et navigateurs sans invite) ── */
.modal__head .head-icon {
  width: 44px; height: 44px; border-radius: 12px; display: block; margin-bottom: .2rem;
}
.steps-visual { display: grid; gap: .7rem; }
.step-row {
  display: flex; align-items: center; gap: .9rem;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: .9rem 1rem;
}
.step-row .step-num {
  flex: none; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand); color: #fff; font-size: .78rem; font-weight: 800;
}
.step-row .step-ico { flex: none; width: 30px; height: 30px; color: var(--brand); display: block; }
.step-row .step-ico svg { width: 100%; height: 100%; display: block; }
.step-row b { display: block; font-size: .96rem; line-height: 1.3; }
.step-row span { font-size: .8rem; color: var(--text-mute); }
.step-note {
  margin: 1rem 0 0; font-size: .84rem; color: color-mix(in srgb, var(--warn) 80%, var(--text));
  background: var(--warn-soft); border-radius: var(--radius-sm); padding: .7rem .9rem;
}

/* ── Retour en haut de page ──
   Discret : un disque translucide qui flotte au-dessus du contenu, et qui
   n'existe qu'une fois la page descendue. Il glisse vers le bas quand il
   s'efface, plutôt que de disparaître d'un coup. */
.haut {
  position: fixed; right: 1.4rem; z-index: 80;
  bottom: max(1.4rem, env(safe-area-inset-bottom));
  width: 2.7rem; height: 2.7rem; border-radius: 50%; padding: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.15rem; line-height: 1; cursor: pointer; color: var(--brand);
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid var(--border); box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; transform: translateY(12px);
  transition: opacity .22s, transform .22s, visibility .22s, border-color .16s, background .16s;
}
.haut.on { opacity: 1; visibility: visible; transform: none; }
.haut:hover {
  border-color: color-mix(in srgb, var(--brand) 55%, var(--border));
  background: color-mix(in srgb, var(--brand) 10%, var(--surface));
}
.haut:active { transform: scale(.94); }
.haut:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
/* La bannière d'installation occupe toute la largeur en bas : le bouton monte
   au-dessus d'elle tant qu'elle est affichée, au lieu de passer dessous. */
body:has(.install-banner) .haut { bottom: max(5.6rem, calc(env(safe-area-inset-bottom) + 4.2rem)); }
@media (max-width: 560px) { .haut { right: .9rem; width: 2.5rem; height: 2.5rem; } }
@media (prefers-reduced-motion: reduce) {
  .haut { transition: opacity .15s, visibility .15s; transform: none; }
  .haut.on { transform: none; }
}

/* ── Bannière d'invitation à installer l'application ── */
.install-banner {
  position: fixed; left: .7rem; right: .7rem; bottom: .7rem; z-index: 90;
  display: flex; align-items: center; gap: .9rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: .85rem 1rem;
  padding-bottom: max(.85rem, env(safe-area-inset-bottom));
  animation: ibIn .35s cubic-bezier(.2, 1, .3, 1);
}
@keyframes ibIn { from { opacity: 0; transform: translateY(28px); } }
.install-banner.out { opacity: 0; transform: translateY(28px); transition: opacity .25s, transform .25s; }
.install-banner .ib-icon { width: 42px; height: 42px; flex: none; border-radius: 11px; }
.install-banner .ib-text { flex: 1; min-width: 0; }
.install-banner .ib-text b { display: block; font-size: .92rem; line-height: 1.3; }
.install-banner .ib-text span { font-size: .78rem; color: var(--text-mute); }
.install-banner .ib-actions { display: flex; flex-direction: column; gap: .35rem; flex: none; }

/* La bannière occupe le bas de l'écran : on remonte les notifications. */
body.has-install-banner .toast-wrap { bottom: 7.5rem; }

@media (max-width: 420px) {
  .install-banner { flex-wrap: wrap; }
  .install-banner .ib-actions { flex-direction: row; width: 100%; }
  .install-banner .ib-actions .btn { flex: 1; }
}

.empty { text-align: center; padding: 3rem 1rem; color: var(--text-mute); }
.empty .em { font-size: 3rem; display: block; margin-bottom: .6rem; opacity: .6; }

.spinner {
  width: 34px; height: 34px; border-radius: 50%; border: 3px solid var(--border); border-top-color: var(--brand);
  animation: spin .8s linear infinite; margin: 3rem auto;
}
@keyframes spin { to { transform: rotate(360deg); } }

.confetti { position: fixed; inset: 0; pointer-events: none; z-index: 150; overflow: hidden; }
.confetti i {
  position: absolute; width: 9px; height: 15px; opacity: .9; top: -20px;
  animation: fall linear forwards;
}
@keyframes fall { to { transform: translateY(105vh) rotate(720deg); opacity: .2; } }

.footer { text-align: center; padding: 2rem 1rem 1rem; font-size: .8rem; color: var(--text-mute); }
.footer a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--border); transition: .18s; }
.footer a:hover { color: var(--brand); border-bottom-color: var(--brand); }

/* ─────────────── Fiches réflexes ───────────────
   Chaque carte est un lien vers son PDF : la cible est la fiche entière, pas
   un bouton minuscule au fond de la carte. La teinte reprend celle du PDF, de
   sorte qu'on reconnaisse à l'écran la fiche qu'on a en main sur papier. */
/* Une couleur par famille, portée par l'intitulé comme par les cartes : le
   classement se voit alors sans avoir à être expliqué. */
.fiche-groupe { --ton: var(--brand); margin-bottom: 2.4rem; }
.fiche-groupe.ton-danger { --ton: var(--danger); }
.fiche-groupe.ton-teal   { --ton: var(--teal); }
.fiche-famille {
  display: flex; align-items: baseline; gap: .8rem;
  font-size: .82rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ton); margin: 0 0 1rem;
  padding-bottom: .5rem; border-bottom: 2px solid color-mix(in srgb, var(--ton) 35%, var(--border));
}
.fiche-famille span { font-size: .74rem; font-weight: 500; letter-spacing: 0; text-transform: none; }

/* Trois par ligne, comme le hub : neuf fiches par famille donnent trois
   rangées nettes, là où « auto-fill » produisait un reliquat bancal. */
.fiche-grille { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
@media (max-width: 940px) { .fiche-grille { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .fiche-grille { grid-template-columns: 1fr; } }

.fiche-carte {
  --ton: var(--brand);
  display: flex; flex-direction: column; text-decoration: none;
  background: var(--surface); border: 1px solid var(--border);
  border-top: 3px solid color-mix(in srgb, var(--ton) 55%, var(--border));
  border-radius: var(--radius); padding: 1.1rem 1.15rem 1rem;
  transition: border-color .18s, box-shadow .18s, transform .18s;
}
.fiche-carte.ton-danger { --ton: var(--danger); }
.fiche-carte.ton-teal   { --ton: var(--teal); }
.fiche-carte:hover {
  border-color: color-mix(in srgb, var(--ton) 45%, var(--border));
  border-top-color: var(--ton);
  box-shadow: var(--shadow); transform: translateY(-2px);
}

.fiche-haut { display: flex; align-items: center; justify-content: space-between; margin-bottom: .7rem; }
.fiche-ico {
  width: 2.3rem; height: 2.3rem; border-radius: var(--radius-sm); font-size: 1.2rem;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--ton) 11%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--ton) 24%, var(--border));
}
.fiche-num {
  font-size: .68rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ton);
}
.fiche-titre { display: block; font-size: 1.04rem; color: var(--text); line-height: 1.25; }
.fiche-ss { font-size: .82rem; color: var(--text-soft); margin-top: .18rem; }
.fiche-resume {
  font-size: .83rem; color: var(--text-mute); line-height: 1.55;
  margin: .7rem 0 0; flex: 1;
}
.fiche-pdf {
  margin-top: .9rem; padding-top: .7rem; border-top: 1px solid var(--border);
  font-size: .78rem; font-weight: 600; color: var(--ton);
}

/* ─────────────── Mentions légales ───────────────
   Page de lecture : mesure de ligne resserrée et interlignage généreux. Ces
   textes ne se parcourent pas, ils se lisent — parfois pour vérifier un point
   précis, d'où les titres de section bien détachés. */
.legal { max-width: 62ch; }
.legal-tabs { display: inline-flex; gap: .3rem; background: var(--bg-soft); padding: .3rem; border-radius: 999px; margin-bottom: 1.6rem; }
.legal-tabs .tab {
  padding: .55em 1.1em; border: 0; background: transparent; border-radius: 999px;
  font-weight: 600; font-size: .9rem; font-family: inherit; color: var(--text-soft); cursor: pointer; transition: .2s;
}
.legal-tabs .tab:hover { color: var(--text); }
.legal-tabs .tab.on { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm); }

.legal-chapo { color: var(--text-soft); font-size: .92rem; font-style: italic; margin-bottom: 2rem; }
.legal-sec { margin-bottom: 2.1rem; }
.legal-sec h3 {
  font-size: 1.02rem; margin-bottom: .7rem; color: var(--text);
  padding-bottom: .45rem; border-bottom: 1px solid var(--border);
}
.legal-sec p { color: var(--text-soft); line-height: 1.72; margin-bottom: .85rem; font-size: .93rem; }
.legal-sec b { color: var(--text); font-weight: 600; }
.legal-sec a { color: var(--brand); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--brand) 35%, transparent); }
.legal-sec a:hover { border-bottom-color: var(--brand); }

.legal-liste { list-style: none; margin: 0 0 .95rem; padding: 0; }
.legal-liste li {
  position: relative; padding-left: 1.1rem; margin-bottom: .55rem;
  color: var(--text-soft); line-height: 1.7; font-size: .93rem;
}
.legal-liste li::before {
  content: ''; position: absolute; left: 0; top: .68em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--border);
}

.legal-champs { display: grid; grid-template-columns: minmax(9rem, 14rem) 1fr; gap: .1rem 1.2rem; margin: 0 0 1rem; }
.legal-champs dt { font-size: .8rem; font-weight: 600; color: var(--text-mute); padding: .45rem 0; }
.legal-champs dd { margin: 0; padding: .45rem 0; color: var(--text-soft); font-size: .93rem; line-height: 1.6; }
.legal-champs dt + dd { border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }
.legal-champs dt { border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }

/* Champ que seul l'organisme peut renseigner. Signalé sans ambiguïté plutôt
   que masqué : une mention légale incomplète doit se voir. */
.a-completer {
  display: inline-block; padding: .1em .55em; border-radius: 999px;
  font-size: .78rem; font-weight: 600; color: var(--warn);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border: 1px dashed color-mix(in srgb, var(--warn) 45%, transparent);
}

.legal-maj { font-size: .8rem; color: var(--text-mute); margin-top: 2.4rem; padding-top: 1rem; border-top: 1px solid var(--border); }

/* Consultation sans compte : pas de bandeau applicatif, une simple page. */
.legal-page { max-width: 780px; margin: 0 auto; padding: 2rem 1.4rem 4rem; }
.legal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding-bottom: 1.4rem; margin-bottom: 2rem; border-bottom: 1px solid var(--border);
}

/* Information affichée sur le formulaire d'inscription lui-même. */
.auth__legal {
  font-size: .78rem; line-height: 1.6; color: var(--text-mute);
  margin: .2rem 0 1rem; padding-left: .85rem;
  border-left: 2px solid var(--border);
}
.auth__legal a { color: var(--brand); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--brand) 35%, transparent); }
.auth__legal a:hover { border-bottom-color: var(--brand); }
.auth__foot { margin-top: 1.4rem; text-align: center; font-size: .8rem; }
.auth__foot a { color: var(--text-mute); text-decoration: none; border-bottom: 1px solid var(--border); }
.auth__foot a:hover { color: var(--brand); border-bottom-color: var(--brand); }

/* ─────────────── Activation d'une invitation ───────────────
 * Rappel de l'identité rattachée au lien, avant que la personne ne pose son
 * mot de passe : elle doit pouvoir vérifier que le lien lui était destiné. */
.activation-qui {
  display: grid; gap: .55rem; margin: 0 0 1.5rem;
  padding: .95rem 1.1rem; border-radius: var(--radius-sm);
  background: var(--bg-soft); border: 1px solid var(--border);
}
.activation-qui > div { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; }
.activation-qui span { font-size: .8rem; color: var(--text-mute); }
.activation-qui b { font-size: .92rem; text-align: right; word-break: break-word; }

/* ─────────────── Tri et filtres du tableau des participants ─────────────── */
.grille-filtres {
  display: flex; gap: .6rem; flex-wrap: wrap; align-items: center;
  margin-bottom: .9rem;
}
.grille-filtres input, .grille-filtres select {
  padding: .55em .8em; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--text); font-size: .9rem; font-family: inherit;
}
.grille-filtres input:focus, .grille-filtres select:focus {
  outline: 0; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft);
}
.grille-q { flex: 1 1 15rem; min-width: 0; max-width: 24rem; }
.grille-compte { margin-left: auto; font-size: .85rem; color: var(--text-mute); white-space: nowrap; }
.grille-compte.actif { color: var(--brand); font-weight: 600; }
/* Pas de `display: flex` sur cette cellule : une case de tableau ainsi
   déclarée sort de l'algorithme de largeur du tableau et cesse de couvrir la
   rangée — le message se retrouvait collé à gauche au lieu d'être centré.
   Une cellule ordinaire et `text-align` suffisent, le bouton étant en ligne. */
.grille-vide { text-align: center; padding: 2.2rem 1rem; color: var(--text-mute); }
/* Le bouton reste sur la ligne du message : la phrase et le geste qu'elle
   propose se lisent d'un trait, et la rangée vide ne prend pas trois lignes. */
.grille-vide .btn { margin-left: .7rem; vertical-align: middle; }

/* En-tête triable. La flèche occupe sa place en permanence, en réserve
   d'opacité : la faire apparaître au clic décalait tous les intitulés d'un
   demi-caractère, et la ligne entière tressautait à chaque tri. */
.data--admin th.triable { cursor: pointer; user-select: none; white-space: nowrap; }
.data--admin th.triable:hover { color: var(--brand); }
.data--admin th .fleche {
  display: inline-block; width: .75em; margin-left: .25em;
  font-style: normal; opacity: 0; transition: opacity .15s;
}
.data--admin th .fleche::before { content: '▲'; font-size: .62em; vertical-align: .1em; }
.data--admin th.triable:hover .fleche { opacity: .35; }
.data--admin th.trie { color: var(--brand); }
.data--admin th.trie .fleche { opacity: 1; }
.data--admin th.trie.desc .fleche::before { content: '▼'; }
/* Colonne centrée : la flèche suit l'intitulé sans casser le centrage. */
.data--admin th.c-num.triable, .data--admin th.c-droite.triable { white-space: nowrap; }

@media (max-width: 760px) {
  .grille-compte { margin-left: 0; }
  .grille-q { flex-basis: 100%; max-width: none; }
}

/* ─────────────── Page pédagogique d'un clic de faux-phishing ───────────────
   Ton apaisé, jamais alarmant : la personne vient de « se faire prendre » à un
   test, la page l'instruit sans la brusquer. Fond neutre, carte centrée. */
.hamec {
  min-height: 100vh; display: grid; place-items: center;
  padding: 2rem 1.2rem; background: var(--bg);
}
.hamec-carte {
  width: 100%; max-width: 720px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 2.4rem 2.6rem;
}
.hamec-tete { display: flex; align-items: center; gap: 1.1rem; margin-bottom: 1.4rem; }
.hamec-ico {
  flex: none; width: 3.4rem; height: 3.4rem; border-radius: 1rem; font-size: 1.7rem;
  display: grid; place-items: center;
  background: var(--warn-soft); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
}
.hamec-sur { font-size: .78rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--warn); }
.hamec-tete h1 { margin: .1rem 0 0; font-size: 1.5rem; letter-spacing: -.02em; }
.hamec-intro { color: var(--text-soft); line-height: 1.6; margin-bottom: 1.6rem; }

.hamec-bloc { margin-top: 1.4rem; padding: 1.1rem 1.3rem; border-radius: var(--radius); border: 1px solid var(--border); }
.hamec-bloc h2 { font-size: .82rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; margin: 0 0 .7rem; }
.hamec-bloc ul { margin: 0; padding-left: 1.2rem; }
.hamec-bloc li { margin: .5rem 0; line-height: 1.55; }
.hamec-indices { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 25%, transparent); }
.hamec-indices h2 { color: color-mix(in srgb, var(--warn) 75%, var(--text)); }
.hamec-conseils { background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 25%, transparent); }
.hamec-conseils h2 { color: color-mix(in srgb, var(--ok) 72%, var(--text)); }
.hamec-pied { margin-top: 1.8rem; }
.hamec-pied p { color: var(--text-soft); }
.hamec-actions { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1rem; }

@media (max-width: 560px) {
  .hamec-carte { padding: 1.6rem 1.3rem; }
  .hamec-tete h1 { font-size: 1.25rem; }
}

/* ─────────────── Campagnes de faux-phishing (console) ─────────────── */
.phish-liste { display: grid; gap: .8rem; }
.phish-carte {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 1rem 1.2rem; font-family: inherit; transition: .15s;
  /* Un <button> n'hérite pas de la couleur de texte de la page : sans cette
     ligne, il prend le noir par défaut du navigateur — invisible en thème
     sombre, où le nom de la campagne et les compteurs disparaissaient. */
  color: var(--text);
}
.phish-carte:hover { border-color: var(--brand); box-shadow: var(--shadow-sm); }
.phish-carte__tete { display: flex; align-items: center; gap: .8rem; }
.phish-modele { font-size: 1.4rem; flex: none; }
.phish-carte__titre { flex: 1; min-width: 0; }
.phish-carte__titre b { display: block; }
.phish-carte__titre span { font-size: .84rem; color: var(--text-mute); }
.phish-carte__chiffres { display: flex; gap: 2rem; margin-top: .8rem; padding-top: .8rem; border-top: 1px solid var(--border); }
.phish-carte__chiffres b { font-size: 1.3rem; font-weight: 800; }
.phish-carte__chiffres span { font-size: .78rem; color: var(--text-mute); margin-left: .35rem; }
.phish-taux-haut b { color: var(--warn); }

.phish-recid-liste { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .7rem; }

/* Palette des domaines de lien : le nom d'hôte prend la place, la pastille
   dit son rôle, l'action (retirer) suit. Réutilise la grille du référentiel. */
.ref-ligne .ref-domaine {
  flex: 1; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9rem; word-break: break-all;
}

.phish-apercu { font-size: .84rem; color: var(--text-mute); margin-top: .4rem; font-style: italic; }

/* Sélecteur de cibles */
.phish-cible-barre { display: flex; align-items: center; gap: .9rem; margin-bottom: .5rem; }
.phish-cible-compte { font-size: .84rem; color: var(--text-mute); }
.phish-cibles {
  max-height: 15rem; overflow-y: auto; display: grid; gap: .2rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .5rem;
}
/* `.phish-cible` est un <label> DANS un .field : la règle `.field label`
   (display:block, margin) le prendrait de vitesse. On monte la spécificité
   pour remettre la ligne à l'horizontale et annuler la marge héritée. */
.phish-cibles label.phish-cible {
  display: flex; align-items: center; gap: .6rem; margin: 0;
  padding: .4rem .5rem; border-radius: var(--radius-sm); cursor: pointer;
}
.phish-cibles label.phish-cible:hover { background: var(--surface-2); }
/* La règle globale .field input impose width:100% : sans cette réserve, la
   case à cocher s'étirait sur toute la ligne et fuyait à droite de l'intitulé. */
.phish-cible input[type="checkbox"] {
  width: auto; flex: none; margin: 0; padding: 0;
  accent-color: var(--brand); width: 1.05rem; height: 1.05rem;
}
.phish-cible span { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.phish-cible small { color: var(--text-mute); }

/* Détail : résumé + liste des cibles */
.phish-resume { display: flex; gap: 1.4rem; align-items: center; flex-wrap: wrap; margin-bottom: 1rem; }
.phish-resume b { font-size: 1.05rem; }
.phish-cibles-detail { display: grid; gap: .4rem; }
.phish-cible-ligne {
  display: grid; grid-template-columns: 1fr auto auto; gap: .8rem; align-items: center;
  padding: .6rem .8rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.phish-cible-ligne.a-clique { border-color: color-mix(in srgb, var(--warn) 45%, var(--border)); background: color-mix(in srgb, var(--warn-soft) 55%, transparent); }
.phish-cible-qui b { display: block; }
.phish-cible-qui small { color: var(--text-mute); }
.phish-cible-actions { display: flex; gap: .4rem; flex-wrap: wrap; }

@media (max-width: 620px) {
  .phish-cible-ligne { grid-template-columns: 1fr; }
  .phish-cible-actions { justify-content: flex-start; }
}

/* ─────────────── Référentiel des structures ─────────────── */
.ref-liste { display: grid; gap: .5rem; }
.ref-ligne {
  display: grid; grid-template-columns: 7.5rem 1fr auto auto;
  gap: .6rem; align-items: center;
}
.ref-ligne .ref-type, .ref-ligne .ref-nom {
  padding: .5em .7em; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--text); font-size: .92rem; font-family: inherit;
}
.ref-ligne .ref-nom:focus, .ref-ligne .ref-type:focus {
  outline: 0; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft);
}
.ref-vide { color: var(--text-mute); font-size: .92rem; margin: 0; }

/* Création d'une structure, en place dans un autre formulaire. */
.creation-structure { margin-top: .7rem; }
.creation-ligne { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.creation-ligne select, .creation-ligne input {
  padding: .5em .7em; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--text); font-size: .92rem; font-family: inherit;
}
.creation-ligne input { flex: 1 1 12rem; min-width: 0; }

/* Colonne « Structure » du tableau : le type devant, le nom derrière. */
.cell-structure { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.cell-structure .pill { flex: none; }

@media (max-width: 620px) {
  .ref-ligne { grid-template-columns: 1fr auto; }
  .ref-ligne .ref-type { grid-column: 1 / -1; }
}

/* ═══════════════ Animations en direct ═══════════════ */
/* ── Participant (téléphone) ── */
.live { min-height: 100vh; background: var(--bg); display: flex; flex-direction: column; }
.live--join { align-items: center; justify-content: center; padding: 1.5rem; }
.live-join {
  width: 100%; max-width: 26rem; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 2rem 1.8rem; text-align: center;
}
.live-join-marque { display: inline-flex; align-items: center; gap: .5rem; font-weight: 800; margin-bottom: 1.2rem; }
.live-join-marque .mark { width: 30px; height: 30px; }
.live-join h1 { font-size: 1.4rem; margin: 0 0 .3rem; }
.live-join p { color: var(--text-soft); margin: 0 0 1.2rem; }
.live-code-input {
  width: 100%; text-align: center; font-size: 2rem; font-weight: 800; letter-spacing: .3em;
  text-transform: uppercase; padding: .6em .3em; margin-bottom: 1rem;
  border: 2px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.live-code-input:focus { outline: 0; border-color: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }

.live-topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .8rem 1.1rem; background: var(--surface); border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 5;
}
.live-topbar__marque { display: flex; align-items: center; gap: .5rem; font-weight: 700; font-size: .95rem; }
.live-topbar__marque .mark { width: 26px; height: 26px; }
.live-topbar__etape { font-size: .82rem; font-weight: 700; color: var(--brand); white-space: nowrap; }

.live-centre { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem 1.5rem; }
.live-centre__ico { font-size: 3.5rem; margin-bottom: 1rem; }
.live-centre h2 { font-size: 1.5rem; margin: 0 0 .4rem; }
.live-centre p { color: var(--text-soft); margin: 0; }

/* Large sur PC : inutile de brider la question à une colonne de téléphone. Le
   plafond garde les lignes lisibles sur très grand écran, sans plus. */
.live-q { flex: 1; padding: 1.6rem clamp(1.2rem, 4vw, 3rem) 2.5rem; max-width: min(96vw, 70rem); width: 100%; margin: 0 auto; }
/* L'explication reste à une largeur de lecture confortable, centrée dans la
   colonne large — boîte et texte. */
.live-explic { max-width: 52rem; margin-left: auto; margin-right: auto; text-align: center; }
.live-q__txt { font-size: 1.5rem; line-height: 1.25; margin: .3rem 0 1.2rem; }
.live-q__consigne { color: var(--text-soft); margin: -0.6rem 0 1rem; }
.live-options { display: grid; gap: .7rem; }
.live-opt {
  display: flex; align-items: center; gap: .8rem; width: 100%; text-align: left;
  padding: 1.05rem 1.1rem; border: 2px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text); font-size: 1.05rem; font-family: inherit; cursor: pointer; transition: .12s;
}
.live-opt__puce { flex: none; width: 1.4rem; height: 1.4rem; border-radius: 50%; border: 2px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: .82rem; font-weight: 800; line-height: 1; color: #fff; }
.live-opt.on { border-color: var(--brand); background: var(--brand-soft); }
.live-opt.on .live-opt__puce { border-color: var(--brand); background: var(--brand); box-shadow: inset 0 0 0 3px var(--surface); }
/* Après révélation : cartes figées, pastille verte (juste) ou rouge (faux). */
.live-opt--fige { cursor: default; }
.live-opt__txt { flex: 1; min-width: 0; }
.live-opt.bon { border-color: var(--ok); background: var(--ok-soft); }
.live-opt.bon .live-opt__puce { border-color: var(--ok); background: var(--ok); box-shadow: none; }
.live-opt.mauvais { border-color: var(--danger); background: var(--danger-soft); }
.live-opt.mauvais .live-opt__puce { border-color: var(--danger); background: var(--danger); box-shadow: none; }
/* Bonne réponse OUBLIÉE : verte, mais pastille creuse — on la distingue d'une
   bonne réponse qu'on avait bien cochée. */
.live-opt.oubli { border-style: dashed; }
.live-opt.oubli .live-opt__puce { background: transparent; color: var(--ok); }
/* Étiquette de droite : « Votre réponse » ou « Oubliée ». */
.live-opt__tag { flex: none; font-size: .72rem; font-weight: 700; padding: .18rem .6rem; border-radius: 999px; white-space: nowrap; }
.live-opt.bon .live-opt__tag.vous { background: var(--ok); color: #fff; }
.live-opt.mauvais .live-opt__tag.vous { background: var(--danger); color: #fff; }
.live-opt__tag.oubli { background: var(--warn-soft); color: color-mix(in srgb, var(--warn) 80%, var(--text)); border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent); }
.live-q__pied { margin-top: 1.3rem; }
.live-q__attente { text-align: center; color: var(--ok); font-weight: 600; }

/* Après révélation (participant) */
.live-verdict { text-align: center; font-size: 1.2rem; font-weight: 800; padding: .6rem; border-radius: var(--radius-sm); margin-bottom: 1rem; }
.live-verdict.juste { color: var(--ok); background: var(--ok-soft); }
.live-verdict.faux { color: var(--danger); background: var(--danger-soft); }
.live-res { margin-bottom: .7rem; }
.live-res__tete { display: flex; justify-content: space-between; gap: 1rem; font-size: .95rem; margin-bottom: .25rem; }
.live-res.bon .live-res__tete { color: var(--ok); font-weight: 700; }
.live-res.mien-faux .live-res__tete { color: var(--danger); }
.live-res__bar { height: 8px; background: var(--bg-soft); border-radius: 99px; overflow: hidden; }
.live-res__bar i { display: block; height: 100%; background: var(--text-mute); border-radius: 99px; }
.live-res.bon .live-res__bar i { background: var(--ok); }
.live-explic { margin-top: 1rem; padding: .9rem 1.1rem; background: var(--info-soft); border-radius: var(--radius-sm); color: color-mix(in srgb, var(--info) 75%, var(--text)); line-height: 1.5; }

.live-mot-ligne { display: flex; gap: .6rem; }
.live-mot-input { flex: 1; padding: 1rem 1.1rem; font-size: 1.1rem; border: 2px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); }
.live-mot-input:focus { outline: 0; border-color: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.live-mesmots { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5rem; }
.live-monmot { padding: .35rem .8rem; background: var(--brand-soft); color: var(--brand); border-radius: 99px; font-weight: 600; font-size: .9rem; }

/* ── Animateur (écran projeté) ── */
.animer { min-height: 100vh; background: var(--bg); display: flex; flex-direction: column; }
.animer-tete { display: flex; align-items: center; gap: 1.2rem; padding: 1rem 1.6rem; border-bottom: 1px solid var(--border); background: var(--surface); }
.animer-tete__titre { display: flex; align-items: center; gap: .6rem; font-weight: 800; font-size: 1.15rem; flex: 1; }
.animer-tete__titre .mark { width: 32px; height: 32px; }
.animer-tete__code { display: flex; align-items: center; gap: .6rem; font-size: .9rem; color: var(--text-soft); }
.animer-tete__code b { font-size: 1.5rem; letter-spacing: .15em; color: var(--brand); font-family: ui-monospace, monospace; }
.animer-tete__n { color: var(--text-mute); }
.animer-quitter { border: 0; background: var(--bg-soft); color: var(--text-soft); width: 34px; height: 34px; border-radius: 50%; cursor: pointer; font-size: 1rem; }
.animer-quitter:hover { background: var(--danger-soft); color: var(--danger); }
.animer-corps { flex: 1; display: flex; padding: 2rem 2.5rem; overflow: hidden; }
.animer-zone { flex: 1; display: flex; flex-direction: column; justify-content: center; min-height: 0; }

/* Écran d'attente projeté : le code en très grand */
.animer-attente { text-align: center; }
.animer-rejoindre p { font-size: 1.6rem; color: var(--text-soft); margin: .3rem 0; }
.animer-url { font-size: 2.4rem; font-weight: 800; color: var(--text); margin: .3rem 0; }
.animer-bigcode {
  font-size: 7rem; font-weight: 900; letter-spacing: .1em; line-height: 1.1;
  color: var(--brand); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.animer-count { font-size: 1.3rem; color: var(--text-mute); margin-top: 1.5rem; }

.animer-q { width: 100%; }
.animer-q__num { font-size: 1rem; font-weight: 700; color: var(--brand); text-transform: uppercase; letter-spacing: .08em; }
.animer-q h1 { font-size: 2.4rem; line-height: 1.15; margin: .4rem 0 1.4rem; }
.animer-q__consigne { font-size: 1.2rem; color: var(--text-soft); margin: -0.8rem 0 1.2rem; }
.animer-barres { display: grid; gap: .9rem; }
.animer-barre { display: grid; grid-template-columns: 1fr auto; gap: .2rem 1rem; align-items: center; }
.animer-barre__txt { grid-column: 1; font-size: 1.4rem; font-weight: 600; }
.animer-barre__n { grid-column: 2; grid-row: 1 / 3; font-size: 2rem; font-weight: 800; color: var(--text-soft); min-width: 2.5rem; text-align: right; }
.animer-barre__jauge { grid-column: 1; height: 18px; background: var(--bg-soft); border-radius: 99px; overflow: hidden; }
.animer-barre__jauge i { display: block; height: 100%; background: linear-gradient(90deg, var(--brand), var(--brand-2)); border-radius: 99px; transition: width .5s cubic-bezier(.2,.8,.2,1); }
.animer-barre.bon .animer-barre__txt { color: var(--ok); }
.animer-barre.bon .animer-barre__jauge i { background: var(--ok); }
.animer-barre.pale { opacity: .5; }
.animer-q__pied { margin-top: 1.4rem; display: flex; flex-direction: column; gap: .6rem; font-size: 1.1rem; color: var(--text-mute); }
.animer-explic { font-size: 1.15rem; color: color-mix(in srgb, var(--info) 75%, var(--text)); background: var(--info-soft); padding: 1rem 1.3rem; border-radius: var(--radius); line-height: 1.5; margin: 0; }

.animer-nuage-wrap { text-align: center; width: 100%; }
.animer-nuage-titre { font-size: 2rem; margin: 0 0 1.5rem; }
.animer-nuage { display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; align-items: center; justify-content: center; line-height: 1.15; }
.animer-mot { font-weight: 800; }
.animer-nuage-vide { font-size: 1.4rem; color: var(--text-mute); }

.animer-commandes { display: flex; gap: .7rem; padding: 1rem 1.6rem; border-top: 1px solid var(--border); background: var(--surface); flex-wrap: wrap; justify-content: center; }
.animer-commandes .btn { font-size: 1.05rem; }

/* Gestionnaire d'animations (console) */
.anim-liste { display: grid; gap: .5rem; }
.anim-ligne { display: flex; align-items: center; gap: 1rem; padding: .8rem 1rem; border: 1px solid var(--border); border-radius: var(--radius); flex-wrap: wrap; }
.anim-ligne__ico { font-size: 1.7rem; flex: none; }
.anim-ligne__txt { flex: 1; min-width: 8rem; }
.anim-ligne__txt b { display: block; }
.anim-ligne__txt span { font-size: .82rem; color: var(--text-mute); }
.anim-ligne__actions { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.anim-nouveau { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1.2rem; }

/* Éditeur de quiz */
.edq { border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.1rem; margin: .9rem 0; background: var(--surface-2); }
.edq__tete { display: flex; align-items: center; justify-content: space-between; margin-bottom: .6rem; }
.edq__outils { display: flex; gap: .3rem; }
.edq__options { margin: .3rem 0 .8rem; }
.edq__type { display: inline-flex; gap: .2rem; padding: .2rem; background: var(--bg-soft); border-radius: 999px; margin-bottom: .6rem; }
.edq__type-btn { border: 0; background: transparent; color: var(--text-soft); font-family: inherit; font-size: .84rem; font-weight: 600; padding: .4em .9em; border-radius: 999px; cursor: pointer; }
.edq__type-btn.on { background: var(--surface); color: var(--brand); box-shadow: var(--shadow-sm); }
.edq__hint { font-size: .82rem; color: var(--text-mute); margin-bottom: .5rem; }
.edq__opt-case input[type="radio"] { accent-color: var(--ok); }
.edq__opt { display: flex; align-items: center; gap: .5rem; margin-bottom: .45rem; }
.edq__opt-case { flex: none; display: inline-flex; align-items: center; cursor: pointer; }
.edq__opt-case input { width: 1.15rem; height: 1.15rem; accent-color: var(--ok); }
.edq__opt-txt { flex: 1; min-width: 0; padding: .55em .8em; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font-family: inherit; }
.edq__opt-txt:focus { outline: 0; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.edq textarea, .edq input[type="text"] { font-family: inherit; }
.act[disabled] { opacity: .35; cursor: default; }

@media (max-width: 640px) {
  .animer-corps { padding: 1.2rem; }
  .animer-q h1 { font-size: 1.6rem; }
  .animer-barre__txt { font-size: 1.1rem; }
  .animer-bigcode { font-size: 4rem; }
  .animer-url { font-size: 1.6rem; }
}

/* ─────────────── Documents support (console) ─────────────── */
.doc-liste { display: grid; gap: .5rem; }
.doc-ligne {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: .7rem .9rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface);
}
.doc-info { flex: 1; min-width: 0; }
.doc-nom { font-weight: 600; color: var(--text); text-decoration: none; word-break: break-all; }
.doc-nom:hover { color: var(--brand); }
.doc-meta { font-size: .8rem; color: var(--text-mute); margin-top: .15rem; }
.doc-actions { display: flex; align-items: center; gap: .5rem; flex: none; }

/* ─────────────── Lien d'invitation, dans la console ─────────────── */
.lien-invit-label {
  display: block; font-size: .85rem; font-weight: 600;
  color: var(--text-soft); margin: 1.2rem 0 .4rem;
}
.lien-invit {
  width: 100%; padding: .75em .9em; border-radius: var(--radius-sm);
  border: 1px solid var(--brand); background: var(--brand-soft); color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .82rem; word-break: break-all;
}

/* ─────────────── Responsive ─────────────── */
@media (max-width: 900px) {
  .legal-champs { grid-template-columns: 1fr; gap: 0; }
  .legal-champs dt { border-bottom: 0; padding-bottom: 0; }
  .legal-champs dd { padding-top: .15rem; padding-bottom: .8rem; }
  .auth { grid-template-columns: 1fr; }
  .auth__brand { padding: 2.6rem 2rem; }
  .auth__features { display: none; }
  .auth__brand h1 { font-size: clamp(1.3rem, 5.4vw, 1.9rem); }
  .auth__brand p { font-size: .95rem; max-width: none; }
  .split, .match-grid { grid-template-columns: 1fr; }
  .grid-cards.cols-2, .grid-cards.cols-3 { grid-template-columns: 1fr; }
  .card { padding: 1.6rem 1.3rem; }
  .game { padding: 1.4rem 1.2rem; }
  .hero-home { padding: 1.8rem 1.5rem; }
  .topbar__ou { display: none; }
  .xpchip .bar { display: none; }
  .cert { padding: 1.8rem 1.2rem; }
  .theme-bar .nm { width: 108px; font-size: .82rem; }
}

/* ── Portrait étroit : la barre haute doit tenir sans déborder ──
   Un débordement horizontal élargit la fenêtre de mise en page, ce qui décale
   et tronque tous les éléments en position fixed (modales, bandeaux). */
@media (max-width: 600px) {
  .topbar__in { padding: .55rem .8rem; gap: .55rem; }
  .topbar__logo .brand-name { display: none; }
  .xpchip { padding: .3rem .6rem .3rem .3rem; gap: .45rem; }
  .xpchip .lvl { width: 26px; height: 26px; font-size: .72rem; }
  .xpchip .val { font-size: .72rem; }
  .theme-switch { width: 56px; height: 30px; }
  .theme-switch .knob { width: 22px; height: 22px; }
  html[data-theme='dark'] .theme-switch .knob { transform: translateX(28px); }
  /* Sur téléphone, « Prénom NOM » mangerait la barre. Le prénom seul y tient,
     reste lisible, et vaut mieux qu'un nom coupé en son milieu. */
  .compte-chip { max-width: 8rem; height: 34px; padding: 0 .5rem 0 .7rem; }
  .compte-chip .nom { display: none; }
  .compte-chip .prenom { display: block; }
  .overlay { padding: .8rem; }
  .modal__head { padding: 1.2rem 1.3rem 1rem; }
  .modal__body { padding: 1.1rem 1.3rem 1.4rem; }
  /* Marges internes resserrées : ~13 px de largeur utile gagnés pour le titre. */
  .hero-home { padding: 1.6rem 1.1rem; }

  /* Écran de connexion : le bandeau de présentation ne doit pas repousser le
     bouton hors de l'écran. Titre resserré, accroche masquée. */
  .auth__brand { padding: 1.4rem 1.2rem 1.2rem; }
  .auth__logo { margin-bottom: 1.1rem; }
  .auth__logo .mark { width: 38px; height: 38px; border-radius: 11px; }
  .auth__brand h1 { font-size: 1.3rem; margin-bottom: 0; }
  .auth__brand p { display: none; }
  .auth__panel { padding: 1.3rem 1.2rem 1.8rem; }
  .auth__tabs { margin-bottom: 1.2rem; }
  .auth__card h2 { font-size: 1.25rem; }
}

/* ── Encart d'accueil empilé : bouton et anneau centrés ──
   Dès que l'anneau passe sous le texte, l'alignement à gauche hérité de la
   disposition en deux colonnes n'a plus de sens. */
@media (max-width: 760px) {
  /* Empilement explicite : sans cela le texte se comprimerait à côté de
     l'anneau au lieu de passer au-dessus. align-items centre les deux blocs. */
  .hero-home .row { flex-direction: column; align-items: center; gap: 1.4rem; }
  .hero-home .hero-text { width: 100%; min-width: 0; text-align: center; }
  /* Titre fluide : « Reprenons où vous en étiez » tient sur une ligne jusqu'aux
     très petits écrans. Pas de white-space: nowrap — un prénom inhabituellement
     long doit pouvoir passer à la ligne plutôt que de déborder de l'écran, ce
     qui élargirait la page et décalerait les modales. */
  .hero-home h1 { font-size: clamp(1rem, 5vw, 1.6rem); }
  .hero-home .hero-text p { margin-left: auto; margin-right: auto; }
  .hero-home .hero-actions { justify-content: center; }
}

/* ── Écrans peu hauts : petits téléphones, ou paysage ──
   Le critère pertinent est la hauteur, pas la largeur : c'est elle qui décide
   si le bouton de connexion tient à l'écran. S'applique donc aussi en paysage. */
@media (max-height: 640px) {
  .auth__brand { padding: 1rem 1.2rem; }
  .auth__logo { margin-bottom: .7rem; font-size: 1rem; }
  .auth__logo .mark { width: 34px; height: 34px; border-radius: 10px; }
  .auth__brand h1 { font-size: 1.15rem; margin-bottom: 0; }
  .auth__brand p { display: none; }
  .auth__panel { padding: 1rem 1.2rem 1.4rem; }
  .auth__card h2 { font-size: 1.15rem; margin-bottom: .3rem; }
  .auth__card .auth__intro { display: none; }
  .auth__tabs { margin-bottom: .9rem; }
  .auth .field { margin-bottom: .75rem; }
}

/* Peu haut mais large — typiquement un téléphone en paysage : on remet le
   bandeau à côté du formulaire au lieu de l'empiler dessus. La hauteur
   disponible est alors entièrement dédiée au formulaire. */
@media (max-height: 640px) and (min-width: 680px) {
  .auth { grid-template-columns: 1fr 1fr; }
  .auth__brand h1 { font-size: 1.4rem; }
  .auth__brand p { display: block; font-size: .9rem; max-width: 32ch; }
}

@media print {
  .topbar, .footer, .btn, .no-print { display: none !important; }
  body { background: #fff; }
  main { padding: 0; max-width: none; }
  /* Une attestation s'imprime sur une page A4, et les aplats de couleur doivent
     survivre au reglage « economiser l'encre » des navigateurs — sans quoi le
     filet, la pastille et le lisere disparaissent. */
  @page { size: A4 portrait; margin: 12mm; }
  .cert {
    box-shadow: none; max-width: none; padding: 1.8rem 2.2rem 1.4rem;
    break-inside: avoid; -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  /* Le pire cas — huit modules complementaires — doit tenir sur la page :
     l'attestation se resserre a l'impression, sans rien retirer. */
  .cert h2 { font-size: 2rem; }
  .cert .who { font-size: 1.45rem; }
  /* La hauteur de la page imprimée, et non celle calculée pour l'écran :
     l'attestation remplit la feuille quel que soit son contenu. */
  .cert { min-height: 265mm; gap: 1rem; }
  .cert-corps { margin-top: .7rem; }
  .cert .cert-niveau { margin-top: .7rem; }
  .cert-modules ul { gap: .2rem; }
  .cert-modules li { break-inside: avoid; font-size: .8rem; }
}

/* ══════════════════════════ Fonds d'écran ══════════════════════════ */
.fond-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.1rem;
  margin-top: 1rem;
}
.fond-carte {
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}
.fond-carte:hover {
  box-shadow: var(--shadow);
  transform: translateY(-2px);
  border-color: var(--fa);
}
.fond-apercu {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--surface-2);
  border-bottom: 3px solid var(--fa);
  overflow: hidden;
}
.fond-apercu img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .3s ease;
}
.fond-carte:hover .fond-apercu img { transform: scale(1.03); }
.fond-info {
  padding: .85rem 1rem 1rem;
  display: flex;
  flex-direction: column;
  gap: .35rem;
}
.fond-saison {
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fa);
}
.fond-slogan {
  font-size: 1rem;
  line-height: 1.25;
  color: var(--text);
}
.fond-dl {
  margin-top: .55rem;
  align-self: flex-start;
  text-decoration: none;
}
