/* ============================================================
   CyberCoach — Design system
   Palette : indigo nuit (confiance) + ambre (vigilance/alerte)
   Typo    : Space Grotesk (display) / Inter (corps) / JetBrains Mono (data)
   ============================================================ */

:root {
  --ink-900: #0F1B2E;
  --ink-800: #16273F;
  --ink-700: #1E3350;
  --ink-600: #2B4368;
  --amber-500: #F2A93B;
  --amber-600: #DB9226;
  --amber-100: #FDF0DA;
  --teal-500: #1F9D82;
  --teal-100: #E1F5EF;
  /* Palier « bon mais perfectible » des jauges — pendant clair de --mat-4. */
  --lime-500: #8FBF4F;
  --lime-100: #EDF5E1;
  --coral-500: #E14F4F;
  --coral-100: #FCE7E7;
  --paper-0: #FBFAF8;
  --paper-50: #F7F5F1;
  --paper-100: #EFEBE4;
  --line: #E3DFD6;
  --text-900: #1A1F26;
  --text-600: #5B6472;
  /* Texte tertiaire. Deux jetons, car le contraste dépend du fond : #8A93A0 tenait sur
     l'indigo mais tombait à 2,6-3,0:1 sur les fonds papier (AA en exige 4,5). */
  --text-400: #606A78;      /* sur fond clair (paper-*) : min 4,61:1 */
  --text-400-dark: #9AA5B4; /* sur fond sombre (ink-*)  : min 5,12:1 */

  /* Échelle de maturité (0 inconscient → 5 champion). Ces teintes sont des
     REMPLISSAGES portant du texte encre : mesuré, le blanc n'y tient que
     1,76–3,87:1, l'encre 4,6–9,8:1. --mat-0 a été éclairci de #E14F4F à
     #E85F5F pour passer AA (4,47 → 5,12:1) sans perdre son rouge. */
  --mat-0: #E85F5F;
  --mat-1: #EA7B3D;
  --mat-2: #F2A93B;
  --mat-3: #D9C43B;
  --mat-4: #8FBF4F;
  --mat-5: #1F9D82;

  /* Déclinaison ENCRE de la même échelle, pour les rares endroits où elle
     colore du TEXTE et non un aplat. Mesuré : la rampe ci-dessus plafonne à
     3,87:1 sur blanc — elle échoue partout en texte. Celle-ci tient 5,4–6,2:1.
     Règle : un aplat prend --mat-N, un texte prend --mat-N-ink. */
  --mat-0-ink: #B3322F;
  --mat-1-ink: #9E4E12;
  --mat-2-ink: #8A5A12;
  --mat-3-ink: #7A6A0A;
  --mat-4-ink: #4A7016;
  --mat-5-ink: #12705C;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --shadow-sm: 0 1px 2px rgba(15,27,46,0.06), 0 1px 3px rgba(15,27,46,0.08);
  --shadow-md: 0 4px 12px rgba(15,27,46,0.08), 0 2px 4px rgba(15,27,46,0.06);
  --shadow-lg: 0 12px 32px rgba(15,27,46,0.14);

  --font-display: 'Space Grotesk', sans-serif;
  --font-body: 'Inter', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--paper-50);
  color: var(--text-900);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { font-family: var(--font-display); margin: 0; letter-spacing: -0.01em; }
p { line-height: 1.55; }
button, input, select { font-family: inherit; }
a { color: inherit; }
::selection { background: var(--amber-100); }

/* Anneau de focus clavier bicolore : l'ambre seul (~1,7:1) est sous le 3:1
   requis sur fond clair. Le halo sombre (--ink-900) garantit le contraste sur
   fond clair, l'ambre sur la sidebar sombre — l'indicateur reste visible partout. */
:focus-visible { outline: 2px solid var(--amber-500); outline-offset: 2px; box-shadow: 0 0 0 2px var(--ink-900); }
/* Cibles de focus programmatiques (ex. <main> visé par le lien d'évitement) :
   le changement d'écran suffit, pas d'anneau autour de toute la zone. */
[tabindex="-1"]:focus { outline: none; box-shadow: none; }

/* Réservé aux lecteurs d'écran : retiré du flux visuel, lu par la synthèse vocale. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Lien d'évitement : caché hors écran, révélé au focus clavier (première tabulation). */
.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 200;
  background: var(--ink-900); color: #fff;
  padding: 10px 16px; border-radius: var(--radius-sm);
  font-size: 0.9rem; font-weight: 600; text-decoration: none;
  transform: translateY(-150%); transition: transform 0.15s ease;
}
.skip-link:focus { transform: translateY(0); }

