/* =====================================================================
   IA PLUS QU'À — feuille de style
   ---------------------------------------------------------------------
   Structure : « Trust & Authority + Conversion » (ui-ux-pro-max, domaine
   landing) → héro, preuve, ce que je fais, méthode, chemin vers le contact.
   Style : « Soft UI Evolution » (ui-ux-pro-max, domaine style) → ombres
   douces multi-couches, rayons 10-16 px, cartes qui ont du poids,
   transitions 200-300 ms.

   RÈGLE DE MISE EN PAGE, une seule : un conteneur centré, UN SEUL bord
   gauche. La version précédente en avait deux (libellés à 190 px, contenu
   décalé) — c'est ce qui donnait l'impression que rien n'était aligné.
   ===================================================================== */

:root{
  /* couleur de marque — inchangée */
  --brand:#2B2D6B;
  --brand-600:#3A3D86;
  --brand-50:#EEEFF7;
  /* LIME — une seule valeur, celle de la marque, et UNE RÈGLE D'EMPLOI.
     Le lime ne s'évanouit pas parce qu'il est trop clair : il s'évanouit
     quand on lui demande de porter un TRAIT. Mesuré : lime sur blanc =
     1,18:1 (un filet de 2 px disparaît) ; encre sur lime = 15,6:1 (une
     pastille pleine claque). D'où la règle, valable partout sur le site :
       · le lime est TOUJOURS une surface pleine, avec du noir dessus
         (pastilles, étiquettes, surlignage, boutons sur fond sombre) ;
       · il n'est JAMAIS un filet, une bordure fine ni un contour.
     Les traits de structure sont en indigo, qui tient sur tous les fonds. */
  --accent:#C1FF72;        /* le lime de la marque — surfaces pleines */
  --accent-soft:#F2FEE0;   /* lime lavé — fonds de bloc */
  --on-accent:#141414;

  /* WASHES — fonds de section, un par bloc (Yassine, 24/08) */
  --w-lav:#EAE6FF;
  --w-blue:#E4F0FF;
  --w-pink:#FFEFFA;

  --ink:#15161A;
  --ink-2:#4E535C;
  --ink-3:#7C818A;

  --bg:#FFFFFF;
  --tint:#F6F7FB;        /* fond des sections alternées */
  --card:#FFFFFF;
  --line:#E4E6EF;
  --line-2:#D3D6E2;

  --on-dark:#FFFFFF;
  --on-dark-2:rgba(255,255,255,.74);
  --dark-line:rgba(255,255,255,.20);
  --dark-field:rgba(255,255,255,.08);

  /* mesure */
  --w:1120px;
  --w-text:44rem;
  --gut:1.5rem;

  --f:'Outfit',system-ui,-apple-system,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,monospace;

  /* formes — Soft UI Evolution */
  --r-sm:10px;
  --r:14px;
  --r-lg:20px;
  --r-pill:999px;

  --sh-1:0 1px 2px rgba(21,22,26,.05), 0 2px 8px rgba(21,22,26,.04);
  --sh-2:0 2px 4px rgba(21,22,26,.05), 0 10px 28px rgba(21,22,26,.07);
  --sh-3:0 4px 8px rgba(21,22,26,.06), 0 20px 48px rgba(21,22,26,.10);

  --t:220ms cubic-bezier(.2,.6,.3,1);
}

/* ─────────────── base ─────────────── */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;scroll-padding-top:88px}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--f);
  font-size:17px;line-height:1.65;-webkit-font-smoothing:antialiased;
  /* `clip` et non `hidden` : `hidden` ferait du body un conteneur de
     défilement et casserait les `position:sticky` (barre du haut, pile de
     l'offre). `clip` retient le débordement sans rien casser. */
  overflow-x:clip}
/* Une ligne trop longue fait démarrer les phrases en bout de ligne (signalé
   par Yassine le 25/08). Deux réglages : une mesure plafonnée en caractères,
   et `text-wrap:pretty`, qui empêche aussi les mots orphelins.            */
