/* ============================================================
   Satoshi : SERVIE EN LOCAL (assets/fonts/), et non plus par fontshare.
   ------------------------------------------------------------
   Les .woff2 sont les fichiers EXACTS que servait cdn.fontshare.com :
   le rendu est identique au pixel. Trois raisons de les avoir rapatriés :

   1. VITESSE. La feuille venait de api.fontshare.com et les polices de
      cdn.fontshare.com : deux origines de plus à résoudre (DNS + TCP +
      TLS) AVANT le premier texte peint, et la 2e n'était découverte
      qu'une fois la 1re téléchargée puis analysée. En local, la connexion
      est déjà ouverte et les fichiers sont préchargés dès la 1re ligne
      du <head>.
   2. VIE PRIVÉE. Chaque visite envoyait l'adresse IP du visiteur à un
      tiers américain, sans consentement et sans que la page
      « Confidentialité » ne le mentionne. C'est exactement ce qui a valu
      des condamnations à des sites utilisant Google Fonts en Europe.
   3. CHAÎNE D'APPROVISIONNEMENT. Un CDN tiers dans la CSP, c'est un
      domaine de plus autorisé à injecter du style dans la page. Il est
      maintenant retiré de la CSP : tout est en 'self'.

   Si une graisse doit être ajoutée un jour, télécharger le .woff2 depuis
   fontshare, le poser ici, et ajouter un bloc identique.
   ============================================================ */
