/* Socle commun Pack Veritas.
 * Les pages conservent leurs accents et leurs simulateurs propres ; ce fichier
 * ne porte que les règles structurelles qui doivent rester identiques partout.
 */

html, body { max-width: 100%; }
body { overflow-x: hidden; }
img, svg, video, canvas { max-width: 100%; }
input, select, textarea, button { max-width: 100%; }

/* Une page privée reste masquée pendant la validation du cookie serveur.
   Cela évite qu'une page restaurée par le bouton Retour réaffiche brièvement
   des données d'une session désormais fermée. */
body[data-veritas-roles]:not(.veritas-session-ok) .main { visibility: hidden; }
body[data-veritas-roles]:not(.veritas-session-ok) .sidebar .user-card,
body[data-veritas-roles]:not(.veritas-session-ok) .sidebar .profile { visibility:hidden; }

/* État réseau commun. L'enfant force sa visibilité afin que l'indicateur soit
   visible même pendant le premier contrôle d'une page privée encore masquée. */
.veritas-connection-overlay {
  position: fixed;
  inset: 0;
  z-index: 11000;
  display: grid;
  place-items: center;
  padding: 18px;
  visibility: visible !important;
  background: color-mix(in srgb, var(--bg, #f7f8fb) 84%, transparent);
  backdrop-filter: blur(5px);
}
.veritas-connection-overlay[hidden] { display: none !important; }
.veritas-connection-card {
  width: min(92vw, 430px);
  padding: 22px;
  border: 1px solid var(--line, #e7e9f1);
  border-radius: 15px;
  background: var(--panel, #fff);
  color: var(--ink, #14151f);
  box-shadow: 0 20px 60px rgba(15, 23, 42, .22);
  text-align: center;
  font-family: Inter, system-ui, sans-serif;
}
.veritas-connection-spinner {
  display: block;
  margin: 0 auto 13px;
  color: var(--blue, #2563eb);
  animation: veritas-connection-spin .85s linear infinite;
}
.veritas-connection-card strong { display: block; font-size: 16px; }
.veritas-connection-card p {
  margin: 7px auto 16px;
  max-width: 350px;
  color: var(--muted, #64748b);
  font-size: 13px;
  line-height: 1.55;
}
.veritas-connection-retry {
  min-height: 44px;
  padding: 9px 16px;
  border: 1px solid var(--line, #e7e9f1);
  border-radius: 9px;
  background: var(--bg-soft, #eef0f6);
  color: var(--ink, #14151f);
  font: 700 13px/1.2 Inter, system-ui, sans-serif;
  cursor: pointer;
}
.veritas-connection-retry:hover { border-color: var(--blue, #2563eb); }
@keyframes veritas-connection-spin { to { transform: rotate(360deg); } }

.veritas-menu-toggle {
  display: none;
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line, #e7e9f1);
  border-radius: 10px;
  background: var(--panel, #fff);
  color: var(--ink, #14151f);
  cursor: pointer;
  font: inherit;
}

.veritas-mobile-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9990;
  background: rgba(5, 12, 24, .48);
  opacity: 0;
  transition: opacity .2s ease;
}

.veritas-mobile-drawer {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: min(86vw, 340px);
  padding: max(18px, env(safe-area-inset-top)) 16px 24px;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--panel, #fff);
  color: var(--ink, #14151f);
  box-shadow: 18px 0 50px rgba(0, 0, 0, .2);
  transform: translateX(-102%);
  transition: transform .22s ease;
}

.veritas-mobile-overlay.open { opacity: 1; }
.veritas-mobile-overlay.open .veritas-mobile-drawer { transform: none; }
.veritas-mobile-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 4px 16px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--line, #e7e9f1);
}
.veritas-mobile-head strong { font-size: 15px; }
.veritas-mobile-close {
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 10px;
  background: var(--bg-soft, #eef0f6);
  color: inherit;
  font-size: 24px;
  cursor: pointer;
}
.veritas-mobile-nav { display: grid; gap: 5px; }
.veritas-mobile-nav .nav-item,
.veritas-mobile-nav a,
.veritas-mobile-nav button {
  min-height: 44px;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: inherit;
  text-align: left;
  text-decoration: none;
  font: inherit;
  cursor: pointer;
}
.veritas-mobile-nav .nav-item:hover,
.veritas-mobile-nav a:hover,
.veritas-mobile-nav button:hover { background: var(--bg-soft, #eef0f6); }
.veritas-mobile-nav .nav-section { margin: 15px 10px 4px; }

.veritas-session-message {
  position: fixed;
  left: 50%;
  bottom: max(20px, env(safe-area-inset-bottom));
  z-index: 10020;
  width: min(92vw, 520px);
  transform: translateX(-50%);
  padding: 13px 16px;
  border-radius: 10px;
  background: #7f1d1d;
  color: #fff;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .28);
  font: 600 14px/1.45 Inter, system-ui, sans-serif;
  text-align: center;
}

.veritas-tenant-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  margin-top: 8px;
  padding: 6px 10px;
  border: 1px solid color-mix(in srgb, var(--tenant-primary, #1e3a8a) 38%, var(--line, #e7e9f1));
  border-left: 4px solid var(--tenant-primary, #1e3a8a);
  border-radius: 9px;
  background: var(--panel, #fff);
  color: var(--ink, #14151f);
  font: 700 12px/1.2 Inter, system-ui, sans-serif;
}
.veritas-tenant-branded .topbar,
.veritas-tenant-branded .mobile-bar { box-shadow: inset 0 3px 0 var(--tenant-primary, #1e3a8a); }
.veritas-tenant-chip img { width: 26px; height: 26px; border-radius: 6px; object-fit: contain; background:#fff; }
.topbar-actions { margin-left: auto; justify-content: flex-end; }
.veritas-assistance-bar {
  position: fixed;
  right: 14px;
  bottom: max(14px, env(safe-area-inset-bottom));
  left: 14px;
  z-index: 10900;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  width: min(900px, calc(100vw - 28px));
  min-height: 52px;
  margin: auto;
  padding: 10px 14px;
  border: 1px solid #b45309;
  border-radius: 12px;
  background: #fff7ed;
  color: #7c2d12;
  box-shadow: 0 16px 45px rgba(15,23,42,.24);
  font: 600 13px/1.4 Inter, system-ui, sans-serif;
}
.veritas-assistance-bar button {
  min-height: 40px;
  padding: 8px 12px;
  border: 0;
  border-radius: 8px;
  background: #9a3412;
  color: #fff;
  font: 700 12px/1.2 Inter, system-ui, sans-serif;
  cursor: pointer;
}

.credential-box {
  margin-bottom: 16px;
  padding: 14px 16px;
  border-radius: 11px;
  background: var(--bg-soft, #eef0f6);
}
.credential-box .row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 7px 0;
  font-size: 14px;
}
.credential-box .row b {
  max-width: 65%;
  overflow-wrap: anywhere;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}

/* Actions de session : le rouge reste identique dans les barres latérales,
   la barre mobile et le menu compact. */
[data-deconnexion], #btnDeconnexion {
  color: #b42318 !important;
  border-color: rgba(180, 35, 24, .28) !important;
}
[data-deconnexion]:hover, #btnDeconnexion:hover {
  background: #fff0ee !important;
  color: #8f1810 !important;
}
body.dark [data-deconnexion]:hover, body.dark #btnDeconnexion:hover {
  background: rgba(239, 68, 68, .14) !important;
  color: #fca5a5 !important;
}

/* États de connexion et d'abonnement. La pulsation attire l'attention, tandis
   que le titre/aria-label du HTML donne aussi l'information sans la couleur. */
.status-dot-pulse {
  --dot-color: #64748b;
  position: relative;
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--dot-color);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--dot-color) 42%, transparent);
  animation: veritas-status-pulse 1.7s ease-out infinite;
}
.status-dot-pulse.online { --dot-color: #16a34a; }
.status-dot-pulse.active { --dot-color: #2563eb; }
.status-dot-pulse.expired { --dot-color: #dc2626; }
.status-dot-pulse.offline { --dot-color: #7c8798; }
@keyframes veritas-status-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--dot-color) 45%, transparent); }
  65%, 100% { box-shadow: 0 0 0 7px transparent; }
}
@keyframes veritas-visible-blink {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .28; transform: scale(.72); }
}
.live-dot,
.activity-dot,
.status-dot,
.status-badge .dot,
.legend-chip .dot,
.veritas-alert-item.non-lue .veritas-alert-dot {
  animation: veritas-visible-blink 1.35s ease-in-out infinite;
  transform-origin: center;
}
.archived-card { margin-top: 20px; }
.archived-card .table-toolbar h3 { margin: 0 0 4px; font-size: 16px; }
.archived-card .table-toolbar p, .notif-preview {
  margin: 0;
  color: var(--muted, #64748b);
  font-size: 12px;
  line-height: 1.5;
}
.row-actions .danger, [data-delete-learner] {
  border-color: #dc2626 !important;
  color: #b42318 !important;
  background: transparent !important;
}

/* Cloche commune aux consoles centre et plateforme. */
.veritas-alert-wrap { position: relative; flex: 0 0 auto; }
.veritas-alert-bell {
  position: relative;
  width: 44px !important;
  height: 44px !important;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.veritas-alert-count {
  position: absolute;
  top: -5px;
  right: -6px;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border: 2px solid var(--panel, #fff);
  border-radius: 999px;
  background: #dc2626;
  color: #fff;
  font: 800 10px/16px Inter, system-ui, sans-serif;
  text-align: center;
}
.veritas-alert-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 120;
  width: min(390px, calc(100vw - 28px));
  overflow: hidden;
  border: 1px solid var(--line, #e7e9f1);
  border-radius: 14px;
  background: var(--panel, #fff);
  color: var(--ink, #14151f);
  box-shadow: 0 20px 55px rgba(15, 23, 42, .2);
}
.veritas-alert-panel[hidden] { display: none !important; }
.veritas-alert-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 15px 16px;
  border-bottom: 1px solid var(--line, #e7e9f1);
}
.veritas-alert-head strong { display: block; font-size: 14px; }
.veritas-alert-head small { display: block; margin-top: 3px; color: var(--muted, #64748b); font-size: 11px; }
.veritas-alert-head a { color: var(--blue, #2563eb); font-size: 12px; font-weight: 700; text-decoration: none; }
.veritas-alert-list { max-height: min(430px, 62vh); overflow-y: auto; }
.veritas-alert-item {
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr);
  gap: 10px;
  min-height: 60px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--line, #e7e9f1);
  color: inherit;
  text-decoration: none;
}
.veritas-alert-item:last-child { border-bottom: 0; }
.veritas-alert-item:hover, .veritas-alert-item:focus-visible { background: var(--bg-soft, #eef0f6); }
.veritas-alert-dot { width: 8px; height: 8px; margin-top: 5px; border-radius: 50%; background: transparent; }
.veritas-alert-item.non-lue .veritas-alert-dot { background: var(--blue, #2563eb); }
.veritas-alert-item strong { display: block; font-size: 13px; line-height: 1.45; }
.veritas-alert-item small { display: block; margin-top: 4px; color: var(--muted, #64748b); font-size: 11px; line-height: 1.4; }
.veritas-alert-empty { margin: 0; padding: 24px 18px; color: var(--muted, #64748b); font-size: 13px; line-height: 1.5; text-align: center; }
.veritas-submission-toast {
  position: fixed;
  top: max(18px, env(safe-area-inset-top));
  right: 18px;
  z-index: 10010;
  width: min(360px, calc(100vw - 28px));
  padding: 14px 16px;
  border: 1px solid rgba(37, 99, 235, .3);
  border-radius: 12px;
  background: var(--panel, #fff);
  color: var(--ink, #14151f);
  box-shadow: 0 16px 45px rgba(15, 23, 42, .22);
  font: inherit;
  text-align: left;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-12px);
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
}
.veritas-submission-toast.visible { opacity: 1; transform: none; pointer-events: auto; }
.veritas-submission-toast strong { display: block; margin-bottom: 4px; color: var(--blue, #2563eb); font-size: 13px; }
.veritas-submission-toast span { display: block; font-size: 12px; line-height: 1.45; }

@media (max-width: 860px) {
  /* Dans les modules, .mobile-bar est un frère de .main à l'intérieur d'un
     conteneur .app normalement horizontal. Sans ce passage en bloc, la barre
     consommait 240 px de largeur et ne laissait qu'environ 130 px aux cartes. */
  .app { display: block !important; width: 100% !important; }
  .mobile-bar { width: 100% !important; }
  .veritas-menu-toggle { display: inline-flex; }
  .veritas-mobile-overlay { display: block; pointer-events: none; }
  .veritas-mobile-overlay.open { pointer-events: auto; }
  body.veritas-menu-open { overflow: hidden !important; }

  .topbar {
    gap: 12px !important;
    padding-left: 14px !important;
    padding-right: 14px !important;
  }
  .topbar > :not(.veritas-menu-toggle) { min-width: 0; }
  .topbar h1 { font-size: clamp(18px, 5vw, 22px) !important; }
  .topbar .sub { overflow-wrap: anywhere; }
  .topbar-actions { flex-wrap: wrap; justify-content: flex-end; }

  .content, .main { min-width: 0; }
  .card, .panel, .module-card, .epreuve-card { min-width: 0; }
  .data-wrap, .table-wrap, .access-table-wrap,
  .card:has(> table), .card:has(> .data) {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  table { min-width: 680px; }
  .modal, .modal-box, .cpt-modal, .copie-boite {
    width: calc(100vw - 24px) !important;
    max-width: calc(100vw - 24px) !important;
    max-height: calc(100dvh - 24px) !important;
    margin: auto !important;
  }
  .drawer { width: min(94vw, 520px) !important; }
}

@media (max-width: 640px) {
  body { font-size: 16px; }
  input, select, textarea { font-size: 16px !important; }
  button, .btn, .btn-primary, .btn-ghost, .nav-item, .icon-btn {
    min-height: 44px;
  }
  .content, .main { padding-left: 14px !important; padding-right: 14px !important; }
  .topbar { align-items: flex-start !important; }
  .topbar-actions { width: 100%; justify-content: stretch; }
  .topbar-actions > a, .topbar-actions > button { flex: 1 1 auto; justify-content: center; }
  .topbar-actions > .veritas-alert-wrap { flex: 0 0 44px; }
  .veritas-alert-panel { position: fixed; top: 76px; right: 14px; left: 14px; width: auto; }
  .veritas-submission-toast { top: auto; right: 14px; bottom: max(14px, env(safe-area-inset-bottom)); }
  .veritas-tenant-chip { width: auto; margin: 8px 0 0; justify-content: flex-start; }
  .veritas-assistance-bar { align-items: stretch; flex-direction: column; gap:8px; text-align:center; }
  .grid2, .two-col, .info-grid, .status-grid { grid-template-columns: minmax(0, 1fr) !important; }
  .modal-actions { flex-direction: column-reverse; }
  .modal-actions > * { width: 100%; }
  .toast {
    left: 12px !important;
    right: 12px !important;
    bottom: max(12px, env(safe-area-inset-bottom)) !important;
    max-width: none !important;
  }
  .simu-head { gap: 8px !important; }
  .simu-head h2, .simu-head h3 { font-size: 15px !important; }
  .credential-box .row { align-items: flex-start; flex-direction: column; gap: 4px; }
  .credential-box .row b { max-width: 100%; }

  /* Accueil : la marque et les trois actions tenaient difficilement sur un
     écran de 360–390 px. Le bouton de compte garde son nom accessible mais
     devient une icône compacte dans l'en-tête. */
  .site-header .header-inner { padding: 10px 12px !important; gap: 7px !important; }
  .site-header .brand { gap: 7px !important; }
  .site-header .brand-badge { width: 38px !important; height: 38px !important; }
  .site-header .brand-name { font-size: 13px !important; white-space: nowrap; }
  .site-header .brand-sub { display: none !important; }
  .site-header .header-actions { gap: 6px !important; margin-left: auto; }
  .site-header .icon-btn, .site-header .hamburger { width: 42px !important; height: 42px !important; }
  .site-header #btnCompte {
    width: 42px !important;
    height: 42px !important;
    padding: 0 !important;
    justify-content: center;
    overflow: hidden;
    font-size: 0 !important;
  }
  .site-header #btnCompte::after { content: '→'; font-size: 20px; line-height: 1; }
  .hero { padding-left: 16px !important; padding-right: 16px !important; }
  .hero h1 { overflow-wrap: anywhere; font-size: clamp(27px, 8.2vw, 32px) !important; }
  .hero p { font-size: 15px !important; }
  .sec { padding-left: 14px !important; padding-right: 14px !important; }

  /* Connexions candidat/centre et plateforme. */
  .auth-panel { padding: 64px 14px 32px !important; }
  .auth-inner { min-width: 0 !important; }
  .brand-row { gap: 10px !important; }
  .brand-title { font-size: clamp(23px, 8vw, 30px) !important; }
  .auth-card { padding: 24px 18px !important; }
  body > .carte { padding: 24px 18px !important; }

  /* Le pied des quatre simulateurs reste toujours dans la fenêtre. Les
     actions peuvent passer sur deux lignes plutôt que de masquer Terminer. */
  .simu-foot {
    flex: 0 0 auto !important;
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
    width: 100% !important;
    padding: 9px 10px calc(9px + env(safe-area-inset-bottom)) !important;
    overflow: visible !important;
  }
  .simu-foot .fleches, .simu-foot .simu-fleches {
    flex: 1 1 150px !important;
    margin: 0 !important;
    justify-content: center !important;
  }
  .simu-foot .btn-pdf { display: none !important; }
  .simu-foot .btn-terminer, .simu-foot .btn-suivant {
    display: inline-flex !important;
    flex: 1 1 120px !important;
    min-height: 46px !important;
    margin-left: auto !important;
    align-items: center !important;
    justify-content: center !important;
    white-space: normal !important;
  }
  .simu-foot .btn-quitter { min-height: 44px !important; }
}

@media (prefers-reduced-motion: reduce) {
  .veritas-submission-toast { transition: none; }
}

@media (max-width: 380px) {
  .content, .main { padding-left: 10px !important; padding-right: 10px !important; }
  .modal, .modal-box, .cpt-modal, .copie-boite {
    width: calc(100vw - 12px) !important;
    max-width: calc(100vw - 12px) !important;
  }
}

@media (min-width: 1600px) {
  .content > .tab-section,
  .main > .content-inner,
  main.container,
  .sec-inner { max-width: 1500px; margin-left: auto; margin-right: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .veritas-mobile-overlay,
  .veritas-mobile-drawer { transition: none; }
  .veritas-connection-spinner { animation: none; }
  .status-dot-pulse { animation: none; outline: 2px solid var(--dot-color); outline-offset: 2px; }
  .live-dot,.activity-dot,.status-dot,.status-badge .dot,.legend-chip .dot,
  .veritas-alert-item.non-lue .veritas-alert-dot { animation:none; }
}
@view-transition { navigation: auto; }
.sidebar { view-transition-name: veritas-sidebar; }
.main, main { view-transition-name: veritas-main; }

/* ==========================================================
   Bouton de plein écran

   Flottant plutôt qu'intégré à chaque en-tête : les onze pages concernées ont
   des barres différentes, et un bouton unique et identique partout se trouve
   sans réapprentissage.

   z-index volontairement bas (90) : il doit passer au-dessus du contenu mais
   RESTER SOUS les fenêtres modales et les simulateurs, qui montent à 400 et
   au-delà. Il disparaît donc de lui-même dès qu'une épreuve commence — où un
   second bouton de plein écran n'aurait aucun sens.
   ========================================================== */
.veritas-plein-ecran {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 90;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  border: 1px solid var(--line, rgba(127,127,127,.25));
  background: var(--panel, #fff);
  color: var(--muted, #667085);
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,.08), 0 12px 28px rgba(0,0,0,.10);
  transition: color .15s, transform .15s, box-shadow .15s;
}
.veritas-plein-ecran:hover {
  color: var(--ink, #14151f);
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(0,0,0,.10), 0 16px 34px rgba(0,0,0,.13);
}
.veritas-plein-ecran:active { transform: none; }
.veritas-plein-ecran:focus-visible {
  outline: 2px solid var(--blue, #2f6fed);
  outline-offset: 2px;
  color: var(--ink, #14151f);
}

/* En attente de reprise : le plein écran était actif avant la navigation et
   reviendra au premier geste. Un liseré discret le signale — sans lui, l'écran
   qui n'est pas encore en plein écran passerait pour un oubli. */
.veritas-plein-ecran.en-attente {
  border-color: var(--blue, #2f6fed);
  color: var(--blue, #2f6fed);
}

/* Sur mobile, la barre de navigation basse occupe déjà le coin : on remonte le
   bouton pour ne pas le recouvrir. */
@media (max-width: 860px) {
  .veritas-plein-ecran { bottom: 76px; right: 14px; }
}

/* Un bouton n'a pas de sens sur du papier. */
@media print { .veritas-plein-ecran { display: none !important; } }

/* Pas d'animation pour qui n'en veut pas. */
@media (prefers-reduced-motion: reduce) {
  .veritas-plein-ecran { transition: none; }
  .veritas-plein-ecran:hover { transform: none; }
}

/* Logo d'un centre en marque blanche. Il remplace le logo de la plateforme —
   SVG en ligne ou image selon les pages — et doit donc s'y substituer sans
   déranger la mise en page qui l'entourait : la taille reprise est celle que
   l'élément remplacé occupait réellement. */
.veritas-logo-centre {
  object-fit: contain;
  border-radius: 8px;
  flex-shrink: 0;
}

/* Monogramme de repli, quand le centre n'a pas encore téléversé de logo.
   L'alternative était de laisser l'écusson de la plateforme, qui porte
   « VERITAS » écrit à l'intérieur du SVG : deux lettres neutres valent mieux
   que le nom du fournisseur affiché dans la barre latérale d'un candidat. */
.veritas-monogramme {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 10px;
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 800;
  letter-spacing: .02em;
  color: #fff;
  background: var(--tenant-primary, #1e3a8a);
  /* Le blanc sur une couleur claire choisie par le centre resterait lisible
     grâce à ce léger assombrissement du fond. */
  box-shadow: inset 0 0 0 999px rgba(0, 0, 0, .12);
}

/* ==================================================================
   AFFICHER / MASQUER UN MOT DE PASSE

   Le bouton est injecté par veritas-layout.js dans un conteneur neutre
   posé autour du champ. Les règles ci-dessous valent donc sur les douze
   pages, sans qu'aucune ait à les recopier.
   ================================================================== */

/* Le conteneur hérite de la largeur que le champ occupait : sans « display
   block » et « width 100% », un champ en pleine largeur se réduisait à sa
   largeur intrinsèque une fois enveloppé. */
.veritas-champ-mdp {
  position: relative;
  display: block;
  width: 100%;
}

/* La place du bouton est réservée dans le champ lui-même, sinon le texte
   saisi passe dessous et devient illisible sur un long mot de passe. */
.veritas-champ-mdp > input {
  width: 100%;
  padding-right: 44px !important;
}

/* CERTAINS NAVIGATEURS AJOUTENT LEUR PROPRE BOUTON DE RÉVÉLATION.
   Edge et Chrome selon la version en posent un dans tout champ de mot de
   passe. Il se superposait au nôtre : deux yeux côte à côte, dont un seul
   obéit au code de la page — et le second peut révéler le mot de passe
   sans que rien ne l'indique. On neutralise ceux du navigateur. */
.veritas-champ-mdp > input::-ms-reveal,
.veritas-champ-mdp > input::-ms-clear { display: none; }
.veritas-champ-mdp > input::-webkit-credentials-auto-fill-button,
.veritas-champ-mdp > input::-webkit-strong-password-auto-fill-button {
  visibility: hidden; pointer-events: none; position: absolute; right: 0;
}

/* Cible tactile de 38 px pour une icône de 18 : en dessous, le doigt manque
   le bouton et atteint le champ, ce qui déplace le curseur au lieu de
   révéler le mot de passe. L'icône, elle, ne grossit pas.

   LE BOUTON NE DOIT PAS BOUGER QUAND ON L'ACTIONNE.
   Il était calé sur le milieu du conteneur (top:50% + translateY). Or le
   conteneur épouse la hauteur du champ, et cette hauteur peut varier d'un
   pixel au passage de « password » à « text » : les deux types n'emploient
   pas la même fonte de repli dans tous les navigateurs. Le bouton sautait
   alors à chaque clic, exactement au moment où l'œil le suit.

   Il est désormais ancré aux DEUX bords verticaux : sa position ne dépend
   plus d'un calcul sur une hauteur qui bouge. */
.veritas-oeil {
  position: absolute;
  right: 4px;
  top: 0;
  bottom: 0;
  margin: auto 0;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--muted, #64748b);
  cursor: pointer;
  transition: color .15s, background .15s;
}
.veritas-oeil svg { width: 18px; height: 18px; }
.veritas-oeil:hover { color: var(--ink, #0f172a); background: rgba(127, 127, 127, .12); }
.veritas-oeil:focus-visible {
  outline: 2px solid var(--blue, #2563eb);
  outline-offset: 1px;
  color: var(--ink, #0f172a);
}

/* ==========================================================================
   ÉCRAN « DÉBLOQUER »

   Affiché quand un candidat touche une épreuve fermée. Volontairement sobre :
   c'est une information, pas une réclame. Le candidat vient de buter sur ce
   qu'il voulait faire ; l'agresser avec une vitrine serait le meilleur moyen
   de lui faire fermer la page.
   ========================================================================== */
.veritas-deblocage{position:fixed;inset:0;z-index:600;display:flex;
  align-items:center;justify-content:center;padding:18px;}
.veritas-deblocage-fond{position:absolute;inset:0;background:rgba(10,14,25,.55);}
.veritas-deblocage-panneau{position:relative;max-width:420px;width:100%;
  background:var(--panel,#fff);color:var(--ink,#14151f);border-radius:14px;
  padding:22px;box-shadow:0 20px 60px rgba(0,0,0,.35);}
.veritas-deblocage-panneau h3{margin:0 0 12px;font-size:16px;font-weight:800;}
.veritas-deblocage-panneau p{margin:0 0 10px;font-size:14px;line-height:1.55;}
.veritas-deblocage-offre{padding:10px 12px;border-radius:9px;
  background:var(--bg-soft,#eef0f6);font-size:14px;}
.veritas-deblocage-note{color:var(--muted,#667085);font-size:13px;}
/* Jusqu'à trois moyens de paiement, empilés : côte à côte, sur un téléphone,
   ils se réduiraient à trois libellés illisibles. */
.veritas-deblocage-action{display:block;min-height:44px;margin-top:8px;padding:11px 18px;
  border-radius:9px;background:var(--tenant-primary,#123d69);color:#fff;
  border:0;box-shadow:none;font:inherit;font-weight:700;text-decoration:none;text-align:center;font-size:14px;cursor:pointer;}
.veritas-deblocage-fermer{margin-top:14px;width:100%;padding:10px;border-radius:9px;
  border:1px solid var(--line,#e7e9f1);background:transparent;color:inherit;
  font-weight:600;cursor:pointer;}
.veritas-paiement-resume{display:grid;gap:6px;padding:13px 14px;margin:12px 0;
  border:1px solid var(--line,#e7e9f1);border-radius:11px;background:var(--bg-soft,#eef0f6);}
.veritas-paiement-resume>b{font-size:15px;}.veritas-paiement-resume>span{font-size:13px;color:var(--muted,#556070);}
.veritas-paiement-resume ul{margin:2px 0 0;padding-left:18px;font-size:12px;line-height:1.5;color:var(--muted,#556070);}
.veritas-paiement-choix{display:grid;gap:9px;margin-top:12px;}
.veritas-paiement-option{position:relative;min-height:68px;display:flex;align-items:center;gap:12px;padding:10px 13px;
  border:1px solid var(--line,#e7e9f1);border-radius:11px;cursor:pointer;background:var(--panel,#fff);}
.veritas-paiement-option:has(input:checked){border-color:var(--tenant-primary,#123d69);box-shadow:0 0 0 3px color-mix(in srgb,var(--tenant-primary,#123d69) 14%,transparent);}
.veritas-paiement-option input{position:absolute;opacity:0;}.veritas-paiement-option img{width:58px;height:38px;object-fit:contain;flex:0 0 58px;}
.veritas-paiement-option span{display:grid;gap:3px;flex:1;}.veritas-paiement-option b{font-size:14px;}.veritas-paiement-option small{font-size:12px;color:var(--muted,#556070);}
.veritas-paiement-option i{width:18px;height:18px;border:2px solid var(--line,#c9ced8);border-radius:50%;}.veritas-paiement-option:has(input:checked) i{border:5px solid var(--tenant-primary,#123d69);}
.veritas-paiement-option.indisponible{opacity:.58;cursor:not-allowed;background:var(--bg-soft,#eef0f6);}.veritas-paiement-erreur{min-height:19px!important;margin:0!important;color:#b42318;font-size:12px!important;}.veritas-credits-offres{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:14px 0}.veritas-credits-offre{appearance:none;text-align:left;display:grid;gap:4px;padding:13px;border:1px solid var(--line,#d9deea);border-radius:12px;background:var(--panel,#fff);color:inherit;cursor:pointer}.veritas-credits-offre:hover,.veritas-credits-offre:focus-visible{border-color:var(--blue,#2563eb);box-shadow:0 0 0 3px color-mix(in srgb,var(--blue,#2563eb) 18%,transparent)}.veritas-credits-offre b{font-size:.92rem}.veritas-credits-offre span{font-size:.82rem;color:var(--muted,#667085)}.veritas-credits-offre strong{color:var(--blue,#2563eb)}@media(max-width:460px){.veritas-credits-offres{grid-template-columns:1fr}}
.veritas-paiement-option:focus-within,.veritas-deblocage-action:focus-visible,.veritas-deblocage-fermer:focus-visible{outline:3px solid var(--tenant-primary,#123d69);outline-offset:3px;}
.veritas-paiement-mode{display:flex;align-items:center;gap:10px;margin:2px 0 10px;padding:9px 11px;border-radius:10px;background:var(--bg-soft,#eef0f6);color:var(--ink,#14151f);font-size:14px;}
.veritas-paiement-mode img{width:54px;height:32px;object-fit:contain;flex:0 0 54px;}
.veritas-paiement-formulaire{display:grid;gap:9px;margin-top:14px;}
.veritas-paiement-formulaire>label{display:grid;gap:3px;font-size:14px;font-weight:800;color:var(--ink,#14151f);}
.veritas-paiement-formulaire>label small{font-size:12px;font-weight:500;color:var(--muted,#556070);}
.veritas-paiement-saisie{display:flex;align-items:stretch;min-height:48px;border:1px solid var(--line,#d8dce6);border-radius:10px;background:var(--panel,#fff);overflow:hidden;transition:border-color .14s ease,box-shadow .14s ease;}
.veritas-paiement-saisie:focus-within{border-color:var(--tenant-primary,#123d69);box-shadow:0 0 0 3px color-mix(in srgb,var(--tenant-primary,#123d69) 14%,transparent);}
.veritas-paiement-saisie span{display:flex;align-items:center;padding:0 12px;background:var(--bg-soft,#eef0f6);border-right:1px solid var(--line,#d8dce6);font-weight:800;color:var(--muted,#556070);}
.veritas-paiement-saisie input{min-width:0;flex:1;border:0!important;outline:0!important;background:transparent!important;padding:0 13px!important;color:var(--ink,#14151f);font:inherit;font-size:16px!important;letter-spacing:.04em;box-shadow:none!important;}
.veritas-paiement-aide{margin:0!important;color:var(--muted,#556070);font-size:12px!important;}

/* ==========================================================
   L'accès qui va se terminer

   Un bandeau, dans les trois derniers jours seulement. Plus tôt il
   deviendrait un décor — on cesse de voir ce qui est toujours là — et il ne
   resterait rien pour signaler le dernier jour.

   Il est posé en tête de <body> et pousse le contenu vers le bas plutôt que
   de le recouvrir : les en-têtes fixes des pages d'épreuve masqueraient un
   bandeau flottant, et un avertissement caché n'avertit personne.
   ========================================================== */
.veritas-fin-proche{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:10px 16px;background:#fff4e5;color:#7a4a06;
  border-bottom:1px solid #f0d5a8;font-size:14px;font-weight:600;
  position:relative;z-index:60;}
.veritas-fin-texte{flex:1;min-width:200px;}
.veritas-fin-action{display:inline-block;padding:7px 14px;border-radius:8px;
  background:#7a4a06;color:#fff;text-decoration:none;font-weight:700;font-size:13px;}
.veritas-fin-fermer{border:0;background:transparent;color:inherit;font-size:20px;
  line-height:1;cursor:pointer;padding:0 4px;opacity:.7;}
.veritas-fin-fermer:hover{opacity:1;}
body.dark .veritas-fin-proche{background:#3a2c12;color:#f5d9a6;border-bottom-color:#5a4520;}
body.dark .veritas-fin-action{background:#f5d9a6;color:#3a2c12;}

/* La référence d'une commande : elle se lit à voix haute au téléphone, donc
   grande, espacée, en chasse fixe. Une référence qu'on dicte de travers ne
   rapproche aucun versement. */
.veritas-reference{font:800 22px/1.3 ui-monospace,SFMono-Regular,Consolas,monospace;
  letter-spacing:.14em;text-align:center;padding:12px;border-radius:9px;
  background:var(--bg-soft,#eef0f6);color:var(--ink,#14151f);
  user-select:all;margin:0 0 12px;}

/* ============================================================
   MOUVEMENT ET TRANSITIONS — LA COUCHE PARTAGÉE

   Elle était recopiée dans les ONZE pages, et son propre commentaire disait
   encore « commune aux six pages ». Six l'avaient à l'identique ; cinq avaient
   déjà dérivé vers des versions plus courtes, chacune avec ses sélecteurs.
   D'où une brusquerie inégale : la même fenêtre s'ouvrait en douceur ici et
   d'un coup là. Cette version prend l'union de toutes.

   CE QUI MANQUAIT PARTOUT : la FERMETURE. Les fenêtres montaient à
   l'ouverture, puis disparaissaient d'un coup — `display:none` ne se
   transitionne pas. C'est ce que l'œil perçoit comme « brusque », et c'est la
   moitié du mouvement qui n'existait pas.

   Tout est neutralisé sous `prefers-reduced-motion` : le réglage système a le
   dernier mot. Une animation décorative ne s'impose jamais à quelqu'un qui a
   demandé à ne pas en avoir — pour certains, elle donne la nausée.
   ============================================================ */
:root{
  /* Trois durées, pas trente. Au-delà, plus personne ne sait laquelle choisir
     et l'ensemble cesse d'avoir un rythme. */
  --v-rapide:.14s;
  --v-normal:.24s;
  --v-lent:.34s;
  /* LA COURBE D'APPLE, ET CE QU'ELLE A DE PARTICULIER.
     Elle démarre TRÈS vite puis s'installe longuement — le geste répond au
     doigt dans les premières millisecondes, et prend son temps pour se poser.
     C'est l'inverse d'un `ease` classique, qui tergiverse au départ et arrive
     sec. Toute la sensation de « fluide » tient dans cette dissymétrie.
     Valeur employée par Apple pour la présentation de ses feuilles. */
  --v-courbe:cubic-bezier(.32,.72,0,1);
  /* Un dépassement très léger à l'arrivée — assez pour que l'élément semble
     avoir un poids, pas assez pour distraire. Un vrai rebond ferait jouet. */
  --v-arrivee:cubic-bezier(.34,1.12,.64,1);
  /* Pour ce qui SORT : une courbe qui accélère. On regarde une fenêtre
     s'installer, on ne regarde jamais une fenêtre partir. */
  --v-depart:cubic-bezier(.4,0,1,1);
}

@keyframes v-fondu        { from{opacity:0;} to{opacity:1;} }
@keyframes v-fondu-sortie { from{opacity:1;} to{opacity:0;} }
@keyframes v-monte        { from{opacity:0;transform:translateY(10px);} to{opacity:1;transform:none;} }
@keyframes v-panneau      { from{opacity:0;transform:translateY(14px) scale(.985);}
                            to  {opacity:1;transform:none;} }
@keyframes v-panneau-sortie{ from{opacity:1;transform:none;}
                             to  {opacity:0;transform:translateY(8px) scale(.985);} }

/* ---- Les fenêtres ----
   Le FOND se fait, le PANNEAU monte. Les deux ensemble : sans le fond, le
   panneau semble surgir de nulle part ; sans le panneau, la page clignote. */
.overlay.open, .modal-overlay.open, .cpt-overlay.open,
.drawer-overlay.open, .auth-overlay.open,
.fond-agrandi, .veritas-deblocage{
  animation:v-fondu var(--v-normal) var(--v-courbe) both;
}
.overlay.open > *, .modal-overlay.open > *, .cpt-overlay.open > *,
.drawer-overlay.open > *, .auth-overlay.open > *,
.fond-agrandi > *, .veritas-deblocage-panneau{
  animation:v-panneau var(--v-normal) var(--v-arrivee) both;
}

/* LA FERMETURE, qui n'existait pas.
   `veritas-layout.js` pose cette classe quand `open` disparaît, garde la
   fenêtre affichée le temps de l'animation, puis la retire. Les clics sont
   coupés dès la première image : une fenêtre qui s'en va ne doit plus
   répondre, sans quoi on ferme deux fois ce qui se ferme déjà. */
.veritas-sortie{
  display:flex !important;
  pointer-events:none;
  animation:v-fondu-sortie var(--v-rapide) var(--v-depart) both;
}
.veritas-sortie > *{
  animation:v-panneau-sortie var(--v-rapide) var(--v-depart) both;
}

/* ---- Le retour au doigt ----
   90 ms à l'appui, plus lent au relâchement : un appui doit se sentir
   instantané, c'est le retour qui peut s'adoucir. La liste réunit les
   sélecteurs des onze pages — chacune avait ajouté les siens. */
button, .btn, .nav-item, .mod-tab, .type-btn, .upload-btn, .role-opt .box,
.btn-primary, .btn-ghost, .btn-submit, .btn-primaire, .cpt-btn, .info-link,
.icon-btn, .option, .pastille, .btn-plein, .btn-masquer, .notif-piece{
  transition:transform .09s var(--v-courbe),
             background-color var(--v-rapide) var(--v-courbe),
             border-color var(--v-rapide) var(--v-courbe),
             color var(--v-rapide) var(--v-courbe),
             box-shadow var(--v-rapide) var(--v-courbe),
             opacity var(--v-rapide) var(--v-courbe);
}
button:not(:disabled):active, .btn:not(:disabled):active, .nav-item:active,
.mod-tab:active, .type-btn:active, .upload-btn:active, .cpt-btn:active,
.icon-btn:active, .option:active, .pastille:active,
.btn-plein:active, .btn-masquer:active{ transform:scale(.97); }
button:disabled{ cursor:not-allowed; }

/* Le clavier doit voir ce que la souris voit, et seulement au parcours
   clavier : un anneau à chaque clic de souris serait du bruit. */
:where(button, a, input, select, textarea, [tabindex]):focus-visible{
  outline:2px solid var(--blue, #2f6fed);
  outline-offset:2px;
}

/* ---- Les cartes ---- */
.card, .epreuve-card, .adv-card, .price-card, .module-card,
.pack-card, .testi-card, .aide-card{
  transition:transform var(--v-rapide) var(--v-courbe),
             box-shadow var(--v-rapide) var(--v-courbe),
             border-color var(--v-rapide) var(--v-courbe);
}
.card:hover, .epreuve-card:hover, .adv-card:hover, .module-card:hover,
.testi-card:hover, .aide-card:hover{ transform:translateY(-3px); }
/* Jamais sur les surfaces du simulateur : leur hauteur est contrainte, et un
   soulèvement y décalerait le texte qu'on est en train de lire. */
.simu-card:hover, .recap-tache:hover, .recap-note:hover,
.rev:hover, .enreg:hover, .echange:hover{ transform:none; }

/* ---- Apparition en cascade ----
   Bornée aux quatre premiers éléments : au-delà, le décalage cumulé ferait
   attendre pour rien — la grille des épreuves en compte cinquante et une. */
.grid > *, .epreuves-grid > *, .modules-grid > *,
.adv-grid > *, .price-grid > *, .stats > *{
  animation:v-monte var(--v-lent) var(--v-courbe) both;
}
.grid > *:nth-child(1), .epreuves-grid > *:nth-child(1), .modules-grid > *:nth-child(1),
.adv-grid > *:nth-child(1), .price-grid > *:nth-child(1), .stats > *:nth-child(1){ animation-delay:0ms; }
.grid > *:nth-child(2), .epreuves-grid > *:nth-child(2), .modules-grid > *:nth-child(2),
.adv-grid > *:nth-child(2), .price-grid > *:nth-child(2), .stats > *:nth-child(2){ animation-delay:40ms; }
.grid > *:nth-child(3), .epreuves-grid > *:nth-child(3), .modules-grid > *:nth-child(3),
.adv-grid > *:nth-child(3), .price-grid > *:nth-child(3), .stats > *:nth-child(3){ animation-delay:80ms; }
.grid > *:nth-child(4), .epreuves-grid > *:nth-child(4), .modules-grid > *:nth-child(4),
.adv-grid > *:nth-child(4), .price-grid > *:nth-child(4), .stats > *:nth-child(4){ animation-delay:120ms; }
.grid > *:nth-child(n+5), .epreuves-grid > *:nth-child(n+5),
.modules-grid > *:nth-child(n+5){ animation-delay:160ms; }

/* ---- Le bandeau de message ----
   Il glissait déjà ; sa courbe rejoint celle du reste, pour que l'ensemble
   ait un seul rythme au lieu de trois. */
.toast, .veritas-session-message{
  transition:transform var(--v-normal) var(--v-arrivee),
             opacity var(--v-normal) var(--v-courbe);
}

/* Une entrée en fondu, courte. Plus long, on attend la page ; plus court, on
   voit un clignotement. */
body{ animation:v-fondu var(--v-normal) var(--v-courbe) both; }

/* ============================================================
   LE RÉGLAGE SYSTÈME A LE DERNIER MOT
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  button:active, .btn:active, .nav-item:active,
  .card:hover, .epreuve-card:hover, .adv-card:hover, .module-card:hover,
  .testi-card:hover, .aide-card:hover{ transform:none !important; }
}

/* ============================================================
   LE VERRE, L'ESPACE ET L'ÉLÉVATION

   Trois échelles qui n'existaient nulle part : les marges étaient écrites en
   pixels au cas par cas, les ombres réinventées par page, et aucune surface
   n'avait de matière. D'où une plateforme qui « fonctionne » sans jamais
   sembler d'un seul tenant.

   CE QUI EST ADDITIF, ET POURQUOI ÇA COMPTE. Rien ici ne redéfinit un jeton
   existant. Les pages gardent leurs `--bg`, `--panel`, `--ink` : les écraser
   depuis une feuille chargée après elles aurait changé quatorze pages d'un
   coup, sans que personne puisse dire laquelle avait bougé. On ajoute, on
   applique là où c'est vérifié, et le reste attend.
   ============================================================ */
:root{
  /* ---- L'espace ----
     Une échelle géométrique, pas une suite de nombres ronds choisis au coup
     par coup. Deux valeurs voisines qui ne se distinguent pas à l'œil sont
     deux occasions de se tromper sans le voir. */
  --espace-1:4px;   --espace-2:8px;   --espace-3:12px;  --espace-4:16px;
  --espace-5:24px;  --espace-6:32px;  --espace-7:48px;  --espace-8:64px;

  /* ---- Le rayon ----
     Le verre a besoin de coins généreux : un angle vif sur une surface
     translucide durcit le bord et casse l'illusion de matière. */
  --rayon-1:8px;  --rayon-2:12px;  --rayon-3:16px;  --rayon-4:22px;  --rayon-plein:999px;

  /* ---- LE VERRE ----
     Une teinte OPAQUE À 72 %, et non un simple flou. C'est ce qui rend le
     contraste du texte prévisible : par-dessus une photo sombre, un flou seul
     laisserait passer assez de noir pour faire tomber le texte sous 4,5:1.
     La teinte porte le contraste, le flou porte la matière.

     La saturation est le second ingrédient d'Apple, et le moins connu : sans
     elle, le flou délave ce qu'il y a derrière et le verre paraît sale. */
  --verre-teinte:rgba(255,255,255,.72);
  --verre-teinte-forte:rgba(255,255,255,.88);
  --verre-flou:20px;
  --verre-saturation:180%;
  --verre-bord:rgba(255,255,255,.65);
  --verre-lueur:rgba(255,255,255,.55);
  --verre-ombre:0 8px 32px rgba(15,23,42,.10), 0 1px 2px rgba(15,23,42,.05);

  /* ---- L'élévation ----
     Trois niveaux, comme les trois durées. Une ombre par composant, c'est une
     profondeur que personne ne peut lire. */
  --ombre-1:0 1px 2px rgba(15,23,42,.06);
  --ombre-2:0 4px 16px rgba(15,23,42,.08), 0 1px 2px rgba(15,23,42,.05);
  --ombre-3:0 16px 48px rgba(15,23,42,.16), 0 2px 8px rgba(15,23,42,.06);
}

body.dark{
  /* Le verre sombre n'est pas le verre clair assombri : sa teinte est plus
     opaque (le texte clair sur fond variable est plus fragile) et son bord
     est une LUEUR, pas une ligne — c'est ce qui distingue une surface posée
     d'un trou découpé. */
  --verre-teinte:rgba(23,26,36,.76);
  --verre-teinte-forte:rgba(23,26,36,.92);
  --verre-bord:rgba(255,255,255,.10);
  --verre-lueur:rgba(255,255,255,.14);
  --verre-ombre:0 8px 32px rgba(0,0,0,.44), 0 1px 2px rgba(0,0,0,.30);
  --ombre-1:0 1px 2px rgba(0,0,0,.30);
  --ombre-2:0 4px 16px rgba(0,0,0,.38), 0 1px 2px rgba(0,0,0,.30);
  --ombre-3:0 16px 48px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.35);
}

/* ---- La surface de verre ----
   `isolation:isolate` et le pseudo-élément : la lueur spéculaire d'Apple est
   un dégradé qui court sur le haut de la surface, pas une bordure claire.
   C'est ce qui donne l'impression que la lumière tombe DESSUS plutôt que
   d'être peinte dedans. */
.verre, .verre-fort{
  position:relative;
  isolation:isolate;
  background:var(--verre-teinte);
  -webkit-backdrop-filter:blur(var(--verre-flou)) saturate(var(--verre-saturation));
  backdrop-filter:blur(var(--verre-flou)) saturate(var(--verre-saturation));
  border:1px solid var(--verre-bord);
  box-shadow:var(--verre-ombre);
}
.verre-fort{ background:var(--verre-teinte-forte); }
.verre::before, .verre-fort::before{
  content:'';
  position:absolute; inset:0;
  border-radius:inherit;
  pointer-events:none;
  background:linear-gradient(180deg, var(--verre-lueur), transparent 46%);
  opacity:.9;
}

/* LE REPLI, ET IL N'EST PAS DÉCORATIF.
   Sans `backdrop-filter`, la teinte à 72 % laisse voir le fond de page à
   travers — lisible, mais laid, et surtout imprévisible sur une photo. On
   repose donc une surface pleine. Firefox l'a longtemps refusé par défaut, et
   les navigateurs de téléphones d'entrée de gamme restent nombreux. */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .verre, .verre-fort{ background:var(--panel, #fff); }
  .verre::before, .verre-fort::before{ display:none; }
}

/* LE RÉGLAGE SYSTÈME A LE DERNIER MOT, ICI AUSSI.
   « Réduire la transparence » est un réglage d'accessibilité d'iOS, d'Android
   et de Windows, demandé par des gens pour qui le texte sur fond mouvant est
   illisible ou donne le vertige. Le respecter n'est pas une option. */
@media (prefers-reduced-transparency: reduce){
  .verre, .verre-fort{
    -webkit-backdrop-filter:none;
    backdrop-filter:none;
    background:var(--panel, #fff);
  }
  .verre::before, .verre-fort::before{ display:none; }
}

/* Confirmation de consommation de crédit : une action facturable ne doit
   jamais reposer sur un libellé de bouton seul. */
.veritas-confirmation-ia{max-width:min(460px,calc(100vw - 28px));border:1px solid var(--line,#e7e9f1);border-radius:16px;padding:0;background:var(--panel,#fff);color:var(--ink,#14151f);box-shadow:0 20px 60px rgba(15,23,42,.24)}
.veritas-confirmation-ia::backdrop{background:rgba(15,23,42,.48);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.veritas-confirmation-ia form{padding:24px}.veritas-confirmation-ia h2{margin:0 0 10px;font:800 20px/1.25 Manrope,system-ui,sans-serif}.veritas-confirmation-ia p{margin:9px 0;color:var(--muted,#556070);font:14px/1.55 Inter,system-ui,sans-serif}.veritas-confirmation-ia strong{color:var(--ink,#14151f)}
.veritas-confirmation-solde{padding:10px 12px;border-radius:10px;background:var(--blue-tint,#eaf1ff);color:var(--blue,#2f6fed)!important;font-weight:700!important}.veritas-confirmation-manuel{padding:10px 12px;border-left:3px solid var(--gold,#bf8b3f);background:color-mix(in srgb,var(--gold,#bf8b3f) 10%,transparent);border-radius:8px}.veritas-confirmation-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:20px;flex-wrap:wrap}.veritas-confirmation-actions button{min-height:44px;border-radius:10px;padding:9px 14px;font:800 13px/1.2 Inter,system-ui,sans-serif;cursor:pointer}.veritas-confirmation-secondaire{border:1px solid var(--line,#e7e9f1);background:transparent;color:var(--ink,#14151f)}.veritas-confirmation-sans-credit{border-color:var(--gold,#bf8b3f);color:#80591d}.veritas-confirmation-primaire{border:1px solid var(--blue,#2f6fed);background:var(--blue,#2f6fed);color:#fff}@media(max-width:480px){.veritas-confirmation-actions{flex-direction:column-reverse}.veritas-confirmation-actions button{width:100%}}

/* LE FLOU EST CHER, ET LE PUBLIC EST SUR TÉLÉPHONE D'ENTRÉE DE GAMME.
   `backdrop-filter` fait recomposer tout ce qui est derrière, à chaque image.
   Sur une surface qui DÉFILE, cela se paie en saccades visibles — et un
   candidat en pleine épreuve chronométrée n'a pas à subir ça.

   Le verre est donc réservé aux surfaces BORNÉES et fixes : barres, panneaux,
   fenêtres. Jamais le corps d'une page, jamais une liste longue, jamais les
   documents d'une épreuve. Cette règle est la raison pour laquelle les classes
   sont posées à la main et non appliquées à `.card` en bloc. */

/* ---- Les fenêtres prennent le verre ---- */
.overlay.open > *, .modal-overlay.open > *, .cpt-overlay.open > *,
.drawer-overlay.open > *, .auth-overlay.open > *,
.fond-agrandi > .info-card, .veritas-deblocage-panneau{
  /* LA LUEUR EN COUCHE DE FOND, ET NON EN PSEUDO-ÉLÉMENT.
     `::before{position:absolute;inset:0}` exige que le panneau soit lui-même
     positionné ; ceux-ci ne le sont pas tous, et la lueur se serait alors
     calée sur la fenêtre entière — un voile blanc en travers de l'écran.
     Deux couches de fond donnent le même reflet sans rien exiger du panneau. */
  background:linear-gradient(180deg, var(--verre-lueur), transparent 46%),
             var(--verre-teinte-forte);
  -webkit-backdrop-filter:blur(var(--verre-flou)) saturate(var(--verre-saturation));
  backdrop-filter:blur(var(--verre-flou)) saturate(var(--verre-saturation));
  border:1px solid var(--verre-bord);
  box-shadow:var(--ombre-3);
  border-radius:var(--rayon-4);
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .overlay.open > *, .modal-overlay.open > *, .cpt-overlay.open > *,
  .drawer-overlay.open > *, .auth-overlay.open > *,
  .fond-agrandi > .info-card, .veritas-deblocage-panneau{ background:var(--panel, #fff); }
}
@media (prefers-reduced-transparency: reduce){
  .overlay.open > *, .modal-overlay.open > *, .cpt-overlay.open > *,
  .drawer-overlay.open > *, .auth-overlay.open > *,
  .fond-agrandi > .info-card, .veritas-deblocage-panneau{
    -webkit-backdrop-filter:none; backdrop-filter:none; background:var(--panel, #fff);
  }
}

/* LE TEXTE SECONDAIRE NE PASSAIT PLUS SUR LE VERRE.
   Mesuré, pas supposé : `--muted` (#667085) donne 4,97:1 sur du blanc plein —
   déjà juste — et tombe à 3,77:1 une fois le verre composé par-dessus un fond
   sombre. Sous le seuil AA de 4,5. C'est le défaut classique du verre, et il
   ne se voit pas : le texte reste « lisible » pour qui a de bons yeux et une
   bonne lumière, ce qui décrit le développeur et pas le candidat.

   #556070 donne 4,83:1 dans le pire cas, et 6,38:1 sur un panneau plein. Assez
   soutenu pour tenir, assez clair pour continuer à se lire comme du secondaire.

   La correction est LOCALE aux surfaces de verre : redéfinir --muted partout
   aurait changé quatorze pages sur la foi d'une mesure faite sur une seule. */
.overlay.open > *, .modal-overlay.open > *, .cpt-overlay.open > *,
.drawer-overlay.open > *, .auth-overlay.open > *,
.fond-agrandi > .info-card, .veritas-deblocage-panneau,
.verre, .verre-fort, .mobile-bar, .veritas-mobile-drawer{
  --muted:#556070;
}
body.dark .overlay.open > *, body.dark .modal-overlay.open > *,
body.dark .cpt-overlay.open > *, body.dark .drawer-overlay.open > *,
body.dark .auth-overlay.open > *, body.dark .fond-agrandi > .info-card,
body.dark .veritas-deblocage-panneau, body.dark .verre, body.dark .verre-fort,
body.dark .mobile-bar, body.dark .veritas-mobile-drawer{
  /* En sombre la mesure passe déjà — 5,32:1 au pire — mais le jeton doit être
     reposé, sinon la règle claire ci-dessus s'appliquerait aussi la nuit. */
  --muted:#9aa0b2;
}

/* Le fond derrière une fenêtre : un voile flouté plutôt qu'un rideau noir.
   C'est la différence entre « la page a disparu » et « la page est derrière ». */
.overlay.open, .modal-overlay.open, .cpt-overlay.open,
.drawer-overlay.open, .auth-overlay.open, .fond-agrandi, .veritas-deblocage{
  -webkit-backdrop-filter:blur(3px);
  backdrop-filter:blur(3px);
}
@media (prefers-reduced-transparency: reduce){
  .overlay.open, .modal-overlay.open, .cpt-overlay.open,
  .drawer-overlay.open, .auth-overlay.open, .fond-agrandi, .veritas-deblocage{
    -webkit-backdrop-filter:none; backdrop-filter:none;
  }
}

/* ---- Les barres fixes ----
   Elles se superposent au contenu qui défile : c'est exactement l'endroit où
   le verre a un sens, et le seul où il ne coûte rien de plus — la surface est
   petite et ne bouge pas. */
.mobile-bar, .veritas-mobile-drawer{
  background:var(--verre-teinte-forte);
  -webkit-backdrop-filter:blur(var(--verre-flou)) saturate(var(--verre-saturation));
  backdrop-filter:blur(var(--verre-flou)) saturate(var(--verre-saturation));
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .mobile-bar, .veritas-mobile-drawer{ background:var(--panel, #fff); }
}
@media (prefers-reduced-transparency: reduce){
  .mobile-bar, .veritas-mobile-drawer{
    -webkit-backdrop-filter:none; backdrop-filter:none; background:var(--panel, #fff);
  }
}