.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 248px; flex-shrink: 0; background: var(--ink-900); color: #EDEFF3;
  display: flex; flex-direction: column; padding: 24px 16px;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.sidebar .brand {
  display: flex; align-items: center; gap: 10px; padding: 0 8px 24px;
  font-family: var(--font-display); font-weight: 700; font-size: 1.15rem;
}
.sidebar .brand .mark {
  width: 30px; height: 30px; border-radius: 8px;
  background: linear-gradient(135deg, var(--amber-500), var(--amber-600));
  display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.sidebar nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.sidebar .nav-item {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: var(--radius-sm); color: #B8C0CE; font-size: 0.92rem; font-weight: 500;
  cursor: pointer; background: none; border: none; text-align: left; width: 100%;
}
.sidebar .nav-item:hover { background: rgba(255,255,255,0.06); color: #fff; }
.sidebar .nav-item.active { background: rgba(242,169,59,0.14); color: var(--amber-500); }
.sidebar .nav-section-label {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-400-dark); padding: 16px 12px 6px;
}
.sidebar .user-box { border-top: 1px solid rgba(255,255,255,0.1); padding-top: 14px; margin-top: 8px; font-size: 0.85rem; }
.sidebar .user-box .name { color: #fff; font-weight: 600; }
.sidebar .user-box .org { color: var(--text-400-dark); font-size: 0.78rem; margin-bottom: 8px; }
.sidebar .logout-btn {
  background: none; border: 1px solid rgba(255,255,255,0.16); color: #B8C0CE;
  padding: 6px 10px; border-radius: var(--radius-sm); font-size: 0.8rem; cursor: pointer; width: 100%;
}
.sidebar .logout-btn:hover { border-color: var(--amber-500); color: var(--amber-500); }

.main { flex: 1; min-width: 0; padding: 32px 40px 64px; max-width: 1180px; }
.topbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; }
.topbar h1 { font-size: 1.5rem; }
.topbar .subtitle { color: var(--text-600); font-size: 0.92rem; margin-top: 2px; }

.login-screen { min-height: 100vh; display: flex; background: var(--ink-900); }
.login-visual {
  flex: 1.1; display: flex; flex-direction: column; justify-content: center; padding: 64px;
  color: #fff; position: relative; overflow: hidden;
  background: radial-gradient(circle at 15% 20%, rgba(242,169,59,0.14), transparent 45%),
              radial-gradient(circle at 85% 80%, rgba(31,157,130,0.12), transparent 50%);
}
.login-visual .mark {
  width: 44px; height: 44px; border-radius: 12px;
  background: linear-gradient(135deg, var(--amber-500), var(--amber-600));
  display: flex; align-items: center; justify-content: center; font-size: 1.4rem; margin-bottom: 28px;
}
.login-visual h1 { font-size: 2.6rem; line-height: 1.1; max-width: 480px; margin-bottom: 18px; }
.login-visual p { color: #B8C0CE; max-width: 440px; font-size: 1.02rem; }
.maturity-strip { display: flex; gap: 6px; margin-top: 48px; }
.maturity-strip .step { height: 6px; flex: 1; border-radius: 4px; background: rgba(255,255,255,0.12); }
.maturity-strip .step.filled { background: var(--amber-500); }
.maturity-strip-label { color: var(--text-400-dark); font-size: 0.78rem; margin-top: 10px; letter-spacing: 0.03em; }

.login-form-panel {
  width: 440px; flex-shrink: 0; background: var(--paper-0);
  display: flex; align-items: center; justify-content: center; padding: 40px;
}
.login-card { width: 100%; max-width: 320px; }
.login-card h3 { font-size: 1.3rem; margin-bottom: 4px; }
.login-card .lead { color: var(--text-600); font-size: 0.9rem; margin-bottom: 28px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 5px; color: var(--text-600); }
input[type=email], input[type=password], input[type=text], select, textarea {
  width: 100%; padding: 10px 12px; border: 1.5px solid var(--line); border-radius: var(--radius-sm);
  font-size: 0.95rem; background: #fff; transition: border-color 0.15s;
}
/* Le changement de couleur de bordure marque le focus à la souris. Au CLAVIER,
   on conserve un anneau de focus visible (accessibilité) : sans lui, un
   utilisateur naviguant au clavier ne sait plus où il se trouve dans un
   formulaire. On ne retire donc l'outline que pour le focus non-clavier. */
input:focus, select:focus, textarea:focus { border-color: var(--ink-700); }
input:focus:not(:focus-visible),
select:focus:not(:focus-visible),
textarea:focus:not(:focus-visible) { outline: none; }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--amber-500); outline-offset: 2px;
}
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 10px 18px; border-radius: var(--radius-sm); font-weight: 600; font-size: 0.92rem;
  cursor: pointer; border: none; transition: opacity 0.15s, transform 0.1s;
}
.btn:active { transform: scale(0.98); }
.btn-primary { background: var(--ink-900); color: #fff; }
.btn-primary:hover { opacity: 0.88; }
.btn-amber { background: var(--amber-500); color: var(--ink-900); }
.btn-amber:hover { opacity: 0.9; }
.btn-ghost { background: transparent; color: var(--text-600); border: 1.5px solid var(--line); }
.btn-ghost:hover { border-color: var(--ink-700); color: var(--ink-900); }
.btn-block { width: 100%; }
.btn-sm { padding: 6px 12px; font-size: 0.82rem; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.error-text { color: var(--coral-500); font-size: 0.85rem; margin-top: 10px; }
.field-hint { color: var(--text-600); font-size: 0.78rem; line-height: 1.55; margin-top: 6px; }
.hint-box {
  margin-top: 22px; padding: 12px 14px; background: var(--paper-50);
  border-radius: var(--radius-sm); font-size: 0.8rem; color: var(--text-600); line-height: 1.6;
}
.hint-box code { font-family: var(--font-mono); background: var(--paper-100); padding: 1px 5px; border-radius: 4px; }

.card { background: #fff; border-radius: var(--radius-lg); border: 1px solid var(--line); box-shadow: var(--shadow-sm); }
.card-pad { padding: 22px 24px; }

/* ============================================================
   TABLEAU DE BORD
   Le reproche auquel ce bloc répond : « on passe d'un niveau à l'autre sans
   s'en rendre compte ». Trois leviers, dans cet ordre d'importance :
   1. un médaillon héro qui porte le niveau en grand, cerclé de sa propre
      progression — c'est LA figure de la vue, et il n'y en a qu'une ;
   2. une échelle à 6 marches NOMMÉES, où la marche courante est surélevée et
      étiquetée « vous êtes ici » — l'ancienne version alignait six pastilles
      de 28 px ne portant qu'un chiffre, franchir un palier ne changeait rien ;
   3. l'état réel de chaque module reporté sur sa carte.
   ============================================================ */

.dash-hero {
  background: linear-gradient(150deg, var(--ink-800) 0%, var(--ink-900) 55%);
  color: #fff; border-radius: var(--radius-lg);
  padding: 30px 32px 26px; margin-bottom: 22px; position: relative; overflow: hidden;
  box-shadow: var(--shadow-lg);
}
/* Halo décoratif teinté du niveau atteint : la vue change d'ambiance quand on
   monte, avant même d'avoir lu un mot. */
.dash-hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 88% 6%, rgba(242,169,59,0.18), transparent 58%);
}
.dash-hero > * { position: relative; }

.dash-hero-top { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; }

/* --- Médaillon : la figure héro de la vue --- */
.level-medallion { position: relative; width: 132px; height: 132px; flex: none; }
.level-medallion svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.level-medallion circle { fill: none; stroke-width: 8; }
.level-medallion .ring-track { stroke: rgba(255,255,255,0.12); }
/* La piste non remplie est un pas plus clair de la même rampe (ici le blanc
   translucide sur l'indigo) : l'état se lit sur tout l'anneau, pas seulement
   sur la portion pleine. */
.level-medallion .ring-fill {
  stroke-linecap: round;
  transition: stroke-dashoffset 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.medallion-core {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 0;
}
/* Figure héro : ≥48 px, dans la sans du corps de texte — une face display à
   cette taille se lirait comme un ornement, pas comme une donnée. Chiffres
   proportionnels (surtout pas tabular-nums, qui délave un nombre isolé). */
.medallion-digit {
  font-family: var(--font-body); font-size: 3.4rem; font-weight: 600;
  line-height: 1; color: #fff;
}
.medallion-scale { font-size: 0.75rem; color: var(--text-400-dark); margin-top: 2px; }

.dash-hero-text { min-width: 240px; flex: 1; }
.dash-hero .eyebrow {
  color: var(--text-400-dark); font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600;
}
.level-name { font-size: 2.1rem; margin: 4px 0 6px; letter-spacing: -0.02em; }
.level-sub { color: var(--text-400-dark); font-size: 0.9rem; }

/* Ce qui manque pour monter d'un cran. Une échelle sans marche suivante
   visible ne donne aucune prise à l'apprenant. */
.next-step {
  margin-top: 14px; padding: 10px 14px; border-radius: var(--radius-sm);
  background: rgba(242,169,59,0.12); border-left: 3px solid var(--amber-500);
  display: flex; flex-direction: column; gap: 2px; max-width: 560px;
}
.next-step-label {
  font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.09em;
  font-weight: 700; color: var(--amber-500);
}
.next-step-text { font-size: 0.88rem; line-height: 1.5; color: #fff; }
/* Au sommet de l'échelle il n'y a plus d'étape suivante : le bandeau cesse
   d'être une relance ambre pour devenir un constat d'accomplissement. */
.next-step.is-complete {
  background: rgba(31,157,130,0.16); border-left-color: var(--teal-500);
}

/* --- L'échelle de maturité --- */
.ladder {
  list-style: none; margin: 26px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px;
}
.ladder-step {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  text-align: center; position: relative; padding-top: 6px;
}
/* Le trait de liaison fait lire les 6 marches comme UN parcours, pas comme six
   pastilles indépendantes. Il s'arrête avant la dernière. */
.ladder-step::before {
  content: ''; position: absolute; top: 20px; left: 50%; width: 100%; height: 2px;
  background: rgba(255,255,255,0.12);
}
.ladder-step:last-child::before { display: none; }
.ladder-step.is-done::before { background: rgba(255,255,255,0.35); }
.ladder-dot {
  width: 30px; height: 30px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; position: relative; z-index: 1;
  font-family: var(--font-mono); font-size: 0.78rem; font-weight: 700;
  background: rgba(255,255,255,0.08); border: 2px solid rgba(255,255,255,0.18);
  color: var(--text-400-dark); transition: transform 0.2s ease;
}
/* Texte encre sur les pastilles remplies : le blanc tombe à 1,76–3,87:1 sur
   cette rampe (mesuré), l'encre tient 4,6–9,8:1. */
.ladder-step.is-done .ladder-dot,
.ladder-step.is-current .ladder-dot { color: var(--ink-900); }
.ladder-step.is-current .ladder-dot {
  width: 40px; height: 40px; font-size: 1rem; margin-top: -5px;
  box-shadow: 0 0 0 5px rgba(255,255,255,0.14), var(--shadow-md);
}
.ladder-name { font-size: 0.74rem; color: var(--text-400-dark); line-height: 1.3; }
.ladder-step.is-current .ladder-name { color: #fff; font-weight: 700; }
.ladder-step.is-todo .ladder-name { opacity: 0.55; }
.ladder-here {
  font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.07em;
  font-weight: 700; color: var(--amber-500);
}

/* --- Rangée d'indicateurs --- */
.kpi-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px; margin-bottom: 24px;
}
.stat-tile {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 16px 18px; box-shadow: var(--shadow-sm);
}
.stat-label {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-400); font-weight: 600;
}
.stat-value {
  font-family: var(--font-body); font-size: 1.9rem; font-weight: 600;
  color: var(--ink-900); line-height: 1.1; margin-top: 6px;
}
.stat-unit { font-size: 0.95rem; font-weight: 500; color: var(--text-400); margin-left: 2px; }
.stat-foot { font-size: 0.76rem; color: var(--text-600); margin-top: 8px; display: flex; align-items: center; gap: 6px; }
/* Pastille de rappel de la jauge. Le libellé porte l'information — la couleur
   ne fait que la redoubler, jamais la remplacer. */
.band-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.band-dot.is-strong { background: var(--teal-500); }
.band-dot.is-good   { background: var(--lime-500); }
.band-dot.is-fair   { background: var(--amber-500); }
.band-dot.is-weak   { background: var(--coral-500); }

/* Jauge : le remplissage porte la sévérité, la piste est un pas plus clair de
   la MÊME rampe — l'état se lit sur toute la barre, pas seulement à gauche. */
.meter { height: 6px; border-radius: 999px; margin-top: 10px; overflow: hidden; background: var(--track); }
.meter > span { display: block; height: 100%; border-radius: 999px; background: var(--fill); transition: width 0.5s ease; }
.meter.is-strong  { --fill: var(--teal-500);  --track: var(--teal-100); }
.meter.is-good    { --fill: var(--lime-500);  --track: var(--lime-100); }
.meter.is-fair    { --fill: var(--amber-500); --track: var(--amber-100); }
.meter.is-weak    { --fill: var(--coral-500); --track: var(--coral-100); }
.meter.is-neutral { --fill: var(--ink-700);   --track: var(--paper-100); }

/* --- Bandeau de recommandation --- */
.reco-banner {
  display: flex; align-items: center; gap: 14px; margin-bottom: 24px;
  background: var(--amber-100); border: 1px solid rgba(219,146,38,0.35);
  border-left: 4px solid var(--amber-600);
  border-radius: var(--radius-md); padding: 14px 18px;
}
.reco-icon { font-size: 1.2rem; color: var(--amber-600); }
.reco-banner .reco-body { flex: 1; }
.reco-banner strong { font-size: 0.92rem; color: var(--ink-900); }
.reco-reason { font-size: 0.82rem; color: var(--text-600); margin-top: 3px; }

/* --- En-tête de palier --- */
.section-heading.level-heading {
  border-left: 4px solid var(--rail); padding-left: 12px;
  margin: 30px 0 14px; align-items: center;
}
.section-heading.level-heading h2 { display: flex; align-items: center; gap: 10px; }
.level-badge {
  font-family: var(--font-mono); font-size: 0.8rem; font-weight: 700;
  width: 26px; height: 26px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-900);
}
.level-count {
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--text-400);
  background: var(--paper-100); padding: 4px 10px; border-radius: 999px;
}