@font-face {
  font-family: "Satoshi";
  src: url("assets/fonts/satoshi-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Satoshi";
  src: url("assets/fonts/satoshi-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Satoshi";
  src: url("assets/fonts/satoshi-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ============================================================
   basarc : Évaluation de potentiel
   Même grammaire que la landing (Satoshi, carte 402 px, mêmes
   tokens) : le tunnel doit se sentir comme le même produit.
   Ce qui change : une question par écran, zéro distraction,
   aucune navigation vers le reste du site avant la fin.
   ============================================================ */
:root {
  --bg:      #ffffff;
  --ink:     #131315;
  /* Assombris pour le VERRE. Ces deux gris étaient réglés pour du blanc plein :
     #6b6f76 y donnait 4,57:1, soit AA tout juste. Le panneau étant devenu
     translucide ET le sol ayant été assombri, son fond effectif descend à
     ~rgb(193,196,202) dans ses zones basses et les mêmes gris tombaient à
     3,9:1, sous le seuil. Mesuré à chaque fois, pas
     estimé. Les écrans sombres du résultat ne sont pas concernés : ils
     réécrivent leurs couleurs (.step--dark, .evprog.is-dark). */
  --muted:   #4c5058;   /* 4,70:1 sur la zone la plus sombre du verre */
  --faint:   #6f757e;   /* rend au gris discret le poids qu'il avait sur blanc */
  --line:    #e7e7ea;
  --black:   #101012;
  --raise:   #8a2b2b;

  /* Plaque sombre : valeurs reprises telles quelles de styles.css. */
  --dark-bg:    #0f0f11;
  --dark-title: #f6f6f7;
  --dark-text:  #9b9ba2;
  --dark-hair:  rgba(255,255,255,.08);

  --r-btn:   14px;
  --r-card:  22px;
  --r-media: 8px;

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s7: 32px; --s8: 40px;
  --s9: 48px;

  --t-eyebrow: 13px;
  --t-body:    16px;
  --t-btn:     15px;
  --t-h1:      28px;

  --pad:      20px;
  --maxw:     402px;
  /* --header-h retiré : il n'était lu NULLE PART dans cette feuille (le tunnel
     n'a ni plaque collante, ni hero « 1 écran », ni ancre interne à décaler),
     et il traînait la même valeur fausse que sur la landing, 56px pour un
     header qui en mesure 60. Un jeton mort qui ment est pire qu'un jeton
     absent : le jour où on s'en sert, il se sert de travers. */

  /* On déclare le schéma de couleurs de la page. Sans cette ligne, `color-scheme`
     vaut `normal` : le navigateur ne sait pas que la page est conçue en clair et,
     poste en thème sombre, il peut assombrir de lui-même ce qu'il dessine : les
     barres de défilement, les commandes de formulaire, et sur Android Chrome le
     thème sombre automatique qui INVERSE toute la page. Le site n'a aucune règle
     prefers-color-scheme : cette déclaration ne change donc rien à son rendu, elle
     ferme seulement la porte à une inversion décidée par le navigateur. */
  color-scheme: light;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Même sol sur <html> : c'est ce qui EMPÊCHE le fond du body de se propager au
   canevas (voir isolation ci-dessous), et ce qui peint les zones de rebond du
   défilement élastique au lieu de laisser du blanc. */
html { background: #8d939f; }

body {
  font-family: "Satoshi", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-feature-settings: "ss01", "cv01";
  /* Aplat remplacé par un dégradé très doux : la carte se détache au lieu de
     flotter sur un gris mort. On reste dans le neutre de la landing : pas de
     virage bleu-vert, qui casserait la palette monochrome du site. */
  /* Sol gris. Les lumières sont portées par body::before / body::after, qui
     dérivent lentement (voir plus bas) : un fond animé par background-position
     repeindrait à chaque frame, alors qu'un transform reste sur la couche GPU.

     C'ÉTAIT l'aplat #c8ccd2. Un aplat n'a pas de haut ni de bas : la carte y
     était posée sans y être tenue, et le reste de l'écran se lisait comme du
     vide non fini plutôt que comme un fond. Le dégradé ci-dessous éclaire le
     haut et fait tomber les bords : la carte est désormais dans quelque chose.
     Aucune couleur nouvelle : la même famille de gris neutres que la landing. */
  background:
    radial-gradient(155% 112% at 50% -16%,
      #bcc1cb 0%,
      #a3a9b5 32%,
      #8a909d 64%,
      #767c89 87%,
      #6a7079 100%);
  background-attachment: fixed;   /* le sol ne défile pas avec les écrans longs */
  /* isolation OBLIGATOIRE : sans elle, le fond du <body> se propage au canevas
     de la page, le <body> est alors traité comme s'il n'avait pas de fond, et
     les nappes en mix-blend-mode:screen n'ont plus rien contre quoi se fondre :
     elles retombent en aplats laiteux. Ici la pile est locale : les nappes en
     z-index:-1 se peignent APRÈS ce fond et se fondent dessus. */
  isolation: isolate;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-tap-highlight-color: transparent;
}

.page {
  max-width: var(--maxw);
  margin: 0 auto;
  background: var(--bg);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  transition: background-color .34s ease;
}
/* Sur la landing, la plaque sombre glisse SOUS la barre : c'est ce qui donne au
   verre sa teinte foncée. Ici rien ne défile derrière le header, donc on fait
   courir le fond sombre jusqu'en haut de la carte quand l'écran sombre s'ouvre.
   Sans ça, la pilule reste laiteuse et l'effet tombe à plat. */
.page.is-dark { background: var(--dark-bg); }

@media (min-width: 480px) {
  .page {
    /* Elle grandit avec l'écran. Figée à 402 px, elle laissait 183 px de gris
       mort de chaque côté sur une tablette : ni le dessin mobile, ni le dessin
       desktop. */
    max-width: clamp(402px, 88vw, 640px);
    margin: var(--s6) auto;
    min-height: calc(100dvh - 48px);
    border-radius: var(--r-card);
    /* Ombre portée longue + liseré clair en haut : la carte flotte et capte la
       lumière, au lieu d'être un rectangle blanc collé sur un fond. */
    box-shadow:
      0 1px 0 0 rgba(255,255,255,.7) inset,
      0 2px 6px rgba(16,18,22,.06),
      0 32px 80px -12px rgba(16,18,22,.28);
    overflow: hidden;
  }
}

/* ===================== VERRE POLI (fond animé) =====================
   Deux calques fixes portant de très larges nappes blanches, sans filtre de
   flou : les radial-gradients sont déjà diffus, et un blur() serait recalculé
   à chaque frame. Seul le transform est animé, donc composition GPU pure,
   zéro repaint. Cycles de 90 et 130 secondes : le mouvement se remarque à
   peine, il donne juste de la matière au gris. */
body::before,
body::after {
  content: "";
  position: fixed;
  inset: -35%;
  z-index: -1;
  pointer-events: none;
  will-change: transform;
  backface-visibility: hidden;
}
body::before {
  /* Nappe large : géométrie reprise de la citation de Daniel (.quote::before
     dans styles.css) : mêmes positions, mêmes rayons, et ses deux halos bleu
     froid parmi les gris.
     Le FONDU, lui, est en SOFT-LIGHT et non en screen. Sur la plaque sombre de
     Daniel, screen éclaire et c'est tout ce qu'on lui demande ; sur un sol gris
     il ne sait que blanchir, et le fond partait en lavis laiteux. Soft-light
     éclaire ET creuse selon que le halo est clair ou sombre : c'est ce qui
     donne un galbe de verre plutôt qu'un voile. La cinquième nappe est
     volontairement sombre : c'est elle qui pose l'ombre en bas de l'écran. */
  filter: blur(46px);
  mix-blend-mode: soft-light;
  background:
    radial-gradient(74% 88% at 10% -2%,  rgba(214, 232, 252, 1),    transparent 66%),
    radial-gradient(72% 84% at 96% 4%,   rgba(255, 255, 255, .92),  transparent 64%),
    radial-gradient(88% 100% at 86% 124%,rgba(200, 220, 244, .82),  transparent 68%),
    radial-gradient(58% 66% at 56% 96%,  rgba( 34,  39,  48, .34),  transparent 66%),
    radial-gradient(84% 92% at 38% 48%,  rgba(255, 255, 255, .52),  transparent 82%),
    /* Sixième nappe : une clarté centrale très large, celle qui porte la carte. */
    radial-gradient(110% 90% at 50% 30%, rgba(255, 255, 255, .34),  transparent 78%);
  animation: derive-a 90s ease-in-out infinite alternate;
}
body::after {
  /* Sur-reflets (.quote::after) : le shimmer par-dessus, moins flouté et plus
     serré que la nappe large. C'est lui qui fait la vitre polie plutôt que le
     simple dégradé, et c'est lui qui porte les lumières blanc cassé. Screen ici,
     mais à faible opacité et sur des halos courts : des éclats, pas un voile. */
  filter: blur(30px);
  mix-blend-mode: screen;
  opacity: .58;
  background:
    radial-gradient(56% 46% at 26% 18%, rgba(255, 253, 245, .40), transparent 74%),
    radial-gradient(62% 50% at 88% 78%, rgba(238, 243, 252, .34), transparent 76%),
    radial-gradient(52% 42% at 62% 8%,  rgba(255, 251, 242, .26), transparent 78%),
    radial-gradient(66% 54% at 8% 62%,  rgba(252, 250, 244, .24), transparent 80%);
  animation: derive-b 130s ease-in-out infinite alternate;
}
@keyframes derive-a {
  from { transform: translate3d(-2.5%, -1.5%, 0) scale(1); }
  to   { transform: translate3d( 3%,   2.5%, 0) scale(1.07); }
}
@keyframes derive-b {
  from { transform: translate3d( 2.5%,  1.5%, 0) scale(1.06); }
  to   { transform: translate3d(-3%,  -2%,   0) scale(1); }
}

a { text-decoration: none; color: inherit; }
img { max-width: 100%; display: block; }

:where(a, button, input, summary):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Les titres reçoivent le focus par programme à chaque changement d'écran, pour
   que les lecteurs d'écran annoncent la nouvelle question. Ils portent
   tabindex="-1" et ne sont donc jamais atteignables au clavier : l'anneau du
   navigateur n'apporte rien et peint un cadre au chargement. */
.step__q:focus, .res__head:focus { outline: none; }

/* ===================== BARRE DU SITE =====================
   COPIE CONFORME de .siteheader dans styles.css : mêmes sélecteurs, mêmes
   valeurs, même géométrie. Le but est qu'on ne voie pas qu'on a changé de page.
   Ne pas retoucher ces règles ici : si la landing bouge, elles se recopient.
   Seul ajout : .nav-mark n'existe pas dans le tunnel, la condensation est
   pilotée par le JS quand l'écran sombre s'ouvre. */
.siteheader {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: 0;
  /* Géométrie CONSTANTE dans les deux états -> le contenu (logo + CTA) ne bouge
     JAMAIS. Seule la plaque de verre ::before se détache au scroll. Hauteur = 56px
     (= --header-h) : 10 + 36 (CTA) + 10. */
  padding: calc(10px + env(safe-area-inset-top)) var(--pad) 10px;
  background: transparent;              /* le verre mat est porté par ::before */
  border-radius: 0;
}
/* Verre mat porté par un PSEUDO-ÉLÉMENT : le backdrop-filter n'est pas un ancêtre
   du panneau du menu (pas d'imbrication de flous). C'est LUI, et lui seul, qui
   s'anime : il se rétracte de 6px (haut/bas) et 12px (côtés) pour se détacher en
   pilule flottante. Le contenu, lui, reste fixe -> alignement garanti. */
.siteheader::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;                          /* plat : suit la barre (0 mobile, coins carte sur desktop) */
  background: rgba(250, 250, 251, .72);            /* verre mat (translucide + flou) */
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
  transition:
    inset .34s ease,
    border-radius .34s ease,
    background-color .34s ease,
    box-shadow .34s ease;
}
/* Pilule flottante détachée : SEULE la plaque change (inset + rayon + fond + ombre). */
.siteheader.is-condensed::before {
  inset: 6px 12px;
  border-radius: 16px;
  /* Même verre que le panneau du menu : couleur, transparence (.58) et matière (flou). */
  background: rgba(20, 20, 24, .58);
  -webkit-backdrop-filter: blur(26px) saturate(1.5);
  backdrop-filter: blur(26px) saturate(1.5);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .28);   /* liseré interne retiré : pilule brute */
}
/* Contenu lisible sur la pilule sombre (état « déployé » au scroll) : logo inversé
   (disque clair, étoile sombre) et points en clair. Transition douce. */
.logo svg circle, .logo svg path { transition: fill .34s ease; }
.siteheader.is-condensed .logo svg circle { fill: #f4f4f6; }
.siteheader.is-condensed .logo svg path   { fill: #14141a; }
.siteheader.is-condensed .menu__grid i { background: #f4f4f6; }

.logo { flex: 0 0 auto; display: inline-flex; }
.logo svg { width: 32px; height: 32px; display: block; }   /* mesuré : 32px, constant dans les deux états */

/* CTA du header : « Reprendre le contrôle ». Style CONSTANT dans les deux états
   (aucun morph) -> rien à animer, rien à désaligner. Coins carré-doux. */
.hcta {
  position: relative;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: 10px;                  /* carré-doux (léger arrondi), plus pilule */
  background: #fff;
  color: var(--ink);
  font-size: var(--t-btn);
  font-weight: 700;   /* Satoshi n'a pas de 600 -> résolu en 700 : on l'écrit explicitement */
  white-space: nowrap;
  touch-action: manipulation;
  transition: transform .18s ease;
}
.hcta::after { content: ""; position: absolute; inset: -5px 0; }   /* hit-slop 44px */
.hcta:active { transform: scale(.98); }
/* Dernier écran : la carte propose déjà « Revenir au site ». Le même lien dans
   la barre ferait doublon, on le retire là, et là seulement (le JS pose
   l'attribut, voir show() dans evaluation.html). La règle est nécessaire :
   sans elle, le `display: inline-flex` ci-dessus l'emporte sur [hidden]. */
.hcta[hidden] { display: none; }

/* ===================== MENU MORPHING (façon offmenu) ===================== */
.menu { position: relative; margin-left: auto; z-index: 40; }

/* Déclencheur : point + grille 3x3, toujours au-dessus du panneau */
.menu__toggle {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 9px;
  height: 40px;
  padding: 0 6px;
  background: transparent;
  border: none;
  cursor: pointer;
  touch-action: manipulation;
}
.menu__grid {
  display: grid;
  grid-template-columns: repeat(3, 4.5px);
  grid-auto-rows: 4.5px;
  gap: 4.5px;
  transition: transform .45s cubic-bezier(.2, .85, .25, 1);
}
.menu__grid i {
  width: 4.5px; height: 4.5px;
  border-radius: 50%;
  background: #101012;                 /* sombre : visible sur le header clair (menu fermé) */
  transition: background-color .28s ease, opacity .28s ease, transform .28s ease;
}
/* Front de vague anti-diagonal : --f = 0 (haut-gauche) -> 4 (bas-droite). */
.menu__grid i:nth-child(1) { --f: 0; }
.menu__grid i:nth-child(2), .menu__grid i:nth-child(4) { --f: 1; }
.menu__grid i:nth-child(3), .menu__grid i:nth-child(5), .menu__grid i:nth-child(7) { --f: 2; }
.menu__grid i:nth-child(6), .menu__grid i:nth-child(8) { --f: 3; }
.menu__grid i:nth-child(9) { --f: 4; }

.menu__toggle:hover .menu__grid { transform: scale(1.14); }

/* OUVERT : plus de dalle. Le panneau sombre passe derrière -> les points deviennent
   BLANCS (contraste direct). Vague ALLER (haut-gauche -> bas-droite) puis RETOUR
   (bas-droite -> haut-gauche), avant de figer la CROIX (coins + centre). */
.menu.open .menu__grid i {
  background: #fff;
  /* La lumière "s'allume" dans le sens de la vague (retard = front --f). */
  transition: background-color .28s ease calc(var(--f) * 80ms),
              transform .28s ease,
              opacity .28s ease;
  /* Vague ALLER (haut-gauche -> bas-droite) puis RETOUR (bas-droite -> haut-gauche).
     Mouvement uniquement -> proprement désactivé en reduced-motion. */
  animation:
    ledPop .30s ease-in-out calc(var(--f) * 95ms),
    ledPop .30s ease-in-out calc(780ms + (4 - var(--f)) * 95ms);
}
/* CROIX en états DIRECTS (tiennent même sans animation) :
   impairs = coins + centre (restent) ; pairs = bords (s'effacent après les vagues). */
.menu.open .menu__grid i:nth-child(odd) { transform: scale(1.15); }
.menu.open .menu__grid i:nth-child(even) {
  opacity: 0;
  transform: scale(.4);
  transition: background-color .28s ease calc(var(--f) * 80ms),
              opacity .34s ease 1.5s,       /* s'efface APRÈS le passage des deux vagues */
              transform .34s ease 1.5s;
}
@keyframes ledPop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.55); }
  100% { transform: scale(1); }
}

/* Panneau PLEIN ÉCRAN : ancré en haut-droite, il s'ouvre en deux temps
   (barre vers la gauche, puis descente). position:fixed -> couvre tout l'écran. */
.menu__panel {
  position: fixed;
  inset: 0;                              /* TOUJOURS plein écran -> zéro liseré possible */
  padding: 96px 30px 40px;
  box-sizing: border-box;
  background: rgba(20, 20, 24, .58);                     /* verre sombre translucide (laisse voir le flou) */
  -webkit-backdrop-filter: blur(26px) saturate(1.5);
  backdrop-filter: blur(26px) saturate(1.5);
  border: none;
  /* DEFILEMENT DU PANNEAU. En `overflow: hidden`, tout ce qui dépassait était
     perdu : ni la molette ni le doigt ne font défiler une boîte cachée. Le menu
     mesure ~680 px de haut ; sous cette hauteur d'écran il était donc tronqué,
     et TÉLÉPHONE EN PAYSAGE (375 à 430 px de haut) coupait 250 à 320 px, soit
     « Estimer mon potentiel », les quatre réseaux ET « Mentions légales »,
     inatteignables. Même chose sur une fenêtre de bureau de 600 px de haut.
     L'axe horizontal reste caché (rien ne doit déborder sur les côtés) et la
     barre n'apparaît que s'il y a vraiment de quoi défiler : sur un écran de
     hauteur normale, rien ne change à l'affichage.
     `overscroll-behavior: contain` empêche en prime le geste d'atteindre la page
     derrière : le fond ne dérive plus pendant qu'on lit le menu. */
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  pointer-events: none;
  z-index: 1;                            /* sous le bouton (croix reste cliquable) */
  /* La plaque de verre se POSE, elle ne se déroule plus : même geste que sur la
     landing, voir le commentaire détaillé dans styles.css à côté du même bloc.
     Le clip-path reste, mais comme simple bascule ouvert/fermé, sans transition. */
  clip-path: inset(0 0 calc(100% - 64px) 100%);
}
.menu.open .menu__panel {
  pointer-events: auto;
  clip-path: inset(0 0 0 0);             /* ouvert plein écran */
}
/* Le panneau reçoit le focus à l'ouverture (voir menu.js) : c'est un conteneur,
   pas une cible cliquable, il ne doit donc porter aucun contour. Sans cette
   ligne, le navigateur peindrait autour de lui son propre cadre de mise au
   point, soit un rectangle bleu sur tout l'écran. */
.menu__panel:focus,
.menu__panel:focus-visible { outline: none; }


/* --- Le panneau se cale sur la CARTE, pas sur la fenêtre ---------------------
   Même correction que sur la landing, avec les largeurs de CETTE carte : elle
   grandit ici dès 480 px au lieu de rester figée à 402. Voir le commentaire
   détaillé dans styles.css, à côté du même bloc. */
.menu__panel { max-width: var(--maxw); margin-inline: auto; }
@media (min-width: 480px) {
  .menu__panel { max-width: clamp(402px, 88vw, 640px); }
}
@media (min-width: 760px) {
  .menu__panel {
    max-width: min(940px, 94vw);   /* identique à .page */
    padding-inline: 32px;          /* même gouttière que le header de cette bande */
  }
}

/* Liens du menu (fondu décalé à l'ouverture) */
.menu__nav a {
  display: block;
  font-size: clamp(1.5rem, 7vw, 2.6rem);   /* fluide : proportionnel à la largeur de la fenêtre */
  font-weight: 700;
  line-height: 1.34;
  letter-spacing: -0.02em;
  color: #f4f4f6;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(8px);
  /* Même durée et même courbe que l'exception « accessibilité motion » plus bas :
     un poste qui réduit les animations et un téléphone qui ne les réduit pas
     jouent alors EXACTEMENT le même fondu, au centième près. */
  transition: opacity .45s cubic-bezier(.2, .85, .25, 1), transform .45s cubic-bezier(.2, .85, .25, 1);
}
.menu__nav a:hover { color: rgba(255, 255, 255, .55); }
.menu.open .menu__nav a { opacity: 1; transform: none; }

/* Cascade d'apparition : le retard se déduit du rang du lien (--i, posé par
   menu.js). Même correction que sur la landing, voir le commentaire détaillé
   dans styles.css : l'énumération en nth-child s'arrêtait au 5e lien des
   ressources alors qu'il y en a 7, donc « CGV » et « Confidentialité »
   n'avaient aucun retard et surgissaient avant les autres, sans fondu. */
.menu__nav      { --casc-debut: .06s; --casc-pas: .06s; }
.menu__nav--sub { --casc-debut: .44s; --casc-pas: .04s; }
.menu.open .menu__nav a {
  transition-delay: calc(var(--casc-debut) + var(--i, 0) * var(--casc-pas)) !important;
}

.menu__sep { height: 1px; background: rgba(255, 255, 255, .14); margin: 18px 0 16px; opacity: 0; transition: opacity .45s cubic-bezier(.2, .85, .25, 1); }
.menu.open .menu__sep { opacity: 1; transition-delay: .36s !important; }
.menu__label { margin: 0 0 12px; font-size: clamp(.66rem, 2.9vw, .9rem); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: rgba(255, 255, 255, .45); opacity: 0; transition: opacity .45s cubic-bezier(.2, .85, .25, 1); }
.menu.open .menu__label { opacity: 1; transition-delay: .40s !important; }
.menu__nav--sub a { font-size: clamp(1rem, 4.4vw, 1.6rem); font-weight: 500; line-height: 1.55; }

/* Signature de marque : épinglée en bas-gauche du panneau, apparaît en dernier.
   L'étoile du logo reprise en blanc (le disque noir serait invisible sur fond sombre). */
.menu__foot {
  position: absolute;
  left: 30px;                       /* aligné sur le padding latéral du panneau */
  bottom: 34px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .45s cubic-bezier(.2, .85, .25, 1), transform .45s cubic-bezier(.2, .85, .25, 1);
}
.menu.open .menu__foot { opacity: 1; transform: none; transition-delay: .72s !important; }

/* ÉCRAN COURT : la signature reprend sa place dans le flux.
   Épinglée en bas du panneau (position: absolute ; bottom: 34px), elle est
   IMPRIMÉE PAR-DESSUS les liens dès que le menu ne tient plus en hauteur.
   Mesuré : à 720 px de haut elle recouvre « Mentions légales », à 600 px
   « Instagram » et « Facebook », à 390 px (téléphone en paysage) « Questions
   fréquentes » et « Estimer mon potentiel ». Une fenêtre de portable sur un
   écran 1366×768 offre ~660 px : le cas est courant, pas marginal.
   Remise dans le flux, elle se range après le dernier lien et se lit en fin
   de défilement, sans jamais rien recouvrir.
   `min-width: 600px` : en dessous, les liens rapetissent (clamp en vw), le
   menu tient en hauteur et rien ne se chevauche : la bande mobile, qui est le
   dessin de référence, n'est donc pas touchée. */
@media (max-height: 730px) and (min-width: 600px) {
  .menu__foot { position: static; margin-top: 26px; }
}
.menu__brand { display: inline-flex; align-items: center; gap: 8px; color: #f2f2f4; }
.menu__star { width: 20px; height: 20px; display: block; }
.menu__wordmark { font-size: 1.28rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1; }
.menu__copy {
  display: block;
  margin-top: 7px;
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .01em;
  color: rgba(255, 255, 255, .38);
}


/* ---- Ligne de progression du tunnel, sous la barre du site ---- */
.evprog {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 10px var(--pad) 12px;
  transition: background-color .34s ease;
}
.evprog.is-dark { background: var(--dark-bg); }

.evprog__back {
  width: 26px; height: 26px;
  flex: none;
  display: grid;
  place-items: center;
  margin-left: -5px;
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
  border-radius: 999px;
  transition: color .34s ease;
}
.evprog__back svg { width: 17px; height: 17px; }
.evprog__back[hidden] { display: none; }
.evprog.is-dark .evprog__back { color: #f4f4f6; }

.evprog__track {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
  transition: background-color .34s ease;
}
.evprog.is-dark .evprog__track { background: rgba(255,255,255,.16); }

.evprog__bar {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--black);
  transition: width .34s cubic-bezier(.22, 1, .36, 1), background-color .34s ease;
}
.evprog.is-dark .evprog__bar { background: #f4f4f6; }

.evprog__count {
  flex: none;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
  min-width: 30px;
  text-align: right;
  transition: color .34s ease;
}
.evprog__count[hidden] { display: none; }
.evprog.is-dark .evprog__count { color: rgba(255,255,255,.5); }

/* ===================== SCÈNE ===================== */
.ev {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.step {
  display: none;
  flex-direction: column;
  flex: 1;
  padding: var(--s6) var(--pad) var(--s8);
}
.step.is-active { display: flex; }

/* Les deux groupes d'un écran de question : l'énoncé, puis les réponses.
   Sur mobile ils s'empilent et le rendu est celui d'une colonne unique ;
   sur desktop ils deviennent les deux colonnes de la carte paysage. Sans ces
   deux groupes, la grille du desktop répartissait les éléments un par cellule
   et l'ordre de lecture partait en morceaux (titre à droite, options à gauche). */
.ask__side,
.ask__main { display: flex; flex-direction: column; }
.ask__main { flex: 1; min-height: 0; }
/* Écart énoncé -> réponses : 20 px quand l'indice est là (il porte déjà sa
   marge basse), 28 px sans lui. Même valeur qu'avant l'introduction des groupes. */
.ask__side { margin-bottom: var(--s5); }
.ask__side:has(.step__hint) { margin-bottom: 0; }

/* Entrée de l'écran : glissement court. Conservé en reduced-motion
   (voir le bloc en fin de feuille) : sans lui, les questions se
   remplacent sans qu'on voie qu'on a avancé.
   Sur les écrans de question, ce sont les CONTENUS des deux groupes qui
   glissent : animer les groupes eux-mêmes empilerait deux fondus. */
.step.is-active > *,
.step.is-active > .ask__side > *,
.step.is-active > .ask__main > * { animation: step-in .34s cubic-bezier(.22, 1, .36, 1) both; }
.step.is-active > .ask__side,
.step.is-active > .ask__main { animation: none; }
.step.is-active > *:nth-child(2),
.step.is-active > .ask__side > *:nth-child(2) { animation-delay: .04s; }
.step.is-active > *:nth-child(3),
.step.is-active > .ask__main > *:first-child { animation-delay: .07s; }

@keyframes step-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.step__eyebrow {
  margin: 0 0 var(--s3);
  font-size: var(--t-eyebrow);
  font-weight: 500;
  letter-spacing: .01em;
  color: #4b4f57;   /* était #71767f : 3,14:1 sur le verre, 4,74:1 ici */
}

/* Les inversions françaises (« verrez-vous », « envoie-t-on ») se coupaient sur
   leur trait d'union en petite largeur, ce qui donnait « verrez- / vous ». */
.nb { white-space: nowrap; }

.step__q {
  margin: 0 0 var(--s2);
  font-size: 22px;
  line-height: 1.12;
  font-weight: 500;
  letter-spacing: -.03em;
  color: var(--ink);
  text-wrap: balance;
}

.step__hint {
  margin: 0 0 var(--s5);
  font-size: 14px;
  line-height: 1.4;
  color: var(--muted);
}

/* ===================== OPTIONS ===================== */
.opts {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.opt {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  min-height: 52px;
  padding: var(--s3) var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  background: #fff;
  font-family: inherit;
  font-size: var(--t-body);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -.01em;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: transform .32s cubic-bezier(.22, 1.25, .4, 1), background .18s ease, border-color .18s ease;
}
.opt:hover { background: #fafafa; border-color: #c9c9ce; }
.opt:active { transform: scale(.98); transition-duration: .09s; }

.opt.is-on {
  border-color: var(--black);
  background: var(--black);
  color: #fff;
  box-shadow: 0 4px 14px rgba(16,16,18,.12);
}
.opt.is-on .opt__sub { color: rgba(255,255,255,.62); }
.opt.is-on .opt__fig { color: #fff; }

/* Case pour les questions à choix multiples. */
.opt__box {
  flex: none;
  width: 18px; height: 18px;
  border: 1.5px solid #cfd0d4;
  border-radius: 5px;
  display: grid;
  place-items: center;
  color: #fff;
  transition: background .16s ease, border-color .16s ease;
}
.opt__box svg { width: 11px; height: 11px; opacity: 0; }
.opt.is-on .opt__box { background: #fff; border-color: #fff; color: var(--black); }
.opt.is-on .opt__box svg { opacity: 1; }

/* Schémas de visage / silhouette : le dessin fait la question. */
.opt__fig {
  flex: none;
  width: 34px; height: 40px;
  color: #c3c5ca;
  transition: color .18s ease;
}
/* Ne PAS remettre .opt.is-on ici : cette règle est plus bas dans la feuille
   que celle de l'état sélectionné, à spécificité égale : elle repeindrait
   le schéma en encre sombre sur le fond noir, donc invisible. */
.opt:hover .opt__fig { color: var(--ink); }
.opt__fig svg { width: 100%; height: 100%; }

.opt__sub {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  font-weight: 400;
  color: var(--muted);
}

/* ===================== CHAMPS ===================== */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--s3); }
.field__lab {
  font-size: var(--t-eyebrow);
  font-weight: 500;
  color: #71767f;
}
/* « facultatif » : doit se lire d'un coup d'œil, sinon le champ est perçu
   comme obligatoire et coûte des abandons qu'il n'est pas censé coûter. */
.field__opt { color: #b9bcc2; font-weight: 400; }
.field input {
  width: 100%;
  min-height: 52px;
  padding: 0 var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  background: #fff;
  font-family: inherit;
  font-size: var(--t-body);
  font-weight: 500;
  color: var(--ink);
  transition: border-color .18s ease;
}
.field input::placeholder { color: #b9bcc2; font-weight: 400; }
.field input:focus { outline: none; border-color: var(--ink); }
.field input[aria-invalid="true"] { border-color: var(--raise); }

.field__err {
  font-size: 13px;
  line-height: 1.35;
  color: var(--raise);
  min-height: 0;
}
.field__err:empty { display: none; }

.step__legal {
  margin: var(--s4) 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--faint);
}
/* La regle globale `a { color: inherit; text-decoration: none }` rendrait les
   liens de la mention legale indistinguables du gris qui les entoure : une
   information obligatoire qu'on ne peut pas atteindre n'est pas donnee. Filet
   fin, meme encre : rien n'est ajoute a la page, le lien devient cliquable a
   l'oeil. */
.step__legal a { text-decoration: underline; text-underline-offset: 2px; }

/* PIEGE A MIEL : le champ qui n'existe que pour les robots (voir la balise dans
   evaluation.html et le controle dans envoi.php).
   PAS `display: none`, et c'est tout l'interet de ces 8 lignes. Les robots un
   peu serieux sautent les champs en display:none ou hidden, precisement parce
   que c'est la facon habituelle de poser un piege. Une boite d'un pixel sortie
   de l'ecran, elle, reste un champ « visible » pour qui lit le DOM sans peindre
   la page. `left: -9999px` et non `opacity: 0` : un champ transparent reste
   cliquable et pourrait recevoir un appui au pouce.
   Les visiteurs humains, eux, sont couverts 3 fois : hors ecran, hors parcours
   clavier (tabindex="-1") et hors arbre d'accessibilite (aria-hidden). */
.miel {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Aveu d'echec d'envoi, sur l'ecran de fin. Il reprend le gabarit de .perk (le
   seul aplat d'information du tunnel) plutot que d'inventer une alerte rouge :
   ce n'est pas une erreur du visiteur, et rien de ce qu'il a fait n'est perdu. */
.done__alerte {
  margin: var(--s5) 0 0;
  padding: var(--s3) var(--s4);
  border-radius: var(--r-media);
  background: #f6f6f7;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
  text-align: left;
}
.done__alerte a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }

/* Contrepartie du numéro : ni encadré promotionnel ni couleur d'alerte :
   le registre du site est sobre, et une mécanique de promo le casserait.
   Un simple aplat gris, avec les deux chiffres en gras. */
/* Tant qu'aucun texte n'y est écrit, l'aplat gris apparaissait vide au milieu
   du formulaire : on ne dessine la boîte que si elle a quelque chose à dire. */
.perk:empty { display: none; }
.perk {
  margin: var(--s4) 0 0;
  padding: var(--s3) var(--s4);
  border-radius: var(--r-media);
  background: #f6f6f7;
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
}
.perk b { font-weight: 700; color: var(--ink); }

/* Rappel de la place tenue, sur l'écran des offres. Trait à gauche plutôt que
   fond coloré : c'est une information, pas une alarme. */
.hold {
  margin: 0 0 var(--s5);
  padding: var(--s3) var(--s4);
  border-left: 2px solid var(--ink);
  background: #f6f6f7;
  border-radius: 0 var(--r-media) var(--r-media) 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
}
.hold b { font-weight: 700; color: var(--ink); }
.hold[hidden] { display: none; }

/* ===================== BOUTONS ===================== */
.spacer { flex: 1; min-height: var(--s6); }

/* ---- Agrandissement des boutons (survol / appui) ----
   Repris tel quel de styles.css : seule la BOÎTE change de taille, le libellé
   est contre-scalé à l'exact inverse (1 / facteur), donc le texte ne bouge
   jamais. Mêmes variables, même courbe, mêmes facteurs. */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  padding: 0 var(--s5);
  border: 1px solid transparent;
  border-radius: var(--r-btn);
  font-family: inherit;
  font-size: var(--t-btn);
  font-weight: 700;
  letter-spacing: -.01em;
  cursor: pointer;

  --btn-ease:  cubic-bezier(.33, 1, .68, 1);
  --btn-hover: 1.026;
  --btn-press: .975;
  transition: transform .42s var(--btn-ease), background .3s ease, border-color .3s ease, box-shadow .3s ease;
  will-change: transform;
  backface-visibility: hidden;
  -webkit-font-smoothing: antialiased;
}
.btn__label {
  display: inline-block;
  transition: transform .42s var(--btn-ease);
  backface-visibility: hidden;
}
@media (hover: hover) {
  .btn:hover             { transform: scale(var(--btn-hover)); }
  .btn:hover .btn__label { transform: scale(calc(1 / var(--btn-hover))); }
}
.btn:active             { transform: scale(var(--btn-press)); transition-duration: .11s; }
.btn:active .btn__label { transform: scale(calc(1 / var(--btn-press))); transition-duration: .11s; }

/* État désactivé peint avec de vraies couleurs, et NON avec une opacité :
   l'animation d'entrée des écrans (.step.is-active > *, fill-mode both) fige
   opacity à 1 en fin de course et l'emporte sur toute déclaration normale.
   Une opacité posée ici serait donc silencieusement annulée. */
.btn[disabled] { pointer-events: none; box-shadow: none; }
.btn-primary[disabled] { background: #d7d8db; color: #fff; }
.btn-outline[disabled] { background: #fff; color: #c3c5ca; border-color: #eeeef0; }
/* EXCEPTION AU GRIS CI-DESSUS, et la raison tient au libellé. #C3C5CA (2,0:1)
   convient aux boutons désactivés du tunnel, dont le texte ne dit rien de plus
   que le bouton actif : « Continuer » pas encore franchissable. Celui du format
   complet est l'inverse , son libellé EST l'information. Illisible, il passe
   pour un bouton cassé. Même valeurs que dans styles.css, 5,8:1. */
.pl--complet .btn-outline[disabled] { background: #f4f4f6; color: #5c6066; border-color: #e6e6ea; }
.btn-ghost[disabled]   { color: #c3c5ca; }

.btn-primary {
  background: rgba(20, 20, 20, .92);
  color: #fff;
  box-shadow: 0 4px 14px rgba(16, 16, 18, .10);
}
.btn-primary:hover { background: var(--black); box-shadow: 0 6px 18px rgba(16, 16, 18, .16); }

.btn-outline {
  background: #fff;
  color: var(--ink);
  border-color: var(--line);
}
.btn-outline:hover { background: #fafafa; border-color: #d9d9dd; }

.btn-ghost {
  background: none;
  color: var(--muted);
  font-weight: 500;
  min-height: 40px;
}
.btn-ghost:hover { color: var(--ink); }

.btn + .btn { margin-top: var(--s2); }

/* Micro-copie sous le bouton : l'engagement réel, énoncé au moment du clic. */
.reassure {
  margin: var(--s3) 0 0;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--faint);
  text-align: center;
}

/* ===================== RÉSULTAT ===================== */
.res__eyebrow {
  margin: 0 0 var(--s3);
  font-size: 11px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: .16em;      /* = .blockers__eyebrow */
  text-transform: uppercase;
  color: var(--faint);
}

.res__head {
  margin: 0 0 var(--s4);
  font-size: var(--t-h1);
  line-height: 1.06;          /* = .blockers__title */
  font-weight: 500;
  letter-spacing: -.03em;
  text-wrap: balance;
}
.res__head b { font-weight: 700; }

.res__sub {
  margin: 0 0 var(--s6);
  font-size: var(--t-body);
  line-height: 1.4;
  color: var(--muted);
}

/* Titres à deux tons : reprend .blockers__title-dim & co. de la landing. La
   première ligne porte l'affirmation, la seconde la nuance en gris. */
.dim { color: var(--muted); font-weight: 500; }
.step--dark .dim { color: var(--dark-text); }

/* ===================== PLAQUE SOMBRE =====================
   Reprise de la section .dark de la landing : c'est la signature visuelle du
   site, et elle tombe ici au moment le plus fort du parcours (le résultat).
   Le fond va jusqu'aux bords de la carte car le padding est porté par .step. */
.step--dark { background: var(--dark-bg); position: relative; overflow: hidden; isolation: isolate; }
/* Nappes de lumière de la citation et des cartes d'avis, très atténuées : la
   plaque cesse d'être un rectangle noir plat et prend de la profondeur. */
.step--dark::before {
  content: "";
  position: absolute;
  inset: -25%;
  z-index: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: .42;
  background:
    radial-gradient(62% 50% at 26% 10%, rgba(255,255,255,.16), transparent 78%),
    radial-gradient(66% 54% at 88% 70%, rgba(202,202,202,.13), transparent 80%),
    radial-gradient(56% 46% at 54% 44%, rgba(203,203,203,.08), transparent 82%);
}
.step--dark > * { position: relative; z-index: 1; }
.step--dark .res__eyebrow { color: rgba(255,255,255,.38); }
.step--dark .res__head    { color: var(--dark-title); }
.step--dark .res__sub     { color: var(--dark-text); }
.step--dark .reassure     { color: rgba(255,255,255,.32); }

.step--dark .btn-primary {
  background: var(--dark-title);
  color: var(--dark-bg);
  box-shadow: none;
}
.step--dark .btn-primary:hover { background: #fff; }

/* ---- La liste des piliers ----
   Même gabarit que .blocker sur la landing : colonne de 54px pour le grand
   numéro, 1fr pour le texte, filet en haut. L'ordre affiché EST le protocole :
   on ne retrie jamais cette liste. */
.lev { list-style: none; margin: 0 0 var(--s7); padding: 0; }

.lev__i {
  display: grid;
  grid-template-columns: 54px 1fr;
  align-items: center;
  gap: 16px;
  padding: 15px 2px;
  border-top: 1px solid var(--dark-hair);
}

/* Grand numéro d'étape : mêmes réglages que .blocker__num, teinte inversée. */
.lev__num {
  font-size: 42px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.03em;
  color: rgba(255,255,255,.22);
  font-variant-numeric: tabular-nums;
}
/* Pilier déjà acquis : coche à la place du numéro, à la même largeur. */
.lev__num--done {
  display: flex;
  align-items: center;
  color: rgba(255,255,255,.30);
}
.lev__num--done svg { width: 20px; height: 20px; }

.lev__name {
  font-size: var(--t-body);
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--dark-title);
}
.lev__when {
  display: block;
  margin-top: 3px;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: .01em;
  color: rgba(255,255,255,.34);
}
.lev__i--on .lev__name { color: rgba(255,255,255,.34); font-weight: 500; }

/* L'unique levier expliqué en clair : le gratuit montre le résultat,
   le payant donne le chemin. */
.first {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: var(--s5);
  border-radius: 16px;
  background: rgba(255,255,255,.055);
  border: 1px solid rgba(255,255,255,.10);
  margin: 0 0 var(--s6);
  box-shadow: 0 1px 0 0 rgba(255,255,255,.07) inset;
}
.first::after {
  content: "";
  position: absolute;
  inset: -25%;
  z-index: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: .55;
  background:
    radial-gradient(40% 32% at 28% 22%, rgba(255,255,255,.30), transparent 68%),
    radial-gradient(46% 36% at 86% 76%, rgba(202,202,202,.22), transparent 70%);
}
.first > * { position: relative; z-index: 1; }
.first__lab {
  margin: 0 0 var(--s2);
  font-size: 11px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(255,255,255,.38);
}
.first__name {
  margin: 0 0 var(--s2);
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -.03em;
  line-height: 1.06;
  color: var(--dark-title);
}
.first__text {
  margin: 0;
  font-size: 15px;
  line-height: 1.45;
  color: var(--dark-text);
}

/* ===================== OFFRES ===================== */
.plans { display: flex; flex-direction: column; gap: var(--s3); margin: 0 0 var(--s5); }

.pl {
  position: relative;
  padding: var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: #fff;
}
.pl--reco { border-color: var(--black); }

/* Repris à l'identique de .plan__badge : rayon 8px, pas de pilule. */
.pl__badge {
  position: absolute;
  top: -11px;
  left: 20px;
  padding: 4px 10px;
  border-radius: 8px;
  background: var(--black);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.pl__name {
  margin: 0 0 2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--faint);
}
.pl__price {
  margin: 0 0 2px;
  font-size: 30px;
  font-weight: 500;
  letter-spacing: -.03em;
  line-height: 1.05;
}
.pl__term { margin: 0 0 var(--s3); font-size: 13px; color: var(--faint); }
.pl__cover {
  margin: 0 0 var(--s4);
  font-size: 15px;
  line-height: 1.4;
  color: var(--muted);
}
.pl__cover b { font-weight: 700; color: var(--ink); }
/* Ce qui est OFFERT, dit comme tel : bloc a part, fond distinct, pastille
   noire. Repris a l'identique de .plan__bonus sur la landing, pour que le bonus
   ait la meme forme aux 2 endroits ou l'offre se decide. */
.pl__bonus {
  margin: 0 0 var(--s4);
  padding: 13px 15px;
  border-radius: 12px;
  background: #f4f4f5;
}
.pl__bonus-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 10px;
}
.pl__bonus-lab {
  display: inline-block;
  margin: 0;
  padding: 4px 9px;
  border-radius: 8px;
  background: var(--black);
  color: #fff;
  font-size: 10px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.pl__bonus-worth {
  margin: 0;
  font-size: 12px;
  line-height: 1.3;
  font-weight: 600;
  color: var(--faint);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pl__bonus-list { margin: 0; padding: 0; }
.pl__bonus-card {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 11px 13px;
  border-radius: 10px;
  background: #fff;
}
.pl__bonus-card + .pl__bonus-card { margin-top: 25px; }
.pl__bonus-card + .pl__bonus-card::before {
  content: "+";
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 16px;
  line-height: 1;
  font-weight: 600;
  color: var(--muted);
}
.pl__bonus-name {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: 14px;
  line-height: 1.35;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
}
.pl__bonus-price {
  flex: none;
  margin: 0;
  font-size: 13px;
  line-height: 1.35;
  font-weight: 600;
  color: var(--faint);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pl__bonus-why {
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--muted);
}

.pl__pay { margin: var(--s3) 0 0; font-size: 13px; color: var(--muted); text-align: center; }
/* Voir styles.css, .plan__risk--complet : même phrase, même raison. Elle
   explique un bouton qui ne répond pas, elle ne peut pas être en retrait. */
.pl__pay--complet { color: var(--ink); font-weight: 500; }
/* Pastille d'état et non de mise en avant : gris, pas le noir de « Conseillé
   pour vous ». Reprise à l'identique de .plan__badge--complet. */
.pl__badge--complet { background: #ececed; color: #3d4046; }
.pl__pay b { font-weight: 700; color: var(--raise); }

/* Contenu détaillé de chaque offre. Le visiteur arrive ici par le
   questionnaire : il n'a pas forcément vu les listes de la landing, et ne
   doit surtout pas avoir à y retourner pour savoir ce qu'il achète. */
.pl__list {
  list-style: none;
  margin: 0 0 var(--s5);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
/* Une ligne = un résultat (en gras) + ce qu'il recouvre (en gris).
   Le catalogue exhaustif faisait onze lignes et ne se lisait plus ;
   quatre lignes hiérarchisées se parcourent en un regard. */
.pl__item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  line-height: 1.35;
  color: var(--muted);
}
.pl__item b {
  display: block;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
}
.pl__item em {
  display: block;
  margin-top: 2px;
  font-style: normal;
  font-size: 13.5px;
  line-height: 1.35;
  color: var(--muted);
}
.pl__item svg {
  flex: none;
  width: 15px; height: 15px;
  margin-top: 2px;
  color: #c3c5ca;
}
/* Ce que le Prestige ajoute : mis en avant par le contraste, pas par une couleur. */
.pl__item--plus { color: var(--ink); font-weight: 500; }
.pl__item--plus svg { color: var(--ink); }

/* ===================== FIN ===================== */
.done__ico {
  width: 46px; height: 46px;
  margin: 0 0 var(--s5);
  border-radius: 999px;
  background: var(--black);
  color: #fff;
  display: grid;
  place-items: center;
}
.done__ico svg { width: 20px; height: 20px; }

/* ===================== ACCESSIBILITÉ MOTION =====================
   Le site principal coupe TOUTES les transitions en reduced-motion.
   On garde ici les trois seules qui portent de l'information :
   sans elles, on ne voit pas qu'on a changé d'écran ni avancé. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }

  /* Même découpage qu'en haut de feuille : sur les écrans de question, ce sont
     les contenus des deux groupes qui glissent, pas les groupes. */
  .step.is-active > *,
  .step.is-active > .ask__side > *,
  .step.is-active > .ask__main > * { animation: step-in .3s cubic-bezier(.22, 1, .36, 1) both !important; }
  .step.is-active > .ask__side,
  .step.is-active > .ask__main { animation: none !important; }
  .evprog__bar { transition: width .3s cubic-bezier(.22, 1, .36, 1) !important; }
    /* Agrandissement des boutons : conservé même en reduced-motion, comme sur la
     landing (mouvement subtil, jugé confortable). Boîte + libellé, même courbe. */
  .btn, .btn__label { transition: transform .42s var(--btn-ease) !important; }
  .opt { transition: transform .3s cubic-bezier(.22, 1.25, .4, 1), background .18s ease, border-color .18s ease, color .18s ease !important; }
  /* Le signe + qui bascule en × accompagne l'ouverture du panneau : sans lui,
     il sauterait tout seul. Même exception que sur la landing. */
  .qa__i summary::after { transition: transform .3s cubic-bezier(.22, 1, .36, 1), color .2s ease !important; }
  .siteheader::before { transition: inset .34s ease, border-radius .34s ease, background-color .34s ease, box-shadow .34s ease !important; }
  /* Le menu garde son fondu d'apparition (opacité, pas déplacement) : c'est
     désormais le seul geste de son ouverture. Les retards en cascade portent
     leur propre `!important` là où ils sont définis, sinon le raccourci
     ci-dessous les remettrait à zéro et les liens surgiraient d'un bloc. */
  .menu__grid, .menu__grid i, .menu__nav a, .menu__sep, .menu__label, .menu__foot { transition: all .45s cubic-bezier(.2, .85, .25, 1) !important; }
  /* Le passage à la plaque sombre accompagne le décollement de la barre :
     coupé, la carte changerait de couleur d'un coup sec sous une pilule animée. */
  .page { transition: background-color .34s ease !important; }
  /* Dérive du fond : conservée. Elle est infiniment lente et sans à-coup, et
     c'est elle qui donne sa matière au gris ; coupée, il redevient un aplat. */
  body::before { animation: derive-a 90s ease-in-out infinite alternate !important; }
  body::after  { animation: derive-b 130s ease-in-out infinite alternate !important; }
}


/* ===================== ANCRAGE =====================
   Deux lignes : ce que coûteraient les mêmes expertises séparément, puis le
   prix d'ici. Le décompte détaillé prenait six lignes pour le même travail ;
   il reste sur la landing pour qui veut le détail. */
.anch { margin: 0 0 var(--s6); padding: 0; }
.anch__row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.anch__row dt {
  flex: 1; min-width: 0;
  font-size: 14px; line-height: 1.3;
  color: var(--faint);
}
.anch__row dd {
  flex: none; margin: 0;
  white-space: nowrap;
  font-size: 15px; line-height: 1.3;
  font-variant-numeric: tabular-nums;
  color: var(--faint);
}
/* Notre prix : pleine encre, filet supprimé. C'est le chiffre qui doit rester. */
.anch__row--us { border-bottom: 0; padding-bottom: 0; }
.anch__row--us dt { color: var(--ink); font-weight: 700; }
.anch__row--us dd { color: var(--ink); font-weight: 700; font-size: 22px; letter-spacing: -.02em; }

/* ===================== GARANTIES =====================
   La double garantie était réduite à une ligne grise de 12 px en pied d'écran.
   C'est l'élément qui renverse le risque : il remonte au niveau du prix. */
.grt {
  margin: 0 0 var(--s5);
  padding: 18px 20px;
  border-radius: 16px;
  background: #fff;
  border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(16, 16, 18, .04);
}
.grt__i {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 6px 0;
  font-size: 14.5px;
  line-height: 1.4;
  color: var(--muted);
}
.grt__i b { font-weight: 700; color: var(--ink); }
.grt__i svg { flex: none; width: 16px; height: 16px; margin-top: 3px; color: var(--ink); }

/* ===================== DESKTOP : CARTE EN PAYSAGE =====================
   Sur large écran, la colonne de 402 px laissait 600 px de vide sous cinq
   options. On reprend le parti de la maquette de référence : carte en paysage,
   énoncé à gauche, réponses à droite. Le mobile garde la colonne unique.
   Les écrans longs (résultat, offres) restent en colonne, centrés. */
@media (min-width: 760px) {
  /* La carte se centre dans l'écran. Avec `margin: 7vh auto` elle pendait en
     haut : sur un 1280x1270 il restait 653px de gris sous elle, ce qui se
     lisait comme une page inachevée. Le body devient donc une boîte flex haute
     d'un écran et la carte se pose au milieu.
     `margin: auto` et non `align-items: center` : quand la carte dépasse la
     hauteur de l'écran (écrans résultat, offres), une marge auto retombe à zéro
     et la carte repart du haut, alors qu'un centrage lui aurait coupé le crâne. */
  body {
    display: flex;
    min-height: 100dvh;
    padding: max(4vh, 20px) 0;
  }
  .page {
    /* width:100% obligatoire : devenue élément flex, la carte se dimensionne
       sur son contenu et retombait à 749px au lieu de ses 940. */
    width: 100%;
    max-width: min(940px, 94vw);
    /* Un plancher : sans lui la carte change de hauteur à chaque question et
       sautille d'un écran à l'autre puisqu'elle est maintenant centrée. */
    min-height: min(560px, 78dvh);
    margin: auto;
    /* VERRE. Le panneau ne masque plus le fond, il le laisse traverser : blanc
       à 55 % posé sur un flou d'arrière-plan très large. Le sol et ses lumières
       continuent donc de dériver DERRIÈRE le panneau, et c'est ce qui lui donne
       sa matière : un blanc plein aurait éteint tout le travail du fond.
       Réservé à ce palier : sous 760px le panneau occupe l'écran entier, il n'y
       a plus rien derrière lui à flouter, et le verre ne ferait que grisailler
       l'interface. Le mobile garde donc son blanc plein. */
    background: rgba(255, 255, 255, .55);
    -webkit-backdrop-filter: blur(64px) saturate(1.3);
    backdrop-filter: blur(64px) saturate(1.3);
  }
  /* Écrans de résultat : même verre, teinte sombre. */
  .page.is-dark { background: rgba(14, 15, 19, .72); }

  .siteheader { padding: calc(10px + env(safe-area-inset-top)) 32px 10px; }
  .evprog  { padding: 10px 32px 12px; }

  .step { padding: clamp(38px, 4vw, 56px) clamp(28px, 3.4vw, 44px) clamp(36px, 4vw, 52px); }

  /* Carte paysage : l'énoncé tient la colonne de gauche, les réponses celle de
     droite. Chaque groupe garde sa propre pile, et les deux sont centrés l'un
     en face de l'autre. */
  .step--ask.is-active {
    display: grid;
    grid-template-columns: 1fr 1.05fr;
    column-gap: clamp(34px, 5vw, 64px);
    align-items: center;
    align-content: center;
    min-height: 430px;
  }
  .step--ask .ask__side { margin-bottom: 0; }        /* l'écart est horizontal ici */
  .step--ask .ask__main { flex: none; justify-content: center; }
  /* Le ressort ne sert à plaquer le bouton en bas que sur l'écran mobile.
     Ici la colonne fait sa hauteur : il redevient un simple écart, sinon le
     bouton vient se coller à la dernière option. */
  .step--ask .ask__main .spacer { flex: none; min-height: var(--s5); }
  .step--ask .step__q { font-size: clamp(27px, 2.4vw + 9px, 34px); line-height: 1.03; }
  .step--ask .step__hint { max-width: 34ch; margin-bottom: 0; }

  /* Écrans longs : colonne lisible, centrée dans la carte élargie. */
  .step:not(.step--ask) > * { max-width: 620px; margin-left: auto; margin-right: auto; width: 100%; }
  /* Exception : la pastille de fin a un gabarit fixe. Le width:100% ci-dessus
     l'étirait en barre noire pleine largeur. On lui rend ses 46 px et on la cale
     sur le bord gauche de la colonne, comme le titre qui la suit. */
  .step:not(.step--ask) > .done__ico {
    width: 46px;
    margin-left: max(0px, calc((100% - 620px) / 2));
    margin-right: auto;
  }
  .step--dark .lev,
  .step--dark .first { max-width: 620px; }
  .plans { max-width: 620px; }

  /* Le résultat gagne en présence : titre plus grand, comme sur la landing. */
  .step--dark .res__head { font-size: clamp(30px, 2.4vw + 10px, 36px); line-height: 1.04; }
}

/* Prénom + Nom côte à côte, moitié-moitié sur toute la largeur (maquette de
   référence). Deux champs courts sur une ligne se remplissent plus vite que
   deux lignes pleines. */
.fields-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.fields-row .field { margin-bottom: var(--s3); }
/* Sous 360 px (iPhone SE), deux colonnes laissent 135 px par champ : le nom de
   famille n'y tient plus et se fait rogner. On repasse à une ligne par champ. */
@media (max-width: 359px) {
  .fields-row { grid-template-columns: 1fr; }
}

/* Justification de l'offre conseillée. Une recommandation qu'on ne motive pas
   se lit comme une vente incitative. */
.why {
  margin: 0 0 var(--s5);
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--muted);
}
.why b { font-weight: 700; color: var(--ink); }
.why:empty { display: none; }

/* ===================== FAQ AU POINT DE DÉCISION =====================
   Accordéon natif : fermé, il ne pèse que le poids de ses questions. C'est ce
   qui permet de traiter cinq objections sans rallonger l'écran. */
.qa { margin: var(--s7) 0 0; }
.qa__lab {
  margin: 0 0 var(--s3);
  font-size: 11px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
}
.qa__i { border-top: 1px solid var(--line); }
.qa__i:last-of-type { border-bottom: 1px solid var(--line); }

.qa__i summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 14px 0;
  list-style: none;
  cursor: pointer;
  font-size: 14.5px;
  line-height: 1.35;
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--ink);
}
.qa__i summary::-webkit-details-marker { display: none; }
/* Le signe bascule de + à × : même geste que la FAQ de la landing. */
.qa__i summary::after {
  content: "+";
  flex: none;
  font-size: 18px;
  line-height: 1;
  font-weight: 500;
  color: var(--faint);
  transition: transform .3s cubic-bezier(.22, 1, .36, 1), color .2s ease;
}
.qa__i[open] summary::after { transform: rotate(45deg); color: var(--ink); }
.qa__i summary:hover { color: var(--ink); }

.qa__i p {
  margin: 0 0 15px;
  padding-right: 30px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
}

/* Sortie discrète vers la projection : un lien, pas un bouton, pour ne pas
   concurrencer le CTA d'achat juste au-dessus. */
.qa__out {
  display: block;
  width: 100%;
  margin: var(--s6) 0 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--faint);
  text-align: center;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color .2s ease;
}
.qa__out:hover { color: var(--ink); }

/* ===================== PALIER INTERMÉDIAIRE =====================
   Entre le mobile et le mode paysage, la typographie sautait de 22 px à 34 px
   d'un coup. Ce bloc est en FIN de feuille à dessein : à spécificité égale,
   c'est l'ordre de source qui tranche, et les règles de base de .step__q sont
   déclarées plus haut. */
@media (min-width: 480px) {
  .step__q   { font-size: 25px; }
  .res__head { font-size: 31px; }
  .step      { padding-left: 26px; padding-right: 26px; }
}

/* ===================== PAGE DE REMERCIEMENT =====================
   merci.html : l'écran où atterrit le client au retour de Stripe. Il reprend
   tel quel le vocabulaire de l'écran de fin du tunnel (pastille noire,
   .res__head, .res__sub) : c'est le même parcours, il ne change pas de langue
   au dernier écran.

   Ce qui s'ajoute est la seule chose que le tunnel n'a pas : du temps. Une
   étape traversée doit s'effacer vite ; une arrivée a le droit de se poser.
   La mise en place est donc jouée plus lentement et dans l'ordre de lecture,
   pastille -> titre -> message -> réserve -> bouton.

   Le bloc est en FIN de feuille à dessein : il surcharge les délais posés par
   `.step.is-active > *:nth-child()`, à spécificité égale, et c'est l'ordre de
   source qui tranche. */

/* Tout sur le même axe : le texte centré, et la pastille avec lui. Sur une
   page qui n'a qu'une chose à dire, la colonne alignée à gauche du tunnel
   donnait un bloc posé de travers sous une pastille isolée.
   Le sélecteur porte 3 classes à dessein : il doit passer devant la règle du
   mode paysage qui cale la pastille sur le bord gauche de la colonne de
   620 px, et qui en porte autant. */
.step--merci { text-align: center; }
.step--merci > .done__ico.merci__ico { margin-left: auto; margin-right: auto; }

/* Centré, un paragraphe de 3 lignes montre ses bords : `balance` répartit les
   mots pour que les lignes soient de longueurs voisines. Le titre le fait
   déjà de son côté (.res__head). */
.merci__sub { text-wrap: balance; }

/* Le bouton reprend le gabarit EXACT du hero, pas une variante. Releve sur
   .hero__actions .btn : 40 px de haut, 240 px de large en bureau, rayon 14 px,
   police 15/700, padding 0 20 px. Tout le reste etait deja identique, y compris
   les 3 variables du geste (--btn-ease, --btn-hover, --btn-press) : seule la
   hauteur divergeait, 48 px herites du tunnel.

   Ces 48 px ont une raison LA-BAS et pas ici : sur un ecran de question, on
   vise le bouton au pouce, vite, des dizaines de fois ; une cible plus haute
   se touche mieux. Cette page n'a qu'un bouton et personne ne court. La regle
   ne vaut donc que pour .merci__cta : le tunnel garde ses 48 px.

   Le selecteur porte 3 classes pour passer devant `.step:not(.step--ask) > *`,
   qui impose width: 100% en mode paysage. */
.step--merci > .btn.merci__cta { min-height: 40px; }
@media (min-width: 760px) {
  /* 240 px : la valeur du hero, telle quelle. Le palier, lui, est celui de la
     CARTE (760 px) et non celui de la landing (1024 px) : c'est ici que la
     colonne se centre a 620 px, et un bouton pleine largeur de 40 px de haut y
     deviendrait une barre. Passer a 1024 px laisserait cette barre visible
     entre les deux paliers. */
  .step--merci > .btn.merci__cta { width: 240px; }
}

/* La pastille se pose : léger dépassement, puis retour au repos. `position`
   est nécessaire à l'onde ci-dessous, .done__ico ne la porte pas. */
.merci__ico { position: relative; }
.step--merci.is-active > .merci__ico {
  animation: merci-pose .52s cubic-bezier(.22, 1.2, .36, 1) both;
}
@keyframes merci-pose {
  from { opacity: 0; transform: scale(.82); }
  to   { opacity: 1; transform: none; }
}

/* L'onde : un seul passage, très pâle, entièrement contenue dans les 46 px de
   la pastille. Elle donne au moment le poids d'un évènement sans rien laisser
   derrière elle une fois retombée : pas de couleur ajoutée, pas de mécanique
   de promo, le registre du site tient. */
.merci__ico::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 1px solid var(--black);
  animation: merci-onde .9s cubic-bezier(.16, 1, .3, 1) .3s both;
}
@keyframes merci-onde {
  from { opacity: .45; transform: none; }
  to   { opacity: 0;   transform: scale(1.85); }
}

/* La coche se trace au lieu d'apparaître. stroke-dasharray et
   stroke-dashoffset sont des propriétés SVG HÉRITÉES : posées sur le <svg>,
   elles traversent le <use> jusqu'au tracé du symbole, que le CSS ne peut pas
   atteindre autrement. 20 = la longueur du tracé (6,36 + 13,44 = 19,80 unités
   du viewBox), arrondie au-dessus pour que le bout arrondi ne dépasse pas. */
.merci__check {
  stroke-dasharray: 20;
  animation: merci-trace .44s cubic-bezier(.65, 0, .35, 1) .24s both;
}
@keyframes merci-trace {
  from { stroke-dashoffset: 20; }
  to   { stroke-dashoffset: 0; }
}

/* Cascade du texte. L'animation elle-même (step-in) vient de la règle générale
   des écrans : seul le retard change, pour que la lecture suive la pose de la
   pastille au lieu de la doubler. */
.step--merci.is-active > .merci__head { animation-delay: .16s; }
.step--merci.is-active > .merci__sub  { animation-delay: .26s; }
.step--merci.is-active > .merci__conf { animation-delay: .34s; }
.step--merci.is-active > .merci__cta  { animation-delay: .42s; }

/* La réserve de confidentialité respire un peu plus que sous le formulaire :
   elle n'y est plus collée à un bouton, elle ferme le message. */
.merci__conf { margin-top: calc(var(--s5) * -1 + 4px); }

/* --- Motion réduit ---------------------------------------------------
   La feuille coupe TOUTES les animations plus haut. Exception assumée ici,
   comme le marquée et le carrousel de la landing : sur cette page, la mise en
   place EST le contenu ; coupée, il ne reste qu'un écran fixe et le client ne
   voit pas que quelque chose s'est conclu.

   Le mouvement conservé est délibérément local : tout se passe dans les 46 px
   de la pastille, plus les glissements de 10 px que les autres écrans font
   déjà. Rien ne traverse la page, rien ne clignote.
   Pour revenir en arrière : supprimer ce bloc, le reste de la page tient
   sans lui. */
@media (prefers-reduced-motion: reduce) {
  .step--merci.is-active > .merci__ico {
    animation: merci-pose .52s cubic-bezier(.22, 1.2, .36, 1) both !important;
  }
  .merci__ico::after {
    animation: merci-onde .9s cubic-bezier(.16, 1, .3, 1) .3s both !important;
  }
  .merci__check {
    animation: merci-trace .44s cubic-bezier(.65, 0, .35, 1) .24s both !important;
  }
  .step--merci.is-active > .merci__head { animation-delay: .16s !important; }
  .step--merci.is-active > .merci__sub  { animation-delay: .26s !important; }
  .step--merci.is-active > .merci__conf { animation-delay: .34s !important; }
  .step--merci.is-active > .merci__cta  { animation-delay: .42s !important; }
}