p{text-wrap:pretty}
.sd,.rt li span,.lede,.bigstat .d{max-width:68ch}
h1,h2,h3,h4,p{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
img,svg{max-width:100%}
a{color:inherit}
button{font:inherit}
:focus-visible{outline:2.5px solid var(--brand);outline-offset:3px;border-radius:6px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.skip{position:absolute;left:-9999px;background:var(--brand);color:#fff;padding:.7rem 1.2rem;z-index:999}
.skip:focus{left:0;top:0}

/* ─────────────── logo ───────────────
   Les pages satellites portaient déjà .lg-p / .lg-i / .lg-w, mais aucune
   règle ne les remplissait : le logo y sortait entièrement noir. On les
   définit ici, une bonne fois, et l'accueil passe sur les mêmes classes. */
.lg-p{fill:var(--accent)}      /* la pastille */
.lg-i{fill:#141414}            /* le « ia », en noir dans la pastille */
.lg-w{fill:var(--ink)}         /* « plus qu'à » */
.dark .lg-p{fill:var(--accent)}
.dark .lg-w{fill:#fff}

/* le conteneur — centré, unique */
.wrap{max-width:var(--w);margin:0 auto;padding:0 var(--gut)}
section{padding:clamp(4rem,7vw,6rem) 0}
section.tint{background:var(--tint)}
/* ⚠️ Les trois pastels de Yassine (lavande, bleu, rose) ne sont PAS des
   fonds de section — l'essai du 24/08 a été rejeté : « trop de dégradés,
   pas clair, moche ». Ils agrémentent des ÉLÉMENTS : pastilles de section,
   puces numérotées, encadrés. Le fond du site reste blanc / gris très clair,
   et le seul dégradé de la page est celui du héro.                        */
section.dark{background:var(--brand);color:var(--on-dark)}

/* ─────────────── typographie ─────────────── */
.eyebrow{display:inline-block;font-family:var(--f);font-size:.86rem;font-weight:600;
  letter-spacing:-.005em;color:var(--brand);background:var(--w-lav);
  padding:.42rem .95rem;border-radius:var(--r-pill);margin-bottom:1.2rem}
.dark .eyebrow{color:var(--on-dark);background:rgba(255,255,255,.12)}
h1{font-size:clamp(2.4rem,5vw,3.6rem);font-weight:600;letter-spacing:-.035em;line-height:1.08;
  text-wrap:balance}
h2{font-size:clamp(1.9rem,3.4vw,2.6rem);font-weight:600;letter-spacing:-.03em;line-height:1.15;
  text-wrap:balance}
h3{font-size:1.15rem;font-weight:600;letter-spacing:-.02em;line-height:1.35}
.lede{font-size:1.15rem;line-height:1.6;color:var(--ink-2)}
.dark .lede{color:var(--on-dark-2)}
.txt{color:var(--ink-2)}
.txt p+p{margin-top:1rem}
.txt b{color:var(--ink);font-weight:600}
.note{font-size:.95rem;color:var(--ink-3)}
/* Le cadre lime débordait trop en hauteur (Yassine, 26/08). On le resserre
   sur la lettre : moins de padding vertical, un rayon plus discret, et un
   décalage négatif qui le recale sur la ligne de base au lieu de le
   laisser flotter sous le texte. */
.hl{background:var(--accent);color:var(--on-accent);border-radius:4px;
  padding:0 .14em .02em;margin:0 -.04em;
  box-decoration-break:clone;-webkit-box-decoration-break:clone}

/* en-tête de section — centré, comme sur la quasi-totalité des sites de service */
.shead{text-align:center;max-width:var(--w-text);margin:0 auto clamp(2.5rem,4vw,3.5rem)}
/* ⚠️ `auto` À GAUCHE ET À DROITE, PAS SEULEMENT `margin-top` (26/08).
   `.shead` centre le TEXTE (`text-align:center`), mais `.lede` porte un
   `max-width:68ch` : sa BOÎTE, elle, restait collée au bord gauche du
   conteneur. Dans un `.shead.wide` (56 rem), la boîte du chapô fait
   ~43 rem — son centre optique tombait donc ~100 px à gauche de celui du
   titre. C'est ce décalage qu'on voyait sous « Les questions que se posent
   les entreprises françaises ». Le héro n'avait pas le défaut parce que
   `.hero .lede` déclare `margin:0 auto` de son côté.
   Corrige TOUS les en-têtes de section d'un coup, pas seulement celui-là. */
.shead .lede{margin:1rem auto 0}
.shead.left{text-align:left;margin-left:0}
.shead.wide{max-width:56rem}
/* TITRE DU CONSTAT RAMENÉ D'UN CRAN (26/08) : c'est le plus long de la page
   (deux propositions), et à la taille commune des h2 il occupait trois
   lignes pleines — on lisait un pavé avant de lire une phrase. Réduit, il
   tient en deux lignes et se lit d'un coup. Le titre reste le plus grand
   texte de sa section : la hiérarchie ne bouge pas. */
#constat .shead h2{font-size:clamp(1.6rem,2.6vw,2.1rem);letter-spacing:-.025em;line-height:1.2}

/* ─────────────── boutons ─────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  min-height:50px;padding:.8rem 1.6rem;border:0;border-radius:var(--r-pill);
  font-family:var(--f);font-weight:600;font-size:1rem;text-decoration:none;cursor:pointer;
  /* 28/08 — L'ACTION PRINCIPALE EST EN LIME, plus en indigo (choix Yassine).
     La règle du lime tient toujours : c'est une SURFACE pleine avec de
     l'encre dessus (15,6:1), jamais un filet ni un texte sur fond clair.
     Le liseré interne à 14 % d'encre lui rend un bord sur le papier crème,
     sinon le bouton flotte sans limite nette. */
  background:var(--accent);color:var(--on-accent);
  box-shadow:inset 0 0 0 1px rgba(20,20,20,.14),var(--sh-1);
  transition:transform var(--t),box-shadow var(--t),background var(--t)}
.btn:hover{background:#CCFE57;transform:translateY(-2px);
  box-shadow:inset 0 0 0 1px rgba(20,20,20,.14),var(--sh-2)}
.btn:active{transform:translateY(0)}
.btn.lime{background:var(--accent);color:var(--on-accent);
  box-shadow:inset 0 0 0 1px rgba(20,20,20,.14),var(--sh-1)}
.btn.lime:hover{background:#CCFE57;box-shadow:inset 0 0 0 1px rgba(20,20,20,.14),var(--sh-2)}
.btn.ghost{background:#fff;color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--line-2)}
.btn.ghost:hover{background:#fff;box-shadow:inset 0 0 0 1.5px var(--ink),var(--sh-1)}
.btn.ondark{background:var(--accent);color:var(--on-accent);box-shadow:var(--sh-2)}
.btn.ondark.ghost{background:transparent;color:#fff;box-shadow:inset 0 0 0 1.5px var(--dark-line)}
.btn.sm{min-height:42px;padding:.55rem 1.1rem;font-size:.94rem}
.btn .ic{width:17px;height:17px;flex:none}
.acts{display:flex;gap:.8rem;flex-wrap:wrap;align-items:center}
.shead .acts{justify-content:center}
.lnk{color:var(--brand);font-weight:600;text-decoration:none;border-bottom:1.5px solid var(--brand-50)}
.lnk:hover{border-bottom-color:var(--brand)}

/* ─────────────── cartes — un seul modèle, avec de la matière ─────────────── */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:1.7rem;box-shadow:var(--sh-1);
  transition:transform var(--t),box-shadow var(--t),border-color var(--t)}
.card:hover{transform:translateY(-3px);box-shadow:var(--sh-3);border-color:var(--line-2)}
.card .ico{width:46px;height:46px;border-radius:var(--r-sm);background:var(--brand-50);
  color:var(--brand);display:flex;align-items:center;justify-content:center;margin-bottom:1.1rem}
.card .ico svg{width:22px;height:22px}
.card h3{margin-bottom:.5rem}
.card p{color:var(--ink-2);font-size:.98rem;line-height:1.6}
.card .more{display:inline-flex;align-items:center;gap:.4rem;margin-top:1.1rem;
  font-size:.94rem;font-weight:600;color:var(--brand);text-decoration:none}
.card .more svg{width:15px;height:15px;transition:transform var(--t)}
.card:hover .more svg{transform:translateX(3px)}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:1.4rem}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem}
.grid-2{display:grid;grid-template-columns:repeat(2,1fr);gap:1.4rem}
.card.flat{box-shadow:none;padding:1.4rem}
.card.flat:hover{transform:none;box-shadow:var(--sh-1)}


/* ─────────────── le constat : une stat qui porte, et des questions ───────────────
   Trois cartes de chiffres identiques ne hiérarchisaient rien et ne disaient
   rien de Yassine. Une seule statistique reste, traitée en éditorial : c'est
   l'échelle qui la fait ressortir, pas une carte. Reprise du traitement de
   `maquette/da-haut-de-page.html`, que Yassine a retenu.                     */
/* le constat est seul dans sa section : c'est ce qui lui donne l'air */
.airy{padding:clamp(5rem,9vw,8rem) 0}
.ctop{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(2.5rem,6vw,5.5rem);
  align-items:center}
.airy .bigstat .n{font-size:clamp(3.8rem,7.2vw,5.8rem)}
.airy .bigstat .d{font-size:1.16rem;max-width:32ch}
.ctop .shead{text-align:left;margin:0;max-width:none}
.bigstat{border-left:3px solid var(--brand);padding-left:clamp(1.2rem,2vw,1.8rem)}
.bigstat .n{font-size:clamp(3.4rem,6.4vw,5rem);font-weight:700;letter-spacing:-.055em;
  line-height:.92;color:var(--ink)}
.bigstat .d{margin-top:1rem;font-size:1.12rem;line-height:1.5;color:var(--ink-2);max-width:30ch}
.bigstat .s{margin-top:1.2rem;font-size:.85rem;color:var(--ink-3);line-height:1.5;max-width:36ch}
/* le chiffre d'appui : l'écart de taille, sous le chiffre dominant */
.gap{margin-top:1.5rem;padding-top:1.4rem;border-top:1px solid var(--line);display:grid;gap:.5rem}
.gap .vs{font-size:.82rem;color:var(--ink-3);margin-bottom:.15rem}
.bars{display:grid;gap:.55rem;margin-top:.2rem}
.bar{display:grid;grid-template-columns:11.5rem 1fr auto;gap:.9rem;align-items:center}
.bar .bl{font-size:.88rem;color:var(--ink-2)}
.bar .bt{height:12px;border-radius:6px;background:var(--tint);
  box-shadow:inset 0 0 0 1px var(--line)}
.bar .bt i{display:block;height:100%;width:0;border-radius:6px;background:var(--brand);
  transition:width .9s cubic-bezier(.2,.7,.3,1) calc(var(--i,0) * 110ms)}
.drawn .bar .bt i{width:var(--w)}
.bar .bv{font-size:1.02rem;font-weight:700;color:var(--ink);letter-spacing:-.02em;
  min-width:3.1rem;text-align:right}
.gap .vs{font-size:.85rem;color:var(--ink-3)}

/* la progression 2023 → 2025 : trois valeurs sur une ligne, un signe « → »
   entre chacune. Source identique aux barres (INSEE, Insee Première 2120).
   DÉPLACÉE LE 27/08 DANS `.bigstat`, sous le chiffre dominant : elle y
   prouve le « triplé en deux ans » de la phrase, comme les barres juste
   en dessous prouvent « l'écart se creuse ». Deux règles sont tombées
   avec le déménagement — `.pv.now` (le surlignage lime du 18 %, devenu
   un doublon du grand chiffre) et `.pc` (la phrase, remontée dans `.d`).
   Le filet du haut est ce qui sépare la phrase de sa démonstration. */
.prog{display:flex;align-items:baseline;flex-wrap:wrap;gap:.55rem .9rem;
  margin-top:1.4rem;padding-top:1.2rem;border-top:1px solid var(--line)}
.prog .py{display:inline-flex;align-items:baseline;gap:.4rem}
.prog .pv{font-size:1.32rem;font-weight:700;letter-spacing:-.03em;color:var(--ink)}
.prog .pk{font-size:.82rem;color:var(--ink-3)}
.prog .pa{color:var(--ink-3);font-size:1rem}

/* ─────────────── les questions, en infographie ───────────────
   Retour aux six questions d'origine (Yassine, 25/08) — ce sont bien des
   questions que se pose un décideur, pas des affirmations. Un personnage
   au centre, trois bulles de chaque côté, une pointe vers lui : le bloc
   accroche l'œil au lieu d'aligner du texte.                           */
.qfig{display:grid;grid-template-columns:1fr auto 1fr;gap:clamp(1rem,2.4vw,2.2rem);
  align-items:center;max-width:66rem;margin:0 auto}
.qcol{display:grid;gap:.85rem}
.qb{position:relative;background:#fff;border:1px solid var(--line);border-radius:16px;
  padding:1rem 1.2rem;box-shadow:var(--sh-1);font-size:1rem;line-height:1.45;
  font-weight:500;color:var(--ink);
  transition:transform var(--t),box-shadow var(--t),border-color var(--t)}
.qb:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--line-2)}
.qb::after{content:"";position:absolute;top:50%;margin-top:-6px;width:12px;height:12px;
  background:#fff;transform:rotate(45deg)}
.qcol.l .qb::after{right:-7px;border-right:1px solid var(--line);border-top:1px solid var(--line)}
.qcol.r .qb::after{left:-7px;border-left:1px solid var(--line);border-bottom:1px solid var(--line)}
.qav{width:clamp(150px,17vw,210px);position:relative}
.qav svg{display:block;width:100%;height:auto}
/* ALLÉGÉE LE 26/08 (« très gras, très épais, pas très lisible, un peu
   grossier »). Deux causes cumulées, pas une :
     · la phrase entière était en 600, à 1,42 rem — du gras sur toute la
       longueur, donc plus rien qui ressorte ;
     · `<b>` n'ayant pas de `font-weight` déclaré, il héritait de
       `bolder` PAR-DESSUS ce 600 — « comment la vôtre fonctionne »
       sortait donc à 700/800, sur un aplat lime. D'où l'effet massif.
   Correction : le corps de phrase repasse en 400 (et en encre secondaire),
   la partie surlignée est FIXÉE à 600 — un gras simple, qui se détache
   parce que ce qui l'entoure est fin. L'interlignage s'ouvre de 1,35 à
   1,5. Le lime reste un aplat plein avec du noir dessus : la règle de
   marque ne bouge pas. */
.qsaid{margin:clamp(2.5rem,4vw,3.5rem) auto 0;max-width:46rem;text-align:center;
  font-size:clamp(1.1rem,1.8vw,1.3rem);font-weight:400;letter-spacing:-.012em;
  line-height:1.5;color:var(--ink-2)}
.qsaid b{font-weight:600;color:var(--on-accent);background:var(--accent);border-radius:6px;
  padding:.02em .18em .1em;box-decoration-break:clone;-webkit-box-decoration-break:clone}

/* le paragraphe qui suit les questions */
.after{max-width:44rem;margin:2.6rem auto 0;text-align:center;font-size:1.12rem;
  line-height:1.6;color:var(--ink-2)}
.after b{color:var(--ink);font-weight:600}

.mhead{padding-bottom:2.5rem}
.cta-band{padding-top:1rem;padding-bottom:clamp(4rem,7vw,6rem)}
.cta-band .acts{justify-content:center}

/* ═══════════ LE FIL ROUGE ═══════════
   Un seul trait lime parcourt toute la méthode : il démarre au diagnostic,
   se remplit au scroll, traverse les cinq étapes, arrive à la feuille de
   route, puis se ramifie vers les briques retenues. Toutes les animations
   de la section sont des variations de ce même trait — c'est ce qui les
   rend cohérentes entre elles.
   Aucune n'est un préalable à la lecture : tout le texte est présent dans
   la page dès le départ, l'animation ne fait que le souligner.          */

/* aligné à gauche sur le bandeau, pas centré : sinon le fil rouge et le
   texte d'introduction ne démarrent pas sur la même verticale.        */
.rail{position:relative;margin:2rem 0 0;--rx:26px}
.rail::before{content:"";position:absolute;left:var(--rx);top:26px;bottom:26px;width:2px;
  transform:translateX(-1px);background:var(--line);border-radius:2px}
.rail-fill{position:absolute;left:var(--rx);top:26px;width:2px;height:0;
  transform:translateX(-1px);background:var(--brand);border-radius:2px;z-index:1;
  box-shadow:0 0 0 5px rgba(43,45,107,.07)}
.rail-fill::after{content:"";position:absolute;left:50%;bottom:-5px;width:10px;height:10px;
  margin-left:-5px;border-radius:50%;background:var(--brand);
  box-shadow:0 0 0 5px rgba(43,45,107,.12)}

/* ─────────────── l'offre : la pile est À CÔTÉ, jamais au-dessus ───────────────
   Troisième version, et c'est la bonne lecture de la demande : l'empilement
   se fait dans une colonne latérale fixe, pas par-dessus le texte. Rien
   n'est jamais recouvert par le défilement — c'était le défaut des en-têtes
   collants. Au passage, le contenu occupe enfin toute la largeur : la
   version précédente laissait un tiers de la section vide.             */
/* La pile 01/02/03 sort de la mesure de lecture : trois colonnes de largeur
   symétrique (pile · texte · vide) placent le texte exactement sur l'axe
   central de la page, donc sous le titre de section. C'est ce que Yassine
   demandait — « décaler la navigation sur la gauche pour que le texte soit
   plus centré ». La section, elle, s'élargit à 1280 px pour que la colonne
   de texte garde une mesure confortable (~700 px) malgré les deux marges. */
.offerpage .wrap{max-width:1280px}
.offer{display:grid;
  grid-template-columns:minmax(0,236px) minmax(0,1fr) minmax(0,236px);
  column-gap:clamp(1.2rem,2.4vw,2.2rem);align-items:start}
/* ─── UN SEUL BORD GAUCHE (26/08) ───────────────────────────────────────
   La section changeait d'axe trois fois : en-tête centré, contenu aligné
   à gauche 100 px plus loin, phrase de fin re-centrée. C'est ça qui la
   faisait lire « brouillon », pas la quantité de texte. L'en-tête est
   maintenant DANS la grille, en colonne 2 : il démarre exactement sur la
   même verticale que les titres, les étapes, la carte et les leviers.
   (Applique enfin à cette section la règle posée en tête de fichier.) */
.offer>.shead{grid-column:2;grid-row:1;text-align:left;max-width:none;
  margin:0 0 clamp(2.2rem,3.5vw,3rem)}
.offer>.shead .lede{margin:1rem 0 0}
.offer>.shead h2{font-size:clamp(1.65rem,2.7vw,2.15rem);letter-spacing:-.025em;line-height:1.2}
.offer>.oside{grid-column:1;grid-row:2}
.offer>.ocol{grid-column:2;grid-row:2}
.offer>.ospace{grid-column:3;grid-row:2}
/* la troisième colonne ne porte rien : c'est elle qui ramène la colonne de
   texte au centre. Elle n'existe qu'au-dessus de 1180 px — en dessous, la
   place revient au texte plutôt que de rester vide. */
.ospace{display:block}
.oside{position:sticky;top:100px;display:grid;gap:.65rem;align-content:start}
.ocard{display:grid;grid-template-columns:auto 1fr;gap:.85rem;align-items:center;
  background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:.9rem 1rem;
  opacity:0;transform:translateY(10px);
  transition:opacity .5s var(--t),transform .5s var(--t),border-color var(--t),
             box-shadow var(--t),background var(--t)}
.ocard.shown{opacity:1;transform:none}
.ocard .oi{display:flex;align-items:center;justify-content:center;min-width:30px;height:28px;
  border-radius:9px;background:var(--tint);color:var(--ink-3);font-size:.78rem;font-weight:700;
  letter-spacing:.04em;transition:background var(--t),color var(--t)}
.ocard .oi svg{width:15px;height:15px;display:none}
.ocard .ol{display:block;font-size:1rem;font-weight:600;letter-spacing:-.02em;line-height:1.25}
.ocard .os{display:block;font-size:.84rem;color:var(--ink-3);margin-top:.12rem}
.ocard.is-active{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand),var(--sh-2)}
.ocard.is-active .oi{background:var(--accent);color:var(--on-accent)}
.ocard.is-done{background:var(--tint)}
.ocard.is-done .ol{color:var(--ink-2)}
.ocard.is-done .oi{background:var(--accent);color:var(--on-accent);min-width:28px}
.ocard.is-done .oi span{display:none}
.ocard.is-done .oi svg{display:block}

/* `.opart` est une <section> : sans ça elle hérite du padding global des
   sections et pose 100 px de vide au-dessus de chaque titre.          */
.opart{padding:0 0 clamp(3rem,6vw,5rem)}
.opart:last-child{padding-bottom:0}
.opart>h3{font-size:clamp(1.28rem,2vw,1.5rem);font-weight:600;letter-spacing:-.025em;
  line-height:1.2}
.opart .intro{margin-top:.7rem;color:var(--ink-2);font-size:1.1rem;line-height:1.6;
  max-width:68ch}
.opart .intro b{color:var(--ink);font-weight:600}

/* une étape sur le fil *//* une étape sur le fil *//* une étape sur le fil */
.stage{position:relative;padding-left:calc(var(--rx) + 2.9rem);padding-bottom:2.8rem}
.stage:last-child{padding-bottom:0}
.node{position:absolute;left:0;top:0;width:52px;height:52px;border-radius:16px;z-index:2;
  background:#fff;border:1.5px solid var(--line);display:flex;align-items:center;
  justify-content:center;font-weight:600;font-size:1.02rem;color:var(--ink-3);
  box-shadow:var(--sh-1);transition:background var(--t),color var(--t),
  border-color var(--t),box-shadow var(--t),transform var(--t)}
.stage.lit .node{background:var(--accent);border-color:transparent;color:var(--on-accent);
  box-shadow:var(--sh-2);transform:scale(1.04)}
.stage h3{font-size:1.05rem;font-weight:600;padding-top:.72rem}
.stage .sd{color:var(--ink-2);margin-top:.55rem}
/* Les pastilles « ce que ça produit » sont retirées (Yassine, 25/08 :
   « ça n'ajoute rien »). Le rail est resserré à la mesure du texte, ce qui
   supprime du même coup le vide qu'elles servaient à combler.          */
.chip{margin-top:1rem;display:inline-flex;align-items:center;gap:.55rem;background:#fff;
  border:1px solid var(--line);border-radius:var(--r-pill);padding:.5rem 1rem;
  box-shadow:var(--sh-1);font-weight:600;font-size:.95rem}
.chip i{font-style:normal;width:7px;height:7px;border-radius:50%;background:var(--brand);flex:none}
.chip em{font-style:normal;font-weight:500;color:var(--ink-3);font-size:.9rem}

/* la feuille de route — le livrable, rendu comme un document */
.stage.pivot .node{background:var(--accent);border-color:transparent;color:var(--on-accent)}
.stage.pivot .node svg{width:22px;height:22px}
.rt{background:#fff;border:1px solid var(--line-2);border-radius:var(--r-lg);
  box-shadow:var(--sh-1);overflow:hidden;margin-top:1.4rem}
.rt ol{padding:.4rem 1.6rem 1rem;counter-reset:rt}
.rt li{display:grid;grid-template-columns:auto 1fr;gap:.9rem;padding:1rem 0;
  border-bottom:1px solid var(--line);opacity:0;transform:translateY(8px);
  transition:opacity .5s var(--t),transform .5s var(--t)}
.rt li:last-child{border-bottom:0}
.rt.drawn li{opacity:1;transform:none}
.rt li::before{counter-increment:rt;content:counter(rt);width:26px;height:26px;border-radius:8px;
  background:var(--w-blue);color:var(--brand);display:flex;align-items:center;
  justify-content:center;font-size:.8rem;font-weight:700;margin-top:.15rem}
.rt li b{display:block;font-size:1.05rem;font-weight:600;letter-spacing:-.01em}
.rt li span{color:var(--ink-2);font-size:1rem;line-height:1.6}

/* la ramification : la feuille de route sélectionne les briques */
.bks{display:grid;gap:.55rem;margin-top:1.2rem}
/* hors du fil rouge : UNE colonne (Yassine, 26/08), pas de connecteur.
   Deux colonnes donnaient huit cartes de hauteurs inégales, décalées les
   unes des autres, avec des titres qui repassaient à la ligne. Sur une
   colonne, chaque levier se lit d'un trait : nom · ce que c'est · état. */
.bks.free{grid-template-columns:1fr;gap:.45rem;margin-top:1.4rem}
.bks.free .bk::before{display:none}
/* Le nom sur sa ligne, la description dessous, l'état à droite. Une
   colonne de noms à largeur fixe étranglait la description à ~280 px ;
   sur toute la largeur, chaque description tient en une ligne ou deux. */
.bks.free .bk{grid-template-columns:minmax(0,1fr) auto;gap:.1rem 1.1rem;
  padding:.95rem 1.3rem;align-items:center}
.bks.free .bn{grid-column:1;grid-row:1}
.bks.free .bd{grid-column:1;grid-row:2;margin-top:.12rem}
.bks.free .tag{grid-column:2;grid-row:1/3;align-self:center}
/* les leviers non retenus n'ont pas d'étiquette : la case reste, pour que
   les trois colonnes restent alignées, mais elle ne dessine rien */
.tag:empty{background:none;padding:0}
.bk{position:relative;display:grid;grid-template-columns:1fr auto;gap:1rem;align-items:center;
  background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:.9rem 1.1rem;
  transition:border-color var(--t),box-shadow var(--t),transform var(--t)}
.bk::before{content:"";position:absolute;right:100%;top:50%;margin-top:-1px;
  width:2.9rem;height:2px;background:var(--line-2);transform:scaleX(0);
  transform-origin:right center;transition:transform .45s var(--t);
  transition-delay:calc(var(--i,0) * 80ms)}
.bks.drawn .bk::before{transform:scaleX(1)}
.bk .bn{font-weight:600;font-size:1.05rem;color:var(--ink);transition:color var(--t)}
.bk .bd{display:block;font-weight:400;font-size:1rem;color:var(--ink-2);margin-top:.2rem;
  line-height:1.5}
.bk .tag{font-family:var(--f);font-size:.72rem;font-weight:700;letter-spacing:.02em;
  background:var(--accent);color:var(--on-accent);padding:.3em .7em;border-radius:var(--r-pill);
  white-space:nowrap;opacity:0;transform:scale(.75);
  transition:opacity .3s var(--t),transform .3s var(--t)}

/* LA SÉLECTION SE JOUE AU SCROLL — 3e demande de Yassine (25/08).
   Un déclenchement unique à l'entrée à l'écran ne se VOYAIT pas : tout
   était déjà joué quand on arrivait dessus. Ici c'est la progression du
   scroll dans le bloc qui pilote la séquence : les huit leviers d'abord
   à égalité, puis les retenus s'allument un par un, puis les autres
   passent en retrait. Aucun n'est jamais illisible.                    */
.bk{transition:background .45s var(--t),border-color .45s var(--t),
  box-shadow .45s var(--t),transform .45s var(--t)}
.bks.receded .bk:not(.on){background:transparent;border-color:var(--line);box-shadow:none}
.bks.receded .bk:not(.on) .bn{color:var(--ink-2)}
.bk.lit{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand),var(--sh-2)}
.bk.lit .tag{opacity:1;transform:none}

/* `.tailor` (la phrase « elle ne s'installe pas, elle s'adapte », centrée
   en fin de section) est SUPPRIMÉ le 26/08. C'était le dernier élément à
   ne pas être sur l'axe de gauche, et il redisait le chapô de section.
   La phrase n'est pas perdue : elle EST devenue le chapô, en tête. */

/* formations */
/* Formations — pas de catalogue, pas de plateforme (Yassine, 25/08) :
   un texte court, une photo en situation, et le partenaire en pied. */
.fbox{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,4rem);align-items:center}
.fbox .lede{margin-top:1rem;max-width:38ch}
.fphoto{position:relative;overflow:hidden;aspect-ratio:4/3;border-radius:var(--r-lg);
  background:#fff;border:1.5px dashed var(--line-2);display:flex;align-items:center;
  justify-content:center;text-align:center;padding:2rem}
.fphoto p{font-size:.9rem;color:var(--ink-3);line-height:1.65}
.fphoto b{display:block;color:var(--ink-2);font-weight:600;margin-bottom:.3rem}
/* même mécanique que le portrait : le cadre d'attente s'efface dès que la
   photo est là, et le pointillé avec — sinon on garderait un liseré autour
   d'une image qui remplit déjà tout. */
.fphoto:has(img){border-color:transparent;padding:0}
.fphoto img ~ p{display:none}
.fphoto img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  border-radius:inherit}
.partner{margin-top:1.8rem;padding-top:1.4rem;border-top:1px solid var(--line);
  display:flex;align-items:center;gap:1rem}