/* Sur mobile, six marches côte à côte deviennent illisibles : l'échelle passe
   en deux rangées de trois plutôt que d'écraser les libellés. */
@media (max-width: 640px) {
  .dash-hero { padding: 22px 18px 20px; }
  .dash-hero-top { gap: 18px; }
  .level-medallion { width: 104px; height: 104px; }
  .medallion-digit { font-size: 2.6rem; }
  .level-name { font-size: 1.65rem; }
  .ladder { grid-template-columns: repeat(3, 1fr); row-gap: 18px; }
  /* Le trait de liaison relie des marches désormais sur deux rangées : il
     induirait un parcours qui n'existe pas. */
  .ladder-step::before { display: none; }
}

/* Respect des préférences système : les transitions de jauge et d'anneau sont
   de l'agrément, jamais de l'information. */
@media (prefers-reduced-motion: reduce) {
  .level-medallion .ring-fill,
  .meter > span,
  .card-progress-bar span,
  .module-card { transition: none; }
}

.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; }

/* Hub « Sécurité & confidentialité » : cartes A2F / sessions / RGPD */
.account-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; align-items: start; }
.account-grid .card { padding: 20px 22px; }
.account-grid .card h3 { margin-bottom: 8px; }
.account-grid .card p { font-size: 0.88rem; margin-bottom: 14px; }
.stat-box {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: 16px 18px;
}
.stat-box .value { font-family: var(--font-mono); font-size: 1.6rem; font-weight: 700; color: var(--ink-900); }
.stat-box .label { font-size: 0.78rem; color: var(--text-600); margin-top: 4px; }

