/* Feuille de style commune aux deux pages du site.
   Extraite de index.html le 2026-08-17, quand la page d'explication et l'outil
   sont devenus deux pages distinctes : deux copies d'un même style finissent
   toujours par diverger, et le navigateur ne la télécharge maintenant qu'une fois.
   La politique de sécurité autorise style-src 'self' — voir public/_headers. */

  :root {
    /* Thème sombre par défaut — c'est l'identité du site. */
    --paper:        #07050e;
    --paper-deep:   rgba(0,0,0,.42);
    --fond-plein:   #14111f;
    --surface:      rgba(255,255,255,.045);
    --line:         rgba(255,255,255,.11);
    --line-soft:    rgba(255,255,255,.07);
    --line-champ:   rgba(255,255,255,.16);
    --ink:          #f6f4ff;
    --ink-2:        #a8a2c6;
    --ink-3:        #7f7aa0;
    --accent:       #7c5cff;
    --accent-2:     #22d3ee;
    --accent-ink:   #ffffff;
    --encre:        #22d3ee;
    --glow:         rgba(124,92,255,.20);
    --fort:         #ff4d6d;
    --moyen:        #fbbf24;
    --faible:       #a3bb80;
    --ok:           #34d399;
    --ombre:        0 1px 2px rgba(0,0,0,.4), 0 18px 44px -22px rgba(0,0,0,.8);
    --ombre-forte:  0 1px 2px rgba(0,0,0,.5), 0 40px 90px -40px rgba(88,40,255,.7);
    /* New York, le serif d'Apple : dessiné pour l'écran, plus ouvert et plus lisible
       en petit corps qu'Iowan Old Style — ce qui compte pour un public souvent âgé.
       `ui-serif` le sélectionne sur Mac et iPhone sans rien télécharger ; ailleurs,
       Charter puis Georgia prennent le relais, très proches de dessin. */
    --serif: ui-serif, "New York", Charter, Georgia, serif;
    --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    --buste: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath fill='%23000' d='M50 12c11 0 19 9 19 21s-8 24-19 24-19-12-19-24 8-21 19-21zM16 96c0-19 15-31 34-31s34 12 34 31z'/%3E%3C/svg%3E");
  }
  /* Variante claire : même énergie, fond lavande très pâle. */
  :root[data-theme="light"] {
    --paper:        #f4f2fb;
    --paper-deep:   #e9e6f6;
    --fond-plein:   #ffffff;
    --surface:      #ffffff;
    --line:         #ded9f0;
    --line-soft:    #eae7f7;
    --line-champ:   #9c93c4;
    --ink:          #15122a;
    --ink-2:        #4a4470;
    --ink-3:        #6f6894;
    --accent:       #5b34e0;
    --accent-2:     #0891b2;
    --accent-ink:   #ffffff;
    --encre:        #b02a86;
    --glow:         rgba(91,52,224,.12);
    --fort:         #d92b4e;
    --moyen:        #a9711a;
    --faible:       #55704a;
    --ok:           #12855f;
    --ombre:        0 1px 2px rgba(21,18,42,.05), 0 14px 36px -20px rgba(21,18,42,.25);
    --ombre-forte:  0 1px 2px rgba(21,18,42,.06), 0 34px 70px -34px rgba(91,52,224,.4);
  }
  * { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
  body {
    margin: 0; background: var(--paper); color: var(--ink);
    font: 16px/1.65 var(--sans); -webkit-font-smoothing: antialiased;
    /* clip, surtout pas hidden : hidden ferait du body un conteneur de défilement,
       et les timelines view() se résoudraient alors contre un élément qui ne défile pas. */
    overflow-x: clip;
  }
  /* ═══════════ le fond : trois nappes floues qui dérivent, du grain, une vignette ═══════════ */
  /* Le flou de 100 px a été remplacé par des dégradés radiaux, qui donnent le même
     halo pour rien : un filtre sur cette surface — une fois et demie la fenêtre —
     devait être recalculé dès qu'une nappe bougeait, c'est-à-dire en permanence,
     puisqu'elles dérivent sans arrêt. Les dégradés, eux, sont peints une fois. */
  /* `isolation: isolate` n'est pas décoratif ici : sans lui, le `mix-blend-mode`
     des nappes se mélange à TOUT ce qui est peint en dessous dans le contexte
     d'empilement — c'est-à-dire à la page entière. Le navigateur doit alors garder
     le texte dans la même couche composée que le décor, et il arrive qu'il ne
     l'invalide pas correctement après un redimensionnement : on voit un fantôme
     du texte précédent derrière la page. Isolé, le mélange ne concerne plus que
     les trois nappes entre elles, ce qui est le seul effet voulu. */
  .fond { position: fixed; inset: -25%; z-index: 0; pointer-events: none; isolation: isolate; }
  /* Pas de `will-change` : ces nappes tournent déjà en boucle, donc le navigateur
     leur donne sa propre couche de lui-même. Le forcer en permanence maintient une
     couche composée figée, et c'est l'autre moitié du fantôme. */
  .couche { position: absolute; mix-blend-mode: screen; }
  .c1 { width: 62vw; height: 62vw; top: -3%; left: -6%; animation: d1 24s ease-in-out infinite alternate;
        background: radial-gradient(circle closest-side, #5b34ff, #5b34ff 26%, transparent 100%); }
  .c2 { width: 52vw; height: 52vw; top: 16%; right: -7%; animation: d2 29s ease-in-out infinite alternate;
        background: radial-gradient(circle closest-side, #00b3d6, #00b3d6 24%, transparent 100%); }
  .c3 { width: 57vw; height: 57vw; bottom: -5%; left: 24%; animation: d3 34s ease-in-out infinite alternate;
        background: radial-gradient(circle closest-side, #2f2bb5, #2f2bb5 26%, transparent 100%); }
  @keyframes d1 { to { transform: translate3d(10vw, 14vh, 0) scale(1.3); } }
  @keyframes d2 { to { transform: translate3d(-12vw, 18vh, 0) scale(.82); } }
  @keyframes d3 { to { transform: translate3d(8vw, -16vh, 0) scale(1.2); } }
  :root[data-theme="light"] .fond { opacity: .5; }


  .grain, .vignette { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
  .grain {
    opacity: .32;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
  }
  :root[data-theme="light"] .grain { opacity: .14; }
  .vignette { background: radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(0,0,0,.5)); }
  :root[data-theme="light"] .vignette { display: none; }

  .colonne { position: relative; z-index: 2; max-width: 46rem; margin: 0 auto; padding: 0 1.5rem; }

  /* ═══════════ barre de progression, pilotée par le défilement ═══════════ */
  .progression {
    position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 50;
    background: var(--accent); transform: scaleX(0); transform-origin: 0 50%;
  }
  @supports (animation-timeline: scroll()) {
    .progression {
      animation: avancer linear both;
      animation-timeline: scroll(root block);
    }
  }
  @keyframes avancer { to { transform: scaleX(1); } }

  /* ═══════════════════════════ en-tête ═══════════════════════════ */
  header {
    position: sticky; top: 0; z-index: 40;
    display: flex; align-items: center; justify-content: space-between;
    padding: .45rem 0; margin-bottom: -1px;
  }
  /* La barre appartient au hero : pas de fond, pas de bandeau posé dessus.
     Et elle s'escamote dès qu'on descend — elle revient si on remonte en haut,
     puisque l'animation suit la position et non un déclencheur. */
  @supports (animation-timeline: scroll()) {
    header {
      animation: escamoter linear both;
      animation-timeline: scroll(root block);
      animation-range: 1rem 8rem;
    }
  }
  @keyframes escamoter {
    to { opacity: 0; transform: translateY(-100%); pointer-events: none; }
  }
  .barre-interne {
    max-width: 46rem; margin: 0 auto; padding: 0 1.5rem; width: 100%;
    display: flex; align-items: center; justify-content: space-between;
    /* Sans gap, « space-between » ne garantit rien : dès que les deux blocs
       remplissent la ligne, ils se touchent. Mesuré à 320 px, écart nul. */
    gap: .75rem;
  }
  .marque { display: flex; align-items: center; gap: .55rem; font-weight: 600; font-size: .88rem; letter-spacing: -.01em; }
  header .marque { min-width: 0; }   /* autorise le bloc à rétrécir sous son contenu */
  .sceau { width: 21px; height: 21px; flex: none; color: var(--accent); }

  /* Emplacement du logo : déposez public/logo.png (npm run logo) et il remplace le
     bouclier ET le nom écrit à côté — le logo les porte tous les deux (voir app.js).
     Largeur libre : on ne connaît pas le rapport de l'image et la déformer serait pire
     que pas de logo. Le plafond en vw protège l'en-tête sur un écran étroit, où un
     logo large pousserait le bouton de compte hors de l'écran. */
  .logo { height: 56px; width: auto; max-width: min(46vw, 320px);
          object-fit: contain; object-position: left center; flex: 0 1 auto; display: block;
          /* Sans min-width: 0, un img en flex refuse de descendre sous sa largeur
             intrinsèque : mesuré à 320 px, il débordait de son parent de 6 px et
             venait toucher « Se connecter ». */
          min-width: 0; }
  /* 36 px et non 42 : à 42 le logo touchait « Se connecter » sur un écran de
     375 px, sans un pixel d'écart. Mesuré, pas estimé. */
  @media (max-width: 560px) { .logo { height: 36px; max-width: min(46vw, 200px); } }
  /* Sous 360 px (iPhone SE, vieux Android), la barre est saturée : « Se connecter »
     et la bascule prennent 137 px à eux seuls. On rend 16 px en resserrant la marge
     de la barre, et on baisse le logo. Mesuré à 320 px, pas estimé. */
  @media (max-width: 360px) {
    .barre-interne { padding: 0 1rem; }
    .logo { height: 28px; max-width: 42vw; }
  }
  .nom-site { white-space: nowrap; }
  .bascule {
    border: 1px solid var(--line-champ); background: transparent; color: var(--ink-3);
    width: 33px; height: 33px; border-radius: 50%; cursor: pointer; display: grid; place-items: center;
    transition: color .2s, border-color .2s, transform .3s;
  }
  .bascule:hover { color: var(--ink); border-color: var(--ink-3); transform: rotate(-25deg); }

  /* ═══ le questionnaire sur le profil ═══
     Des lignes simples, des cibles larges : le public est souvent âgé, et une
     pastille de 14 px ne se clique pas avec des doigts qui tremblent. */
  .note-intro { margin-top: 0; }
  .question { border: 0; margin: 0 0 1.1rem; padding: 0; }
  .question legend {
    padding: 0; margin-bottom: .5rem;
    font: 500 .92rem/1.35 var(--sans); color: var(--ink-2);
  }
  .choix-liste { display: flex; flex-wrap: wrap; gap: .45rem; }
  .choix {
    display: inline-flex; align-items: center; gap: .5rem;
    /* 44 px de haut : la taille de cible recommandée. En dessous, ça se rate. */
    padding: .6rem .85rem; border-radius: .6rem; cursor: pointer;
    border: 1px solid var(--line); background: var(--paper-deep);
    font-size: .9rem; color: var(--ink-2);
    transition: border-color .15s, color .15s, background .15s;
  }
  .choix:hover { border-color: var(--ink-3); color: var(--ink); }
  .choix input { accent-color: var(--accent); width: 1rem; height: 1rem; margin: 0; flex: none; }
  /* :has est répandu depuis 2023 ; là où il manque, le bouton radio suffit à
     montrer la sélection — on perd la mise en valeur, pas la fonction. */
  .choix:has(input:checked) {
    border-color: color-mix(in srgb, var(--accent) 55%, transparent);
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    color: var(--ink);
  }
  .choix:focus-within { outline: 2px solid var(--accent-2); outline-offset: 2px; }
  @media (max-width: 560px) { .choix { width: 100%; } }

  /* ═══════════════ la page d'accueil : ce qu'on explique avant d'entrer ═══════════════ */
  .accueil-hero { padding-block: 2rem 3rem; }
  .accueil-actions {
    display: flex; align-items: center; gap: 1.1rem 1.4rem; flex-wrap: wrap; margin-top: 1.8rem;
  }
  .accueil-note { font-size: .9rem; color: var(--ink-3); }

  .etapes-accueil { padding-block: 1rem 2.6rem; }
  .etapes {
    list-style: none; margin: 0; padding: 0;
    display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  }
  .etapes li {
    border-top: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
    padding-top: .9rem;
  }
  .etapes b { display: block; font-size: 1rem; margin-bottom: .35rem; color: var(--ink); }
  .etapes span { font-size: .95rem; color: var(--ink-2); line-height: 1.6; }

  .services { padding-block: 1rem 3rem; }
  .services-intro { color: var(--ink-2); margin: 0 0 1.8rem; max-width: 52ch; }
  .service {
    border-top: 1px solid var(--line); padding: 1.4rem 0 0; margin-bottom: 1.4rem;
  }
  .service h3 {
    font: 600 1.12rem/1.3 var(--sans); margin: 0 0 .55rem;
    display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap;
  }
  .service-option {
    font: 500 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
    color: var(--ink-3); border: 1px solid var(--line); border-radius: 999px;
    padding: .28rem .55rem;
  }
  .service p { margin: 0 0 .6rem; color: var(--ink-2); line-height: 1.65; max-width: 58ch; }
  .service p:last-child { margin-bottom: 0; }
  /* Le second paragraphe porte la nuance — la garantie, la limite. Il doit se lire
     comme une note de bas de page, pas comme un argument de vente. */
  .service-detail { font-size: .93rem; color: var(--ink-3); }
  .service-detail strong { color: var(--ink-2); }

  .compte-solde {
    margin: .8rem 0 1.1rem; padding: .8rem .95rem; border-radius: .6rem;
    border: 1px solid var(--line); background: var(--paper-deep);
    display: flex; align-items: baseline; justify-content: space-between; gap: .8rem; flex-wrap: wrap;
  }
  .solde-fort { margin: 0; font: 600 1rem/1.3 var(--sans); color: var(--ink); }
  .solde-vide { margin: 0; font: 600 1rem/1.3 var(--sans); color: var(--moyen); }
  .compte-solde .dlg-note { flex-basis: 100%; margin: .2rem 0 0; }
  .lien-tarifs { color: var(--accent-2); font-size: .9rem; }

  /* ═══════════════ le premier passage et son mur ═══════════════ */
  .mur { border: 1px solid var(--line); border-radius: .9rem; padding: 1.5rem 1.4rem; }
  /* Le titre est le résultat : il doit se lire avant tout le reste. */
  .mur-titre { font: 800 clamp(1.4rem, 3.4vw, 1.8rem)/1.25 var(--sans); color: var(--ink); margin: 0 0 .4rem; }
  .mur-source { font-size: .9rem; color: var(--ink-3); margin: 0 0 1.2rem; }

  .mur-apercu {
    position: relative; border-left: 3px solid var(--moyen); margin-top: 1rem;
    background: color-mix(in srgb, var(--moyen) 7%, transparent);
    border-radius: 0 .6rem .6rem 0; padding: 1rem 1.1rem; margin-bottom: 1.1rem;
  }
  .mur-etiquette {
    display: inline-block; font: 600 .65rem/1 var(--sans);
    text-transform: uppercase; letter-spacing: .1em; color: var(--moyen); margin-bottom: .5rem;
  }
  .mur-constat { margin: 0 0 .7rem; color: var(--ink-2); line-height: 1.6; }
  .mur-citation {
    margin: 0; padding: .6rem .8rem; border-radius: .4rem;
    background: var(--paper-deep); color: var(--ink);
    font-family: var(--mono, ui-monospace, monospace); font-size: .88rem; line-height: 1.55;
  }
  .mur-reste {
    margin: 1rem 0 0; font: 600 1.02rem/1.5 var(--sans); color: var(--moyen);
  }
  .mur-liste li { margin-bottom: .3rem; }
  .mur-liste b { color: var(--ink); font-weight: 600; }
  .mur-bouton { width: 100%; justify-content: center; margin-top: .3rem; }
  .mur-prix {
    margin: .7rem 0 0; text-align: center; font-size: .85rem; color: var(--ink-3);
  }

  /* La limite passe en note de bas de bloc : dite, mais pas en travers du résultat. */
  .mur-limite {
    font-size: .84rem; color: var(--ink-3); line-height: 1.6;
    border-top: 1px solid var(--line); padding-top: .9rem; margin: 1.3rem 0 0;
  }

  .mur-suite {
    border-radius: .7rem; padding: 1.2rem 1.2rem 1.3rem;
    background: color-mix(in srgb, var(--accent) 9%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  }
  .mur-suite-titre { font: 700 1.05rem/1.3 var(--sans); color: var(--ink); margin: 0 0 .6rem; }
  .mur-liste { margin: 0 0 1.1rem; padding-left: 1.1rem; color: var(--ink-2); line-height: 1.7; font-size: .95rem; }

  /* La marque est un lien vers l'accueil : réflexe universel, et c'est souvent le
     seul moyen de sortir d'une page pour quelqu'un qui n'ose pas toucher au reste.
     Cible large et retour visuel au survol — pas de soulignement, ça reste un logo. */
  a.marque { text-decoration: none; color: inherit; border-radius: .5rem; padding: .2rem .3rem; margin: -.2rem -.3rem; transition: opacity .15s; }
  a.marque:hover { opacity: .78; }
  a.marque:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

  /* ═══════════════ la recherche d'image, guidée ═══════════════ */
  .guide-etapes { margin: 1.2rem 0 0; padding-left: 1.3rem; }
  .guide-etapes li { margin-bottom: 1.2rem; color: var(--ink-2); }
  .guide-etapes b { display: block; color: var(--ink); font-weight: 600; margin-bottom: .25rem; }
  .guide-etapes span { display: block; line-height: 1.6; font-size: .95rem; }
  .guide-moteurs { display: grid; gap: .55rem; margin-top: .8rem; }
  .guide-moteur {
    display: block; text-decoration: none; padding: .8rem .95rem;
    border: 1px solid var(--line); border-radius: .6rem; background: var(--paper-deep);
    transition: border-color .15s, transform .15s;
  }
  .guide-moteur:hover { border-color: var(--accent); transform: translateX(2px); }
  .guide-moteur b { color: var(--accent-2); margin-bottom: .15rem; }
  .guide-moteur span { color: var(--ink-3); font-size: .88rem; }
  /* Les réponses sont des boutons, pas des liens : même allure, mais ils agissent
     sur le rapport au lieu d'ouvrir un onglet. */
  .guide-reponse { width: 100%; text-align: left; cursor: pointer; font: inherit; }
  .guide-reponse b { color: var(--ink); }
  .guide-reponse[aria-pressed="true"] {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, var(--paper-deep));
  }
  .guide-reponse[aria-pressed="true"] b::after { content: " ✓"; color: var(--accent-2); }


  /* La case de renoncement au droit de rétractation. Elle doit se lire, pas se
     survoler : le texte est en taille normale, pas en note de bas de page. Une
     mention légale qu'on ne peut pas lire ne vaut rien devant un juge. */
  .renonciation {
    display: flex; gap: .75rem; align-items: flex-start;
    margin: 1.4rem 0 0; padding: .95rem 1.1rem;
    border: 1px solid var(--line); border-radius: 12px; background: var(--paper-deep);
    cursor: pointer; max-width: 44rem;
  }
  .renonciation input { margin-top: .18rem; flex: none; width: 1.05rem; height: 1.05rem; accent-color: var(--accent); }
  .renonciation span { color: var(--ink-2); font-size: .88rem; line-height: 1.6; }

  /* ═══════════════ pages légales ═══════════════ */
  .texte-legal { padding-block: 1.5rem 3rem; max-width: 44rem; }
  .texte-legal h1 { font: 800 clamp(1.7rem,4vw,2.3rem)/1.2 var(--sans); margin: 0 0 1.4rem; }
  .texte-legal h2 { font: 700 1.05rem/1.35 var(--sans); margin: 2rem 0 .6rem; color: var(--ink); }
  .texte-legal p { color: var(--ink-2); line-height: 1.75; margin: 0 0 .9rem; }
  .texte-legal a { color: var(--accent-2); }
  .texte-legal code {
    font-family: var(--mono, ui-monospace, monospace); font-size: .85em;
    background: color-mix(in srgb, var(--moyen) 18%, transparent);
    color: var(--ink); padding: .12rem .4rem; border-radius: .3rem;
  }
  .avis-incomplet {
    border: 1px solid color-mix(in srgb, var(--moyen) 45%, transparent);
    background: color-mix(in srgb, var(--moyen) 9%, transparent);
    border-radius: .7rem; padding: 1rem 1.1rem; margin-bottom: 1.8rem;
  }
  .fiche { margin: 0 0 1rem; display: grid; grid-template-columns: minmax(9rem,14rem) 1fr; gap: .45rem 1.2rem; }
  .fiche dt { color: var(--ink-3); font-size: .9rem; }
  .fiche dd { margin: 0; color: var(--ink-2); }
  @media (max-width: 560px) { .fiche { grid-template-columns: 1fr; gap: .1rem .6rem; } .fiche dd { margin-bottom: .6rem; } }

  /* ═══════════════ tarifs ═══════════════ */
  .titre-tarifs { max-width: 20ch; }
  .offres { padding-block: 1rem 2rem; }
  .grille-offres {
    display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  }
  .offre {
    position: relative; border: 1px solid var(--line); border-radius: .9rem;
    padding: 1.3rem 1.2rem; background: var(--paper-deep);
    display: flex; flex-direction: column; gap: .35rem;
  }
  .offre h3 { font: 600 1rem/1.3 var(--sans); margin: 0; color: var(--ink-2); }
  .offre-prix { font: 800 1.9rem/1 var(--sans); color: var(--ink); margin: .3rem 0 0; }
  .offre-detail { font-size: .88rem; color: var(--ink-3); margin: 0 0 .8rem; }
  .offre button { margin-top: auto; width: 100%; justify-content: center; }
  .offre-marque {
    position: absolute; top: -.6rem; left: 1.1rem;
    font: 600 .65rem/1 var(--sans); text-transform: uppercase; letter-spacing: .08em;
    background: var(--accent); color: #fff; padding: .32rem .55rem; border-radius: 999px;
  }

  .offres-details { padding-block: 1rem 3rem; }
  .liste-compris { margin: 0; padding-left: 1.1rem; color: var(--ink-2); line-height: 1.75; max-width: 58ch; }
  .liste-compris strong { color: var(--ink); }

  /* ═══════════════════════════ hero ═══════════════════════════ */
  .hero { padding-block: 1.2rem 2.4rem; position: relative; }
  .hero > * { position: relative; z-index: 1; }
  /* Parallaxe : trois plans qui remontent à des vitesses différentes. */
  @supports (animation-timeline: scroll()) {
    .oeil { animation: plan-rapide linear both; }
    h1 { animation: plan-lent linear both; }
    .chapo { animation: plan-moyen linear both; }
    .oeil, h1, .chapo {
      animation-timeline: scroll(root block);
      animation-range: 0 90vh;
    }
  }
  @keyframes plan-lent   { to { transform: translateY(1.6rem); opacity: .35; } }
  @keyframes plan-moyen  { to { transform: translateY(2.6rem); opacity: .25; } }
  @keyframes plan-rapide { to { transform: translateY(3.6rem); opacity: .2; } }

  .oeil {
    display: inline-flex; align-items: center; gap: .5rem;
    font: 600 .7rem/1 var(--sans); letter-spacing: .12em; text-transform: uppercase;
    color: var(--accent-2); background: color-mix(in srgb, var(--accent-2) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent-2) 30%, transparent);
    padding: .34rem .7rem .34rem .55rem; border-radius: 999px; margin-bottom: 1.1rem;
  }
  .oeil svg { width: 13px; height: 13px; }
  h1 {
    font-family: var(--sans); font-weight: 800; font-size: clamp(1.85rem, 4.6vw, 2.7rem);
    /* 1.02 faisait se toucher les accents du bas et les jambages du haut. */
    line-height: 1.14; letter-spacing: -.025em; margin: 0 0 .8rem; text-wrap: balance; max-width: 22ch;
  }
  h1 em {
    font-style: normal;
    background: linear-gradient(102deg, var(--accent), var(--accent-2) 55%, var(--ok));
    -webkit-background-clip: text; background-clip: text; color: transparent;
    background-size: 220% 100%; animation: glisse 7s ease-in-out infinite alternate;
  }
  @keyframes glisse { to { background-position: 100% 0; } }
  .chapo { font-size: 1.04rem; color: var(--ink-2); margin: 0 0 1.5rem; max-width: 33rem; }
  .cta {
    display: inline-flex; align-items: center; gap: .55rem;
    color: var(--ink); text-decoration: none; font-weight: 600; font-size: .95rem;
    border-bottom: 1px solid var(--line); padding-bottom: .3rem;
    transition: border-color .25s, gap .25s;
  }
  .cta:hover { border-bottom-color: var(--accent); gap: .85rem; }
  .cta svg { width: 15px; height: 15px; color: var(--accent); }

  /* ═══════════════ manifeste : la phrase qui porte tout ═══════════════ */
  .manifeste { padding-block: 4rem 5rem; }
  @supports (animation-timeline: view()) {
    .manifeste p {
      animation: monter linear both;
      animation-timeline: view();
      animation-range: entry 18% cover 28%;
    }
  }
  .manifeste p {
    font-family: var(--serif); font-size: clamp(1.4rem, 4vw, 1.9rem); line-height: 1.35;
    letter-spacing: -.015em; margin: 0; color: var(--ink-2); max-width: 34rem;
  }
  .manifeste strong { font-weight: 400; color: var(--ink); }
  .manifeste .surligne {
    color: var(--ink); background-image: linear-gradient(transparent 62%, color-mix(in srgb, var(--encre) 26%, transparent) 0);
    background-repeat: no-repeat; background-size: 0% 100%;
  }
  @supports (animation-timeline: view()) {
    .manifeste .surligne {
      animation: surligner linear both;
      animation-timeline: view();
      animation-range: entry 42% cover 42%;
    }
  }
  @keyframes surligner { to { background-size: 100% 100%; } }

  /* ═══════════════════════ les scénarios ═══════════════════════ */
  .scenarios { padding-bottom: 5rem; }
  .titre-section {
    font: 600 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .14em;
    color: var(--ink-3); margin: 0 0 2rem; display: flex; align-items: center; gap: 1rem;
  }
  .titre-section::after {
    content: ""; flex: 1; height: 1px; background: var(--line);
    transform: scaleX(0); transform-origin: 0 50%;
  }
  @supports (animation-timeline: view()) {
    .titre-section::after {
      animation: tracer linear both;
      animation-timeline: view();
      animation-range: entry 30% cover 30%;
    }
  }
  @keyframes tracer { to { transform: scaleX(1); } }
  .fiche {
    display: grid; grid-template-columns: 3.2rem 1fr; gap: 1.2rem;
    padding: 1.6rem 0; border-top: 1px solid var(--line-soft);
  }
  .fiche:last-child { border-bottom: 1px solid var(--line-soft); }
  .fiche-num { font: 400 .82rem/1.9 var(--mono); color: var(--encre); letter-spacing: .04em; }
  .fiche h3 { font: 400 1.22rem/1.3 var(--serif); margin: 0 0 .4rem; letter-spacing: -.012em; }
  .fiche p { margin: 0; color: var(--ink-2); font-size: .93rem; }
  /* Révélation au défilement. Deux mécanismes, dans cet ordre :
     — CSS piloté par le défilement quand le navigateur sait faire (Chrome, Edge) :
       la révélation suit exactement la position, pas un déclencheur ;
     — IntersectionObserver ailleurs (Safari, Firefox), via la classe .vu.
     La classe .reveal est dans le HTML et un <style> dans <noscript> la neutralise :
     sans JavaScript ni défilement piloté, tout reste visible. */
  .reveal { opacity: 0; transform: translateY(1.6rem); }
  .reveal.vu {
    opacity: 1; transform: none;
    transition: opacity .65s cubic-bezier(.2,.7,.3,1), transform .65s cubic-bezier(.2,.7,.3,1);
  }
  @supports (animation-timeline: view()) {
    .reveal {
      animation: monter linear both;
      animation-timeline: view();
      animation-range: entry 20% cover 30%;
    }
  }
  @keyframes monter {
    from { opacity: 0; transform: translateY(1.6rem); }
    to   { opacity: 1; transform: none; }
  }


  /* ═══════════════ la séquence : le défilement joue la conversation ═══════════════
     Sans prise en charge du défilement piloté (Safari, Firefox), tout reste
     simplement visible en flux normal : la démonstration se lit, elle ne s'anime pas. */
  .sequence { position: relative; padding-block: 2rem 4rem; }
  .sequence-ecran { max-width: 46rem; margin: 0 auto; padding: 0 1.5rem; }
  .sequence-titre {
    font: 600 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .14em;
    color: var(--ink-3); margin-bottom: 1.1rem; display: flex; align-items: center; gap: 1rem;
    flex: none;
  }
  .sequence-titre::after { content: ""; flex: 1; height: 1px; background: var(--line); }
  /* La scène est un espace en profondeur : chaque message vit à sa propre distance
     et sous son propre angle, puis vient vers le lecteur quand il se révèle.
     Aucune bibliothèque — la perspective CSS suffit. */
  .scene {
    display: grid; grid-template-columns: 1fr; gap: .4rem;
    transform-style: preserve-3d;
  }
  .scene > * { transform-style: preserve-3d; }

  .msg {
    max-width: 84%; padding: .55rem .85rem; border-radius: 13px;
    font-size: .88rem; line-height: 1.45; position: relative;
  }
  .msg b { display: block; font-size: .72rem; letter-spacing: .04em; opacity: .6; margin-bottom: .2rem; }
  .msg.lui { background: var(--surface); border: 1px solid var(--line); justify-self: start; border-bottom-left-radius: 4px; }
  .msg.moi { background: color-mix(in srgb, var(--accent) 12%, transparent); justify-self: end; border-bottom-right-radius: 4px; }
  .msg.marque { border-color: var(--fort); box-shadow: 0 0 0 1px var(--fort); }

  .anno {
    justify-self: start; max-width: 90%; margin: .1rem 0 .35rem 1rem;
    padding: .55rem .8rem; border-left: 2px solid var(--fort); border-radius: 0 10px 10px 0;
    background: color-mix(in srgb, var(--fort) 7%, transparent);
    font-size: .82rem; line-height: 1.45; color: var(--ink-2);
  }
  .anno strong { color: var(--fort); font-weight: 600; display: block; font-size: .66rem;
                 text-transform: uppercase; letter-spacing: .09em; margin-bottom: .2rem; }
  .sequence-fin {
    margin-top: 1rem; padding: .9rem 1.1rem; border-radius: 14px;
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--fort) 40%, var(--line));
    box-shadow: var(--ombre);
    display: flex; align-items: center; gap: 1.1rem; flex-wrap: nowrap;
  }
  /* La note est le seul chiffre de toute la page : elle doit se lire d'un coup d'œil,
     sans qu'on ait à la chercher. */
  .sequence-fin .note {
    font: 700 2.4rem/1 var(--sans); color: var(--fort);
    font-variant-numeric: tabular-nums; flex: none;
    display: flex; align-items: baseline; gap: .12rem;
  }
  .sequence-fin .note::after {
    content: "/100"; font: 600 .82rem/1 var(--sans);
    color: color-mix(in srgb, var(--fort) 60%, transparent);
  }
  .sequence-fin p { margin: 0; font-size: .9rem; line-height: 1.55; color: var(--ink-2); flex: 1 1 12rem; }

  @supports (animation-timeline: view()) {
    .sequence { height: 440vh; view-timeline: --seq block; padding-block: 0; }
    .sequence-ecran {
      position: sticky; top: 0; height: 100vh;
      display: flex; flex-direction: column; justify-content: center;
      perspective: 1100px; perspective-origin: 50% 45%;
      /* Isole le rendu de la séquence du reste de la page. */
      contain: layout paint;
      /* Sans ce clip, un contenu plus haut que l'écran déborde par le haut ET par le
         bas d'un conteneur centré, et vient se superposer aux sections voisines. */
      overflow: hidden;
    }
    .scene > *, .sequence-fin { opacity: 0; }
    .scene > *, .sequence-fin { animation: surgir linear both; animation-timeline: --seq; }
    .m1  { animation-range: cover  5% cover 11%; }
    .m2  { animation-range: cover 13% cover 18%; }
    .a1  { animation-range: cover 20% cover 25%; }
    .m3  { animation-range: cover 27% cover 32%; }
    .m4  { animation-range: cover 34% cover 39%; }
    .a2  { animation-range: cover 41% cover 46%; }
    .m5  { animation-range: cover 48% cover 52%; }
    .m6  { animation-range: cover 54% cover 59%; }
    .a3  { animation-range: cover 61% cover 67%; }
    /* Le bloc final monte sur place, sans profondeur. Avec la perspective ancrée à
       45 % de hauteur, un départ à -420px en Z le tirait vers le haut pendant son
       entrée et il passait par-dessus la dernière annotation. */
    .sequence-fin {
      animation-name: surgir-fin;
      /* Toute la séquence a été resserrée pour finir avant 80 % : au-delà, l'écran
         collant commence à défiler vers le haut, et la note — la chute de la
         démonstration — n'atteignait l'opacité pleine qu'une fois sortie du champ.
         Mesuré : elle était encore à 0,50 quand la section se terminait. */
      animation-range: cover 70% cover 78%;
    }
  }
  /* La 3D est dans le TRAJET, jamais dans la position d'arrivée. Un texte figé de
     travers est moins lisible et donne l'air d'un accident ; ici chaque bulle vient
     du fond en tournant, puis se pose parfaitement droite et alignée. */
  /* Même arrivée que le reste, mais strictement verticale : pas de translation en
     profondeur, donc aucune dérive à l'écran. */
  @keyframes surgir-fin {
    from { opacity: 0; transform: translateY(1.1rem); }
    to   { opacity: 1; transform: none; }
  }

  @keyframes surgir {
    from {
      opacity: 0;
      transform: translate3d(var(--dx, 0), 1.4rem, -420px)
                 rotateY(var(--ry, 0deg)) rotateX(var(--rx, 0deg)) scale(.94);
    }
    to {
      opacity: 1;
      transform: translate3d(0, 0, 0) rotateY(0deg) rotateX(0deg) scale(1);
    }
  }
  /* Chaque bulle a sa distance et son angle : sans ça, tout arriverait au même
     endroit et l'espace paraîtrait plat malgré la perspective. */
  .m1 { --dx: -2rem; --ry: 26deg;  --rx: -6deg; }
  .m2 { --dx:  2.4rem; --ry: -30deg; --rx:  5deg; }
  .a1 { --dx: -1.6rem; --ry: 22deg;  --rx: -4deg; }
  .m3 { --dx:  2rem; --ry: -24deg; --rx:  6deg; }
  .m4 { --dx: -2.6rem; --ry: 28deg;  --rx: -5deg; }
  .a2 { --dx:  1.8rem; --ry: -20deg; --rx:  4deg; }
  .m5 { --dx: -2rem; --ry: 24deg;  --rx: -6deg; }
  .m6 { --dx:  2.4rem; --ry: -26deg; --rx:  5deg; }
  .a3 { --dx: -1.8rem; --ry: 20deg;  --rx: -4deg; }
  /* Sur téléphone, on retire la profondeur : c'est le calcul le plus lourd, sur
     les appareils les moins puissants, et pour le public le plus fragile. */
  @media (max-width: 760px) {
    .sequence-ecran { perspective: none; }
    .scene, .scene > * { transform-style: flat; }
    .scene > *, .sequence-fin { --dx: 0; --ry: 0deg; --rx: 0deg; }
  }
  @media (max-width: 560px) {
    .msg { max-width: 94%; font-size: .84rem; padding: .5rem .75rem; }
    .anno { max-width: 97%; margin-left: .5rem; font-size: .78rem; padding: .5rem .7rem; }
    .scene { gap: .3rem; }
  }
  /* Écrans peu hauts (portables 13", téléphones paysage) : dernier cran de resserrement. */
  @media (max-height: 780px) {
    .msg { font-size: .82rem; padding: .45rem .75rem; line-height: 1.4; }
    .anno { font-size: .76rem; padding: .45rem .7rem; line-height: 1.4; }
    .scene { gap: .28rem; }
    .sequence-titre { margin-bottom: .7rem; }
    .sequence-fin { margin-top: .7rem; padding: .7rem .9rem; }
    .sequence-fin p { font-size: .8rem; }
  }

  /* ═══════════════════════ l'outil ═══════════════════════ */
  .outil { position: relative; z-index: 2; scroll-margin-top: 4.5rem; }
  .champ { margin-bottom: 1.05rem; }
  .etiq { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: .5rem; }
  label { font-weight: 600; font-size: .82rem; }
  .indice { font-weight: 400; color: var(--ink-3); font-size: .8rem; }
  .compteur { font: 400 .72rem/1 var(--mono); color: var(--ink-3); font-variant-numeric: tabular-nums; }
  .boite {
    background: color-mix(in srgb, var(--paper) 55%, transparent);
    border: 1px solid var(--line-champ); border-radius: 18px;
    box-shadow: var(--ombre); transition: border-color .2s, box-shadow .3s;
    /* `backdrop-filter` retiré. Il échantillonne ce qui est peint DERRIÈRE, et sur
       cette page le derrière est fait de trois nappes en `mix-blend-mode` animées
       en boucle. C'est la combinaison qui produit, sur certaines cartes graphiques,
       un fond figé sur une image ancienne — un « fantôme » de la page précédente.
       Sur un fond aussi sombre, le flou ne se voyait de toute façon presque pas :
       on échange un effet imperceptible contre une classe entière de bugs. */
  }
  .boite:hover { box-shadow: var(--ombre-forte); }
  .boite:focus-within {
    border-color: var(--accent); box-shadow: var(--ombre-forte);
    outline: 2px solid var(--accent); outline-offset: 2px;
  }
  input[type=text], input[type=email], input[type=password], textarea {
    width: 100%; border: 0; background: transparent; color: var(--ink);
    font: inherit; padding: .9rem 1.05rem; border-radius: 16px; resize: vertical; display: block;
  }
  input::placeholder, textarea::placeholder { color: var(--ink-3); opacity: 1; }
  input:focus, textarea:focus { outline: none; }
  /* 1rem minimum : en dessous, Safari iOS zoome de force sur le champ. */
  textarea { min-height: 8rem; font: 400 1rem/1.7 var(--mono); letter-spacing: -.005em; }
  .actions { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; }
  .primaire {
    position: relative; overflow: hidden; text-decoration: none;
    background: linear-gradient(100deg, var(--accent), #b14cff 45%, var(--accent-2));
    background-size: 200% 100%;
    color: #fff; border: 0; border-radius: 999px;
    padding: 1rem 2.1rem; font: 800 1.05rem var(--sans); cursor: pointer;
    display: inline-flex; align-items: center; gap: .6rem;
    transition: transform .15s, box-shadow .25s, opacity .2s;
    box-shadow: 0 16px 40px -16px rgba(124,92,255,.95);
  }
  /* Sans taille explicite, une icône sans attributs width/height s'étale à sa
     taille par défaut — ce qui déformait le bouton dès qu'il devenait un lien. */
  .primaire svg { width: 1.05em; height: 1.05em; flex: none; }
  .primaire { white-space: nowrap; }
  .primaire:hover:not(:disabled) { background-position: 100% 0; transform: translateY(-1px); }
  .primaire::after {
    content: ""; position: absolute; inset: 0; transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.35), transparent);
    animation: brille 5s 2s ease-in-out infinite;
  }
  @keyframes brille { 0%, 72% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
  .primaire:disabled { opacity: .6; cursor: default; }
  button.lien {
    background: none; border: 0; padding: .5rem 0; color: var(--ink-3); cursor: pointer;
    font: 400 .88rem var(--sans); text-decoration: underline; text-underline-offset: 3px;
    text-decoration-color: var(--line); transition: color .2s;
  }
  button.lien:hover { color: var(--ink); }
  .rotation { animation: tourne 1s linear infinite; }
  @keyframes tourne { to { transform: rotate(360deg); } }

  /* ═══ analyse de la photo : un balayage sur l'image envoyée ═══ */
  .scan-photo {
    position: relative; width: 132px; aspect-ratio: 1; flex: none;
    border-radius: 16px; overflow: hidden; border: 1px solid var(--line-champ);
    background: var(--paper-deep);
  }
  .scan-photo img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: .55; }
  .scan-photo .trame {
    position: absolute; inset: 0;
    background-image: radial-gradient(var(--accent-2) 1px, transparent 1.2px);
    background-size: 9px 9px; opacity: .25;
  }
  .scan-photo .rayon {
    position: absolute; left: -10%; right: -10%; height: 2px; border-radius: 2px;
    background: linear-gradient(90deg, transparent, var(--accent-2), transparent);
    box-shadow: 0 0 20px 5px color-mix(in srgb, var(--accent-2) 55%, transparent);
    animation: balayer 2.4s ease-in-out infinite;
  }
  @keyframes balayer { 0%,100% { top: 0; } 50% { top: 100%; } }
  .scan-photo .cadre-visee {
    position: absolute; inset: 8px; border-radius: 10px;
    border: 1px solid color-mix(in srgb, var(--accent-2) 40%, transparent);
    animation: viser 2.4s ease-in-out infinite;
  }
  @keyframes viser { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
  .attente-photo { display: flex; align-items: center; gap: 1.3rem; padding: 1.6rem 0; flex-wrap: wrap; }
  .attente-photo .colonne-texte { flex: 1 1 14rem; }
  .attente-photo .etape-photo { font-size: .95rem; color: var(--ink-2); margin: 0 0 .4rem; }
  .attente-photo .sous-etape { font-size: .84rem; color: var(--ink-3); margin: 0; }

  .attente { display: flex; align-items: center; gap: .8rem; color: var(--ink-3); font-size: .92rem; padding: 2.5rem 0; }
  .points { display: inline-flex; gap: 4px; }
  .points i { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); animation: respire 1.3s ease-in-out infinite; }
  .points i:nth-child(2) { animation-delay: .18s; }
  .points i:nth-child(3) { animation-delay: .36s; }
  @keyframes respire { 0%,100% { opacity: .25; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }

  /* ═══════════════════════ le rapport ═══════════════════════ */
  #sortie { padding-top: 1rem; scroll-margin-top: 5rem; }
  .bloc {
    background: linear-gradient(180deg, var(--surface), rgba(255,255,255,.012));
    border: 1px solid var(--line); border-radius: 22px;
    padding: 1.9rem; margin-bottom: 1.1rem; box-shadow: var(--ombre);
    transition: border-color .3s;
    animation: paraitre .55s cubic-bezier(.2,.7,.3,1) backwards;
  }
  @keyframes paraitre { from { opacity: 0; transform: translateY(16px) scale(.99); } }
  .bloc h2 {
    font: 600 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .13em;
    color: var(--ink-3); margin: 0 0 1.2rem;
  }
  /* ── le relief de la carte de résultat ─────────────────────────────────
     Une inclinaison qui suit le curseur, et trois plans qui se décollent : le
     chiffre devant, la jauge un peu en arrière, le reste au fond. Volontairement
     retenu — 5 degrés au maximum. Un rapport qui annonce peut-être une arnaque
     n'est pas un jouet, et une carte qui gigote donnerait envie de la refermer.

     Rien de tout ceci ne bouge si la personne a demandé moins d'animations, ni sur
     un écran tactile où il n'y a pas de curseur à suivre. */
  .carte-relief {
    /* Le chiffre flotte au-dessus du bord : rien ne doit le rogner. */
    overflow: visible;
    transform-style: preserve-3d;
    transform:
      perspective(1100px)
      rotateX(calc(var(--inclinaison-x, 0) * 1deg))
      rotateY(calc(var(--inclinaison-y, 0) * 1deg));
    transition: transform .5s cubic-bezier(.2,.8,.2,1), box-shadow .5s;
    will-change: transform;
  }
  .carte-relief[data-survol] {
    transition: transform .12s linear, box-shadow .12s linear;
    box-shadow:
      0 1px 2px rgba(0,0,0,.4),
      calc(var(--inclinaison-y, 0) * -1.6px) calc(var(--inclinaison-x, 0) * 1.6px) 26px -14px rgba(0,0,0,.85),
      0 34px 70px -34px var(--glow);
  }
  .carte-relief .verdict-tete { transform-style: preserve-3d; transform: translateZ(30px); }
  .carte-relief .jauge,
  .carte-relief .jauge-zones { transform: translateZ(24px); }
  .carte-relief .puces-gravite { transform: translateZ(14px); }
  .carte-relief .resume,
  .carte-relief .avertissement { transform: translateZ(6px); }

  /* ── le chiffre en lévitation ──────────────────────────────────────────
     Trois choses font qu'un objet paraît flotter, et il les faut toutes les trois :

       1. il est plus près de l'œil que ce qui l'entoure  → translateZ(90px), soit
          trois fois le titre ; en s'inclinant, la carte le décale davantage que le
          reste, et c'est cette parallaxe que le cerveau lit comme de la hauteur ;
       2. il projette une ombre SUR la surface d'en dessous  → ::after, remis au ras
          de la carte par un translateZ négatif de la même valeur ;
       3. il ne tient pas parfaitement immobile  → une oscillation de 5 px sur 7
          secondes, assez lente pour qu'on ne la surprenne jamais en train de bouger. */
  .carte-relief .verdict-chiffre {
    position: relative; transform-style: preserve-3d;
    transform: translateZ(150px);
    animation: leviter 6s ease-in-out infinite;
  }
  /* 150 px et une oscillation de 14 px : à 90 px et 5 px, la lévitation était une
     intention plus qu'un effet. Ici le chiffre se décale nettement plus vite que la
     carte quand on la tourne, et c'est ce décalage qui fait la hauteur. */
  /* Un ballon ne monte pas rigide : il s'étire en s'élevant et se tasse en
     redescendant. Trois pour cent suffisent — au-delà, les chiffres se déforment
     visiblement et l'objet devient élastique au lieu d'être gonflé. */
  @keyframes leviter {
    0%   { transform: translateZ(150px) translateY(0) rotateY(0deg) scale(1, 1); }
    30%  { transform: translateZ(150px) translateY(-10px) rotateY(-1.6deg) scale(.975, 1.03); }
    55%  { transform: translateZ(150px) translateY(-14px) rotateY(-2.5deg) scale(1, 1); }
    80%  { transform: translateZ(150px) translateY(-5px) rotateY(-1deg) scale(1.025, .972); }
    100% { transform: translateZ(150px) translateY(0) rotateY(0deg) scale(1, 1); }
  }
  /* Le halo de couleur, juste derrière le chiffre. */
  .carte-relief .verdict-chiffre::before,
  .carte-relief .verdict-chiffre::after { pointer-events: none; }
  .carte-relief .verdict-chiffre::before {
    content: ""; position: absolute; inset: -45% -30%;
    background: radial-gradient(closest-side, currentColor, transparent 72%);
    filter: blur(22px); opacity: .34;
    border-radius: 50%; z-index: -1; transform: translateZ(-12px);
    animation: allumer 1.8s cubic-bezier(.2,.8,.2,1) backwards;
  }
  /* La trace au ras de la carte. C'est elle qui donne la hauteur : sans elle, le
     chiffre est simplement gros.

     Sur fond sombre, une ombre noire ne se voit pas — la carte est déjà presque
     noire. On projette donc l'inverse : une flaque de LUMIÈRE, dans la couleur du
     verdict, comme celle que laisserait un objet lumineux suspendu au-dessus d'une
     table. Le thème clair, lui, reçoit une vraie ombre. */
  .carte-relief .verdict-chiffre::after {
    content: ""; position: absolute;
    left: 2%; right: 2%; bottom: -14%; height: 62%;
    background: radial-gradient(closest-side, currentColor, transparent 76%);
    filter: blur(16px); opacity: .2; z-index: -2;
    transform: translateZ(-150px) scale(1.1);
    animation: trace-leviter 7s ease-in-out infinite;
  }
  /* La trace s'élargit et pâlit quand le chiffre monte — comme une vraie. */
  @keyframes trace-leviter {
    0%, 100% { opacity: .26; transform: translateZ(-150px) scale(1.02); }
    50%      { opacity: .12; transform: translateZ(-150px) scale(1.34); }
  }
  :root[data-theme="light"] .carte-relief .verdict-chiffre::after {
    background: radial-gradient(closest-side, rgba(30,20,70,.42), transparent 76%);
    filter: blur(14px);
  }
  :root[data-theme="light"] .carte-relief .verdict-chiffre {
    animation-name: leviter;
  }

  @media (prefers-reduced-motion: reduce) {
    .carte-relief .verdict-chiffre,
    .carte-relief .verdict-chiffre::after { animation: none; }
  }

  @media (prefers-reduced-motion: reduce) {
    .verdict-chiffre strong, .carte-relief .verdict-chiffre::before { animation: none; }
  }
  @media (prefers-reduced-motion: reduce), (hover: none) {
    /* Sur un écran tactile, l'inclinaison n'a jamais lieu : il n'y a pas de curseur
       à suivre. Or `preserve-3d` fait tester le POINTAGE en trois dimensions pour
       tout le contenu de la carte — mesuré à 375 px, des éléments du rapport
       interceptaient des touchers destinés au formulaire situé bien au-dessus.
       On repasse donc la carte à plat : sur téléphone, la 3D ne coûte que ça. */
    .carte-relief, .carte-relief * { transform-style: flat !important; }
    .carte-relief, .carte-relief[data-survol] { transform: none; transition: none; }
    .carte-relief > * > *, .carte-relief .verdict-tete, .carte-relief .jauge,
    .carte-relief .jauge-zones, .carte-relief .puces-gravite,
    .carte-relief .resume, .carte-relief .avertissement { transform: none; }
  }

  /* ── la carte de résultat ──────────────────────────────────────────────
     Le cadran circulaire a été retiré : un anneau rempli à 41 % ne dit pas si 41
     est beaucoup. La jauge, elle, porte les deux seuils réels du barème et nomme
     les trois zones — on lit un résultat, plus seulement un nombre. */
  .synthese { display: block; }
  .verdict-tete { display: flex; align-items: flex-start; justify-content: space-between; gap: 1.6rem; }
  .verdict-nom { font: 400 clamp(1.7rem, 4.4vw, 2.35rem)/1.08 var(--serif); letter-spacing: -.03em; margin: 0; }
  /* ── le chiffre ────────────────────────────────────────────────────────
     C'est le premier élément que l'œil cherche : il doit se voir de loin. La lueur
     est faite de trois ombres portées de plus en plus larges, dans la couleur du
     verdict — donc verte quand tout va bien, et jamais rouge par défaut.

     Elle s'allume une fois, à l'apparition, puis se tient tranquille. Une lueur qui
     palpite en permanence sur un rapport annonçant une arnaque serait insupportable
     à lire, et donnerait au site un air de machine à angoisse. */
  .verdict-chiffre { flex: none; text-align: right; line-height: 1; padding-top: .1rem; }

  /* La pile : quatorze copies du nombre échelonnées dans la profondeur, plus la face
     visible. C'est un objet à trois dimensions, pas une ombre portée — en inclinant
     la carte on en voit la tranche. */
  /* Le chiffre est un décor : il ne doit JAMAIS capter un toucher.
     Sans ça, ses quatorze couches en 3D interceptent les taps bien au-delà de ce
     qu'elles occupent à l'écran — le navigateur teste le pointage en trois
     dimensions, et un élément poussé à 150 px vers l'œil ratisse large. Sur un
     téléphone, ça donne des boutons qui « ne répondent pas » sans raison visible. */
  .verdict-chiffre, .chiffre-pile, .chiffre-couche, .chiffre-face, .chiffre-lueur,
  .chiffre-legende { pointer-events: none; }
  .chiffre-pile { position: relative; transform-style: preserve-3d; }
  /* Le chiffre a un aspect de ballon : gras, arrondi, luisant.
     `ui-rounded` sélectionne SF Pro Rounded sur Mac et iPhone — des chiffres pleins
     aux angles ronds, exactement la forme d'un ballon gonflé. Ailleurs, Arial
     Rounded puis une grasse ordinaire prennent le relais. */
  .chiffre-couche, .chiffre-face, .chiffre-lueur {
    display: block;
    font: 800 clamp(3.8rem, 10vw, 5.4rem)/.86
      ui-rounded, "SF Pro Rounded", "Arial Rounded MT Bold", var(--sans);
    font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  }
  /* Les couches se superposent exactement : seule la face occupe le flux.

     Leur couleur est un assombrissement du verdict, pas le verdict lui-même : sur un
     vrai objet, la tranche est dans l'ombre pendant que la face prend la lumière.
     Avec la même teinte des deux côtés, l'empilement se lisait comme une auréole. */
  .chiffre-couche {
    position: absolute; inset: 0;
    color: color-mix(in srgb, currentColor 52%, #05030d);
  }
  /* La surface du ballon : un reflet blanc en haut à gauche, la couleur du verdict au
     centre, un bord assombri en bas à droite. C'est ce dégradé, découpé dans la forme
     des chiffres, qui donne le caoutchouc gonflé plutôt que l'aplat. */
  .chiffre-face {
    position: relative;
    background: radial-gradient(
      circle at 30% 24%,
      #fff 0%,
      color-mix(in srgb, currentColor 55%, #fff) 16%,
      currentColor 46%,
      color-mix(in srgb, currentColor 72%, #12061e) 88%
    );
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
    animation: allumer 1.4s cubic-bezier(.2,.8,.2,1) backwards;
  }
  /* Le jumeau qui porte la lueur, juste derrière la face. */
  .chiffre-lueur {
    position: absolute; inset: 0; color: currentColor;
    transform: translateZ(-1px);
    text-shadow:
      0 0 24px color-mix(in srgb, currentColor 70%, transparent),
      0 0 56px color-mix(in srgb, currentColor 42%, transparent),
      0 0 110px color-mix(in srgb, currentColor 28%, transparent);
    animation: allumer 1.4s cubic-bezier(.2,.8,.2,1) backwards;
  }
  .chiffre-legende {
    font: 600 .56rem/1 var(--sans); letter-spacing: .18em; color: var(--ink-3);
    display: block; margin-top: .6rem;
  }
  @keyframes allumer {
    from { opacity: 0; text-shadow: none; transform: translateY(6px) scale(.94); }
    45%  { opacity: 1; }
  }

  /* En thème clair, une lueur sur fond pâle ne se voit pas : on la remplace par un
     halo dense derrière le chiffre, et on assombrit à peine le trait. */
  :root[data-theme="light"] .chiffre-lueur {
    text-shadow:
      0 0 26px color-mix(in srgb, currentColor 42%, transparent),
      0 0 60px color-mix(in srgb, currentColor 26%, transparent);
  }
  /* Sur fond clair, le reflet blanc se confond avec la page : on le rentre vers
     l'intérieur du chiffre et on renforce le bord sombre. */
  :root[data-theme="light"] .chiffre-face {
    background: radial-gradient(
      circle at 32% 26%,
      color-mix(in srgb, currentColor 22%, #fff) 0%,
      color-mix(in srgb, currentColor 70%, #fff) 20%,
      currentColor 52%,
      color-mix(in srgb, currentColor 62%, #1a0e2e) 92%
    );
    -webkit-background-clip: text; background-clip: text;
  }
  /* La tranche doit rester sombre sur fond clair, sinon elle disparaît. */
  :root[data-theme="light"] .chiffre-couche { color: color-mix(in srgb, currentColor 55%, #1a1030); }

  /* Le curseur de la jauge porte la même lueur : les deux disent le même chiffre. */
  .jauge-curseur { box-shadow: 0 0 0 1px var(--line), 0 0 18px -2px currentColor, 0 4px 14px -4px currentColor; }

  .jauge { position: relative; margin: 1.6rem 0 0; }
  .jauge-piste {
    height: 10px; border-radius: 99px; opacity: .24;
    background: linear-gradient(90deg, var(--ok), var(--faible) 26%, var(--moyen) 50%, var(--fort) 82%);
  }
  .jauge-actif {
    position: absolute; inset: 0 auto 0 0; width: 0; border-radius: 99px;
    background: linear-gradient(90deg, var(--ok), var(--faible) 26%, var(--moyen) 50%, var(--fort) 82%);
    transition: width 1.1s cubic-bezier(.2,.8,.2,1);
  }
  .jauge-seuil { position: absolute; top: -4px; bottom: -4px; width: 1px; background: var(--ink); opacity: .22; }
  .jauge-curseur {
    position: absolute; top: 50%; left: 22px; translate: -50% -50%;
    min-width: 28px; height: 26px; padding: 0 .38rem; border-radius: 99px;
    display: grid; place-content: center;
    font: 600 .72rem/1 var(--sans); font-variant-numeric: tabular-nums;
    color: var(--fond-plein); border: 3px solid var(--fond-plein);
    transition: left 1.1s cubic-bezier(.2,.8,.2,1);
  }
  .jauge-zones {
    display: flex; margin-top: .85rem;
    font: 600 .6rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em; color: var(--ink-3);
  }
  .jauge-zones span { position: relative; padding-top: .45rem; opacity: .5; transition: opacity .4s, color .4s; }
  .jauge-zones span::before { content: ""; position: absolute; top: 0; left: 0; width: 12px; height: 1px; background: currentColor; }
  .jauge-zones span[data-active] { opacity: 1; color: var(--ink); }

  .puces-gravite { display: flex; flex-wrap: wrap; gap: .45rem; margin: 1.2rem 0 0; padding: 0; list-style: none; }
  .puces-gravite li {
    display: inline-flex; align-items: center; gap: .42rem;
    font: 500 .78rem/1 var(--sans); color: var(--ink-2);
    border: 1px solid var(--line); border-radius: 99px;
    padding: .38rem .7rem .38rem .55rem; background: var(--paper-deep);
  }
  .puces-gravite i { width: 7px; height: 7px; border-radius: 50%; flex: none; }
  .puces-gravite .puces-reste { color: var(--ink-3); padding-left: .7rem; }

  .resume { margin: 1.6rem 0 0; color: var(--ink-2); font-size: 1rem; line-height: 1.62; }
  .avertissement {
    margin: .9rem 0 0; padding-left: .8rem; border-left: 2px solid var(--line);
    font-size: .84rem; color: var(--ink-3);
  }

  .signal {
    padding: 1.15rem 0 1.15rem 1rem; border-top: 1px solid var(--line-soft);
    border-left: 2px solid transparent; margin-left: -1rem;
    transition: border-left-color .25s, background .25s;
  }
  .signal:hover { border-left-color: var(--gravite-couleur, var(--line)); }
  .signal:first-of-type { padding-top: 0; border-top: 0; }
  .signal:last-child { padding-bottom: 0; }
  .signal-tete { display: flex; align-items: center; gap: .6rem; margin-bottom: .45rem; flex-wrap: wrap; }
  .pastille { width: 8px; height: 8px; border-radius: 50%; flex: none; }
  .signal-nom { font-weight: 600; font-size: .95rem; }
  .gravite { font: 600 .62rem/1 var(--sans); text-transform: uppercase; letter-spacing: .09em; padding: .25rem .5rem; border-radius: 5px; }
  .constat { margin: 0; color: var(--ink-2); font-size: .93rem; }
  blockquote {
    margin: .75rem 0 0; padding: .55rem .85rem; border-radius: 8px;
    background: var(--paper-deep); border-left: 3px solid var(--fort);
    font: italic .92rem/1.6 var(--serif); color: var(--ink-2);
  }
  .vide { margin: 0; color: var(--ink-2); font-size: .95rem; }

  ol.propre, ul.propre { margin: 0; padding: 0; list-style: none; }
  ul.propre li, ol.propre li { position: relative; padding-left: 1.5rem; margin-bottom: .7rem; color: var(--ink-2); font-size: .93rem; }
  ul.propre li:last-child, ol.propre li:last-child { margin-bottom: 0; }
  ul.propre li::before { content: ""; position: absolute; left: .3rem; top: .62em; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
  ol.propre { counter-reset: n; }
  ol.propre li { counter-increment: n; }
  ol.propre li::before {
    content: counter(n); position: absolute; left: 0; top: .22em;
    font: 600 .68rem/1.45 var(--mono); width: 1.05rem; height: 1.05rem; text-align: center;
    border-radius: 50%; color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
  }
  .pages-trouvees { display: grid; gap: .5rem; margin: 1rem 0 0; }
  .page-trouvee {
    display: flex; align-items: baseline; gap: .55rem; text-decoration: none;
    background: var(--paper-deep); border: 1px solid var(--line); border-radius: 12px;
    padding: .7rem .9rem; transition: border-color .2s, transform .2s;
  }
  .page-trouvee:hover { border-color: var(--accent-2); transform: translateX(2px); }
  .page-trouvee b { color: var(--accent-2); font-size: .95rem; }
  .page-trouvee span { color: var(--ink-3); font: 400 .82rem var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


  .defi {
    margin: 1.1rem 0; border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  }
  .defi-ligne {
    display: flex; align-items: center; gap: 1rem; padding: .75rem 1rem;
    border-bottom: 1px solid var(--line-soft);
  }
  .defi-ligne:last-child { border-bottom: 0; }
  .defi-cle {
    font: 600 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
    color: var(--ink-3); width: 7.5rem; flex: none;
  }
  .defi-valeur { font-size: .95rem; color: var(--ink); }
  .defi-mot {
    font: 600 1.15rem/1 var(--mono); letter-spacing: .12em; color: var(--accent);
  }
  .defi-message {
    background: var(--paper-deep); border-radius: 12px; padding: 1rem 1.1rem;
  }
  .defi-message p {
    margin: 0 0 .8rem; font-size: .92rem; line-height: 1.6; color: var(--ink-2); font-style: italic;
  }

  .erreur { color: var(--fort); font-size: .95rem; padding: 1.5rem 0; }
  .hors-ecran {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
  /* Le titre de verdict est un h2 (navigation par titres) mais garde son allure. */
  .bloc h2.verdict-nom {
    font: 400 1.75rem/1.12 var(--serif); text-transform: none;
    letter-spacing: -.02em; margin: .1rem 0 .6rem; color: inherit;
  }

  .badge-exemple {
    display: inline-block; font: 600 .62rem/1 var(--sans); text-transform: uppercase;
    letter-spacing: .1em; color: var(--ink-3); border: 1px solid var(--line);
    padding: .3rem .55rem; border-radius: 5px; margin-bottom: 1rem;
  }
  details.calcul { margin-top: 1.2rem; border-top: 1px solid var(--line-soft); padding-top: .95rem; }
  details.calcul summary { cursor: pointer; font: 600 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em; color: var(--ink-3); list-style: none; }
  details.calcul summary::-webkit-details-marker { display: none; }
  details.calcul summary::before { content: "+ "; font-family: var(--mono); }
  details.calcul[open] summary::before { content: "− "; }
  .calcul-corps { margin-top: .9rem; font: 400 .8rem/1.95 var(--mono); }
  .calcul-ligne { display: flex; justify-content: space-between; gap: 1rem; color: var(--ink-2); }
  .calcul-ligne span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .calcul-ligne b { font-weight: 400; font-variant-numeric: tabular-nums; flex: none; }
  .calcul-ligne.negatif b { color: var(--ok); }
  .calcul-total { display: flex; justify-content: space-between; gap: 1rem; margin-top: .5rem; padding-top: .5rem; border-top: 1px solid var(--line-soft); color: var(--ink); }
  .calcul-note { margin: .75rem 0 0; font: 400 .78rem/1.6 var(--sans); color: var(--ink-3); }

  /* ═══════════════ recours officiels ═══════════════ */
  .aide { padding-block: 1rem 2rem; }
  .chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 1rem; margin-bottom: 1.6rem; }
  .chiffre {
    background: linear-gradient(180deg, var(--surface), rgba(255,255,255,.012));
    border: 1px solid var(--line); border-radius: 18px; padding: 1.3rem;
  }
  .chiffre b {
    display: block; font: 800 2.1rem/1 var(--sans); letter-spacing: -.03em; margin-bottom: .5rem;
    background: linear-gradient(102deg, var(--accent), var(--accent-2));
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
  .chiffre span { font-size: .92rem; color: var(--ink-2); }

  .recours { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: .8rem; }
  .recours-carte {
    display: block; text-decoration: none; color: inherit;
    background: var(--paper-deep); border: 1px solid var(--line); border-radius: 16px;
    padding: 1.1rem 1.2rem; transition: border-color .25s, transform .25s;
  }
  .recours-carte:hover { border-color: var(--accent); transform: translateY(-2px); }
  .recours-carte b { display: block; font-size: 1.05rem; margin-bottom: .35rem; color: var(--accent-2); }
  .recours-carte span { font-size: .88rem; color: var(--ink-2); line-height: 1.55; }

  .premier-reflexe {
    margin: 1.4rem 0 0; padding: 1rem 1.2rem; border-radius: 14px;
    background: color-mix(in srgb, var(--moyen) 10%, transparent);
    border-left: 3px solid var(--moyen); font-size: .95rem; color: var(--ink-2);
  }
  .premier-reflexe strong { color: var(--ink); }
  .sources { margin: 1.1rem 0 0; font-size: .8rem; line-height: 1.7; color: var(--ink-3); }
  .sources a { color: var(--ink-2); }

  /* ═══════════════════════ pied ═══════════════════════ */
  footer { margin-top: 4.5rem; padding: 1.6rem 0 5rem; border-top: 1px solid var(--line); color: var(--ink-3); font-size: .8rem; line-height: 1.75; }
  footer strong { color: var(--ink-2); font-weight: 600; }

  @media (max-width: 560px) {
    /* Sur téléphone, tout l'enjeu est que le bouton reste au-dessus de la ligne
       de flottaison : on grignote partout plutôt que de sacrifier une seule chose. */
    .hero { padding-block: 1.4rem 1.6rem; }
    h1 { font-size: clamp(2rem, 8vw, 2.6rem); margin-bottom: .7rem; }
    .oeil { margin-bottom: 1.1rem; padding: .3rem .65rem .3rem .5rem; }
    .chapo { font-size: 1rem; margin-bottom: 1.3rem; }
    textarea { min-height: 8.5rem; }
    input[type=text], textarea { padding: .85rem .95rem; }
    .champ { margin-bottom: 1.1rem; }
    .primaire { padding: .85rem 1.6rem; }
    .garanties { margin-top: 1.1rem; gap: .8rem 1.1rem; font-size: .76rem; }
    .manifeste { padding-block: 2.5rem 3.5rem; }
    .scenarios { padding-bottom: 3.5rem; }
    .verdict-tete { flex-direction: column-reverse; align-items: flex-start; gap: .5rem; }
    .verdict-chiffre { text-align: left; }

    /* ── ce que le téléphone a révélé ────────────────────────────────────
       Mesuré à 375 px sur la vraie page : les libellés de zones tombaient à
       9,6 px et se coupaient en deux lignes qui se télescopaient. C'est
       précisément le texte qui donne son sens au chiffre — « vous êtes dans
       ARNAQUE PROBABLE » — et le public de ce site a souvent 70 ans.

       Deux corrections : on remonte à 11 px en resserrant l'interlettrage
       (l'espacement mangeait la place), et on réserve la hauteur de deux lignes
       pour que le retour à la ligne ne chevauche plus rien. */
    .jauge-zones { font-size: .69rem; letter-spacing: .04em; align-items: start; }
    .jauge-zones span { line-height: 1.25; min-height: 2.4em; padding-right: .35rem; }

    /* Coller une conversation entière dans quatre lignes visibles décourage
       avant même d'avoir commencé. */
    #conversation { min-height: 40vh; }

    /* Le compteur de caractères passait à la ligne au milieu de « 734 car. ». */
    .compteur, .duree { white-space: nowrap; }

    /* Les pastilles de marqueurs : cibles tactiles et lisibilité. */
    .puces-gravite li { font-size: .82rem; padding: .45rem .75rem .45rem .6rem; }
    .bloc { padding: 1.3rem; }
    .fiche { grid-template-columns: 2.4rem 1fr; gap: .9rem; }
  }
  /* ═══════════════════ accroches ═══════════════════ */
  .duree {
    font: 400 .82rem/1 var(--sans); color: var(--ink-3);
    display: inline-flex; align-items: center; gap: .35rem; margin-left: auto;
  }
  .duree::before {
    content: ""; width: 11px; height: 11px; border-radius: 50%; flex: none;
    border: 1.5px solid currentColor;
    background:
      linear-gradient(currentColor, currentColor) center/1.5px 4px no-repeat,
      linear-gradient(currentColor, currentColor) 55% 45%/3px 1.5px no-repeat;
  }
  .chrono {
    margin-left: auto; font: 400 .78rem/1 var(--mono); color: var(--ink-3);
    font-variant-numeric: tabular-nums; flex: none;
  }
  .attente { width: 100%; }
  @media (max-width: 560px) { .duree { margin-left: 0; font-size: .78rem; } }

  .garanties {
    display: flex; gap: 1.5rem; flex-wrap: wrap; margin-top: 1.5rem;
    font: 400 .8rem/1 var(--sans); color: var(--ink-3);
  }
  .garanties span { display: inline-flex; align-items: center; gap: .45rem; }
  .garanties svg { width: 13px; height: 13px; color: var(--accent); flex: none; }

  .outils-entete { display: flex; align-items: center; gap: .9rem; }
  .lien-compte {
    background: none; border: 0; padding: .4rem 0; cursor: pointer;
    font: 500 .82rem var(--sans); color: var(--ink-3);
    border-bottom: 1px solid transparent; transition: color .2s, border-color .2s;
  }
  .lien-compte:hover { color: var(--ink); border-bottom-color: var(--line-champ); }

  dialog {
    /* Fond plein et non translucide : avec var(--surface) le popup laissait voir
       le dégradé du site et devenait illisible. */
    border: 1px solid var(--line); border-radius: 20px; background: var(--fond-plein);
    color: var(--ink); padding: 2rem; max-width: 30rem; width: calc(100% - 2rem);
    box-shadow: var(--ombre-forte);
  }
  dialog::backdrop { background: rgba(4,3,10,.72); backdrop-filter: blur(6px); }
  dialog h2 { font: 400 1.5rem/1.2 var(--serif); margin: 0 0 .6rem; letter-spacing: -.02em; }
  .dlg-sous-titre { font: 600 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em; color: var(--ink-3); margin: 1.6rem 0 .8rem; }
  .dlg-intro { margin: 0 0 1.4rem; font-size: .9rem; color: var(--ink-2); }
  .dlg-note { margin: 1.2rem 0 0; font-size: .78rem; line-height: 1.6; color: var(--ink-3); }
  .dlg-identite { margin: 0; font-size: .92rem; color: var(--ink-2); }
  .dlg-actions { display: flex; gap: 1.2rem; flex-wrap: wrap; margin-top: 1.6rem; padding-top: 1.1rem; border-top: 1px solid var(--line-soft); }
  .fermer-dlg { position: absolute; top: .8rem; right: .9rem; }
  .fermer-dlg button {
    background: none; border: 0; font-size: 1.5rem; line-height: 1; color: var(--ink-3);
    cursor: pointer; padding: .2rem .4rem; border-radius: 6px;
  }
  .fermer-dlg button:hover { color: var(--ink); }
  .onglets { display: flex; gap: .3rem; margin-bottom: 1.3rem; border-bottom: 1px solid var(--line); }
  .onglet {
    background: none; border: 0; padding: .5rem .1rem; margin-right: 1.2rem; cursor: pointer;
    font: 500 .88rem var(--sans); color: var(--ink-3); border-bottom: 2px solid transparent;
    margin-bottom: -1px; transition: color .2s, border-color .2s;
  }
  .onglet.actif { color: var(--ink); border-bottom-color: var(--accent); }
  dialog .champ { margin-bottom: 1rem; }
  dialog .boite { background: color-mix(in srgb, var(--fond-plein) 60%, #000); }
  :root[data-theme="light"] dialog .boite { background: var(--paper); }
  dialog label { display: block; margin-bottom: .4rem; }
  dialog .primaire { width: 100%; justify-content: center; margin-top: .3rem; }
  .lien.danger { color: var(--fort); text-decoration-color: color-mix(in srgb, var(--fort) 40%, transparent); }
  .lien.danger:hover { color: var(--fort); }
  .rapport-ligne {
    display: flex; align-items: baseline; gap: .8rem; padding: .7rem 0;
    border-top: 1px solid var(--line-soft); font-size: .88rem;
  }
  .rapport-ligne:first-child { border-top: 0; }
  .rapport-ligne .titre { flex: 1; color: var(--ink); }
  .rapport-ligne .date { color: var(--ink-3); font: 400 .76rem var(--mono); }
  .rapport-ligne .pastille-score { font: 600 .76rem var(--mono); }

  .apres-sequence { padding-block: 1rem 2rem; }
  .bascule-action {
    margin-top: 3.5rem; padding: 2rem; border-radius: 16px;
    border: 1px solid var(--line); background: var(--surface); box-shadow: var(--ombre);
  }
  .bascule-action h3 {
    font: 400 1.5rem/1.25 var(--serif); letter-spacing: -.02em; margin: 0 0 .7rem;
  }
  .bascule-action p { margin: 0 0 1.4rem; color: var(--ink-2); font-size: .96rem; }
  .accroche-outil {
    margin: 0 0 1.6rem; font-size: .95rem; color: var(--ink-2);
    padding-left: .9rem; border-left: 2px solid var(--encre);
  }
  .note-bouton { margin: 1.1rem 0 0; font-size: .82rem; color: var(--ink-3); }
  .options { margin: -.1rem 0 1.1rem; }
  .options > summary {
    cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: .5rem;
    font: 500 .9rem var(--sans); color: var(--ink-2); padding: .55rem 0;
    border-bottom: 1px solid var(--line); transition: color .2s, border-color .2s;
  }
  .options > summary::-webkit-details-marker { display: none; }
  .options > summary::before { content: "+"; font: 400 1.1rem/1 var(--mono); color: var(--accent); }
  .options[open] > summary::before { content: "−"; }
  .options > summary:hover { color: var(--ink); border-bottom-color: var(--line-champ); }
  .options > summary span { color: var(--ink-3); font-weight: 400; }
  .options-corps { padding-top: 1.3rem; }

  .depot {
    display: flex; align-items: center; gap: .9rem; cursor: pointer;
    background: var(--surface); border: 1px dashed var(--line-champ); border-radius: 16px;
    padding: 1rem 1.15rem; transition: border-color .2s, background .2s;
  }
  .depot:hover { border-color: var(--accent); }
  .depot.rempli { border-style: solid; border-color: var(--accent); }
  .depot-icone { width: 34px; height: 34px; flex: none; display: grid; place-items: center;
    border-radius: 10px; background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); }
  .depot-icone svg { width: 19px; height: 19px; }
  .depot-texte { font-size: .95rem; }
  .depot-texte em { font-style: normal; color: var(--ink-3); font-size: .85rem; display: block; }

  .note-champ { margin: .5rem 0 0; font-size: .78rem; line-height: 1.5; color: var(--ink-3); }

  @media (max-width: 560px) {
    .bascule-action { padding: 1.4rem; }
    .garanties { gap: 1rem .9rem; }
  }
  /* À l'impression, on ne garde que le rapport : quelqu'un qui veut montrer ça à
     un proche, à sa banque ou à la gendarmerie n'a pas besoin du reste. */
  @media print {
    .fond, .progression, header, .hero-contenu, .outil, .sequence, .apres-sequence,
    .manifeste, .bascule { display: none !important; }
    body { background: #fff; color: #000; }
    .bloc {
      break-inside: avoid; box-shadow: none; border: 1px solid #bbb;
      background: #fff; margin-bottom: .8rem; padding: 1rem;
    }
    .colonne { max-width: none; padding: 0; }
    footer { border-top: 1px solid #bbb; font-size: .7rem; }
    details.calcul { display: none; }
    blockquote { background: #f4f4f4; }
    a[href]::after { content: ""; }
  }

  .actions-rapport {
    display: flex; gap: 1rem; flex-wrap: wrap; align-items: center;
    margin-top: 1.4rem; padding-top: 1.1rem; border-top: 1px solid var(--line-soft);
  }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { animation: none !important; transition: none !important; }
    .manifeste .surligne { background-size: 100% 100%; }
    .reveal { opacity: 1 !important; transform: none !important; }
    .couche { opacity: 1 !important; }
    .c2, .c3 { opacity: 0 !important; }
    .progression { display: none; }
  }

  /* Plancher de lisibilité sur petit écran. Mesuré : sept textes descendaient à
     12,5 px — notes du dialogue, sources, mentions du pied de page. Ce sont des
     textes secondaires, mais le public de ce site a souvent plus de soixante ans
     et lit sur un téléphone. Rien ne descend plus sous 13 px. */
  @media (max-width: 560px) {
    .dlg-note, .sources, .pied-legal, .note-champ, .indice { font-size: .83rem; }
  }

  /* ═══════════════ cibles tactiles ═══════════════
     EN DERNIER, DÉLIBÉRÉMENT. Une requête de média n'ajoute aucune spécificité :
     placées plus haut, ces règles étaient écrasées par les règles de base situées
     après elles. C'est exactement ce qui s'est produit — et ça ne se voyait pas.

     Mesuré à 375 px sur la vraie page : « D'où vient ce chiffre » faisait 11 px de
     haut, les liens du rapport 33, « Mentions légales » 16. Un doigt vise mal, et
     le public de ce site a souvent 70 ans. On vise les 44 px que recommandent Apple
     et le WCAG, sans changer l'aspect du texte — seulement la zone qui répond. */
  @media (max-width: 560px) {
    details.calcul summary { padding: .95rem 0; }
    .options > summary { padding: .8rem 0; }
    button.lien, a.lien {
      padding: .8rem 0; min-height: 44px; display: inline-flex; align-items: center;
    }
    .lien-compte { padding: .55rem .3rem; min-height: 44px; display: inline-flex; align-items: center; }
    .bascule { width: 42px; height: 42px; }
    footer a { padding: .5rem 0; display: inline-block; }
    .cta { padding: .8rem 0; min-height: 44px; }

    /* Sous 16 px, iOS Safari ZOOME tout seul quand on touche un champ, puis laisse
       la page décalée. Mesuré ici : le champ de mot de passe était à 13,1 px, hérité
       d'un `font: inherit` dans une fenêtre au texte réduit. Pour quelqu'un qui n'est
       pas à l'aise, ce zoom brutal donne l'impression d'avoir cassé quelque chose. */
    input[type=text], input[type=email], input[type=password], textarea { font-size: 16px; }
    .actions-rapport { gap: .2rem 1.2rem; }
  }

  /* ═══════════════ la démonstration sur téléphone ═══════════════
     MESURÉ à 375 × 812 : l'écran collant fait 100 vh, soit 812 px, mais son contenu
     en fait 929. Les 117 px de trop étaient tout simplement COUPÉS — le panneau
     final se terminait au milieu d'une phrase, « chacun avec la phrase exac… ».
     Personne ne l'avait vu parce que sur un écran d'ordinateur tout tient.

     Et un vrai téléphone a moins de place encore : la barre d'adresse mange une
     centaine de pixels. On resserre donc jusqu'à tenir dans 100 dvh, l'unité qui
     tient compte de cette barre, avec de la marge. */
  /* ── écrans courts ──────────────────────────────────────────────────────
     À 320 × 568, la scène déborde encore de 37 px même mise à l'échelle : à cette
     largeur le texte se replie davantage, et rapetisser encore le rendrait
     illisible — l'inverse de ce qu'il faut pour un public âgé.

     Alors on renonce à l'écran figé. La démonstration défile avec la page comme
     une section ordinaire : l'animation perd son effet, mais RIEN N'EST COUPÉ.
     Une belle mécanique qui tronque une phrase au milieu ne vaut rien. */
  @media (max-height: 640px) {
    @supports (animation-timeline: view()) {
      .sequence { height: auto; }
      .sequence-ecran {
        position: static; height: auto; overflow: visible;
        padding-block: 2.5rem; contain: none;
      }
      /* Sans écran figé, il n'y a plus de progression à suivre : tout est visible. */
      .scene > *, .sequence-fin { opacity: 1; animation: none; }
    }
  }

  @media (max-width: 560px) {
    @supports (animation-timeline: view()) {
      .sequence-ecran { height: 100dvh; padding: 0 1rem; }
    }
    .sequence-ecran { padding: 0 1rem; }
    /* TOUT EST RELATIF À LA HAUTEUR DE L'ÉCRAN, et c'est le fond de l'affaire.
       Avec des tailles en rem, la démonstration tenait à 812 px et débordait de
       62 px sur un iPhone SE (667 px) : une taille fixe ne peut pas s'adapter à
       une hauteur variable. En vh, la scène se met à l'échelle du téléphone —
       elle tient partout, et reste confortable sur les grands écrans grâce aux
       bornes hautes du clamp. */
    .sequence-titre { margin-bottom: clamp(.2rem, .6vh, .45rem); font-size: .62rem; }
    .scene { gap: clamp(.06rem, .26vh, .2rem); }
    .msg {
      padding: clamp(.26rem, .72vh, .45rem) .7rem;
      font-size: clamp(.68rem, 1.62vh, .82rem); line-height: 1.32; max-width: 92%;
    }
    .msg b { font-size: clamp(.58rem, 1.4vh, .68rem); margin-bottom: .05rem; }
    /* Les trois annotations pesaient 252 px à elles seules, plus du tiers de la
       scène. Ce sont elles qu'on resserre en priorité : le texte des MESSAGES est
       celui que la personne doit pouvoir lire. */
    .anno {
      padding: clamp(.18rem, .55vh, .34rem) .6rem;
      font-size: clamp(.62rem, 1.46vh, .75rem); line-height: 1.26;
    }
    .anno strong { font-size: clamp(.52rem, 1.25vh, .6rem); margin-bottom: .03rem; }
    .sequence-fin {
      margin-top: clamp(.2rem, .55vh, .4rem);
      padding: clamp(.42rem, 1.1vh, .7rem) .8rem; gap: clamp(.45rem, 1.4vh, .8rem);
    }
    .sequence-fin p { font-size: clamp(.66rem, 1.52vh, .8rem); line-height: 1.34; }
    .sequence-fin .note { font-size: clamp(1.25rem, 4vh, 2.1rem); }
  }

  /* Une page qui tient en un demi-écran laissait le pied de page au milieu, suivi
     d'un grand vide. On donne simplement de la hauteur au contenu.

     Surtout PAS de `display: flex` sur le body : les nappes de décor et le grain
     sont des enfants directs, et en faire des éléments de flex les déforme — essayé,
     la page s'est retrouvée tassée dans un coin. */
  body.page-courte main { min-height: 72dvh; display: flex; align-items: center; }

  /* ═══════════════ envoi de captures d'écran ═══════════════ */
  .depot-captures {
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .9rem;
    margin-top: .7rem;
  }
  .depot-captures-bouton {
    display: inline-flex; align-items: center; gap: .5rem; cursor: pointer;
    color: var(--accent-2); text-decoration-color: color-mix(in srgb, var(--accent-2) 40%, transparent);
  }
  .depot-captures-bouton:hover { color: var(--ink); }
  .depot-captures-note { font-size: .82rem; }
  .etat-captures {
    margin: .7rem 0 0; padding: .7rem .9rem; border-radius: 10px;
    background: var(--paper-deep); border: 1px solid var(--line);
    border-left: 3px solid var(--accent-2);
    font-size: .88rem; line-height: 1.55; color: var(--ink-2);
  }
  .etat-captures[data-etat="erreur"] { border-left-color: var(--fort); color: var(--ink-2); }
  .etat-captures[data-etat="fait"] { border-left-color: var(--ok); }
  .etat-captures b { color: var(--ink); font-weight: 600; }
  @media (max-width: 560px) {
    .depot-captures-bouton { min-height: 44px; }
  }
