/* ═══════════════════════════════════════════════════════════════
   Nexus — nexus-agent.be
   Aucune dépendance externe. Aucune requête réseau.
   ═══════════════════════════════════════════════════════════════ */

/* ── typographie ──────────────────────────────────────────────
   Geist Variable + Geist Mono (Vercel / Basement Studio) — licence SIL OFL, libre et gratuite. Auto-hébergées, sous-ensemblées pour le français :
   36 Ko à deux, aucune requête externe.
   Le mono sert aux petits libellés — motif dominant chez les sites primés 2026
   (6 lauréats Awwwards sur 11 étudiés).
   ⚠️ L'espace fine insécable U+202F est ABSENTE de Geist (comme de 22 polices
   sur 23 testées). On écrit donc &nbsp; avant : ; ! ? — jamais &#8239;, qui déclencherait un repli de police et décalerait les mesures du texte animé. */
@font-face{
  font-family:"Geist";
  src:url("fonts/geist.woff2") format("woff2-variations");
  font-weight:300 700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Geist Mono";
  src:url("fonts/geist-mono.woff2") format("woff2");
  font-weight:500;font-style:normal;font-display:swap;
}
:root{
  --noir:#05070d;      /* conserve : sert encore a l'encadre du hero */
  --noir-2:#0a0e1a;
  --clair:#EDF1F7;     /* le fond de page, quand le film ne couvre pas */
  /* ── PALETTE CLAIRE ──────────────────────────────────────────
     Le fond n'est plus noir : la sequence de fond est claire, et un aplat
     sombre par-dessus revenait a la masquer. Les textes passent donc en
     fonce. Seul l'encadre du hero reste sombre (voir .voile-hero) : c'est
     le seul endroit ou le film est a la fois clair ET charge derriere le
     titre principal. Contrastes verifies sur le fond clair. */
  --voile:rgba(17,24,38,.05);
  --bord:rgba(17,24,38,.12);
  --bord-fort:rgba(17,24,38,.26);
  --texte:#111826;     /* 15,8:1 — largement AAA */
  --texte-2:#414D63;   /* 8,4:1  — AAA */
  --texte-3:#5A6780;   /* 5,5:1  — AA, discret sans devenir illisible */

  --vela:#22D3EE;
  --atlas:#F5A524;
  --nova:#A855F7;
  --cortex:#10B981;
  --pulsar:#FF6B5B;

  /* ── LES SURFACES ────────────────────────────────────────────
     Un seul jeu de valeurs pour TOUTES les cartes du site. Avant, chaque
     module avait les siennes — rayon 14 ici et 12 la, fond a .018 puis
     .035, bordure tantot neutre tantot coloree — d'ou l'impression de
     pieces rapportees. Un changement ici se voit partout, une seule fois.

     ⚠️ Pas de `backdrop-filter` sur ces surfaces : au-dessus d'un fond qui
     bouge, le navigateur refloute a CHAQUE image. C'est un tueur de
     fluidite sur iOS, deja paye une fois. Ces panneaux sont simplement
     translucides. */
  /* Il ne reste que le retrait : les aplats et les bordures de carte ont
     ete retires, le texte se pose directement sur la page. Ne pas
     reintroduire de `--carte` sans raison — c'est le parti pris. */
  --carte-pad:clamp(20px,2.4vw,30px);

  --gouttiere:clamp(20px, 5vw, 80px);
  --max:1240px;
  --r:14px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}
*, *::before, *::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;
  background:var(--clair);
  color:var(--texte);
  font-family:"Geist",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  font-feature-settings:"ss01","cv01";
  font-size:clamp(16px,1.05vw,19px);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