.section-heading { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.section-heading h2 { font-size: 1.1rem; }
.modules-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; margin-bottom: 28px; }
.module-card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 20px; cursor: pointer; transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
  position: relative; overflow: hidden;
}
/* Filet de palier en tête de carte : rattache visuellement la carte à sa
   section, même quand on parcourt la grille sans lire les en-têtes. */
.module-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--accent, transparent);
}
.module-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--ink-600); }
.module-card .top-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
/* Texte encre, jamais blanc : voir la note sur --mat-0 (le blanc échoue AA
   sur toute cette rampe). */
.level-chip { font-family: var(--font-mono); font-size: 0.7rem; font-weight: 700; padding: 3px 8px; border-radius: 20px; color: var(--ink-900); }

/* Pastille d'état — icône + libellé, jamais la couleur seule. */
.state-chip {
  margin-left: auto; font-size: 0.7rem; font-weight: 700;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.state-chip.is-reussi  { color: #12705C; background: var(--teal-100); }
.state-chip.is-echoue  { color: #A32C2C; background: var(--coral-100); }
.state-chip.is-encours { color: #8A5A12; background: var(--amber-100); }
.module-card.card-reussi { border-color: rgba(31,157,130,0.4); }

/* Avancement des leçons, repris de l'état serveur du module. */
.card-progress { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; }
.card-progress-bar { flex: 1; height: 5px; border-radius: 999px; background: var(--paper-100); overflow: hidden; }
.card-progress-bar span { display: block; height: 100%; border-radius: 999px; background: var(--accent); transition: width 0.4s ease; }
.card-progress-text { font-family: var(--font-mono); font-size: 0.7rem; color: var(--text-400); }
.module-card h3 { font-size: 1rem; margin-bottom: 8px; color: var(--ink-900); }
.module-card p { color: var(--text-600); font-size: 0.85rem; margin: 0 0 14px; }
.module-card .meta { display: flex; align-items: center; gap: 6px; color: var(--text-400); font-size: 0.78rem; font-family: var(--font-mono); }

.back-link { display: inline-flex; align-items: center; gap: 6px; color: var(--text-600); cursor: pointer; font-size: 0.88rem; font-weight: 500; margin-bottom: 18px; }
.back-link:hover { color: var(--ink-900); }
.lesson-card { padding: 22px 24px; margin-bottom: 14px; }
.lesson-card h3 { font-size: 1.02rem; margin-bottom: 12px; color: var(--ink-900); }
.lesson-card p { font-size: 0.92rem; color: var(--text-900); }
.lesson-card ul { padding-left: 20px; font-size: 0.92rem; }
.lesson-card li { margin-bottom: 6px; }

/* Validation explicite des leçons — la barre en tête de module donne l'avancement,
   le liseré vert marque ce qui est acquis sans masquer le contenu (une leçon lue
   reste consultable : c'est du contenu de référence, pas une étape à cocher). */
.lesson-progress { margin: 0 0 16px; }
.lesson-progress-label { font-size: 0.8rem; color: var(--text-600); margin-bottom: 6px; }
.lesson-progress-bar {
  height: 6px; border-radius: 4px; background: var(--line); overflow: hidden;
}
.lesson-progress-bar span {
  display: block; height: 100%; background: var(--teal-500);
  border-radius: 4px; transition: width 0.25s ease;
}
.lesson-card.lesson-done { border-left: 3px solid var(--teal-500); }
.lesson-ack {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px;
}
.lesson-ack-done { color: var(--teal-500); font-size: 0.85rem; font-weight: 600; }
.callout { background: var(--paper-50); border-left: 3px solid var(--amber-500); padding: 12px 16px; border-radius: 6px; font-size: 0.88rem; margin: 10px 0; }
.callout.danger { background: var(--coral-100); border-color: var(--coral-500); }
.scenario-block { background: var(--paper-50); border-radius: var(--radius-md); padding: 16px; margin: 14px 0; }
.scenario-choice { padding: 6px 0; font-size: 0.9rem; }

.quiz-question { margin-bottom: 22px; }
.quiz-question p.q-text { font-weight: 600; margin-bottom: 10px; font-size: 0.95rem; }
.quiz-option {
  display: block; width: 100%; text-align: left; background: var(--paper-50); border: 1.5px solid var(--line);
  color: var(--text-900); margin-bottom: 8px; padding: 10px 14px; border-radius: var(--radius-sm); cursor: pointer; font-size: 0.9rem;
}
.quiz-option:hover { border-color: var(--ink-700); }
.quiz-option.correct { border-color: var(--teal-500); background: var(--teal-100); }
.quiz-option.incorrect { border-color: var(--coral-500); background: var(--coral-100); }
.explanation { background: var(--amber-100); border-left: 3px solid var(--amber-500); padding: 12px 16px; border-radius: 6px; margin-top: 10px; font-size: 0.85rem; }
.quiz-result { border-radius: var(--radius-lg); padding: 20px 24px; margin-top: 18px; background: var(--ink-900); color: #fff; }
.quiz-result .score { font-family: var(--font-mono); font-size: 1.8rem; font-weight: 600; }

.data-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.data-table th {
  text-align: left; padding: 10px 14px; color: var(--text-600); font-weight: 600;
  font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.04em; border-bottom: 1.5px solid var(--line);
}
.data-table td { padding: 12px 14px; border-bottom: 1px solid var(--line); }
.data-table tr:last-child td { border-bottom: none; }
.status-badge { font-size: 0.72rem; font-weight: 600; padding: 3px 9px; border-radius: 20px; font-family: var(--font-mono); }
.status-badge.terminee { background: var(--teal-100); color: var(--teal-500); }
.status-badge.brouillon { background: var(--paper-100); color: var(--text-600); }
.status-badge.en_cours { background: var(--amber-100); color: var(--amber-600); }

.metric-row { display: flex; gap: 12px; margin-top: 6px; flex-wrap: wrap; }
.metric-chip { background: var(--paper-50); border-radius: var(--radius-sm); padding: 6px 10px; font-size: 0.78rem; font-family: var(--font-mono); color: var(--text-600); }

.modal-overlay { position: fixed; inset: 0; background: rgba(15,27,46,0.5); display: flex; align-items: center; justify-content: center; z-index: 50; }
.modal-box { background: #fff; border-radius: var(--radius-lg); padding: 26px 28px; width: 420px; box-shadow: var(--shadow-lg); }
.modal-box h3 { margin-bottom: 4px; }
.modal-box .sub { color: var(--text-600); font-size: 0.85rem; margin-bottom: 18px; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; }

.empty-state { text-align: center; padding: 60px 20px; color: var(--text-600); }
.empty-state h3 { color: var(--ink-900); margin-bottom: 6px; }
.loading-state { text-align: center; padding: 80px 20px; color: var(--text-400); font-size: 0.9rem; }

@media (max-width: 900px) {
  .sidebar { display: none; }
  .main { padding: 20px; }
  .login-visual { display: none; }
  .login-form-panel { width: 100%; }
}

.radio-row, .checkbox-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 2px; font-size: 0.88rem; cursor: pointer;
}
.checkbox-row { font-size: 0.85rem; }

.classification-table { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.classification-row {
  display: grid; grid-template-columns: 140px 1fr 1fr; gap: 12px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: 10px 14px; font-size: 0.85rem; align-items: center;
}
.classification-niveau { font-weight: 700; color: var(--ink-900); }
.classification-exemple { color: var(--text-600); }
.classification-regle { color: var(--teal-500); font-weight: 600; }
@media (max-width: 640px) {
  .classification-row { grid-template-columns: 1fr; gap: 4px; }
}

.badges-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}
.badge-card {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 24px 18px 20px; gap: 6px; transition: transform 0.15s, box-shadow 0.15s;
}
.badge-card.badge-earned:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
/* Un badge non obtenu se distingue par sa MÉDAILLE éteinte, pas par un voile
   d'opacité sur toute la carte : le texte doit rester lisible, c'est lui qui
   dit comment le débloquer. L'ancienne version passait la carte entière à
   55 % d'opacité et en nuances de gris. */
.badge-medal {
  width: 76px; height: 76px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; margin-bottom: 6px;
  background: var(--paper-100); border: 2px solid var(--line);
}
.badge-card.badge-earned .badge-medal {
  background: linear-gradient(145deg, var(--amber-100), #fff);
  border-color: var(--amber-500);
  box-shadow: 0 0 0 4px rgba(242,169,59,0.14);
}
.badge-card.badge-locked .badge-medal { filter: grayscale(1); opacity: 0.75; }
.badge-icon { font-size: 2.2rem; line-height: 1; }
.badge-card h3 { font-size: 0.95rem; margin: 0; }
.badge-card.badge-locked h3 { color: var(--text-600); }
.badge-desc { font-size: 0.8rem; color: var(--text-600); min-height: 48px; }
.badge-earned-date { font-size: 0.75rem; color: #12705C; font-weight: 700; margin: 4px 0 10px; }
.badge-locked-label {
  font-size: 0.75rem; color: var(--text-400); margin-top: 6px; line-height: 1.45;
  border-top: 1px solid var(--line); padding-top: 10px; width: 100%;
}
/* L'en-tête de collection reprend le médaillon du tableau de bord, mais la
   vue est plus courte : on resserre. */
.collection-hero { padding-bottom: 30px; }

/* ============================================================
   CLASSEMENT
   Le trio de tête passe en podium : un tableau met les trois premiers sur la
   même ligne que le douzième, alors que c'est là que se joue l'émulation.
   ============================================================ */
.podium {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
  align-items: end; margin-bottom: 22px;
}
.podium-place {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 18px 16px; text-align: center; box-shadow: var(--shadow-sm);
}
/* La première place est surélevée et plus contrastée : la hiérarchie se lit
   avant la lecture des chiffres. */
.podium-place.place-1 {
  padding: 26px 16px; border-color: var(--amber-500);
  box-shadow: 0 0 0 3px rgba(242,169,59,0.16), var(--shadow-md);
}
.podium-place.is-me { border-color: var(--ink-700); box-shadow: 0 0 0 3px rgba(30,51,80,0.12), var(--shadow-md); }
.podium-medal { font-size: 1.8rem; line-height: 1; }
.podium-place.place-1 .podium-medal { font-size: 2.3rem; }
.podium-name { font-weight: 700; font-size: 0.92rem; margin-top: 8px; color: var(--ink-900); }
.podium-score {
  font-family: var(--font-body); font-size: 1.6rem; font-weight: 600;
  color: var(--ink-900); margin-top: 8px; line-height: 1;
}
.podium-score-unit { font-size: 0.8rem; color: var(--text-400); font-weight: 500; }
.podium-place .meter { margin-top: 8px; }
.podium-meta {
  display: flex; justify-content: center; gap: 14px;
  font-size: 0.8rem; color: var(--text-600); margin-top: 10px;
}
.you-tag {
  font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  background: var(--ink-900); color: #fff; padding: 2px 7px; border-radius: 999px;
  vertical-align: middle; margin-left: 4px;
}
.rank-cell { width: 44px; font-family: var(--font-mono); color: var(--text-400); }
tr.row-me { background: var(--paper-50); }
tr.row-me strong { color: var(--ink-900); }
.score-cell { display: flex; align-items: center; gap: 10px; min-width: 110px; }
.score-num { font-family: var(--font-mono); font-size: 0.85rem; font-weight: 600; color: var(--ink-900); }
.score-cell .meter { flex: 1; margin-top: 0; }

@media (max-width: 640px) {
  .podium { grid-template-columns: 1fr; align-items: stretch; }
  .podium-place.place-1 { padding: 18px 16px; }
}

.module-card.module-locked { opacity: 0.6; filter: grayscale(0.3); cursor: not-allowed; }
.lock-chip {
  font-size: 0.7rem; font-weight: 700; color: var(--amber-500);
  background: rgba(198,130,42,0.12); padding: 3px 8px; border-radius: 999px;
}
.module-locked-hint { font-size: 0.75rem; color: var(--amber-500); margin-top: 8px; font-weight: 600; }

.grid-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 900px) { .grid-2col { grid-template-columns: 1fr; } }
.plan-modules-list { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.plan-module-row {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 0.88rem; padding: 8px 10px; border-radius: 8px; background: #fff;
  border: 1px solid var(--line);
}
.plan-module-row.locked { color: var(--text-400); }
.callout.danger { background: rgba(198,42,42,0.08); color: #9b2c2c; }

.muted { color: var(--text-600); }

.form-grid { display: flex; flex-direction: column; gap: 10px; }
.form-grid input, .form-grid select {
  padding: 9px 12px; border: 1px solid var(--line); border-radius: 8px; font-size: 0.88rem; font-family: inherit;
}
.form-grid hr { border: none; border-top: 1px solid var(--line); margin: 4px 0; }
.callout-success { background: rgba(20,150,105,0.08); border: 1px solid rgba(20,150,105,0.25); }
.status-badge.actif { background: var(--teal-100); color: var(--teal-500); }
.status-badge.suspendu { background: rgba(198,42,42,0.1); color: #9b2c2c; }
.plan-select { padding: 6px 10px; border-radius: 6px; border: 1px solid var(--line); font-size: 0.82rem; font-family: inherit; }
.internal-tag {
  font-size: 0.6rem; font-weight: 700; background: var(--amber-500); color: #fff;
  padding: 2px 6px; border-radius: 4px; margin-left: 6px; vertical-align: middle;
}

/* ---------- Authentification à deux facteurs (A2F) ---------- */
.btn-danger { background: var(--coral-500); color: #fff; }
.btn-danger:hover { opacity: 0.9; }

.mfa-qr-wrap { text-align: center; margin: 8px 0 18px; }
.mfa-qr {
  width: 190px; height: 190px; border-radius: var(--radius-md);
  border: 1px solid var(--line); background: #fff; padding: 8px;
}
.mfa-secret { margin-top: 10px; font-size: 0.8rem; color: var(--text-600); }
.mfa-secret code {
  font-family: var(--font-mono); background: var(--paper-100);
  padding: 2px 6px; border-radius: 4px; word-break: break-all;
}

.recovery-codes {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  margin: 6px 0 20px;
}
.recovery-codes code {
  font-family: var(--font-mono); font-size: 0.9rem; text-align: center;
  background: var(--paper-50); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 8px 6px; letter-spacing: 0.5px;
}
.mfa-status-ok {
  margin: 6px 0 18px; padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--teal-100); color: var(--teal-500); font-weight: 600; font-size: 0.9rem;
}

/* ---------- SSO login ---------- */
.sso-divider { display:flex; align-items:center; text-align:center; margin:16px 0 12px; color:var(--text-400); font-size:0.8rem; }
.sso-divider::before, .sso-divider::after { content:""; flex:1; height:1px; background:var(--line); }
.sso-divider span { padding:0 12px; }

/* ---------- Sélecteur de langue (i18n) ---------- */
.lang-switch { display: inline-flex; gap: 2px; margin-bottom: 14px; }
.lang-switch .lang-opt {
  font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600;
  padding: 3px 8px; border: 1px solid var(--line); background: transparent;
  color: var(--text-600); cursor: pointer; border-radius: var(--radius-sm);
}
.lang-switch .lang-opt.active { background: var(--ink-900); color: #fff; border-color: var(--ink-900); }
/* Dans la barre latérale sombre, adapter les couleurs de repos. */
.sidebar .lang-switch .lang-opt { color: #B8C0CE; border-color: rgba(255,255,255,0.18); }
.sidebar .lang-switch .lang-opt.active { background: var(--amber-500); color: var(--ink-900); border-color: var(--amber-500); }

/* ---------- Accessibilité : mouvement réduit ----------
   Respecte le réglage système « réduire les animations » (utilisateurs
   sensibles au mouvement, troubles vestibulaires). N'a aucun effet pour les
   autres. On neutralise transitions et animations plutôt que de les supprimer
   du code, pour ne rien changer au rendu par défaut. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