.partner .plogo{width:104px;height:44px;border-radius:10px;flex:none;
  border:1.5px dashed var(--line-2);display:flex;align-items:center;justify-content:center;
  font-size:.72rem;color:#B6BAC4;overflow:hidden}
/* un logo de certification ne se désature PAS et ne se retouche PAS : sa
   charte graphique impose ses couleurs et ses proportions. C'est la seule
   image de la page à qui on ne touche pas. */
.partner .plogo:has(img){border-color:transparent;width:auto;height:46px}
.partner .plogo img{height:46px;width:auto;max-width:none;object-fit:contain}
.partner p{font-size:.93rem;color:var(--ink-2);line-height:1.5}

/* ─────────────── en-tête ─────────────── */
.nav{position:sticky;top:0;z-index:100;background:rgba(255,255,255,.9);
  backdrop-filter:saturate(1.6) blur(14px);-webkit-backdrop-filter:saturate(1.6) blur(14px);
  border-bottom:1px solid transparent;transition:border-color var(--t),box-shadow var(--t)}
.nav.stuck{border-bottom-color:var(--line);box-shadow:0 1px 12px rgba(21,22,26,.05)}
.nav .in{max-width:var(--w);margin:0 auto;padding:0 var(--gut);height:76px;
  display:flex;align-items:center;gap:2rem}
.nav .links{margin-left:auto;display:flex;align-items:center;gap:.2rem}
.nav .links a{font-size:.97rem;font-weight:500;color:var(--ink-2);text-decoration:none;
  padding:.55rem .85rem;border-radius:var(--r-sm);transition:color var(--t),background var(--t)}
.nav .links a:hover{color:var(--ink);background:var(--tint)}
.nav .links a[aria-current="true"]{color:var(--brand);background:var(--brand-50)}
/* `.nav .links a` (0,2,1) l'emportait sur `.btn` (0,1,0) : le texte du bouton
   repassait en gris sur l'indigo. On rescope. */
.nav .links a.btn{margin-left:.9rem;color:#fff;background:var(--brand);padding:.55rem 1.1rem}
.nav .links a.btn:hover{color:#fff;background:var(--brand-600)}
.burger{display:none;margin-left:auto;width:46px;height:46px;border:0;background:none;
  cursor:pointer;align-items:center;justify-content:center;border-radius:var(--r-sm)}
.burger i{display:block;width:20px;height:2px;background:var(--ink);border-radius:2px;position:relative;
  transition:background var(--t)}
.burger i::before,.burger i::after{content:"";position:absolute;left:0;width:20px;height:2px;
  background:var(--ink);border-radius:2px;transition:transform var(--t),top var(--t)}
.burger i::before{top:-6px}.burger i::after{top:6px}
.burger[aria-expanded="true"] i{background:transparent}
.burger[aria-expanded="true"] i::before{top:0;transform:rotate(45deg)}
.burger[aria-expanded="true"] i::after{top:0;transform:rotate(-45deg)}
.menu{position:fixed;inset:76px 0 auto;z-index:110;background:#fff;display:none;
  flex-direction:column;padding:.5rem var(--gut) 2rem;box-shadow:var(--sh-2)}
.menu.open{display:flex}
.menu a{font-size:1.1rem;font-weight:500;text-decoration:none;padding:.95rem .2rem;
  border-bottom:1px solid var(--line)}
.menu .btn{margin-top:1.4rem;align-self:stretch;border-bottom:0}

/* ─────────────── héro — centré, la convention des sites de service ─────────────── */
.hero{padding:clamp(3rem,6vw,5rem) 0 0;text-align:center;
  /* la preuve est redevenue un élément du héro : plus rien à réserver
     en dessous, on retrouve la règle du 24/08 — le héro tient l'écran. */
  min-height:calc(100svh - 76px);display:flex;align-items:center;
  background:linear-gradient(180deg,var(--brand-50) 0%,rgba(238,239,247,0) 62%)}
/* ⚠️ MESURÉ SUR L'IPHONE DE YASSINE LE 30/08 (sonde `?diag`, écran 393 px) :
   `.wrap` sortait à 430 px de large — 37 px de plus que l'écran, soit
   exactement deux gouttières. Tout ce qu'il contenait débordait donc de
   18 px à droite, en paraissant décalé vers la droite.
   POURQUOI : la règle ci-dessus fait de `.hero` un conteneur FLEX, donc
   de `.wrap` un élément flex. Un élément flex a `min-width:auto` : il
   refuse de descendre sous la largeur minimale de son contenu. Or il
   contient la bande de logos, large de 100vw (393) — à quoi s'ajoutent
   ses propres 2 × 18,4 px de gouttière : 430.
   `min-width:0` lève ce refus ; `width:100%` lui redonne une largeur
   définie au lieu de la déduire du contenu.
   ⚠️ AUCUN NAVIGATEUR DE BUREAU NE REPRODUIT CE DÉFAUT — vérifié à 375,
   393 et 402 px. Il n'a été vu que sur l'appareil réel, via la sonde.
   Ne pas retirer ces deux propriétés en croyant qu'elles ne servent à
   rien : elles ne se voient que sur un vrai téléphone. */
.hero > .wrap{width:100%;min-width:0}
.hero .in{max-width:52rem;margin:0 auto}
.hero .eyebrow{margin-bottom:1.5rem}   /* 27/08 : décollé du titre */
.hero h1{margin-bottom:1.3rem}
.hero .lede{max-width:38rem;margin:0 auto;font-size:1.22rem}
.hero .acts{justify-content:center;margin-top:2.2rem}

/* ─────────────── bandeaux qui défilent ───────────────
   Un seul mécanisme pour deux usages : les logos d'outils et les noms de
   clients. La piste porte plusieurs copies du même jeu ; on la translate
   d'exactement UNE largeur de jeu, en pixels, ce qui rend la boucle
   invisible. Le nombre de copies est calculé en JS pour que la piste
   dépasse toujours la fenêtre — sinon on voit le vide à la fin du jeu,
   la piste s'arrête et repart d'un coup (défaut signalé le 25/08).     */
.marq{position:relative;overflow:hidden;width:100vw;margin-inline:calc(50% - 50vw)}
.marq::before,.marq::after{content:"";position:absolute;top:0;bottom:0;width:12%;
  z-index:2;pointer-events:none}
.marq::before{left:0;background:linear-gradient(90deg,#fff,rgba(255,255,255,0))}
.marq::after{right:0;background:linear-gradient(270deg,#fff,rgba(255,255,255,0))}
.tint .marq::before{background:linear-gradient(90deg,var(--tint),rgba(246,247,251,0))}
.tint .marq::after{background:linear-gradient(270deg,var(--tint),rgba(246,247,251,0))}
/* pas de `gap` : la boucle ne tombe juste que si chaque élément porte la
   même marge, la dernière comprise — un `gap` ne se répète pas après le
   dernier enfant et décale le raccord de quelques pixels. */
.marq .run{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  padding:.3rem clamp(1rem,4vw,3rem)}
.marq.rolling .run{flex-wrap:nowrap;justify-content:flex-start;width:max-content;
  padding-inline:0;animation:marq var(--dur,40s) linear infinite}
.marq.rolling:hover .run,.marq.rolling:focus-within .run{animation-play-state:paused}
@keyframes marq{from{transform:translate3d(0,0,0)}
                to{transform:translate3d(calc(-1 * var(--shift,50%)),0,0)}}

/* ─────────────── les outils, en filigrane ───────────────
   Version allégée (25/08) : la pastille blanche à bord arrondi, ombrée,
   faisait « grossier » — elle donnait à un logo de 20 px le poids d'une
   carte. Plus de fond, plus de bordure, plus d'ombre : le logo, son nom,
   et beaucoup d'air entre les deux. C'est le blanc qui porte le rythme. */
.tools{margin-top:clamp(1.6rem,3vw,2.2rem)}
.tools .lab{font-size:.85rem;color:var(--ink-3);margin-bottom:.7rem}
.tool{display:inline-flex;align-items:center;gap:.5rem;flex:none;
  margin:.35rem 2.2rem .35rem 0;transition:opacity var(--t)}
.tool img{width:20px;height:20px;flex:none;display:block;opacity:.9}
.tool b{font-size:.9rem;font-weight:500;letter-spacing:-.01em;color:var(--ink-2);
  white-space:nowrap}
/* un logo qui EST un mot se suffit — pas de nom redoublé à côté */
.tool.wm img{width:auto;height:14px}
.marq.rolling:hover .tool{opacity:.55}
.marq.rolling .tool:hover{opacity:1}

/* ─────────────── LE BANDEAU DE PREUVE ───────────────
   Format arrêté le 26/08 sur une référence de Yassine : étiquette à
   GAUCHE sur deux lignes, marques à droite, dégradés aux deux bords.
   Remplace le bloc de treize logos empilé dans le héro.

   PLEINE LARGEUR RÉELLE (100vw), pas la largeur du conteneur : c'est ce
   qui fait qu'une bande est une bande. Le `overflow-x:clip` posé sur
   <body> absorbe le débordement sans créer de conteneur de défilement —
   `hidden` aurait cassé tous les `position:sticky` de la page.

   HAUTEUR ANNONCÉE EN VARIABLE (`--band-h`) : le héro la retranche de sa
   propre hauteur d'écran, pour que le haut du bandeau reste visible
   au-dessus de la ligne de flottaison. Sans ça, la preuve tombait juste
   sous le pli — invisible pour qui ne défile pas. Si la bande change de
   hauteur, c'est la seule valeur à retoucher. */
/* ─────────────── « ILS ME CONFIENT LEURS MISSIONS » ───────────────
   27/08, 2ᵉ forme : LES CERCLES, à la façon d'un profil LinkedIn.
   Demande de Yassine, et c'est elle qui a débloqué le sujet — le détail
   du raisonnement est dans le commentaire du bloc, index.html.

   CE QUI REND LES CERCLES POSSIBLES : ils ne reçoivent PAS les logotypes
   de la bande, mais les ASSETS CARRÉS publiés par chaque marque
   (fichiers `-icone.png`). D'où `object-fit:cover` : l'image est carrée
   comme le cercle, il n'y a donc rien à rogner, elle le remplit d'un
   bord à l'autre. Un logotype couché passé là-dedans, lui, serait
   massacré — c'est pour ça qu'on ne mélange pas les deux jeux.

   LE CHEVAUCHEMENT SE LIT GRÂCE À L'ANNEAU BLANC, pas grâce à l'ombre :
   sur un fond presque blanc une ombre portée ne détache rien, alors
   qu'un anneau de 2 px découpe franchement chaque pastille de celle du
   dessous. C'est le même procédé que les piles d'avatars de LinkedIn.
   L'ordre de superposition est inversé (la 1ʳᵉ passe au-dessus) pour que
   la pile parte vers la droite, sens de lecture.

   ELLE EST BLANCHE, PAS GRISE. Le héro est un dégradé qui, à cette
   hauteur, est déjà presque blanc : une pastille grise y ferait une
   tache sale. Blanc + filet d'un pixel, comme les cartes du site. */
/* 27/08 : réduite d'un cran à la demande de Yassine. Même esprit — la
   pile de cercles et les deux lignes — mais l'ensemble recule : cercles
   28 px au lieu de 36, ombre supprimée, texte d'un demi-point plus bas. */
.hero .via{display:inline-flex;align-items:center;gap:.7rem;margin-top:1.5rem;
  padding:.34rem .85rem .34rem .42rem;border-radius:999px;
  background:var(--card);border:1px solid var(--line)}
.via-av{display:inline-flex;align-items:center}
/* `position:relative` N'EST PAS DÉCORATIF : sans lui, `z-index` ne
   s'applique pas et c'est le dernier cercle du source qui passe devant,
   donc la pile se recouvre à l'envers du sens de lecture. */
.av{position:relative;width:28px;height:28px;border-radius:50%;overflow:hidden;flex:none;
  background:var(--card);box-shadow:0 0 0 2px var(--card);
  transition:margin-left var(--t)}
/* Le recouvrement est volontairement PLUS FAIBLE que sur une pile
   d'avatars LinkedIn (un quart, pas un tiers). Là-bas ce sont des
   visages : en cacher la moitié ne gêne pas. Ici chaque cercle porte un
   symbole — un soleil, un « M », un « G » — qui cesse d'être
   identifiable dès qu'il est mordu. Sans décalage du tout, en revanche,
   trois cercles espacés ne forment plus un groupe mais une énumération. */
.av + .av{margin-left:-7px}
.via-av .av:nth-child(1){z-index:3}
.via-av .av:nth-child(2){z-index:2}
.via-av .av:nth-child(3){z-index:1}
.av img{width:100%;height:100%;object-fit:cover;display:block}
/* au survol la pile s'ouvre : chaque marque redevient entièrement
   visible, ce que le chevauchement empêche au repos. */
.via:hover .av + .av{margin-left:2px}
.via-tx{font-size:.78rem;color:var(--ink-3);line-height:1.28;
  padding-left:.75rem;border-left:1px solid var(--line)}
.via-tx b{display:block;font-weight:600;color:var(--ink-2);white-space:nowrap}
.via-tx span{display:block;font-size:.7rem;margin-top:.1rem;white-space:nowrap}
@media(max-width:560px){
  /* les cercles plus les deux lignes dépassent l'écran d'un téléphone
     étroit : la pastille se plie, et le filet vertical devient
     horizontal. */
  .hero .via{flex-direction:column;gap:.55rem;border-radius:18px;padding:.85rem 1.1rem}
  .via-tx{padding:.6rem 0 0;border-left:0;border-top:1px solid var(--line);
    text-align:center;align-self:stretch}
  .via-tx b,.via-tx span{white-space:normal}
}

/* ─────────────── LA PREUVE, DANS LE HÉRO ───────────────
   5ᵉ forme (27/08) : UNE BANDE QUI DÉFILE, DISCRÈTE.
   Retour de Yassine sur la 4ᵉ et sur les trois variantes du matin :
   « un bandeau qui défile », « assez subtil », « un peu grossi ».
   Les formes écartées, à ne pas ressortir : bloc empilé · bandeau plein
   écran à étiquette gauche · grille fixe de dix cellules · les trois
   variantes chiffrées de la planche `bandeau-defilant.html`.

   UN SEUL NOMBRE COMMANDE LA DISCRÉTION : `--band-k`. Il multiplie toutes
   les hauteurs d'un coup. C'est volontairement le seul réglage : régler
   les logos un par un, c'est reperdre l'égalité de poids visuel qui a
   demandé un relevé au pixel de chaque fichier (voir SOURCES.md).
     0.85 → très effacé · 1 → l'actuel · 1.2 → affirmé
   La hauteur moyenne d'un logo vaut 20 px × `--band-k`.

   PAS DE FILET AU-DESSUS (demande de Yassine) : c'est ce trait qui
   faisait de la preuve un bloc rapporté sous le héro. La bande n'a donc
   ni fond, ni bordure — elle partage le fond du héro. */
/* 28/08 : la bande est posée TOUT EN BAS du héro. Le padding-bottom du
   héro est passé à 0 (voir .hero) : c'est elle qui ferme la section. */
.proof3{--band-k:1;margin-top:clamp(5rem,9vw,8rem);padding-bottom:clamp(1.6rem,2.6vw,2.2rem)}

/* étiquette centrée, en capitales très espacées : l'interlettrage suffit à
   dire que c'est une mention et non du texte à lire. */
.pb-lab{text-align:center;font-size:.7rem;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-3);margin-bottom:clamp(.9rem,1.7vw,1.2rem)}

/* LES BORDS S'ÉTEIGNENT PAR MASQUE, PAS PAR VOILE BLANC. Les dégradés
   blancs de `.marq` (posés pour la bande d'outils, qui vit sur du blanc)
   feraient ici deux taches claires sur le dégradé du héro. Un masque
   efface vers la transparence : il marche sur n'importe quel fond, et
   restera juste si le fond du héro change un jour. */
.proof3 .marq::before,.proof3 .marq::after{display:none}
.proof3 .marq{-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.proof3 .marq .run{padding-block:.35rem}

/* la cellule. Pas de `gap` : la boucle ne tombe juste que si CHAQUE
   élément porte la même marge, le dernier compris — un `gap` ne se répète
   pas après le dernier enfant et décale le raccord de quelques pixels. */
.slot{flex:none;display:flex;align-items:center;justify-content:center;
  margin-right:clamp(2.2rem,5vw,3.6rem)}
/* `aspect-ratio` DONNE LA LARGEUR AVANT LE CHARGEMENT DE L'IMAGE. C'est
   ce qui permet à site.js de mesurer la piste dès l'analyse du document :
   sans lui, une image en `width:auto` mesure zéro, la mesure échoue et la
   bande ne démarre jamais. Il évite aussi tout saut de mise en page. */
.slot img{height:calc(var(--h,20px) * var(--band-k,1));width:auto;
  aspect-ratio:var(--r,4);display:block;
  filter:grayscale(1);opacity:var(--o,.5);
  transition:filter var(--t),opacity var(--t)}
/* au survol la bande s'arrête (site.css `.marq.rolling:hover`) et TOUT
   s'efface un peu, sauf le logo pointé qui retrouve ses couleurs : c'est
   le seul moment où la couleur des marques est autorisée. Le reste du
   temps, treize encres d'origine écraseraient le titre juste au-dessus. */
.proof3 .marq:hover .slot img{opacity:calc(var(--o,.5) * .55)}
.slot:hover img,.proof3 .marq:hover .slot:hover img{filter:none;opacity:1}
/* repli si un fichier manque : le nom s'affiche à la place du logo */
.slot i{font-style:normal;font-family:var(--mono);font-size:.6rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3);text-align:center;line-height:1.2}
.slot img ~ i{display:none}

/* bandeau de preuve */
.proof{padding:2.2rem 0 0;text-align:center}
.proof .lab{font-size:.88rem;font-weight:500;color:var(--ink-3);margin-bottom:1rem}
.proof .row{display:flex;flex-wrap:wrap;justify-content:center;gap:.6rem 2rem}
.proof .row b{font-size:1.02rem;font-weight:600;color:var(--ink-2);letter-spacing:-.015em}
.proof .via{margin-top:1rem;font-size:.9rem;color:var(--ink-3);max-width:46rem;
  margin-left:auto;margin-right:auto}

/* ─────────────── référentiel, briques, moi ─────────────── */
.lay{display:flex;gap:1.1rem;align-items:flex-start}
.lay .n{flex:none;width:38px;height:38px;border-radius:var(--r-sm);background:var(--brand-50);
  color:var(--brand);display:flex;align-items:center;justify-content:center;
  font-size:.9rem;font-weight:600}
.card.key{border-color:var(--brand);box-shadow:var(--sh-2)}
.card.key .n{background:var(--accent);color:var(--on-accent)}
.nots{display:grid;grid-template-columns:repeat(2,1fr);gap:.7rem}
.not{display:flex;gap:.75rem;align-items:center;background:#fff;border:1px solid var(--line);
  border-radius:var(--r);padding:.9rem 1.1rem;color:var(--ink-2)}
.not svg{flex:none;width:16px;height:16px;color:var(--ink-3)}
/* `align-items:center` faisait flotter le portrait au milieu d'une colonne
   de texte bien plus haute ; et les boutons n'avaient aucune respiration
   au-dessus d'eux — c'est ce qui les faisait paraître mal placés. */
.me{display:grid;grid-template-columns:300px 1fr;gap:3rem;align-items:center}
.me .acts{margin-top:1.9rem}
.me .figs{margin-top:2.4rem}
.portrait{position:relative;overflow:hidden;aspect-ratio:5/7;border-radius:var(--r-lg);
  background:var(--tint);border:1px solid var(--line);display:flex;align-items:center;
  justify-content:center;padding:1.5rem;text-align:center;box-shadow:var(--sh-1)}
.portrait p{font-family:var(--f);font-size:.9rem;color:var(--ink-3);line-height:1.7}
/* LE CADRE D'ATTENTE S'EFFACE DÈS QUE LA PHOTO EST LÀ : plus de bordure ni
   de fond une fois l'image en place — sinon on verrait un liseré autour
   d'un portrait qui remplit déjà tout le cadre. */
.portrait:has(img){border-color:transparent;background:none}
.portrait img ~ p{display:none}
/* `cover` et non `contain` : le cadre est en 4/5 (portrait) et la photo
   fournie est carrée. `cover` remplit la hauteur et rogne les CÔTÉS —
   quelques centimètres d'épaules — au lieu de couper le haut du crâne.
   `object-position` remonte légèrement le cadrage pour que le visage
   tombe dans le tiers supérieur, comme sur un portrait posé. */
.portrait img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:50% 12%;border-radius:inherit}
/* 28/08 — LE SENS DE `object-position` EST CONTRE-INTUITIF ICI, note-le :
   portrait.jpg fait 832×1255 (plus haut que le cadre), donc `cover` rogne
   EN HAUT ET EN BAS. Faire DESCENDRE le visage dans le cadre = DIMINUER
   le pourcentage (on montre davantage le haut de la photo), pas
   l'augmenter. Le 48 % du 27/08 le remontait, à l'inverse du but. */

/* ─────────────── les chiffres du parcours ───────────────
   ⚠️ VALEURS À FOURNIR PAR YASSINE. Les cases marquées « .todo » portent un
   repère visible exprès : aucun chiffre n'est inventé ici (règle du projet,
   « zéro statistique empruntée non vérifiée »). Retirer la classe .todo
   quand la valeur réelle est saisie.                                     */
.figs{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));gap:1px;margin-top:2.2rem;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden}
.fig{background:#fff;padding:1.25rem 1.3rem}
.fig .fv{font-size:clamp(1.6rem,2.6vw,2.05rem);font-weight:700;letter-spacing:-.045em;
  line-height:1;color:var(--brand)}
.fig .fk{margin-top:.45rem;font-size:.88rem;color:var(--ink-2);line-height:1.4}
.fig.todo{background:repeating-linear-gradient(135deg,#fff,#fff 9px,var(--tint) 9px,var(--tint) 18px)}
.fig.todo .fv{color:var(--ink-3)}

/* le bandeau d'outils, quand il sert d'appui au déploiement : il répond à
   la ligne « l'outil qui tient chez vous » de la feuille de route, donc il
   se place là, et pas en décoration de héro. */
.opart .tools{margin-top:1.6rem;padding-top:1.3rem;border-top:1px solid var(--line)}
.opart .marq{width:auto;margin-inline:0}
.opart .marq::before,.opart .marq::after{width:7%}

/* ─────────────── contact ─────────────── */
.cbox{display:grid;grid-template-columns:1fr 1fr;gap:3rem;align-items:start}
.form{display:grid;gap:.9rem}
.field label{display:block;font-size:.9rem;font-weight:500;color:var(--on-dark-2);margin-bottom:.4rem}
/* « facultatif » : dit à l'œil ce qu'on peut sauter, sans alourdir le libellé */
.field .opt{font-size:.75rem;font-weight:400;letter-spacing:.04em;text-transform:uppercase;
  color:rgba(255,255,255,.45);margin-left:.45rem}
.field input,.field textarea{width:100%;font-family:var(--f);font-size:1rem;padding:.85rem 1rem;
  border:1px solid var(--dark-line);border-radius:var(--r-sm);background:var(--dark-field);
  color:#fff;transition:border-color var(--t),background var(--t)}
.field textarea{min-height:120px;resize:vertical}
.field ::placeholder{color:var(--on-dark-2)}
.field input:focus,.field textarea:focus{border-color:var(--accent);background:rgba(255,255,255,.12);outline:none}
/* le piège à robots : présent dans le DOM, jamais à l'écran ni au clavier.
   `display:none` serait détecté par les moissonneurs les plus soignés —
   on le sort du cadre à la place. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* consentement — case NON pré-cochée, exigée par le RGPD */
.consent{display:flex;gap:.65rem;align-items:flex-start;margin-top:.2rem}
.consent input{flex:none;margin-top:.25rem;width:17px;height:17px;accent-color:var(--accent)}
.consent label{font-size:.85rem;line-height:1.5;color:var(--on-dark-2)}
.consent a{color:#fff;text-decoration:underline;text-underline-offset:2px}

/* le retour d'envoi, lisible sur le fond sombre du bloc contact */
.form .note{color:var(--on-dark-2);border-left:3px solid var(--dark-line);padding-left:.8rem}
.form .note.is-ok{color:var(--accent);border-left-color:var(--accent)}
.form .note.is-err{color:#FFB4B4;border-left-color:#FFB4B4}

/* la confirmation qui REMPLACE le formulaire une fois le message parti */
.form{transition:opacity .22s ease, transform .22s ease}
.form.is-out{opacity:0;transform:translateY(-8px);pointer-events:none}

.form-merci{display:grid;gap:.75rem;justify-items:start;padding:2rem 1.8rem;
  border:1px solid var(--dark-line);border-radius:var(--r-sm);
  background:rgba(193,255,114,.08);
  opacity:0;transform:translateY(14px);
  transition:opacity .45s ease, transform .5s cubic-bezier(.2,.75,.25,1)}
.form-merci.is-in{opacity:1;transform:none}
.form-merci .fm-ic{width:44px;height:44px;display:grid;place-items:center;
  border-radius:50%;background:var(--accent);color:#0B0B0B;margin-bottom:.3rem;
  transform:scale(.4);transition:transform .5s cubic-bezier(.2,1.5,.4,1) .15s}
.form-merci.is-in .fm-ic{transform:none}
.form-merci .fm-ic svg{width:22px;height:22px}
/* la coche se DESSINE : le trait est masqué puis déroulé sur sa longueur */
.form-merci .fm-ic path{stroke-dasharray:26;stroke-dashoffset:26;
  transition:stroke-dashoffset .45s ease .35s}
.form-merci.is-in .fm-ic path{stroke-dashoffset:0}
/* respect du réglage système « réduire les animations » */
@media (prefers-reduced-motion:reduce){
  .form,.form-merci,.form-merci .fm-ic,.form-merci .fm-ic path{transition:none}
  .form-merci{opacity:1;transform:none}
  .form-merci .fm-ic{transform:none}
  .form-merci .fm-ic path{stroke-dashoffset:0}
}
.form-merci h3{font-size:1.45rem;line-height:1.2;margin:0;color:var(--on-dark)}
.form-merci p{margin:0;color:var(--on-dark-2);line-height:1.6}
.form-merci .fm-sub{font-size:.9rem}
.form-merci a{color:#fff;text-decoration:underline;text-underline-offset:2px}

.ways{display:grid;gap:.8rem;margin-top:1.8rem}
.way{display:flex;gap:.9rem;align-items:center;background:rgba(255,255,255,.07);
  border:1px solid var(--dark-line);border-radius:var(--r);padding:1rem 1.2rem;
  text-decoration:none;transition:background var(--t)}
.way:hover{background:rgba(255,255,255,.13)}
.way .wi{flex:none;width:38px;height:38px;border-radius:var(--r-sm);background:rgba(255,255,255,.12);
  display:flex;align-items:center;justify-content:center}
.way .wi svg{width:18px;height:18px}
.way .wk{font-size:.82rem;color:var(--on-dark-2)}
.way .wv{font-weight:600}

/* ─────────────── pied de page ─────────────── */
.foot{padding:3rem 0;border-top:1px solid var(--line);background:var(--tint)}
.foot .in{display:flex;gap:1.5rem 2rem;justify-content:space-between;align-items:center;flex-wrap:wrap}
.foot .links{display:flex;gap:1.6rem;flex-wrap:wrap}
.foot a{font-size:.95rem;color:var(--ink-2);text-decoration:none}
.foot a:hover{color:var(--ink)}
.foot .cr{width:100%;margin-top:1.6rem;padding-top:1.4rem;border-top:1px solid var(--line);
  font-size:.88rem;color:var(--ink-3)}

/* ─────────────── pages satellites ─────────────── */
.doc{max-width:48rem;margin:0 auto}
.doc h1{font-size:clamp(2rem,4vw,2.8rem);margin-bottom:1.1rem}
.doc h2{font-size:1.35rem;margin:2.6rem 0 .8rem}
.doc p,.doc li{color:var(--ink-2)}
.doc p+p{margin-top:.85rem}
.doc ul{margin-top:.7rem;display:grid;gap:.4rem}
.doc ul li{padding-left:1.1rem;position:relative}
.doc ul li::before{content:"";position:absolute;left:0;top:.7em;width:5px;height:5px;
  border-radius:50%;background:var(--brand)}
.doc .todo{border:1px solid var(--line);border-left:3px solid var(--brand);border-radius:var(--r);
  background:var(--tint);padding:1.1rem 1.3rem;margin:1.4rem 0;font-size:.96rem;color:var(--ink-2)}
.doc .todo b{color:var(--ink)}
.crumb{font-size:.94rem;color:var(--ink-3);margin-bottom:1.4rem}
.crumb a{color:var(--brand);text-decoration:none}
.fiche{border:1px solid var(--line);border-radius:var(--r-lg);padding:1.6rem;margin-top:1rem;
  box-shadow:var(--sh-1)}
.fiche dl{display:grid;grid-template-columns:auto 1fr;gap:.5rem 1.4rem;margin-top:1rem;font-size:.95rem}
.fiche dt{font-size:.8rem;font-weight:600;color:var(--ink-3);padding-top:.15em}
.fiche dd{margin:0;color:var(--ink-2)}

/* ─────────────── révélations ─────────────── */
.rv{transition:opacity .6s var(--t),transform .6s var(--t)}
.js .rv{opacity:0;transform:translateY(14px)}
.rv.on,.js .rv.on{opacity:1;transform:none}

/* ─────────────── responsive ─────────────── */
@media(max-width:1180px){
  /* sous 1180 px, la marge de droite ne sert plus : on la rend au texte
     plutôt que de laisser la colonne de lecture s'étrangler */
  .offerpage .wrap{max-width:var(--w)}
  .offer{grid-template-columns:minmax(0,230px) minmax(0,1fr)}
  .ospace{display:none}
}
@media(max-width:1000px){
  .ctop{grid-template-columns:1fr;gap:2.2rem}
  .grid-4{grid-template-columns:repeat(2,1fr)}
  .fbox{grid-template-columns:1fr}
  .me{grid-template-columns:1fr;gap:2rem}
  .me .portrait{max-width:280px}
  .cbox{grid-template-columns:1fr;gap:2.2rem}
}
@media(max-width:800px){
  .nav .links{display:none}
  .burger{display:flex}
  /* ⚠️ ALIGNEMENT OPTIQUE DU BURGER (30/08, signalé par Yassine).
     Le bouton fait 46 px de large pour rester atteignable au pouce, mais
     son DESSIN n'en fait que 20, centré dedans. Résultat mesuré : l'encre
     du logo tombait à 18 px du bord gauche et celle du burger à 31 px du
     bord droit — 13 px de déséquilibre, que l'œil lit immédiatement comme
     « l'en-tête n'est pas centré ».
     On sort le BOUTON de 13 px sans toucher au dessin : la cible tactile
     reste à 46 px, et les deux encres retombent à 18 px de leur bord.
     Ne pas « corriger » en rétrécissant le bouton : ce serait rendre la
     cible trop petite (WCAG 2.5.8). */
  .burger{margin-right:-13px}
  /* ⚠️ LE HÉRO CESSE DE TENIR L'ÉCRAN SOUS 800 px (ajout du 26/08).
     La règle « le héro tient l'écran » (24/08) vaut pour un grand écran.
     Sur un téléphone, avec le titre, le texte, deux boutons empilés, la
     signature et treize emplacements de logos, le contenu DÉPASSE les
     100svh : on se retrouvait à défiler à l'intérieur d'un écran censé
     tenir, et la barre du haut restait collée sur du vide. Le héro
     reprend sa hauteur naturelle. */
  .hero{min-height:auto;padding-top:clamp(2.2rem,7vw,3rem)}
  .qfig{grid-template-columns:1fr;gap:1rem}
  .qav{width:120px;margin:.5rem auto}
  .qb::after{display:none}
  .offer{grid-template-columns:1fr;gap:1.6rem}
  .offer>.shead{grid-column:1;grid-row:1;margin-bottom:0}
  .offer>.oside{grid-column:1;grid-row:2}
  .offer>.ocol{grid-column:1;grid-row:3}
  .oside{position:static;grid-template-columns:1fr;top:auto}
  .figs{grid-template-columns:repeat(2,1fr)}
  .bar{grid-template-columns:1fr auto;gap:.4rem .8rem}
  .bar .bt{grid-column:1/-1;order:2}
  .bks.free .bk{grid-template-columns:minmax(0,1fr) auto;gap:.3rem .9rem}
  .bks.free .bn{grid-column:1}
  .bks.free .bd{grid-column:1/-1}
  .stage .body{grid-template-columns:1fr;gap:1rem}
}
@media(max-width:640px){
  /* TROIS colonnes et non deux : à deux, dix logos font cinq rangées, soit
     ~250 px rien que pour ce bloc sur un écran de 390 px. À trois, quatre
     rangées et des cellules de ~105 px — largement de quoi lire un logo. */
  /* la bande est mise À L'ÉCHELLE (82 %) plutôt que ses logos forcés à
     une hauteur unique — forcer effacerait la normalisation optique et on
     retomberait exactement sur le défaut d'origine. Elle continue de
     défiler : sur mobile c'est même le seul moyen de montrer dix marques
     sans les empiler sur quatre rangées. */
  .proof3{--band-k:.82}
  .pb-lab{font-size:.64rem;letter-spacing:.14em}
  .slot{margin-right:2rem}
  .hero .lede{font-size:1.08rem}
  .rail{--rx:19px}
  .stage{padding-left:calc(var(--rx) + 1.5rem);padding-bottom:2.2rem}
  .node{width:38px;height:38px;border-radius:12px;font-size:.9rem}
  .stage h3{font-size:1.15rem;padding-top:.2rem}
  .bk::before{width:1.5rem}
  .bk{grid-template-columns:1fr;gap:.5rem}
  .bk .tag{justify-self:start}
  .rt ol{padding-left:1.1rem;padding-right:1.1rem}
}
@media(max-width:560px){
  :root{--gut:1.15rem}
  body{font-size:16px}
  /* 2,4 rem sur 343 px de contenu utile poussait le titre à quatre lignes
     et mangeait la ligne de flottaison. */
  .hero h1{font-size:2.05rem;letter-spacing:-.03em}
  /* le <br> du titre est une respiration de grand écran : en mobile il
     force une coupure au mauvais endroit, on laisse le texte se replier.
     ⚠️ CORRIGÉ LE 27/08 : cette règle produisait « convaincu.Reste » — le
     <br> disparaissait et les deux phrases se collaient, faute d'espace
     entre elles dans le source. Le correctif est DANS LE HTML, une espace
     posée juste APRÈS le <br> : sur grand écran elle tombe en début de
     ligne et le rendu la supprime, en mobile elle sépare les deux mots.
     Ne pas la retirer en croyant nettoyer le source. */
  .hero h1 br{display:none}
  .grid-4{grid-template-columns:1fr}
  .figs{grid-template-columns:1fr}
  .acts .btn{flex:1 1 100%}
  .foot .in{flex-direction:column;align-items:flex-start}
}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{transition-duration:1ms!important;animation-duration:1ms!important}
  .js .rv{opacity:1;transform:none}
  /* le bandeau d'outils cesse de défiler et redevient une rangée posée */
  .marq.rolling .run{animation:none;flex-wrap:wrap;justify-content:center;width:auto;
    padding-inline:clamp(1rem,4vw,3rem)}
  .marq::before,.marq::after{display:none}
  /* la bande de preuve devient une rangée posée, qui se replie sur
     plusieurs lignes : le masque des bords n'a plus rien à estomper et
     rongerait le premier et le dernier logo de chaque ligne. */
  .proof3 .marq{-webkit-mask-image:none;mask-image:none}
  .slot{margin:.5rem 1.6rem .5rem 0}
  /* le fil rouge se remplit d'un coup, les briques restent branchées :
     le contenu est identique, seule la mise en mouvement disparaît */
  .rail-fill{height:100%!important}
  .bar .bt i{width:var(--w)}
  .rt li{opacity:1;transform:none}
  .bk::before{transform:scaleX(1)}
  .bk.on{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand),var(--sh-2)}
  .bk.on .tag{opacity:1;transform:none}
  .ocard{opacity:1;transform:none}
}
@media print{.nav,.menu,.btn{display:none!important}
  .rt li{opacity:1;transform:none}.bk::before{transform:scaleX(1)}
  .dark{background:#fff;color:#000}}

/* ═══════════════════════════════════════════════════════════════════════
   L'OFFRE — refonte du 27/08 (3 temps · 3 développements)
   Préfixe `o2-` : les anciennes classes de la section offre (.offerpage,
   .oside, .ocard, .opart, .rail, .stage, .rt, .bks) ne sont plus employées
   par index.html — elles restent plus haut dans ce fichier, en attente de
   nettoyage, mais plus rien ne les référence.
   Règle du lime respectée partout : surface pleine + encre dessus, jamais
   un filet ni un texte sur fond clair.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── les trois temps ── */
.o2-rail{margin-top:clamp(2.5rem,5vw,3.75rem);display:grid;grid-template-columns:repeat(3,1fr);
  gap:1.75rem;position:relative}
.o2-rail::before{content:"";position:absolute;top:26px;left:8%;right:8%;height:1px;
  background:var(--line);z-index:0}
.o2-st{position:relative;z-index:1;display:flex;flex-direction:column}
.o2-dot{width:52px;height:52px;border-radius:var(--r-pill);background:var(--bg);
  border:1px solid var(--line);display:grid;place-items:center;font-family:var(--mono);
  font-size:.78rem;color:var(--ink-3)}
.o2-st.on .o2-dot{background:var(--accent);border-color:var(--accent);color:var(--on-accent);
  font-weight:500}
.o2-st h3{margin-top:1.1rem;font-size:1.35rem;font-weight:600;letter-spacing:-.028em;
  line-height:1.2}
.o2-st>p{margin-top:.75rem;color:var(--ink-2);font-size:1rem;line-height:1.62;flex:1}
.o2-liv{margin-top:1.35rem;border-top:1px solid var(--line);padding-top:.85rem}
.o2-liv em{display:block;font-style:normal;font-family:var(--mono);font-size:.68rem;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:.3rem}
.o2-liv b{font-weight:600;font-size:1rem}

/* ── l'atelier-diagnostic : cinq scènes dessinées (piste F, 28/08) ──
   Remplace la carte blanche à cinq colonnes. Le bloc ne se distingue plus
   par un cadre mais par ses aplats : c'est la seule respiration colorée de
   la page, et elle tombe sur le moment où l'offre commence vraiment.      */
.o2-diag{margin-top:clamp(3rem,6vw,4.5rem)}
.o2-dh{display:flex;justify-content:space-between;gap:1.75rem;align-items:baseline;flex-wrap:wrap}
.o2-dh h3{margin-top:.6rem;font-size:clamp(1.4rem,2.4vw,1.85rem);font-weight:600;
  letter-spacing:-.03em;line-height:1.15}
.o2-dh p{margin-top:.5rem;color:var(--ink-2);max-width:52ch}
.o2-tag{font-size:.86rem;color:var(--ink-3);border:1px solid var(--line);
  border-radius:var(--r-pill);padding:.5rem .9rem;background:var(--tint);white-space:nowrap}
.o2-scenes{margin-top:clamp(1.8rem,3.5vw,2.6rem);display:grid;grid-template-columns:repeat(5,1fr);
  gap:1rem}
.o2-sc{background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;box-shadow:var(--sh-1);display:flex;flex-direction:column;
  transition:transform var(--t),box-shadow var(--t)}
.o2-sc:hover{transform:translateY(-3px);box-shadow:var(--sh-2)}
/* les aplats : trois pastels de la charte + le lime plein sur la dernière,
   celle du livrable — c'est elle qu'on veut voir arriver. */
.o2-vg{padding:1rem;display:grid;place-items:center}
.o2-vg.lav{background:var(--w-lav)}
.o2-vg.blue{background:var(--w-blue)}
.o2-vg.soft{background:var(--accent-soft)}
.o2-vg.lime{background:var(--accent)}
.o2-vg svg{width:100%;max-width:120px;height:auto;display:block}
.o2-scb{padding:1rem 1.05rem 1.25rem;flex:1}
.o2-scn{display:block;font-family:var(--mono);font-size:.62rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3)}
.o2-sc h4{margin-top:.35rem;font-size:1rem;font-weight:600;letter-spacing:-.02em;line-height:1.25}
.o2-sc p{margin-top:.4rem;font-size:.88rem;line-height:1.5;color:var(--ink-2)}

/* ── la feuille de route : ce qu'elle tranche + les 8 leviers ── */
.o2-lab{display:block;font-family:var(--mono);font-size:.68rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-3)}
/* le configurateur — le tri se joue sous les yeux du visiteur */
.o2-cfg{margin-top:clamp(2.5rem,5vw,3.5rem);background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);overflow:hidden}
.o2-q{padding:1.35rem 1.6rem;border-bottom:1px solid var(--line);display:flex;gap:.6rem;
  align-items:center;flex-wrap:wrap}
.o2-q .o2-lab{margin-right:.4rem}
.o2-chip{border:1px solid var(--line);background:var(--tint);border-radius:var(--r-pill);
  padding:.65rem 1.05rem;font-size:.95rem;color:var(--ink-2);cursor:pointer;
  transition:background var(--t),color var(--t),border-color var(--t)}
.o2-chip:hover{border-color:var(--line-2)}
.o2-chip.on{background:var(--brand);border-color:var(--brand);color:#fff;font-weight:500}
.o2-out{display:grid;grid-template-columns:340px 1fr}
.o2-lft{padding:1.85rem;border-right:1px solid var(--line);background:var(--tint)}
.o2-lft h3{margin-top:.75rem;font-size:1.25rem;font-weight:600;letter-spacing:-.03em;
  line-height:1.22}
.o2-lft>p{margin-top:.75rem;color:var(--ink-2);font-size:.98rem;line-height:1.6}
.o2-mini{margin-top:1.5rem;border-top:1px solid var(--line-2);padding-top:1.1rem;display:grid;
  gap:.65rem}
.o2-mini div{display:flex;gap:.65rem;align-items:center;font-size:.92rem;color:var(--ink-2)}
.o2-mini b{font-family:var(--mono);font-size:.6rem;font-weight:400;letter-spacing:.06em;
  background:var(--brand);color:#fff;border-radius:5px;padding:.22rem .4rem}
.o2-mini em{font-style:normal;font-weight:600;color:var(--ink)}
/* les huit leviers — le tri se joue à l'écran : les retenus s'étiquettent
   et s'appuient, les autres reculent sans jamais disparaître. */
.o2-lv{padding:1.5rem;display:grid;grid-template-columns:repeat(2,1fr);gap:.75rem;
  align-content:start}
.o2-l{border:1px solid var(--line);border-radius:var(--r-sm);padding:.95rem 1rem;
  background:var(--card);opacity:.5;
  transition:opacity var(--t),border-color var(--t),box-shadow var(--t)}
.o2-l b{display:flex;justify-content:space-between;align-items:center;gap:.6rem;
  font-size:.98rem;font-weight:600;letter-spacing:-.015em}
.o2-l b i{font-style:normal;font-family:var(--mono);font-size:.58rem;letter-spacing:.1em;
  text-transform:uppercase;background:var(--accent);color:var(--on-accent);border-radius:5px;
  padding:.2rem .4rem;opacity:0;transform:translateY(-2px);
  transition:opacity var(--t),transform var(--t)}
.o2-l span{display:block;margin-top:.35rem;font-size:.88rem;line-height:1.5;color:var(--ink-3)}
.o2-l.on{opacity:1;border-color:var(--brand);box-shadow:var(--sh-2)}
.o2-l.on b i{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.o2-l,.o2-l b i{transition:none}}

/* ── le déploiement : 3 principes ── */
.o2-pr3{margin-top:clamp(2.5rem,5vw,3.5rem);display:grid;grid-template-columns:repeat(3,1fr);
  gap:1.25rem}
.o2-c{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:1.6rem;box-shadow:var(--sh-1)}
.o2-c h3{margin-top:.85rem;font-size:1.18rem;font-weight:600;letter-spacing:-.028em;
  line-height:1.25}
.o2-c p{margin-top:.65rem;color:var(--ink-2);font-size:.98rem;line-height:1.6}

/* ── la sortie vers le contact ── */
.o2-fin{margin-top:clamp(2.5rem,5vw,3.5rem);border-top:1px solid var(--line);
  padding-top:1.75rem;display:flex;justify-content:space-between;align-items:center;
  gap:1.75rem;flex-wrap:wrap}
.o2-fin p{color:var(--ink-2);max-width:54ch}
@media(max-width:640px){.o2-fin .btn{width:100%}}

@media(max-width:1000px){
  .o2-out{grid-template-columns:1fr}
  .o2-lft{border-right:0;border-bottom:1px solid var(--line)}
  .o2-scenes{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:820px){
  .o2-rail,.o2-pr3,.o2-lv,.o2-ref{grid-template-columns:1fr}
  .o2-rail::before{display:none}
  .o2-scenes{grid-template-columns:repeat(2,1fr)}
  .o2-dh{flex-direction:column;align-items:flex-start}
  .o2-tag{white-space:normal}
}


/* le bandeau d'outils, DANS le bloc « Qui je suis » (28/08) */
/* `min-width:0` N'EST PAS COSMÉTIQUE : sans lui, la piste `.run` en
   `width:max-content` force la colonne de droite à s'élargir et tout le
   bloc « Qui je suis » déborde de l'écran. */
.me>div{min-width:0}
#moi .tools{margin-top:2.2rem}
#moi .marq{width:auto;margin-inline:0;border-radius:var(--r)}
#moi .marq::before,#moi .marq::after{width:8%}
#moi .tools .lab{margin-bottom:.35rem}

/* ─────────────── le déploiement — les formes qu'il prend ───────────────
   Bloc refondu le 27/08 : quatre formes, une ligne chacune, rien de plus.
   Volontairement plus sobre que les cartes du reste de la page : c'est le
   moment où l'on redescend en régime, pas un nouveau moment fort.        */
/* ── le déploiement (refondu le 28/08) ──
   Deux étages seulement : une photo qui montre le travail en cours, puis
   toutes les offres en tuiles. Rien à lire en diagonale, rien à trier. */
.o2-top{display:grid;grid-template-columns:1fr .82fr;gap:clamp(2rem,4vw,3.4rem);
  align-items:center}
.o2-ph{margin:0;border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--sh-2)}
.o2-ph img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:4/3}
.o2-tiles{margin-top:clamp(2.5rem,5vw,3.5rem);display:grid;
  grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.o2-t{background:var(--card);padding:1.4rem 1.25rem;transition:background var(--t)}
.o2-t:hover{background:var(--tint)}
.o2-i{width:26px;height:26px;color:var(--brand);display:block}
.o2-t b{display:block;margin-top:.85rem;font-size:1rem;font-weight:600;letter-spacing:-.02em;
  line-height:1.25}
.o2-t span{display:block;margin-top:.35rem;font-size:.88rem;line-height:1.5;color:var(--ink-3)}
@media(max-width:1000px){.o2-tiles{grid-template-columns:repeat(2,1fr)}}
@media(max-width:820px){.o2-top{grid-template-columns:1fr}}
@media(max-width:520px){.o2-tiles{grid-template-columns:1fr}}


/* ─────────────── les illustrations du parcours (28/08) ───────────────
   Trois dessins, un par temps, pour que la section cesse d'être un mur de
   texte. Ils ne décorent pas : chacun montre le MÉCANISME du temps —
   ce qui converge, ce qui monte par paliers, ce qui se sélectionne.
   Deux couleurs seulement, celles de la marque, et le lime toujours en
   surface pleine (jamais un filet), comme partout ailleurs.            */
.o2-ill{display:block;margin-bottom:1rem;min-height:92px}
.o2-ill svg{width:100%;max-width:168px;height:92px;display:block}
.o2-ill .ln{stroke:var(--line-2);stroke-width:1.6}
.o2-ill .st{stroke:var(--line-2);stroke-width:1.6;stroke-linecap:round}
.o2-ill .fl{stroke:var(--brand);stroke-width:1.6;opacity:.55}
.o2-ill .fl.bold{stroke-width:2.2;opacity:1;stroke-linejoin:round;stroke-linecap:round}
.o2-ill .hit{fill:var(--accent)}
.o2-ill .hit.sq{fill:var(--accent);stroke:none}
.o2-ill .tick{stroke:var(--on-accent);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
/* le trait de liaison entre les trois temps passe DERRIÈRE l'illustration :
   il partait du haut des colonnes, il tombe maintenant sur les pastilles. */
.o2-rail::before{top:auto;bottom:0;display:none}
.o2-st{gap:0}


/* ── mobile : le parcours en colonne (28/08) ──
   ⚠️ CE BLOC DOIT RESTER EN FIN DE FICHIER. Les styles des illustrations
   (.o2-ill, .o2-st) sont déclarés plus haut SANS media query : placé avant
   eux, ce bloc perdait l'arbitrage et la pastille repartait sur sa propre
   ligne. Empilés, dessin et numéro laissaient un grand vide ; ils tiennent
   maintenant sur la même ligne, titre et texte dessous. */
@media(max-width:820px){
  /* `flex-direction:row` est indispensable : .o2-st est déjà en
     `flex-direction:column` plus haut, sans ce reset tout reste empilé. */
  .o2-st{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;gap:.9rem}
  .o2-st .o2-dot{order:1;flex:none}
  .o2-st .o2-ill{order:2;margin-bottom:0;min-height:0;flex:none}
  .o2-st .o2-ill svg{max-width:128px;height:70px}
  .o2-st h3{order:3;width:100%;margin-top:.2rem}
  .o2-st>p{order:4;width:100%;margin-top:.55rem}
  .o2-st .o2-liv{order:5;width:100%}
}

/* mobile étroit : une scène par ligne, vignette à gauche du texte — cinq
   grandes cartes empilées feraient un couloir interminable. */
@media(max-width:560px){
  .o2-scenes{grid-template-columns:1fr}
  .o2-sc{flex-direction:row;align-items:stretch}
  .o2-vg{flex:0 0 104px;padding:.7rem}
  .o2-vg svg{max-width:88px}
  .o2-scb{padding:.85rem 1rem}
}

/* ═══════════════════════════════════════════════════════════════════
   CORRECTIONS MOBILE — 28/08/2026
   Relevées en émulant un vrai téléphone (390 px, DPR 2) et en mesurant
   dans la page, pas à l'œil. Chaque bloc dit ce qu'il répare.
   ═══════════════════════════════════════════════════════════════════ */

/* 1 · LA BANDE BLANCHE À DROITE.
   `overflow-x:clip` était posé sur <body> seulement. Cette propriété ne
   se propage pas au viewport de façon fiable selon les moteurs — sous
   Safari iOS, un enfant en pleine largeur (la bande de logos, en 100vw)
   peut encore faire glisser la page et découvrir une bande blanche.
   Le poser aussi sur <html> ferme la porte côté viewport.
   ⚠️ `clip` et non `hidden` : `hidden` créerait un conteneur de
   défilement et casserait les en-têtes `position:sticky` de la page. */
html{overflow-x:clip}

/* 2 · LES TITRES COLLÉS À LEUR PARAGRAPHE.
   Mesuré : `h2` sort avec `margin-bottom:0`, et quatre paragraphes de
   suite avec `margin-top:0` — dont « On comprend, on décide, on
   installe. » et « Votre feuille de route… ». Sur mobile, où tout est
   empilé, le texte semble tomber dans le titre. */
@media(max-width:640px){
  h2 + p,
  h2 + .lede{margin-top:1rem}
}

/* 3 · LES PETITES CAPITALES ILLISIBLES.
   `--ink-3` (#7C818A) donnait 3,66:1 sur le fond teinté et 3,91:1 sur
   blanc, sous le seuil de 4,5:1. Sur un téléphone, en extérieur, ces
   libellés disparaissent. #666C79 monte à 4,92 / 5,27 en restant un
   gris secondaire — la hiérarchie ne bouge pas, la lisibilité oui. */
.o2-lab,
.o2-tag,
.o2-scn,
.o2-liv em{color:#666C79}

/* 4 · LE CONFIGURATEUR : LES LEVIERS NON RETENUS ÉTAIENT EFFACÉS.
   `opacity:.5` rendait cinq leviers sur huit quasi illisibles — alors
   que la règle posée le 25/08 est justement que les non retenus
   RESTENT LISIBLES, et que c'est le cadre qui dit la sélection.
   La distinction repose désormais sur ce qui la porte vraiment :
   bordure indigo + ombre + étiquette « RETENU » sur les retenus. */
.o2-l{opacity:1}
.o2-l:not(.on) b{color:var(--ink-2)}
.o2-l.on b{color:var(--ink)}
/* la description d'un levier RETENU ne doit pas être plus pâle que celle
   d'un levier écarté — c'était le cas, la hiérarchie était inversée. */
.o2-l span{color:var(--ink-2)}
/* l'étiquette « RETENU » ne se laisse pas écraser par un titre long */
.o2-l b i{flex:none}

/* 5 · LES TROIS CHOIX DE SITUATION EN ESCALIER.
   Mesuré à 390 px : 287, 216 puis 274 px de large dans un bloc de 353.
   Trois largeurs différentes empilées, ça ne se lit pas comme un choix,
   ça se lit comme un accident. Sur mobile, un choix = une ligne pleine. */
@media(max-width:640px){
  .o2-q{flex-direction:column;align-items:stretch;gap:.5rem}
  .o2-q .o2-lab{margin-right:0;margin-bottom:.2rem}
  .o2-chip{width:100%;text-align:center;padding:.8rem 1rem}
}

/* 6 · LE TITRE DU HÉRO COUPÉ SUR LE BORD DROIT (constaté sur iPhone 16 Pro,
   402 px, Safari — invisible sous Chrome, qui replie correctement).
   Cause la plus probable : `text-wrap:balance` sur les titres. Safari
   évite de couper à l'intérieur d'une boîte en ligne — ici le surlignage
   lime « par où commencer », qui porte en plus `box-decoration-break:clone`.
   La ligne reste donc entière et sort de l'écran : le titre fait 549 px de
   large pour 365 px disponibles.
   `balance` est un CONFORT de grand écran (il égalise la longueur des
   lignes d'un titre court). Sur mobile il n'apporte rien et il fait courir
   ce risque : on le retire sous 640 px, et on autorise explicitement le
   repli. */
@media(max-width:640px){
  h1,h2,h3{text-wrap:wrap;overflow-wrap:break-word}
  .hero h1 .hl{box-decoration-break:clone;-webkit-box-decoration-break:clone}
}

/* ═══════════════════════════════════════════════════════════════════
   CHANTIER 1 · SOCLE TECHNIQUE MOBILE — 29/08/2026
   Trois défauts objectifs, relevés par `outils/apercu-mobile.py` à
   402 px (iPhone 16 Pro). Rien d'éditorial ici : aucun contenu ne
   change, seules la lisibilité et la préhension au pouce sont corrigées.
   ═══════════════════════════════════════════════════════════════════ */
@media(max-width:640px){

  /* a · LE GRIS SECONDAIRE PASSAIT SOUS LE SEUIL DE LISIBILITÉ.
     `--ink-3` (#7C818A) sortait à 3,91:1 sur blanc et 3,66:1 sur fond
     teinté — le minimum est 4,5:1. Dix-sept textes étaient concernés
     (source INSEE, sous-titres des leviers, « Déjà intervenu chez »,
     mentions du pied de page) : tous héritent de ce SEUL jeton, donc
     tous sont réglés d'un coup. #666C79 monte à 5,27 / 4,92.
     ⚠️ Redéfini POUR MOBILE UNIQUEMENT : la version bureau, validée le
     24/08, garde ses valeurs. Le même défaut y existe — c'est un choix
     de périmètre, pas un oubli. */
  :root{--ink-3:#666C79}

  /* b · le plus petit libellé de la page tombait à 10,2 px : illisible
     sur un téléphone tenu à bout de bras. */
  .pb-lab{font-size:.72rem;letter-spacing:.12em}

  /* c · CIBLES TACTILES. 44 px de haut est le minimum tenable au pouce
     (recommandation Apple, et critère WCAG 2.5.8 « Target Size »).
     Trois cas réels ; on agrandit la ZONE, jamais le dessin. */
  /* le logo de l'en-tête : 26 px de haut, donc quasi impossible à viser */
  .nav .in > a:first-child{display:inline-flex;align-items:center;min-height:44px}
  /* les quatre liens du pied de page : 25 px */
  .foot .links{gap:0 1.4rem}
  .foot .links a{display:inline-flex;align-items:center;min-height:44px}
  /* la case de consentement : 17 px, la plus petite cible du site — et
     elle conditionne l'envoi du formulaire. La rater, c'est perdre le
     message. */
  .consent input{width:24px;height:24px;margin-top:0}
  .consent{gap:.8rem;align-items:center}
}

/* ── LE TITRE DU HÉRO, VERSION QUI NE PEUT PLUS DÉBORDER (29/08) ──
   Le correctif précédent (retirer `text-wrap:balance` sur mobile) n'a pas
   suffi : sur iPhone le titre est resté coupé. Sur iOS, TOUS les
   navigateurs — Chrome compris — utilisent le moteur de Safari : changer
   de navigateur ne change donc rien au rendu.
   On arrête de compter sur l'algorithme de coupure du moteur, et on
   reprend la main sur trois plans :
     1. des coupures EXPLICITES, écrites dans le HTML (`<br class="br-m">`),
        pour imposer « L'IA vous a convaincu. / Reste à savoir / par où
        commencer. » — plus rien à deviner ;
     2. une taille FLUIDE : le titre rétrécit avec l'écran au lieu de
        rester fixe et de sortir du cadre sur un téléphone étroit ;
     3. `balance` n'est plus seulement écrasé, il n'est PLUS DÉCLARÉ sous
        640 px — si un moteur ignorait la valeur de remplacement, il
        retombait sur `balance`. */
.br-m{display:none}
@media(max-width:640px){
  .hero h1{font-size:clamp(1.65rem,7.6vw,2.05rem);text-wrap:initial}
  .hero h1 br{display:inline}      /* la coupure de grand écran resservie */
  .hero h1 .br-m{display:inline}   /* plus celle propre au mobile */
}

/* ── LE PREMIER ÉCRAN, REPRIS SUR RETOUR DE YASSINE (29/08) ──
   Trois remarques, trois causes distinctes. Aucune n'était un bug de
   mise en page : le titre ne débordait plus, c'est l'ŒIL qui décrochait. */
@media(max-width:640px){

  /* a · « le texte du titre n'est pas centré ».
     Il l'était au pixel — mais la 3ᵉ ligne commence par le bloc lime et
     se terminait par un point posé HORS du surlignage. L'œil centre la
     masse colorée, pas la ligne de texte : le bloc paraissait décalé de
     10 px vers la gauche. Le point est passé DANS le surlignage (HTML),
     la 3ᵉ ligne n'est plus qu'un seul bloc, centré pour de bon. */

  /* b · « les boutons sont trop longs et pas centrés ».
     Ils faisaient toute la largeur (`flex:1 1 100%`), et la flèche en
     bout de ligne poussait le libellé à gauche du centre optique. Sur
     mobile ils épousent désormais leur texte et se centrent. */
  .hero .acts{flex-direction:column;align-items:center;gap:.7rem}
  .hero .acts .btn{flex:0 0 auto;width:auto;max-width:100%}

  /* c · « les logos » — la pastille de références.
     Les trois cercles se chevauchaient de 7 px : chaque marque était
     mordue et le groupe devenait une tache. On ouvre la pile — mais on
     ne l'agrandit PAS : la version à 36 px a été jugée « trop grosse »
     par Yassine le 29/08. Elle prenait le pas sur le titre, alors que
     cette pastille est une signature, pas un argument. 30 px : les
     symboles redeviennent identifiables, le bloc reste discret. */
  .hero .via-av .av{width:30px;height:30px}
  .hero .via-av .av + .av{margin-left:2px}
  .hero .via{padding:.7rem .95rem;gap:.45rem}
  .via-tx{font-size:.74rem}
  .via-tx span{font-size:.68rem}
}