h1, h2, h3{margin:0;font-weight:600;letter-spacing:-.025em;line-height:1.08}
h1{font-size:clamp(2rem,4.2vw,3.6rem);letter-spacing:-.036em;line-height:1}
h2{font-size:clamp(1.9rem,4.2vw,3.4rem);line-height:1.05;letter-spacing:-.032em}
h3{font-size:clamp(1.05rem,1.5vw,1.3rem);letter-spacing:-.015em;line-height:1.3}
p{margin:0}
.skip{position:absolute;left:-9999px;top:0;z-index:999;background:#fff;color:#000;padding:.7rem 1.1rem;border-radius:8px}
.skip:focus{left:12px;top:12px}
/* Titre lu par les lecteurs d'ecran, invisible a l'oeil. Surtout PAS
   « display:none » ni « visibility:hidden » : les deux le retireraient aussi
   de l'arbre d'accessibilite, donc de la navigation par titres. */
.titre-lecteur{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;
}
:focus-visible{outline:2px solid var(--vela);outline-offset:3px;border-radius:6px}
/* ── fond ─────────────────────────────────────────────────── */
#ciel{position:fixed;inset:0;width:100%;height:100%;z-index:-2;display:block}
.grain{
  position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:.16;
  background-image:radial-gradient(circle at 50% 0%,rgba(34,211,238,.10),transparent 55%),
                   radial-gradient(circle at 90% 70%,rgba(168,85,247,.07),transparent 50%);
}
/* ── en-tête ──────────────────────────────────────────────── */
.entete{
  position:fixed;top:0;left:0;right:0;z-index:100;
  /* Trois colonnes : la marque a gauche, les menus AU MILIEU, le burger a
     droite. Les colonnes laterales sont a `1fr` chacune, donc le bloc
     central est centre sur la page — et le reste centre meme quand le
     burger est masque sur ordinateur. */
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  padding:18px var(--gouttiere);
  background:none;              /* plus de bandeau sombre */
  transition:padding .4s var(--ease);
}
.entete .marque{justify-self:start}
.entete .nav{justify-self:center}
.entete .burger{justify-self:end}
.entete.compact{
  padding:12px var(--gouttiere);
  /* Ni bandeau sombre, ni `backdrop-filter` : au-dessus d'un fond qui
     bouge, le flou se recalcule a chaque image — tueur de fluidite sur
     iOS, deja paye une fois. Un simple voile clair suffit. */
  background:rgba(237,241,247,.82);
  border-bottom:1px solid var(--bord);
}
.marque{display:flex;align-items:center;gap:11px;text-decoration:none;font-weight:600;letter-spacing:-.02em;font-size:1.12rem}
.marque{color:var(--logo,var(--texte))}
.marque-signe{
  width:26px;height:26px;flex:none;display:block;
  color:var(--logo,var(--vela));
  transition:color 1s var(--ease);
}
.marque-mot{color:var(--texte)}
.pied-marque .marque-signe{width:22px;height:22px;color:var(--texte-2)}
.nav{display:flex;align-items:center;gap:clamp(16px,2vw,34px);font-size:.94rem}
.nav a{text-decoration:none;color:var(--texte-2);transition:color .25s var(--ease);white-space:nowrap}
.nav a:hover{color:var(--texte)}
.nav-cta{
  color:var(--texte)!important;border:1px solid var(--bord-fort);
  padding:.42em 1.05em;border-radius:100px;transition:border-color .25s,background .25s;
}
.nav-cta:hover{border-color:var(--vela);background:rgba(34,211,238,.10)}
.burger{display:none;width:40px;height:40px;position:relative}
.burger span{position:absolute;left:9px;right:9px;height:1.5px;background:var(--texte);transition:transform .3s var(--ease),opacity .3s}
.burger span:first-child{top:16px}
.burger span:last-child{top:23px}
.burger[aria-expanded="true"] span:first-child{transform:translateY(3.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:last-child{transform:translateY(-3.5px) rotate(-45deg)}
.menu-mobile{
  position:fixed;inset:0;z-index:99;background:rgba(237,241,247,.97);
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
}
.menu-mobile a{text-decoration:none;font-size:1.55rem;font-weight:500;padding:.5em 1em;color:var(--texte-2);transition:color .2s}
.menu-mobile a:hover, .menu-mobile a:active{color:var(--texte)}
/* ── éléments communs ─────────────────────────────────────── */
.sur-titre{
  font-size:.74rem;text-transform:uppercase;letter-spacing:.16em;
  color:var(--texte-3);font-weight:500;margin-bottom:1.1rem;white-space:nowrap;
}
.chapo{color:var(--texte-2);font-size:clamp(1rem,1.25vw,1.16rem);max-width:52ch;line-height:1.7}
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  padding:.92em 1.7em;border-radius:100px;text-decoration:none;
  font-size:.96rem;font-weight:500;letter-spacing:-.005em;
  transition:transform .3s var(--ease-out),background .3s,border-color .3s,box-shadow .3s;
  will-change:transform;
}
.btn:hover{transform:translateY(-2px)}
/* Sur la page claire : bouton plein sombre, texte blanc. */
.btn-primaire{background:var(--texte);color:#fff}
.btn-primaire:hover{box-shadow:0 12px 40px -12px rgba(17,24,38,.45)}
.btn-fantome{border:1px solid var(--bord-fort);color:var(--texte)}
.btn-fantome:hover{border-color:var(--vela);background:rgba(34,211,238,.10)}
/* Dans l'encadre sombre du hero, tout s'inverse — sinon le bouton sombre
   disparait sur le panneau sombre. */
.hero-texte .btn-primaire{background:#E9EDF5;color:var(--noir)}
.hero-texte .btn-primaire:hover{box-shadow:0 12px 40px -12px rgba(233,237,245,.45)}
.hero-texte .btn-fantome{border-color:rgba(255,255,255,.30);color:#E9EDF5}
.btn-grand{padding:1.1em 2.3em;font-size:1.06rem}

/* animations d'entrée — en @keyframes (fill:both) plutôt qu'en transitions :
   l'état final est verrouillé, rien ne peut rester bloqué à mi-course. */
@keyframes revele{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:none}}
@keyframes revele-mot{from{opacity:0;transform:translateY(.45em) rotate(1.1deg)}to{opacity:1;transform:none}}
.js [data-reveal]{opacity:0}
.js [data-reveal].vu{animation:revele .8s var(--ease-out) var(--d,0ms) both}
[data-delai="1"]{--d:90ms}
[data-delai="2"]{--d:180ms}
[data-delai="3"]{--d:270ms}
.mot{display:inline-block}
.js .titre .mot{opacity:0}
.js .titre.vu .mot{animation:revele-mot .72s var(--ease-out) var(--dm,0ms) both}
/* filet de sécurité : au bout de 3, 5 s, plus rien ne peut rester invisible.

   ⚠️ `:not(.motion-pret)` est indispensable — et manquait.
   Ce filet s'armait 3, 5 s après le chargement SANS condition, alors que ses
   deux jumelles (lignes ~416 et ~746) se protègent avec `:not(.moteur-ok)`.
   Conséquence : tout ce que le visiteur n'avait pas encore atteint au bout
   de 3, 5 s apparaissait d'un coup, sans animation. Autrement dit, les
   apparitions ne jouaient que sur le premier écran.
   Le filet doit couvrir le cas où le moteur d'animation n'est pas là —
   celui-là seulement. `motion-pret` est posé par assets/mouvement.js une
   fois qu'il a réellement pris la main. */
.secours:not(.motion-pret) [data-reveal]:not(.vu), .secours:not(.motion-pret) .titre:not(.vu) .mot{opacity:1!important;animation:none!important}
/* Quand Motion est la, c'est LUI qui fait ENTRER les pastilles d'outils
   (voir mouvement.js). La cascade CSS `monte` doit donc se taire, sinon les
   deux moteurs se disputent les memes elements et le resultat saute.
   ⚠️ Ici se trouvait `.motion .integ{animation:none!important}` — un coup de
   hache : il coupait TOUTE animation CSS sur les pastilles, y compris celles
   qui n'ont rien a voir avec l'entree. La respiration (plus bas) etait
   silencieusement annulee des que Motion se chargeait.
   La cascade s'exclut desormais elle-meme, via `:not(.motion)` sur ses
   propres regles (`.js:not(.motion) .chapitre.sN .integ`). Le creneau
   `animation` de .integ reste donc libre pour autre chose. */
/* ── les libellés en monospace ─────────────────────────────── */
.sur-titre, .agent-metier, .agent-num, .etape-n, .integ-titre, .diag-fil li, .reponse-tete em, .indice-mot{
  font-family:"Geist Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  font-weight:500;
}
.sur-titre, .agent-metier, .integ-titre, .indice-mot{letter-spacing:.14em}
.diag-fil li{letter-spacing:.01em}
.agent-liste li, .integ, .mot-def summary{font-feature-settings:"ss01"}
/* ── HERO ─────────────────────────────────────────────────── */
.hero{
  position:relative;min-height:100svh;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:104px var(--gouttiere) clamp(58px,8vh,90px);
  overflow:hidden;
}
.hero-texte{position:relative;z-index:2;max-width:min(100%,720px)}
.hero .chapo{max-width:46ch;line-height:1.62}
.hero h1{margin-bottom:1.5rem}
.hero-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:1.7rem}
.indice-scroll{
  position:absolute;bottom:14px;left:50%;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:11px;
  font-size:.7rem;letter-spacing:.19em;text-transform:uppercase;color:var(--texte-3);
}
.indice-trait{width:1px;height:44px;background:linear-gradient(var(--texte-3),transparent);animation:coule 2.4s var(--ease) infinite}
@keyframes coule{0%{transform:scaleY(0);transform-origin:top}45%{transform:scaleY(1);transform-origin:top}55%{transform:scaleY(1);transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}
/* ── AMBIANCE : le fond prend la couleur de la catégorie ──── */
.ambiance{
  position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:0;
  transition:opacity 1.1s var(--ease),background 1.1s var(--ease);
  background:
    radial-gradient(ellipse 90% 60% at 50% 108%,color-mix(in srgb,var(--amb,#22D3EE) 26%,transparent),transparent 70%),
    radial-gradient(ellipse 70% 50% at 88% 8%,color-mix(in srgb,var(--amb,#22D3EE) 13%,transparent),transparent 66%),
    linear-gradient(180deg,transparent 40%,color-mix(in srgb,var(--amb,#22D3EE) 7%,transparent));
}
.ambiance.on{opacity:1}
/* ── ÉQUIPAGE ─────────────────────────────────────────────── */
.equipage{padding:0}
.equipage-piste{display:block}
.agent-id{display:flex;align-items:center;gap:13px;margin-bottom:1.2rem;flex-wrap:wrap}
.agent-pastille{width:10px;height:10px;border-radius:50%;background:var(--c);box-shadow:0 0 18px var(--c);flex:none}
.agent-metier{font-size:.75rem;text-transform:uppercase;letter-spacing:.18em;color:var(--c)}
.agent-num{margin-left:auto;font-size:.72rem;letter-spacing:.16em;color:var(--texte-3);font-variant-numeric:tabular-nums}
.agent-phrase{color:var(--texte);font-size:clamp(1.06rem,1.6vw,1.42rem);line-height:1.45;margin-bottom:1.1rem;max-width:26ch}
.agent-detail{color:var(--texte-2);font-size:clamp(.94rem,1.06vw,1.02rem);line-height:1.72;max-width:48ch}
.agent-liste{list-style:none;margin:1.6rem 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.agent-liste li{
  font-size:.82rem;color:var(--texte-2);padding:.42em .95em;border-radius:100px;
  border:1px solid color-mix(in srgb,var(--c) 26%,var(--bord));
  background:color-mix(in srgb,var(--c) 6%,transparent);
}
/* ── les intégrations ─────────────────────────────────────── */
.agent-integ{position:relative}
.integ-titre{
  display:flex;align-items:center;gap:12px;
  font-size:.74rem;text-transform:uppercase;letter-spacing:.17em;color:var(--texte-3);
  margin-bottom:clamp(12px,1.8vh,20px);
}
.integ-trait{height:1px;width:34px;background:var(--c);flex:none;opacity:.7}
.integ-grille{display:flex;flex-wrap:wrap;gap:9px}
.integ{
  display:inline-flex;align-items:center;gap:12px;
  padding:.62em 1.15em .62em .72em;border-radius:100px;
  /* Pastille sans aplat : un simple filet, le logo fait le travail. */
  border:1px solid var(--bord);background:none;
  font-size:.95rem;color:var(--texte-2);white-space:nowrap;
  transition:border-color .3s var(--ease),background .3s,transform .35s var(--ease-out);
}
.integ:hover{border-color:color-mix(in srgb,var(--c) 55%,transparent);background:rgba(17,24,38,.04);transform:translateY(-2px)}

/* ═══════════════════════════════════════════════════════════════
   LA RESPIRATION DES PASTILLES  (choix d'Admir, 06/08/2026)

   Chaque pastille flotte sur SA propre phase et SA propre duree. C'est la
   condition pour que le motif ne se mette jamais a battre : avec une duree
   unique, les seize pastilles d'un chapitre repassent au meme instant et
   l'oeil percoit une pulsation collective au lieu d'une vie diffuse.
   Duree = 4,6 s + 170 ms par rang → de 4,6 s a 7,2 s sur seize pastilles,
   des valeurs qui ne sont multiples d'aucune autre.

   ⚠️ On anime « translate », PAS « transform ».
   Ce sont deux proprietes CSS distinctes et elles se composent. « transform »
   est deja pris : par le survol (translateY(-2px)) et, quand Motion est la,
   par l'animation d'entree en WAAPI. Animer « transform » ici ecraserait
   l'un ou l'autre — la pastille sauterait au survol, ou l'entree serait
   annulee. Avec « translate », les trois cohabitent.

   AMPLITUDE : 2,5 px. Volontairement basse. Au-dela de 4 px, seize pastilles
   qui bougent en desordre dans une grille qu'on essaie de LIRE deviennent
   penibles — et cette grille repond a une vraie question du visiteur :
   « est-ce que ca marche avec mon Odoo ? ». Le mouvement ne doit jamais
   couter la lecture.

   COUT : nul. Une animation de transformation composee par le processeur
   graphique, aucun travail par image sur le fil principal, aucun JavaScript.
   ═══════════════════════════════════════════════════════════════ */
@keyframes souffle-integ{
  0%, 100%{ translate:0 -2.5px }
  50%     { translate:0  2.5px }
}
.integ{
  animation:souffle-integ 5s ease-in-out infinite;
  /* Duree propre a chaque rang, et depart deja en cours (delai NEGATIF) :
     sans lui, les seize pastilles partiraient toutes du meme point bas. */
  animation-duration:calc(4.6s + var(--i, 0) * 170ms);
  animation-delay:calc(var(--i, 0) * -430ms);
}
/* Au survol, la pastille se pose : on lit une etiquette immobile. */
.integ:hover{animation-play-state:paused}
/* « Reduire les animations » : la grille existe, elle ne bouge plus. */
@media (prefers-reduced-motion: reduce){
  /* Les pastilles ne flottent plus, mais elles restent reactives au survol :
     on coupe le mouvement permanent, pas la vie de l'interface. */
  .integ{animation:none}
}
.integ img{
  /* Les outils sont un argument de vente, pas une note de bas de page :
     19 → 30 px. C'est le logo qu'on reconnait de loin, pas le libelle. */
  width:30px;height:30px;flex:none;border-radius:6px;
  background:#fff;padding:3.5px;box-sizing:content-box;
}
.integ em{font-style:normal}
/* ── DIAGNOSTIC ───────────────────────────────────────────── */
.diagnostic{padding:clamp(80px,12vh,170px) var(--gouttiere);max-width:var(--max);margin-inline:auto}
.diag-entete{max-width:56ch;margin-bottom:clamp(38px,6vh,64px)}
.diag-entete h2{margin-bottom:1.4rem}
.diag-cadre{
  border:0;border-top:1px solid var(--bord);border-radius:0;
  background:none;
  overflow:hidden;
}
.diag-fil{
  display:flex;list-style:none;margin:0;padding:0;
  border-bottom:1px solid var(--bord);overflow-x:auto;scrollbar-width:none;
}
.diag-fil::-webkit-scrollbar{display:none}
.diag-fil li{
  display:flex;align-items:center;gap:9px;padding:15px clamp(14px,2.2vw,26px);
  font-size:.85rem;color:var(--texte-3);white-space:nowrap;
  border-right:1px solid var(--bord);transition:color .35s var(--ease);
}
.diag-fil li span{
  width:22px;height:22px;border-radius:50%;flex:none;
  display:grid;place-items:center;font-size:.72rem;
  border:1px solid var(--bord-fort);transition:background .35s,color .35s,border-color .35s;
}
.diag-fil li.actif{color:var(--texte)}
.diag-fil li.actif span{background:var(--vela);border-color:var(--vela);color:var(--noir);font-weight:600}
.diag-fil li.fait span{background:rgba(34,211,238,.16);border-color:var(--vela);color:var(--vela)}
.diag-scene{padding:clamp(26px,4vw,52px);min-height:clamp(400px,52vh,560px)}
.diag-question{font-size:clamp(1.25rem,2.2vw,1.75rem);font-weight:600;letter-spacing:-.022em;margin-bottom:.7rem;line-height:1.2}
.diag-aide{color:var(--texte-3);font-size:.92rem;margin-bottom:clamp(24px,3.4vh,36px)}
.cartes{display:grid;grid-template-columns:repeat(auto-fill,minmax(178px,1fr));gap:11px}
.carte{
  position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:7px;
  padding:19px 20px;border:1px solid var(--bord);border-radius:12px;text-align:left;
  background:rgba(255,255,255,.018);
  transition:border-color .3s var(--ease),transform .4s var(--ease-out),background .3s;
  animation:monte .55s var(--ease-out) backwards;
}
.carte:hover, .carte:focus-visible{border-color:var(--bord-fort);transform:translateY(-3px);background:rgba(255,255,255,.045)}
.carte.choisi{border-color:var(--vela);background:rgba(34,211,238,.09)}
.carte-titre{font-weight:500;font-size:1rem;letter-spacing:-.01em}
.carte-note{font-size:.81rem;color:var(--texte-3);line-height:1.5}
@keyframes monte{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.douleurs{display:flex;flex-direction:column;gap:9px;max-width:70ch}
.douleur{
  display:flex;align-items:flex-start;gap:14px;padding:16px 19px;
  border:1px solid var(--bord);border-radius:12px;text-align:left;width:100%;
  background:rgba(255,255,255,.018);line-height:1.5;
  transition:border-color .3s,background .3s,transform .35s var(--ease-out);
  animation:monte .5s var(--ease-out) backwards;
}
.douleur:hover{border-color:var(--bord-fort);transform:translateX(3px)}
.douleur.choisi{border-color:var(--c,var(--vela));background:color-mix(in srgb,var(--c,var(--vela)) 10%,transparent)}
.case{
  width:21px;height:21px;border-radius:6px;border:1.5px solid var(--bord-fort);flex:none;margin-top:1px;
  display:grid;place-items:center;transition:background .25s,border-color .25s;
}
.douleur.choisi .case{background:var(--c,var(--vela));border-color:var(--c,var(--vela))}
.case svg{opacity:0;transition:opacity .2s}
.douleur.choisi .case svg{opacity:1}
.diag-pied{display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin-top:clamp(26px,3.6vh,38px);padding-top:22px;border-top:1px solid var(--bord)}
.diag-retour{color:var(--texte-3);font-size:.9rem;transition:color .25s}
.diag-retour:hover{color:var(--texte)}
.diag-compte{color:var(--texte-3);font-size:.88rem;margin-left:auto}
.reponses{display:flex;flex-direction:column;gap:13px}
.reponse{
  border:1px solid var(--bord);border-left:2px solid var(--c);border-radius:12px;
  padding:22px 24px;background:color-mix(in srgb,var(--c) 5%,transparent);
  animation:monte .6s var(--ease-out) backwards;
}
.reponse-tete{display:flex;align-items:center;gap:11px;margin-bottom:.7rem}
.reponse-tete strong{font-size:1.06rem;font-weight:600;letter-spacing:-.015em}
.reponse-tete em{font-style:normal;font-size:.75rem;text-transform:uppercase;letter-spacing:.15em;color:var(--c)}
.reponse p{color:var(--texte-2);font-size:.96rem;line-height:1.7}
.bilan{
  margin-top:clamp(22px,3vh,32px);padding:24px;border-radius:14px;
  border:1px solid var(--bord);background:rgba(255,255,255,.03);
  display:flex;flex-wrap:wrap;align-items:center;gap:18px;
}
.bilan p{flex:1 1 260px;color:var(--texte-2);font-size:.95rem;line-height:1.6}
.bilan strong{color:var(--texte)}
/* ── MÉTHODE ──────────────────────────────────────────────── */
.methode{padding:clamp(70px,10vh,150px) var(--gouttiere);max-width:var(--max);margin-inline:auto}
.methode-intro{max-width:54ch;margin-bottom:clamp(42px,6vh,72px)}
.methode-intro p{color:var(--texte-2);margin-top:1.3rem}
.etapes{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));gap:clamp(18px,2.4vw,30px)}
/* Plus de cadre : les etapes sont separees par la grille et le numero, pas par une boite. Un mince filet a gauche suffit a les tenir. */
.etape{padding:2px 0 2px var(--carte-pad);border:0;border-left:1px solid var(--bord);border-radius:0;background:none}
.etape-n{display:block;font-size:.78rem;letter-spacing:.16em;color:var(--texte-3);margin-bottom:1.5rem;font-variant-numeric:tabular-nums}
.etape h3{margin-bottom:.75rem}
.etape p{color:var(--texte-2);font-size:.94rem;line-height:1.68}
.franchise{
  margin-top:clamp(30px,4.2vh,48px);padding:2px 0 2px var(--carte-pad);
  /* Il ne reste que le liseré corail — l'accent, pas la boite. */
  border:0;border-left:2px solid var(--pulsar);border-radius:0;
  background:none;max-width:76ch;
}
.franchise h3{margin-bottom:.75rem}
.franchise p{color:var(--texte-2);font-size:.95rem;line-height:1.7}
/* ── LEXIQUE ──────────────────────────────────────────────── */
.lexique{padding:clamp(70px,10vh,150px) var(--gouttiere);max-width:var(--max);margin-inline:auto}
.lexique-intro{max-width:56ch;margin-bottom:clamp(38px,5.5vh,62px)}
.lexique-intro h2{margin-bottom:1.3rem}
.mots{columns:2;column-gap:clamp(16px,2.2vw,26px)}
/* Plus de boite : une simple ligne de separation entre les entrees, comme
   dans un glossaire imprime. C'est plus sobre et ca se lit mieux. */
.mot-def{
  break-inside:avoid;margin:0;
  border:0;border-bottom:1px solid var(--bord);border-radius:0;background:none;
  transition:border-color .3s var(--ease);
}
.mot-def[open]{border-bottom-color:var(--bord-fort);background:none}
.mot-def summary{
  list-style:none;cursor:pointer;padding:17px 46px 17px 20px;position:relative;
  font-size:1rem;font-weight:500;letter-spacing:-.012em;line-height:1.4;
}
.mot-def summary::-webkit-details-marker{display:none}
.mot-def summary::after{
  content:"";position:absolute;right:20px;top:50%;width:11px;height:11px;
  border-right:1.5px solid var(--texte-3);border-bottom:1.5px solid var(--texte-3);
  transform:translateY(-70%) rotate(45deg);transition:transform .3s var(--ease),border-color .3s;
}
.mot-def[open] summary::after{transform:translateY(-30%) rotate(-135deg);border-color:var(--vela)}
.mot-def summary:hover{color:var(--texte)}
.mot-def p{
  padding:0 20px 19px;color:var(--texte-2);font-size:.93rem;line-height:1.72;
  animation:monte .4s var(--ease-out);
}
.mot-def p strong{color:var(--texte);font-weight:500}
.mot-def p em{font-style:normal;color:var(--vela)}
/* ── CONTACT ──────────────────────────────────────────────── */
.contact{padding:clamp(90px,14vh,190px) var(--gouttiere);text-align:center;max-width:var(--max);margin-inline:auto}
.contact h2{margin-bottom:1.2rem}
.contact > p{color:var(--texte-2);margin-bottom:2.5rem}
.contact-note{font-size:.87rem;color:var(--texte-3);margin-top:1.8rem}
/* ── PIED ─────────────────────────────────────────────────── */
.pied{
  padding:44px var(--gouttiere) 54px;border-top:1px solid var(--bord);
  display:flex;flex-direction:column;gap:11px;align-items:center;text-align:center;
  color:var(--texte-3);font-size:.88rem;
}
.pied-marque{display:flex;align-items:center;gap:10px;color:var(--texte);font-weight:600;font-size:1.02rem;letter-spacing:-.02em}
.pied-legal{font-size:.8rem;color:#7B8598}   /* 4,7:1 — au-dessus du seuil AA */

/* ═══ ADAPTATIONS ÉCRANS ═══════════════════════════════════ */

/* télévision et très grands écrans */
@media (min-width:1800px){
:root{--max:1560px}
body{font-size:21px;line-height:1.7}
h1{font-size:clamp(4.4rem,5.4vw,7rem)}
.cartes{grid-template-columns:repeat(auto-fill,minmax(232px,1fr))}
}

/* tablette */
@media (max-width:1000px){
.agent-phrase{max-width:none}
}

/* mobile */
@media (max-width:720px){
.nav{display:none}
.burger{display:block}
.hero{min-height:100svh;padding-top:96px}
.hero-actions .btn{flex:1 1 100%}
.mots{columns:1}
.cartes{grid-template-columns:1fr 1fr;gap:9px}
.carte{padding:15px 15px}
.carte-note{display:none}
.diag-fil li{padding:13px 14px;font-size:.8rem}
.diag-scene{min-height:auto}
.agent-num{display:none}
.integ{font-size:.86rem;padding:.52em .95em .52em .6em}
.integ img{width:24px;height:24px}
.bilan{flex-direction:column;align-items:stretch}
.bilan .btn{width:100%}
}

@media (max-width:400px){
.cartes{grid-template-columns:1fr}
}
/* ── mode paysage sur téléphone : la révélation horizontale ── */
.revelation{
  position:fixed;inset:0;z-index:200;display:none;
  background:radial-gradient(circle at 50% 42%,#0d1424,#04060c 72%);
  padding:26px 30px;
  flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:18px;
}
.revelation.on{display:flex}
.revelation h2{font-size:clamp(1.5rem,6vw,2.4rem)}
.revelation p{color:var(--texte-2);max-width:44ch;font-size:.95rem}
.rev-systeme{display:flex;gap:clamp(10px,3vw,26px);margin-top:6px}
.rev-astre{
  width:clamp(26px,7vw,46px);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 30% 28%,color-mix(in srgb,var(--c) 90%,white),color-mix(in srgb,var(--c) 34%,#070a12) 70%);
  box-shadow:0 0 26px -4px var(--c);
  animation:apparait .7s var(--ease-out) backwards;
}
.rev-fermer{position:absolute;top:16px;right:18px;color:var(--texte-3);font-size:.85rem}
@keyframes apparait{from{opacity:0;transform:scale(.5) translateY(16px)}to{opacity:1;transform:none}}

/* ── respect des préférences ──────────────────────────────── */
@media (prefers-reduced-motion:reduce){
*, *::before, *::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
[data-reveal], .mot{opacity:1!important;transform:none!important;animation:none!important}
#ciel{display:none}
}
@media (max-width:720px){
}
/* ═══════════════════════════════════════════════════════════════
   LE FILM EST LE FOND DE LA PAGE
   Un conteneur fixe, plein écran, derrière tout le contenu.
   Règle de Tic : la vidéo en fond, 100 % d'opacité, sans overlay, pilotée au scroll — jamais une vignette dans un cadre.
   ═══════════════════════════════════════════════════════════════ */
.film{position:fixed;inset:0;z-index:-3;overflow:hidden;background:var(--noir);transition:opacity 1s var(--ease)}
.plan{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 50%;
  opacity:0;transition:opacity .9s var(--ease);will-change:opacity;
}
.plan.actif{opacity:1}
#ciel{z-index:-2;opacity:.22}
.ambiance{z-index:-1;mix-blend-mode:screen;opacity:0}
.ambiance.on{opacity:.38}
/* le hero : plus de fausse planète, le film s'en charge */
.voile-hero{
  position:absolute;inset:0;pointer-events:none;
  /* ⚠️ D'OU VENAIT LA BANDE NOIRE.
     L'ancien voile etait un degrade `to top` opaque a 96 % EN BAS. Comme il
     est en `inset:0` dans la section, il s'arretait net au bord de celle-ci :
     noir dense d'un cote de la ligne, film nu de l'autre. D'ou la coupure
     horizontale franche entre le hero et la suite.
     Ici c'est une ellipse ancree derriere le texte, qui s'eteint dans
     TOUTES les directions — donc aucun bord droit, nulle part. */
  background:none;   /* le voile pleine largeur a disparu : c'est l'encadre
                        ci-dessous qui porte la lisibilite, lui seul. */
}
.voile-hero::after{content:none}
/* ── L'ENCADRE DU HERO — le seul bloc sombre qui reste sur le site ──
   Le film est clair ET charge juste derriere le titre principal : c'est le
   seul endroit ou du texte clair sur fond sombre reste le choix lisible.
   Partout ailleurs, le noir a ete retire. */
.hero-texte{
  /* 46ch etait la mesure de LECTURE d'un paragraphe — appliquee par erreur a
     tout l'encadre, titre compris. Resultat mesure le 06/08/2026 en 1440 px :
     l'encadre tombait a 494 px et le titre de 67 px cassait en SIX lignes,
     avec un « de » tout seul sur la cinquieme. La mesure de confort se pose
     donc sur le paragraphe (voir .hero-texte .chapo), pas sur le cadre. */
  max-width:min(100%,760px);
  padding:clamp(26px,3vw,44px);
  border-radius:var(--r);
  background:rgba(5,7,13,.72);
  border:1px solid rgba(255,255,255,.10);
}
.hero-texte, .hero-texte .chapo{color:#E9EDF5}
.hero-texte .chapo{max-width:46ch}
.hero-texte .sur-titre{color:#9AA6BC}
.hero h1{margin-bottom:1.15rem}
/* ═══════════════════════════════════════════════════════════════
   L'OBJET 3D DU CHAPITRE  (06/08/2026)

   UN SEUL par chapitre, jamais trois. Six chapitres x trois objets = dix-huit
   boucles simultanees sur une page qui porte deja le fond calcule et la
   respiration des pastilles : le mouvement se mangerait lui-meme. Les deux
   autres objets de chaque categorie servent aux pages produit et aux vitrines.

   Il est pose en ABSOLU dans .ch-fixe, donc il ne touche pas a la grille du
   panneau de texte. C'etait la condition pour l'ajouter sans rejouer la mise
   en page des six chapitres.

   Le mouvement est la RESPIRATION — le meme que les pastilles, choisi par
   Admir. Meme raison d'animer « translate » et « rotate » plutot que
   « transform » : ces proprietes se composent, et « transform » reste libre.
   ═══════════════════════════════════════════════════════════════ */
.ch-objet{
  position:absolute;
  /* DEBORDEMENT ASSUME. Le panneau fait jusqu'a 1080 px : en 1440, il ne
     reste qu'une bande de 180 px de chaque cote. Un objet contenu dans cette
     bande a l'air COINCE, pas pose — constate a l'apercu du 06/08. On le
     sort donc partiellement du cadre : un objet coupe par le bord se lit
     comme un choix, un objet ratatine se lit comme une erreur. */
  right:clamp(-90px,-4vw,-30px);
  top:16%;
  width:clamp(200px,23vw,360px);
  height:auto;
  z-index:1;                 /* sous le panneau de texte, jamais devant */
  pointer-events:none;
  filter:drop-shadow(0 26px 46px rgba(17,24,38,.20));
  animation:souffle-objet 7.5s ease-in-out infinite;
}
@keyframes souffle-objet{
  0%, 100%{ translate:0 -11px; rotate:-2.4deg }
  50%     { translate:0  11px; rotate: 2.4deg }
}
/* Rien ne doit deborder HORIZONTALEMENT de la page : un objet qui sort du
   cadre a droite creerait une barre de defilement laterale sur certains
   navigateurs. On coupe au niveau du chapitre, pas du body. */
.chapitre{overflow-x:clip}
/* Le panneau de texte repasse devant : l'objet decore, il ne gene jamais
   la lecture. Sans ca, il passerait par-dessus le titre sur ecran etroit. */
.ch-texte{position:relative;z-index:2}

@media (max-width:1100px){
  /* Sous cette largeur le panneau occupe toute la place : l'objet passerait
     derriere le texte et ne se verrait plus qu'en fragments. On le retire —
     mieux vaut rien qu'un morceau d'objet. */
  .ch-objet{display:none}
}
@media (prefers-reduced-motion: reduce){
  .ch-objet{animation:none}
}

/* ── les chapitres : du texte qui flotte sur le film ───────── */
.equipage{padding:0}
.equipage-piste{display:block}
.chapitre{position:relative;height:240svh;--p:0}
.ch-fixe{
  position:sticky;top:0;height:100svh;display:flex;align-items:center;
  padding:clamp(88px,11vh,120px) var(--gouttiere) clamp(40px,6vh,70px);
  max-width:calc(var(--max) + var(--gouttiere) * 2);margin-inline:auto;
}
.ch-fixe::before{
  content:"";position:absolute;top:0;bottom:0;left:50%;width:100vw;
  transform:translateX(-50%);pointer-events:none;z-index:-1;
  /* Plus aucun assombrissement pleine largeur : c'est la carte claire de
     .ch-texte qui porte la lisibilite, pas un aplat sur toute la page. */
  background:none;
}
/* Plus d'encadre : le texte du chapitre se pose directement sur le film.
   C'est la typographie qui porte, pas un panneau. */
.ch-texte{position:relative;max-width:48ch}
.ch-centre{max-width:38ch;margin-inline:auto;text-align:center}
.ch-centre::after{content:none}
.chapitre h3{
  font-size:clamp(2rem,4.4vw,3.5rem);font-weight:600;letter-spacing:-.035em;
  margin-bottom:.7rem;line-height:1;
}
.chapitre-retour .ch-fixe{justify-content:center}
.chapitre-retour .ch-fixe::before{
  background:none;
}
.chapitre-retour h3{font-size:clamp(1.6rem,3.8vw,3rem);margin-bottom:2rem}
.chapitre-retour .sur-titre{margin-bottom:1.1rem}
/* déploiement par paliers — après le mouvement, pendant la lecture */
/* Le deploiement par paliers visait six blocs de texte. Il n'en reste QU'UN :
   le titre. Garder l'ancienne liste le laissait a opacity:0 tant que la
   classe « s1 » n'etait pas posee — dans un apercu isole, le chapitre
   apparaissait donc vide. */
.js .chapitre .ch-titre{opacity:0;transform:translateY(26px);transition:opacity .7s var(--ease-out),transform .7s var(--ease-out)}
.js .chapitre.s1 .ch-titre{opacity:1;transform:none}
.js .chapitre.s2 .agent-phrase, .js .chapitre.s2 .agent-detail, .js .chapitre.s2 .btn{opacity:1;transform:none}
.js .chapitre.s3 .agent-liste li{opacity:1;transform:none;transition-delay:calc(var(--i) * 50ms)}
.js .chapitre.s4 .agent-integ{opacity:1;transform:none}
/* ⚠️ LE FILET NE DOIT PAS TOUCHER AU CARROUSEL.
   Il existe pour qu'aucun TEXTE ne reste invisible si le moteur d'animation
   n'a pas demarre. Mais « .chapitre * » incluait les vues du carrousel : au
   bout de 3,5 s, les quatre produits d'une categorie s'affichaient EN MEME
   TEMPS, empiles les uns sur les autres avec leurs legendes superposees.
   Constate en capture le 06/08/2026.
   Un carrousel cache ses vues par CHOIX, pas par accident — il n'a jamais
   besoin d'etre secouru. */
.secours:not(.moteur-ok) .chapitre *:not(.vue):not(.vue *){opacity:1!important;transform:none!important}

@media (max-width:1000px){.chapitre{height:230svh}.ch-texte{max-width:none} }
@media (max-width:720px){
.chapitre{height:220svh}
  /* Les voiles de ce palier sont definis plus bas, dans le bloc 9:16 :
     les redeclarer ici ne servait a rien, la derniere regle l'emportant. */
}
/* ═══════════════════════════════════════════════════════════════
   LES CHAPITRES : le texte occupe toute la largeur
   Le haut à gauche laisse la planète respirer à droite ;
   le bas s'étale sur toute la largeur en deux colonnes.
   Tient en un écran, en 16:9 comme en 9:16.
   ═══════════════════════════════════════════════════════════════ */
.ch-fixe{
  display:flex;flex-direction:column;justify-content:space-between;
  align-items:stretch;
}
.ch-fixe::before{
  background:none;
}
.ch-texte{
  position:relative;max-width:none;width:100%;
  display:flex;flex-direction:column;justify-content:space-between;height:100%;
  gap:clamp(16px,2.6vh,34px);
}
.ch-haut{max-width:46ch}
.chapitre h3{font-size:clamp(1.9rem,3.9vw,3.1rem);margin-bottom:.6rem}
.agent-phrase{font-size:clamp(1rem,1.42vw,1.28rem);margin-bottom:.9rem;max-width:30ch}
.agent-detail{font-size:clamp(.92rem,1.02vw,1rem);line-height:1.68;max-width:52ch}
.ch-bas{
  display:grid;grid-template-columns:minmax(200px,.8fr) minmax(280px,1.35fr);
  gap:clamp(20px,3vw,54px);align-items:start;
  padding-top:clamp(14px,2vh,24px);border-top:1px solid rgba(255,255,255,.09);
}
.ch-bas .integ-titre{margin-bottom:.9rem}
.ch-bas .agent-liste{margin:0}
.ch-bas .agent-liste li{font-size:.79rem;padding:.36em .8em}
/* Les outils sont un argument, pas une note de bas de page : on ne les
   rapetisse plus dans les chapitres. C'est cette regle-ci qui gagnait et
   ramenait les logos a 16 px malgre les 30 px definis plus haut. */
.ch-bas .integ{font-size:.92rem;padding:.55em 1.05em .55em .65em}
.ch-bas .integ img{width:28px;height:28px}
.ch-bas .integ-grille{gap:7px}

/* 9:16 et petits écrans : une seule colonne, contenu resserré */
@media (max-width:900px){
.ch-bas{grid-template-columns:1fr;gap:16px}
.ch-haut{max-width:none}
.agent-detail{max-width:none}
.ch-bas .integ:nth-child(n+9){display:none}
}
@media (max-width:720px){
.ch-fixe::before{
    background:none;
  }
.agent-detail{font-size:.9rem;line-height:1.6}
.ch-bas .agent-liste li:nth-child(n+5){display:none}
.ch-bas .integ:nth-child(n+7){display:none}
}
/* écrans courts (portable en 16:9 réel) : on allège encore */
@media (max-height:760px) and (min-width:901px){
.agent-detail{font-size:.9rem;line-height:1.6}
.ch-bas .agent-liste li:nth-child(n+6){display:none}
.ch-bas .integ:nth-child(n+11){display:none}
}
/* ── après le voyage : l'espace nu ─────────────────────────────
   À partir du diagnostic, le film s'éteint. Il ne reste que le noir
   et les étoiles en CSS : le texte redevient prioritaire. */
.espace-nu .film{opacity:0}
.espace-nu #ciel{opacity:.9}
.espace-nu .ambiance{opacity:0}
.espace-nu .grain{opacity:.22}
/* ═══════════════════════════════════════════════════════════════
   CHAPITRES — occupation des deux côtés, aucun temps mort
   Le titre à gauche, l'explication et les livrables à droite, les intégrations en bande basse. Cinq paliers étalés sur toute
   la course du chapitre : il apparaît toujours quelque chose.
   ═══════════════════════════════════════════════════════════════ */
.chapitre{height:190svh}
.ch-texte{
  display:grid;
  grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr);
  grid-template-rows:1fr auto;
  column-gap:clamp(28px,5vw,90px);row-gap:clamp(16px,2.4vh,30px);
  height:100%;align-items:start;
}
.ch-haut{grid-column:1;grid-row:1;align-self:center;max-width:none}
.ch-droite{grid-column:2;grid-row:1;align-self:center;max-width:46ch}
.ch-bas{grid-column:1 / -1;grid-row:2;display:block}
.ch-droite .agent-detail{max-width:none;margin-bottom:clamp(16px,2.4vh,26px)}
.ch-droite .integ-titre{margin-bottom:.75rem}
.ch-droite .agent-liste{margin:0}
.chapitre .agent-phrase{max-width:22ch}
/* le voile suit : sombre en bas et sur les deux bords, clair au centre */
.ch-fixe::before{
  background:none;
}
/* les cinq paliers */
.js .chapitre .ch-droite .agent-detail, .js .chapitre .ch-droite .integ-titre, .js .chapitre .ch-droite .agent-liste li{opacity:0;transform:translateY(24px);transition:opacity .7s var(--ease-out),transform .7s var(--ease-out)}
.js .chapitre.s3 .ch-droite .agent-detail{opacity:1;transform:none}
.js .chapitre.s4 .ch-droite .integ-titre, .js .chapitre.s4 .ch-droite .agent-liste li{opacity:1;transform:none;transition-delay:calc(var(--i,0) * 45ms)}
.js .chapitre.s5 .agent-integ{opacity:1;transform:none}
/* Repli sans Motion : l'entree ET la respiration, en LISTE. Le raccourci
   « animation » remplace toute la liste — declarer la seule entree ici
   supprimerait donc la respiration posee sur .integ. */
.js:not(.motion) .chapitre.s5 .integ{
  animation:monte .5s var(--ease-out) backwards,
            souffle-integ 5s ease-in-out infinite;
  animation-duration:.5s, calc(4.6s + var(--i,0) * 170ms);
  animation-delay:calc(var(--i) * 40ms), calc(var(--i,0) * -430ms);
}

@media (max-width:1000px){
.chapitre{height:200svh}
.ch-texte{grid-template-columns:1fr;grid-template-rows:auto auto auto;row-gap:clamp(14px,2vh,22px);align-content:center}
.ch-haut{grid-column:1;grid-row:1;align-self:end}
.ch-droite{grid-column:1;grid-row:2;align-self:start;max-width:none}
.ch-bas{grid-column:1;grid-row:3}
.ch-fixe::before{background:none;
  }
.voile-hero{
    background:none;
  }
/* Et pour liberer ce tiers haut : la bande d'integrations disparait.
     Elle debordait de 71 px hors du cadre collant de toute facon. */
  .ch-bas{display:none}
/* (le flou d'arriere-plan est desactive tout en bas du fichier : la regle
     doit venir APRES celle qu'elle remplace, sinon elle ne s'applique pas) */
  .chapitre .agent-phrase{max-width:none}
.ch-droite .agent-liste li:nth-child(n+5){display:none}
.integ:nth-child(n+7){display:none}
}

/* ── une seule pellicule, jamais echangee ─────────────────────
   Methode Tic : un <canvas> plein ecran ou l'on dessine l'image
   correspondant a la progression du scroll. Il apparait des que la
   premiere image est chargee, et ne disparait qu'apres le voyage.
   object-fit fait le recadrage : la meme sequence 16:9 sert le
   telephone en 9:16, sans second fichier. */
/* LE MOUVEMENT CONTINU DU FOND.
   Sur ordinateur, la vague ondule image par image (la « respiration » dans
   app.js). Sur telephone la sequence est trop courte pour cela — un
   va-et-vient n'y parcourrait que trois ou quatre images, on verrait des
   a-coups. Cette derive tres lente prend le relais : elle est composee par
   le processeur graphique, donc elle ne coute rien et reste fluide meme
   pendant le defilement. */
@keyframes derive-fond{
0%, 100%{transform:scale(1.06) translate3d(-1.2%,.6%,0)}
50%{transform:scale(1.13) translate3d(1.2%,-.8%,0)}
}
.film .plan{opacity:0;transition:opacity 1.2s var(--ease);animation:derive-fond 26s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){.film .plan{animation:none} }
.film.pret .plan{opacity:1}
.film.sans-film{background:radial-gradient(ellipse 80% 60% at 50% 45%,#0d1526,#05070d 75%)}
/* ── le panneau de droite ──────────────────────────────────────
   Un fond à la couleur de la catégorie, 20 % d'opacité, posé sur
   un flou d'arrière-plan : le texte devient lisible sans masquer
   la vague, qui reste visible et colorée à travers. */
.ch-droite{
  position:relative;
  padding:clamp(20px,2.4vw,30px) clamp(20px,2.4vw,32px);
  border-radius:clamp(14px,1.6vw,20px);
  background:color-mix(in srgb, var(--c) 20%, transparent);
  border:1px solid color-mix(in srgb, var(--c) 26%, transparent);
  backdrop-filter:blur(16px) saturate(125%);
  -webkit-backdrop-filter:blur(16px) saturate(125%);
  box-shadow:0 18px 60px -30px rgba(0,0,0,.8);
}
/* repli pour les navigateurs sans flou d'arrière-plan : un voile sombre dessous */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
.ch-droite{background:linear-gradient(rgba(255,255,255,.55),rgba(255,255,255,.55)),color-mix(in srgb, var(--c) 20%, transparent)}
}
.ch-droite .agent-detail{color:#DCE4F0}
.ch-droite .agent-liste li{
  border-color:color-mix(in srgb, var(--c) 40%, rgba(255,255,255,.12));
  background:rgba(255,255,255,.05);
  color:#DCE4F0;
}
.ch-droite .integ-titre{color:color-mix(in srgb, var(--c) 62%, #E9EDF5)}

@media (max-width:1000px){
.ch-droite{padding:clamp(16px,3vw,22px)}
}
/* ── corrections du panneau de droite ─────────────────────────
   1. Il apparaissait avant son contenu : une boîte vide flottait.
      Il se révèle maintenant EN MÊME TEMPS que son premier texte.
   2. Opacité du fond ramenée de 20 % à 10 %. */
.ch-droite{
  background:color-mix(in srgb, var(--c) 10%, transparent);
  border-color:color-mix(in srgb, var(--c) 20%, transparent);
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
.ch-droite{background:linear-gradient(rgba(255,255,255,.55),rgba(255,255,255,.55)),color-mix(in srgb, var(--c) 10%, transparent)}
}
.js .chapitre .ch-droite{
  opacity:0;transform:translateY(26px);
  transition:opacity .75s var(--ease-out),transform .75s var(--ease-out);
}
.js .chapitre.s3 .ch-droite{opacity:1;transform:none}
/* le contenu suit dans la foulée, sans double décalage */
.js .chapitre.s3 .ch-droite .agent-detail{transition-delay:.12s}

/* ═══════════════════════════════════════════════════════════════
   TÉLÉPHONE — refonte
   Le titre passait sous l'entête, et les paliers étalés laissaient
   l'écran vide pendant de longues portions de scroll. Sur un petit
   écran, tout doit tenir et apparaître vite.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width:720px){
.chapitre{height:150svh}
.ch-fixe{
    padding:clamp(96px,15vh,124px) var(--gouttiere) clamp(28px,5vh,48px);
    justify-content:center;
  }
.ch-texte{
    grid-template-rows:auto auto auto;
    align-content:center;row-gap:16px;height:auto;
  }
.chapitre h3{font-size:clamp(1.75rem,8.2vw,2.3rem);line-height:1.06;margin-bottom:.45rem}
.chapitre .agent-phrase{font-size:1rem;line-height:1.45;margin-bottom:0}
.ch-droite{padding:16px 17px;border-radius:14px}
.ch-droite .agent-detail{font-size:.88rem;line-height:1.6;margin-bottom:14px}
.ch-droite .agent-liste li:nth-child(n+4){display:none}
.ch-bas .integ-titre{margin-bottom:.6rem}
.integ{font-size:.8rem;padding:.45em .85em .45em .52em}
.integ img{width:21px;height:21px}
.integ:nth-child(n+7){display:none}
.agent-num{display:none}
/* deux paliers seulement : le contenu arrive vite, l'écran n'est jamais vide */
  .js .chapitre .ch-droite, .js .chapitre .agent-phrase, .js .chapitre .agent-detail, .js .chapitre .agent-liste li, .js .chapitre .agent-integ{transition-duration:.55s}
.js .chapitre.s1 .agent-phrase, .js .chapitre.s2 .ch-droite, .js .chapitre.s2 .agent-detail, .js .chapitre.s2 .integ-titre, .js .chapitre.s2 .agent-liste li, .js .chapitre.s3 .agent-integ{opacity:1;transform:none}
/* Repli sans Motion : l'entree ET la respiration, en LISTE. Le raccourci
   « animation » remplace toute la liste — declarer la seule entree ici
   supprimerait donc la respiration posee sur .integ. */
.js:not(.motion) .chapitre.s3 .integ{
  animation:monte .45s var(--ease-out) backwards,
            souffle-integ 5s ease-in-out infinite;
  animation-duration:.45s, calc(4.6s + var(--i,0) * 170ms);
  animation-delay:calc(var(--i) * 30ms), calc(var(--i,0) * -430ms);
}
/* hero : le titre respire, les boutons ne se chevauchent plus */
  .hero{padding-top:92px}
.hero h1{font-size:clamp(1.95rem,8.4vw,2.5rem);line-height:1.08}
.hero .chapo{font-size:.95rem;line-height:1.55}
.hero-actions{gap:9px;margin-top:1.3rem}
.hero-actions .btn{padding:.85em 1.2em;font-size:.92rem;text-align:center}
.indice-scroll{display:none}
}
/* .btn etant un conteneur flex, le nœud de texte fait d'un seul espace
   disparait au rendu : « Faire le diagnostic— 90 secondes ». On remet
   l'espace en marge. */
.btn-plus{margin-left:.35em}
@media (max-width:720px){.btn-plus{display:none} }

/* ═══════════════════════════════════════════════════════════════
   TELEPHONE — ce qui coute cher, et qu'on retire
   Ces regles sont volontairement EN DERNIER : une media query
   n'ajoute aucune specificite, seul l'ordre departage. Placees plus
   haut, elles etaient ecrasees par les regles de base.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width:820px){
/* ⚠️ LE FLOU D'ARRIERE-PLAN EST CE QUI TUE LA FLUIDITE SUR IPHONE.
     backdrop-filter oblige le navigateur a re-flouter tout ce qui se
     trouve derriere le panneau A CHAQUE IMAGE — et derriere, justement, il y a un fond qui bouge. Un fond sombre teinte donne la meme
     lisibilite pour aucun calcul. */
  .ch-droite{
    backdrop-filter:none !important;-webkit-backdrop-filter:none !important;
    background:linear-gradient(rgba(255,255,255,.55),rgba(255,255,255,.55)),
               color-mix(in srgb, var(--c) 26%, transparent);
  }
.entete.compact{
    backdrop-filter:none;-webkit-backdrop-filter:none;
    background:rgba(255,255,255,.72);
  }
/* Le grain est une texture fixe repetee sur tout l'ecran : sur telephone
     il ne se voit pas et coute une couche de composition de plus. */
  .grain{display:none}
}

/* ═══════════════════════════════════════════════════════════════
   TELEPHONE — la mise en page devient une page normale
   Six sections collantes de 210 % de hauteur d'ecran obligent Safari
   a recalculer leur position en permanence pendant le defilement,
   et c'est lui qui saccade — pas le fond. En flux normal, le
   defilement redevient celui du systeme : rien a calculer.
   Le site y gagne aussi en longueur : ~4 200 px au lieu de ~10 000.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width:820px){
.chapitre{height:auto;min-height:0}
.ch-fixe{
    position:relative;height:auto;
    padding-block:clamp(56px,10vh,88px);
    display:block;
  }
.ch-texte{height:auto;display:block}
.ch-haut, .ch-droite{max-width:none}
.ch-droite{margin-top:clamp(18px,3vh,26px)}

  /* (le style de .fond-m est global : il sert aussi sur ordinateur quand
     « reduire les animations » est actif — voir plus bas) */
}

/* La cascade d'apparition sur telephone : en CSS, pas en minuteries. */
@media (max-width:820px){
.js .chapitre h3{transition-delay:0ms}
.js .chapitre .agent-phrase{transition-delay:90ms}
.js .chapitre .ch-droite{transition-delay:170ms}
.js .chapitre .agent-detail{transition-delay:240ms}
.js .chapitre .agent-liste li{transition-delay:calc(300ms + var(--i) * 45ms)}
}

/* En flux normal, le voile de chaque chapitre devient une bande sombre
   franche entre deux sections — il etait concu pour un cadre collant qui
   occupait tout l'ecran. On le retire, et on protege le texte par une
   ombre portee : meme lisibilite, aucune couture. */
@media (max-width:820px){
.ch-fixe::before{display:none}
.chapitre h3,
.chapitre .agent-phrase{text-shadow:none}
}

/* ⚠️ RÈGLE RÉPARÉE — elle avait été détruite par un de mes correctifs.
   En retirant les ombres noires du thème sombre, l'expression
   `text-shadow:[^;]*` a débordé : faute de point-virgule avant l'accolade,
   elle a avalé le `}` de fin ET le sélecteur `.fond-m{` qui suivait. Les
   déclarations de .fond-m se sont retrouvées collées à `.chapitre h3`, et
   le fichier s'est retrouvé avec une accolade manquante — ce qui enfermait
   tout ce qui était ajouté ensuite dans le @media précédent.
   .fond-m porte les fonds sur téléphone : la casse n'était pas cosmétique. */
.fond-m{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 50%;
  opacity:0;transition:opacity 1.1s var(--ease);
  animation:derive-fond 34s ease-in-out infinite;
}
.fond-m.actif{opacity:1}
@media (prefers-reduced-motion:reduce){
/* on coupe les MOUVEMENTS, pas le decor : l'image reste, elle ne derive plus */
  .fond-m, .film .plan{animation:none}
.fond-m{transition:opacity .35s linear}
}
/* ═══════════════════════════════════════════════════════════════
   FIN DE FICHIER — LE NOIR EST RETIRE
   `.ch-fixe::before` est declare SEPT fois dans ce fichier (lignes ~784, 806, 847, 885, 932, 954, 961, 1169). C'est la meme maladie que les six
   `.chapitre{height}` releves par l'audit de Tic : chaque correctif
   successif a rajoute sa regle au lieu de modifier la precedente. Tant que
   ce n'est pas consolide, la seule facon fiable de retirer le voile sombre
   est de le neutraliser ici, en dernier.
   ⚠️ A CONSOLIDER : supprimer les sept declarations et n'en garder qu'une.
   ═══════════════════════════════════════════════════════════════ */
.ch-fixe::before, .chapitre-retour .ch-fixe::before{background:none!important}

/* ═══════════════════════════════════════════════════════════════
   LES VITRINES — trois projets, quatre surfaces
   Le contenu vient de assets/vitrines.js.
   ═══════════════════════════════════════════════════════════════ */
.vitrines{
  position:relative;
  padding:clamp(70px,10vh,150px) var(--gouttiere);
  max-width:var(--max);margin-inline:auto;
  --teinte:var(--vela);
}
/* Le fond coloré par projet : une transition, pas un recalcul. Il déborde
   la section en pleine largeur sans provoquer de barre horizontale. */
.vitrines::before{
  content:"";position:absolute;top:0;bottom:0;left:50%;width:100vw;
  transform:translateX(-50%);z-index:-1;pointer-events:none;
  transition:background 1.2s var(--ease);
  background:
    radial-gradient(70% 50% at 84% 4%, color-mix(in srgb,var(--teinte) 22%,transparent) 0%, transparent 62%),
    radial-gradient(58% 46% at 4% 94%, color-mix(in srgb,var(--teinte) 14%,transparent) 0%, transparent 60%);
}
.vitrines-tete{max-width:56ch;margin-bottom:clamp(30px,4.5vh,50px)}
.vitrines-tete .chapo{margin-top:1.2rem}

.vit-onglets{display:flex;gap:8px;margin-bottom:clamp(24px,3.4vh,38px);flex-wrap:wrap}
.vit-ong{
  font:inherit;font-size:.9rem;font-weight:500;cursor:pointer;
  padding:.55em 1.15em;border-radius:100px;
  border:1px solid var(--bord);background:rgba(255,255,255,.5);color:var(--texte-2);
  transition:background .3s var(--ease),color .3s,border-color .3s;
}
.vit-ong[aria-selected="true"]{background:var(--texte);color:#fff;border-color:var(--texte)}
.vit-ong .pt{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--c);margin-right:8px;vertical-align:1px}

.vit-piste{touch-action:pan-y;cursor:grab}
.vit-piste:active{cursor:grabbing}
.vit-projet{display:none}
.vit-projet.actif{display:block}

.vit-entete{display:flex;align-items:flex-end;gap:18px;margin-bottom:clamp(18px,2.6vh,30px);flex-wrap:wrap}
.vit-entete h3{font-size:clamp(1.25rem,2.2vw,1.7rem);letter-spacing:-.03em}
.vit-entete p{font-size:.94rem;color:var(--texte-3);margin-top:.35rem;max-width:56ch}
.vit-num{margin-left:auto;font-family:"Geist Mono",ui-monospace,monospace;font-size:.72rem;color:var(--texte-3);letter-spacing:.1em}

/* ── la scène : l'ordinateur, et le téléphone posé devant ── */
.vit-scene{position:relative;display:flex;align-items:flex-end;gap:clamp(14px,2.4vw,40px)}
.appareil{position:relative;flex:none}
.appareil.mac{flex:1;max-width:860px}
.appareil.tel{width:clamp(120px,15vw,208px);margin-bottom:2%}
.appareil .cadre{width:100%;display:block;position:relative;z-index:2;pointer-events:none}
.appareil .ecran{position:absolute;overflow:hidden;z-index:1;background:#fff}
.appareil.tel .ecran{border-radius:6%/2.8%}
.appareil .livrable{width:100%;display:block;will-change:transform}

/* Repli téléphone : pas de pilotage au défilement (ce serait du travail par
   image), mais un glissement lent en CSS — joué sur le compositeur. */
.vit-lent .appareil .livrable{animation:vit-glisse 46s ease-in-out infinite alternate}
@keyframes vit-glisse{from{transform:translate3d(0,0,0)}to{transform:translate3d(0,-58%,0)}}

.vit-surfaces{display:flex;gap:8px;flex-wrap:wrap;margin-top:clamp(16px,2.2vh,24px)}
.vit-surfaces span{
  font-size:.78rem;color:var(--texte-2);border:1px solid var(--bord);
  padding:.35em .9em;border-radius:100px;
}
.vit-outils{margin-top:clamp(20px,3vh,32px);padding-top:clamp(16px,2.2vh,24px);border-top:1px solid var(--bord)}
.vit-geste{display:none;font-size:.8rem;color:var(--texte-3);margin-top:18px}

@media (max-width:820px){
  .vit-scene{flex-direction:column;align-items:center;gap:18px}
  .appareil.mac{max-width:100%;width:100%}
  .appareil.tel{width:min(46vw,190px);margin:0}
  .vit-geste{display:block}
  .vit-onglets{overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none}
  .vit-onglets::-webkit-scrollbar{display:none}
  .vit-ong{flex:none}
}
@media (prefers-reduced-motion:reduce){
  .vitrines::before{transition:none}
  .vit-lent .appareil .livrable{animation:none}
}

/* ═══════════════════════════════════════════════════════════════
   LE CHAPITRE — deux colonnes qui alternent  (06/08/2026)
   Titre a gauche, maquette a droite ; puis l'inverse. Six chapitres
   identiques donnent un couloir. L'alternance donne un rythme, et l'oeil
   retrouve le titre parce qu'il a change de cote.
   ═══════════════════════════════════════════════════════════════ */
.ch-fixe{
  position:sticky;top:0;min-height:100svh;
  display:grid;align-items:center;
  grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  grid-template-rows:none;grid-template-areas:none;
  gap:clamp(28px,5vw,80px);
  padding:clamp(80px,10vh,120px) var(--gouttiere) clamp(40px,6vh,70px);
  max-width:1320px;margin-inline:auto;
}
.chapitre.droite .ch-mots{order:2}
.chapitre.droite .ch-scene{order:1}

.ch-mots{position:relative;z-index:3}

/* ── LE TITRE ET SON OBJET, cote a cote ──
   L'objet etait pose en ABSOLU sur la scene : il pouvait recouvrir la
   maquette ou le titre selon la taille de l'ecran. Il vit desormais dans une
   grille a deux colonnes avec le titre — il a donc sa PLACE, et un
   chevauchement devient structurellement impossible. */
.ch-tete{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  align-items:center;gap:clamp(12px,2vw,28px);
  grid-template-columns:minmax(0,1fr) var(--taille-objet);
  margin-bottom:clamp(18px,2.6vh,30px);
}
.ch-titre{
  margin:0;
  font-size:clamp(1.75rem,3.5vw,3.1rem);line-height:1.04;letter-spacing:-.04em;
  font-weight:600;color:var(--texte);
}
.ch-points{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
.ch-points li{
  position:relative;padding-left:22px;
  font-size:clamp(.95rem,1.15vw,1.06rem);color:var(--texte-2);max-width:36ch;
}
.ch-points li::before{
  content:"";position:absolute;left:0;top:.62em;
  width:8px;height:8px;border-radius:50%;background:var(--c);
}

/* ── L'OBJET : il monte en SPIRALE et TRIPLE de taille ──
   La trajectoire est une vraie spirale d'Archimede, obtenue sans sinus ni
   cosinus : on TOURNE d'un angle proportionnel a l'avancee, on AVANCE d'un
   rayon lui aussi proportionnel, puis on CONTRE-TOURNE du meme angle pour
   que l'objet reste d'aplomb. Trois transformations composees, aucune
   trigonometrie, aucun calcul par image — « --p » est deja pose par le
   moteur sur chaque chapitre.

   ⚠️ LA PLACE EST RESERVEE D'AVANCE. L'objet finit a 3x sa taille de depart :
   sa colonne de grille mesure donc la taille FINALE, et l'image demarre au
   tiers. Sans cette reserve, un objet qui triple viendrait recouvrir le titre
   en fin de course — exactement ce qu'on venait de corriger.

   LA LUEUR monte avec « --elan » : deux « drop-shadow » a la couleur de la
   categorie, une serree et une large, parce qu'une seule ombre donne un
   contour dur au lieu d'un rayonnement.
   ── */
.ch-tete{
  --taille-objet:clamp(108px,12.5vw,190px);   /* la place reservee = la taille FINALE */
}
.ch-objet{
  width:calc(var(--taille-objet) / 3);        /* le depart : un tiers */
  height:auto;flex:none;
  transform-origin:center;
  transform:
    rotate(calc(var(--p, 0) * 520deg))
    translate(calc(var(--p, 0) * 26%))
    rotate(calc(var(--p, 0) * -520deg))
    scale(calc(1 + var(--p, 0) * 2));
  /* La respiration reste par-dessus, sur la propriete « scale » : elle se
     compose avec le « transform » au lieu de l'ecraser. */
  animation:souffle-objet 7.5s ease-in-out infinite;
  /* La lueur ne se recalcule PLUS a chaque image : elle change avec la
     classe « vif », par transition. Un filtre recalcule soixante fois par
     seconde sur six objets est ce qui a bloque la page. */
  filter:drop-shadow(0 14px 26px rgba(17,24,38,.20))
         drop-shadow(0 0 6px color-mix(in srgb,var(--c) 32%,transparent));
  transition:filter .45s var(--ease);
}
@keyframes souffle-objet{0%,100%{scale:.97} 50%{scale:1.04}}
/* La colonne doit laisser l'objet deborder de son cadre pendant la spirale. */
.ch-tete,.ch-mots{overflow:visible}

/* ── LES DEUX ETATS DU DEFILEMENT ──
   « vif » est pose sur <html> pendant qu'on defile, retire 220 ms apres
   l'arret. Tout ce qui « s'allume » au defilement passe par ici : deux
   changements de style par salve, au lieu de soixante par seconde. */
.vif .ch-objet{
  filter:drop-shadow(0 14px 26px rgba(17,24,38,.22))
         drop-shadow(0 0 34px color-mix(in srgb,var(--c) 78%,transparent))
         drop-shadow(0 0 12px color-mix(in srgb,var(--c) 62%,transparent));
}
.vif .sat img{filter:saturate(2.2) brightness(1.18)}

/* ── L'ORBITE DIAGONALE autour du titre ──
   ⚠️ AUCUN « scaleY » sur l'anneau, et c'est une correction, pas un choix
   esthetique. Un ecrasement vertical suivi de rotations ne s'annule PAS dans
   l'element enfant : la matrice n'est pas commutative, et les logos
   sortaient cisailles — vus en capture, ils ressemblaient a des
   parallelogrammes. Seules des ROTATIONS PURES s'inversent exactement.
   La diagonale vient donc de l'inclinaison du plan (-18 degres) et du fait
   que l'anneau est bien plus large que haut, pas d'un ecrasement.

   « --tour » est ecrit UNE fois par image, sur la racine, pour toute la
   page. Les huit satellites s'y branchent en CSS : aucun calcul par
   satellite, aucune boucle par chapitre. */
.orbite{
  /* L'anneau encercle TOUT le bloc de texte et deborde largement : un
     satellite ne doit jamais croiser un titre ni une puce. Debordement
     lateral volontaire — c'est ce qui garantit qu'il passe a cote. */
  position:absolute;inset:-26% -34%;z-index:1;pointer-events:none;
  display:grid;place-items:center;
  transform:rotate(-18deg);
}
.anneau{
  position:absolute;width:100%;height:74%;display:grid;place-items:center;
  transform:rotate(var(--tour,0deg));
}
/* Le trait de l'anneau a ete retire : il etait dessine sur la taille du
   conteneur, alors que les satellites orbitent a un rayon fixe — les deux ne
   coincidaient pas, et un anneau que ses propres satellites debordent se lit
   comme une erreur. Ce sont les logos qui decrivent la trajectoire ; c'est
   suffisant, et c'est juste. */
.sat{
  position:absolute;top:50%;left:50%;
  width:clamp(28px,3.2vw,44px);height:clamp(28px,3.2vw,44px);
  margin:calc(clamp(28px,3.2vw,44px) / -2);
  display:grid;place-items:center;
  /* Tourner, avancer, se remettre droit : trois rotations pures et une
     translation. Le satellite est sur le cercle ET reste d'aplomb. */
  transform:
    rotate(calc(var(--s) * (360deg / var(--n))))
    translate(min(29vw,330px))
    rotate(calc(var(--s) * (-360deg / var(--n))));
}
.sat img{
  width:66%;height:66%;object-fit:contain;
  /* Une seule contre-rotation : celle de l'anneau, plus l'inclinaison. */
  transform:rotate(calc(var(--tour,0deg) * -1)) rotate(18deg);
  /* LA VIVACITE AU DEFILEMENT : saturation et lumiere montent avec l'elan. */
  /* Idem : deux etats, une transition. Jamais un calcul par image. */
  filter:saturate(1) brightness(1);
  transition:filter .4s var(--ease);
}

.carrousel{position:relative;z-index:2;width:100%;display:grid;place-items:center}
.vue{
  grid-area:1 / 1;margin:0;width:100%;
  display:flex;flex-direction:column;align-items:center;gap:14px;
  opacity:0;scale:.94;translate:0 26px;
  transition:opacity .55s var(--ease),scale .55s var(--ease-out),translate .55s var(--ease-out);
  pointer-events:none;
}
/* Les vues glissent LATERALEMENT : c'est ce qui dit au visiteur que l'axe
   horizontal est manipulable. « --glisse » suit le doigt pendant le geste ;
   la transition ne s'applique qu'au relachement, sinon la vue trainerait
   derriere le doigt. */
.vue.actif{opacity:1;scale:1;translate:var(--glisse,0) 0}
.vue.avant{opacity:0;scale:.92;translate:calc(var(--glisse,0px) - 52px) 0}
.vue.apres{opacity:0;scale:.92;translate:calc(var(--glisse,0px) + 52px) 0}
.carrousel{touch-action:pan-y;cursor:grab;outline:none}
.carrousel:active{cursor:grabbing}
.carrousel:focus-visible{outline:2px solid var(--c);outline-offset:14px;border-radius:8px}
/* Les puces deviennent des commandes : plus larges, cliquables au doigt. */
.jauge{cursor:pointer;padding:9px 0;background-clip:content-box}
.ch-scene{position:relative;display:grid;place-items:center;min-width:0}
.vue .ecran.page{
  display:block;border-radius:14px;object-fit:cover;object-position:top center;
  width:100%;max-width:620px;aspect-ratio:16/10;
  box-shadow:0 30px 70px -24px rgba(17,24,38,.35),0 2px 8px rgba(17,24,38,.10);
}
.coque{position:relative;display:block}
.vue.macbook .coque{width:min(100%,640px)}
.vue.iphone  .coque{width:min(58%,260px)}
.coque .chassis{width:100%;display:block;position:relative;z-index:2;pointer-events:none;
  filter:drop-shadow(0 34px 70px rgba(17,24,38,.34))}
.coque .hublot{position:absolute;z-index:1;overflow:hidden;background:#fff;display:block}
.vue.iphone .coque .hublot{border-radius:6%/2.8%}
/* ⚠️ « height: 100% » N'EST PAS FACULTATIF. Sans elle, l'image prend sa
   hauteur naturelle — plus courte que le hublot — et laisse une bande
   TRANSPARENTE en haut et en bas de l'ecran. La coque paraissait alors mal
   remplie, quelle que soit la capture. Avec la hauteur imposee, « cover »
   remplit toujours, meme si le ratio de la source ne correspond pas. */
.coque .ecran{
  width:100%;height:100%;display:block;
  object-fit:cover;object-position:top center;
}
.vue figcaption{font-size:.85rem;color:var(--texte-3);display:flex;gap:9px;align-items:baseline}
.vue figcaption b{color:var(--texte);font-weight:600}
.jauges{position:absolute;bottom:-24px;display:flex;gap:7px}
.jauge{width:26px;height:21px;border-radius:100px;background:rgba(17,24,38,.16);transition:background .3s}
.jauge.actif{background:var(--c)}

@media (max-width:900px){
  .ch-fixe{grid-template-columns:1fr;gap:clamp(20px,4vh,34px);align-content:center}
  .chapitre.droite .ch-mots,.chapitre.droite .ch-scene{order:initial}
  .ch-titre{font-size:clamp(1.7rem,7.2vw,2.3rem);max-width:none}
  .ch-points li{max-width:none}
  .ch-tete{--taille-objet:clamp(78px,20vw,120px)}
  .sat{width:26px;height:26px;margin:-13px;transform:rotate(calc(var(--s) * (360deg / var(--n)))) translate(min(42vw,190px)) rotate(calc(var(--s) * (-360deg / var(--n))))}
  .vue.iphone .coque{width:min(52vw,220px)}
  /* Moins de satellites sur telephone : l'anneau est plus serre, huit logos
     s'y chevaucheraient. */
  .sat:nth-child(n+6){display:none}
}
@media (prefers-reduced-motion: reduce){
  /* On retire les DEPLACEMENTS amples — la spirale, l'agrandissement par
     trois, la respiration — parce que ce sont eux qui genent. On garde
     l'orbite (rotation lente, pilotee en JS) et la lueur, qui ne sont pas
     des deplacements. Une page entierement figee passe pour cassee ; c'est
     l'erreur qu'on avait deja faite sur le fond du site. */
  .ch-objet{animation:none;transform:none}
  .ch-objet{transition:filter .5s var(--ease)}
}

/* ── LES TAILLES : on monte d'un cran partout ── */
.chapitre h3{font-size:clamp(2.3rem,5vw,4rem);line-height:1.02;letter-spacing:-.04em}
.agent-phrase{font-size:clamp(1.15rem,1.9vw,1.6rem);line-height:1.38}
.agent-detail{font-size:clamp(1rem,1.2vw,1.14rem);line-height:1.68}
.ch-texte .agent-liste li{font-size:.92rem;padding:.5em 1em}
.hero h1{font-size:clamp(2.4rem,5vw,4.2rem)}
.hero-texte .chapo{font-size:clamp(1.02rem,1.35vw,1.2rem)}
.methode-intro h2,.lexique-intro h2,.diag-entete h2,.contact h2,.vitrines-tete h2{
  font-size:clamp(2rem,4.4vw,3.4rem);letter-spacing:-.038em;
}
.etape h3{font-size:clamp(1.12rem,1.6vw,1.35rem)}
.etape p,.franchise p{font-size:1rem;line-height:1.7}
.mot-def summary{font-size:1.06rem}
.mot-def p{font-size:1rem}

/* ── L'ACCENT DE COULEUR SUR LES MOTS IMPORTANTS ──
   `--c` porte déjà la couleur du chapitre courant ; on s'en sert pour
   colorer les mots marqués, plutôt que d'introduire une teinte de plus. */
.titre .mot.accent,
.chapitre h3 .mot.accent{color:var(--c,var(--vela))}
.hero h1 .mot.accent{color:var(--vela)}
