/* Copie générée, source : le vault, ne pas éditer ici. */
/* Primitives : la couleur réelle, jamais lue par un composant. */
:root {
  --creme: #f2ece8;
  --ardoise: #415371;
  --ardoise-moyenne: #5c6e8a;
  --ardoise-claire: #c3ccd9;
  --noir-bleute: #0a0d12;
  --cuivre: #715441;
  --bleu-nuit: #0e1b2d;
  --gris: #696969;
  --blanc-casse: #fbfaf9;
  --gris-perle: #d9d9dc;
  --brume: #e8edf3;
  --cuivre-clair: #e7cdb9;
  --blanc: #ffffff;
  --noir: #000000;
}

/* Rôles : ce que lisent les composants, et seulement ça. */
:root {
  --accent: var(--cuivre);
  --fond-page: var(--creme);
  --fond-carte: var(--blanc-casse);
  --fond-alterne: var(--brume);
  --fond-fonce: var(--ardoise);
  --fond-blanc: var(--blanc);
  --fond-pied: var(--noir-bleute);
  --fond-entete: rgba(251, 250, 249, .92);
  --fond-neutre: var(--gris);
  --texte: var(--bleu-nuit);
  --texte-attenue: var(--gris);
  --texte-sur-fonce: var(--blanc);
  --texte-sur-fonce-attenue: var(--ardoise-claire);
  --texte-sur-accent: var(--blanc-casse);
  --texte-marque: var(--ardoise);
  --accent-sur-fonce: var(--cuivre-clair);
  --action: var(--cuivre);
  --filet: var(--gris-perle);
  --filet-sur-fonce: var(--ardoise-moyenne);
  --chiffre: var(--noir);
  --echelle-1: var(--ardoise);
  --echelle-2: var(--ardoise-moyenne);
  --echelle-3: var(--ardoise-claire);
  --police: 'Geist', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --police-mono: 'Chivo Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --t-titre-page: clamp(38px, 4.6vw, 68px);
  --t-titre-section: clamp(30px, 4.03vw, 58px);
  --t-titre-bloc: clamp(21px, 1.9vw, 28px);
  --t-pastille: clamp(40px, 4.4vw, 64px);
  --t-chiffre-cle: clamp(44px, 4.4vw, 72px);
  --t-corps: clamp(16px, 1.02vw, 18px);
  --t-interface: 16px;
  --t-etiquette: 14px;
  --lh-titre-page: 1.1;
  --lh-titre-section: 1.2;
  --lh-corps: 1.6;
  --e1: 4px;
  --e2: 8px;
  --e3: 12px;
  --e4: 16px;
  --e5: 24px;
  --e6: 36px;
  --e7: 48px;
  --e8: 64px;
  --e9: 96px;
  --marge-section: clamp(72px, 6.5vw, 120px);
  --largeur-page: 1660px;
  --gouttiere: clamp(20px, 3vw, 40px);
  --t-heros: 80px;
  --rayon-carte: 16px;
  --rayon-pilule: 100px;
  --ombre-flottante: 0 0 0 1px rgba(0, 0, 0, .08),
    0 8px 24px 0 rgba(0, 0, 0, .12);
  --courbe-geste: cubic-bezier(0.32, 0.72, 0, 1);
  --courbe-survol: cubic-bezier(0.4, 0, 0.2, 1);
  --duree-geste: .7s;
  --duree-micro: .15s;
  --photo-gris: .32;
  --photo-satur: .90;
  --photo-contraste: 1.06;
  --texte-sur-fonce-82: rgba(255, 255, 255, .82);
  --texte-sur-fonce-86: rgba(255, 255, 255, .86);
  --texte-sur-fonce-88: rgba(255, 255, 255, .88);
  --filet-pied: rgba(255, 255, 255, .14);
  --voile-heros: linear-gradient(
    to top,
    rgba(0, 0, 0, .6),
    rgba(0, 0, 0, .5) 45%,
    rgba(0, 0, 0, .5) 58%,
    rgba(0, 0, 0, .28) 67%,
    rgba(0, 0, 0, 0) 77%
  );
  --ombre-titre-heros: 0 2px 28px rgba(0, 0, 0, .55), 0 0 2px rgba(0, 0, 0, .25);
  --t-chapo-heros: 18px;
  --t-chapo-heros-mobile: 17px;
  --t-surtitre: 14px;
  --t-mention: 14px;
  --t-bouton-compact: 15px;
  --t-nav-mobile: 17px;
  --t-signe: 17px;
  --t-enonce: clamp(18px, 1.3vw, 22px);
  --t-question: clamp(18px, 1.6vw, 21px);
  --t-dispositif-nom: clamp(14px, 1vw, 17px);
  --t-dispositif-montant: clamp(16px, 1.42vw, 26px);
  --t-dispositif-montant-mobile: clamp(22px, 6vw, 28px);
  --t-pastille-secondaire: clamp(24px, 2.2vw, 34px);
  --t-signe-egal: clamp(20px, 1.6vw, 26px);
  --t-titre-rubrique: clamp(24px, 2.2vw, 32px);
  --t-titre-carte: clamp(19px, 1.5vw, 22px);
  --t-titre-carte-large: clamp(24px, 2vw, 30px);
  --lh-plein: 1;
  --lh-etiquette: 1.2;
  --lh-serre: 1.3;
  --lh-enonce: 1.35;
  --lh-compact: 1.4;
  --lh-mention: 1.5;
  --lh-petit: 1.55;
  --lh-nom-nav: 1.12;
  --lh-dispositif-nom: 1.25;
  --lh-dispositif-montant: 1.15;
  --lh-question: 1.32;
  --ls-etiquette: .06em;
  --ls-titre: -.045em;
  --ls-affiche: -.05em;
  --ls-titre-bloc: -.02em;
  --ls-titre-reset: -.035em;
  --ls-nom-nav: .1em;
  --ls-surtitre: .12em;
  --ls-signe: -.04em;
  --ls-enonce: -.15px;
  --graisse-legere: 300;
  --graisse-normale: 400;
  --graisse-moyenne: 500;
  --h-entete: 72px;
  --decalage-ancre: 88px;
  --haut-colle: 96px;
  --rayon-etiquette: 8px;
  --z-evitement: 60;
  --z-entete: 40;
  --z-contenu-heros: 3;
  --z-section: 1;
  --z-base: 0;
  --z-dessous: -1;
  --opacite-survol: .8;
  --duree-survol: 265ms;
  --duree-nappe: 420ms;
  --flou-entete: saturate(150%) blur(14px);
  --photo-heros-gris: .2;
  --photo-heros-satur: .95;
  --photo-heros-contraste: 1.04;
  --photo-portrait-gris: .30;
  --photo-portrait-satur: .92;
  --photo-portrait-contraste: 1.05;
}

/* Redéfinitions : par seuil (héros, entête) et par contexte (fond ardoise, pied). */
@media (max-width: 1439.98px) {
  :root { --t-heros: 64px; --h-entete: 64px; }
}
@media (max-width: 767.98px) {
  :root { --t-heros: 48px; }
}
.sur-marine {
  --accent: var(--accent-sur-fonce);
  --texte-attenue: var(--texte-sur-fonce-attenue);
  --filet: var(--filet-sur-fonce);
}
.disp--tete {
  --accent: var(--accent-sur-fonce);
  --texte-attenue: var(--texte-sur-fonce-attenue);
}
.faq-carte {
  --texte-attenue: var(--texte-sur-fonce-attenue);
  --accent: var(--accent-sur-fonce);
}
.rdv__panneau {
  --accent: var(--accent-sur-fonce);
  --texte-attenue: var(--texte-sur-fonce-attenue);
}
.pied {
  --accent: var(--accent-sur-fonce);
}
/* Source : ce fichier. Depuis le 25/09/2026, l’accueil s’édite dans le dépôt, plus dans la maquette du vault. */
/* ==========================================================================
   V2.3, home epargnesalariale.com — direction Vectura.
   Relevé en styles calculés sur vectura.framer.website le 20/09/2026, à dix
   largeurs de fenêtre, sur le HTML servi et non sur des captures.
   Le bleu ardoise structure, le cuivre est le seul accent, les blancs cassés
   portent les sections. Geist pour les titres et pour le corps, Chivo Mono en
   capitales pour les étiquettes. Rayon 16 partout, sauf les boutons en pilule.
   Les grands titres sont en Geist 300 et 400, jamais en graisse lourde : le
   caractère du modèle vient de la tension entre un corps léger et un
   interlettrage très serré, pas d'un gras. Survols et bascules d'état en
   transitions CSS ; révélations, titres, compteurs, tracés et FAQ en GSAP.
   ========================================================================== */


*, *::before, *::after { box-sizing: border-box; }

/* Sans `text-size-adjust`, Safari sur iPhone grossit le texte quand on
   tourne l'écran en paysage, et toutes les mesures de la page tombent. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fond-page);
  color: var(--texte);
  font-family: var(--police);
  font-weight: var(--graisse-normale);
  font-size: var(--t-corps);
  line-height: var(--lh-corps);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img { display: block; max-width: 100%; border-radius: var(--rayon-carte); }

a { color: inherit; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--police);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre-reset);
}

p { margin: 0; overflow-wrap: break-word; }
ul, ol { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--texte-marque); color: var(--fond-page); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------- squelette */

.enveloppe {
  width: 100%;
  max-width: var(--largeur-page);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

.section { padding-block: var(--marge-section); }

/* Les sections occupent toute la largeur de l'ecran. Leur contenu, lui, est
   plafonne par --largeur-page via .enveloppe. Elles gardent en revanche un plan
   propre : le heros est colle derriere elles et doit etre recouvert.
   Corrige le 20/09 : plafonner les sections laissait voir la video du heros
   de part et d'autre de la bande de reperes au-dela de 1660 px. */
main > section:not(#hero),
.pied {
  position: relative;
  z-index: var(--z-section);
}

/* L'entête est fixe et haute de 72 px : une ancre doit s'arrêter en dessous. */
section[id] { scroll-margin-top: var(--decalage-ancre); }

.sur-vellum    { background: var(--fond-page); }
.sur-secondaire{ background: var(--fond-alterne); }
.sur-marine {
  background: var(--fond-fonce);
  color: var(--texte-sur-fonce);
  --accent: var(--accent-sur-fonce);
  --texte-attenue: var(--texte-sur-fonce-attenue);
  --filet: var(--filet-sur-fonce);
}

.evitement {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--fond-fonce);
  color: var(--texte-sur-fonce);
  font-size: var(--t-interface);
  padding: var(--e3) var(--e4);
  border-radius: var(--rayon-carte);
  z-index: var(--z-evitement);
}
.evitement:focus { left: var(--e4); top: var(--e4); }

/* Le sprite SVG des pictos : hors flux. */
.sprite { position: absolute; }

.masque {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* -------------------------------------------------------------- typographie */

.h1 {
  font-size: var(--t-titre-page);
  line-height: var(--lh-titre-page);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre);
}

.h2 {
  font-size: var(--t-titre-section);
  line-height: var(--lh-titre-section);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre);
}

.h3 {
  font-size: var(--t-titre-bloc);
  line-height: var(--lh-titre-section);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre-bloc);
}

/* Le geste signature survit à la fin de l'italique : la phrase détachée du
   titre garde la fonte et la graisse du titre, et ne se distingue plus que
   par l'accent cuivré. `font-style: normal` est indispensable, <em> penche
   par défaut et l'italique est sorti de la page. */
.h1 em, .h2 em, .reperes__citation em {
  font-style: normal;
  color: var(--accent);
}

/* Le corps ne pèse plus 300 : en Geist, à 16 px, le trait maigre demandait un
   effort de lecture. Le caractère Vectura vit dans les titres, qui gardent
   leurs 300 et 400, pas dans le texte courant. */
.corps {
  font-size: var(--t-corps);
  line-height: var(--lh-corps);
  font-weight: var(--graisse-normale);
  max-width: 64ch;
}


.petit {
  font-size: var(--t-interface);
  line-height: var(--lh-petit);
  font-weight: var(--graisse-normale);
}

/* L'étiquette de section, relevée en styles calculés sur la page produit du
   modèle : une petite boîte à hauteur fixe, un picto noir de 16 px, un mot en
   Chivo Mono capitales. Aucune bordure, aucune ombre, rayon 8.
   La hauteur de 32 px est posée, pas déduite du contenu : c'est ce qui fait
   que toutes les étiquettes de la page s'alignent, quel que soit leur mot. */
.libelle {
  display: inline-flex;
  align-items: center;
  --libelle-ecart: 3px;
  width: min-content;
  height: 32px;
  --libelle-marge: 8px 13px;
  gap: var(--libelle-ecart);
  padding: var(--libelle-marge);
  border-radius: var(--rayon-etiquette);
  background: var(--fond-alterne);
  font-family: var(--police-mono);
  /* Le 12 px en dur du relevé passait sous le plancher de lisibilité du
     22/09 : l'étiquette suit désormais le jeton, comme les autres libellés. */
  font-size: var(--t-etiquette);
  line-height: var(--lh-etiquette);
  letter-spacing: var(--ls-etiquette);
  text-transform: uppercase;
  font-weight: var(--graisse-normale);
  white-space: nowrap;
  color: var(--texte);
}

/* Le picto est un vrai élément du document, pas un pseudo-élément.
   Mesuré le 20/09 : Firefox exclut un `::before` du calcul de largeur
   intrinsèque d'un conteneur flex. La pastille y faisait 90,42 px au lieu de
   106,45, soit exactement les 16 px du picto en moins, et le mot débordait de
   3 px par-dessus le bord droit. Aucune valeur de `width` ne rattrape ça,
   `min-content` comme `auto` : seul un élément réel entre dans la mesure.

   Le losange plein qui tenait la place a cédé à un trait de 1,5 px : un aplat
   noir de 16 px pesait trop lourd à côté d'un mot de 12 px, l'icône du
   modèle est un trait. */
.libelle__picto {
  flex: 0 0 16px;
  height: 16px;
  display: inline-flex;
  color: var(--chiffre);
}
.libelle__picto svg { width: 16px; height: 16px; display: block; }

/* Le mot porte ses 3 px de padding, en plus des 3 px de gap : c'est le relevé. */
.libelle__mot { padding-inline: 3px; }

/* Sur les sections crème, la boîte prend la teinte crème pour rester visible
   sans virer au bleu. */
.sur-vellum .libelle,
.sur-marine .libelle,
.rdv__panneau .libelle { background: var(--fond-page); }

/* Variante posée sur pilule claire : elle sert dans « Le constat », où les
   étiquettes ne titrent plus une section mais qualifient une ligne de calcul.
   Ce n'est pas la même bête que l'étiquette de section : son libellé est une
   phrase, il doit pouvoir passer à la ligne. Elle remet donc à zéro les trois
   règles qui font tenir l'étiquette de section sur une seule ligne à hauteur
   fixe. Sans ces reprises, « EN PRIME SUR LE BULLETIN DE PAIE » reste
   insécable et pousse la page à 381 px de large sur un écran de 360.
   Le sélecteur porte deux classes : il doit passer devant `.sur-vellum
   .libelle`, qui teinterait la pilule en crème sur une carte déjà crème. */
.libelle.libelle--pilule {
  display: inline-block;
  align-self: flex-start;
  width: auto;
  height: auto;
  max-width: 100%;
  white-space: normal;
  --pilule-marge: 7px 14px;
  padding: var(--pilule-marge);
  border-radius: var(--rayon-pilule);
  background: var(--fond-alterne);
  color: var(--texte);
  line-height: var(--lh-compact);
}
/* Le retrait de 3 px du mot sert à caler l'étiquette de section contre son
   picto. Sans picto, il s'ajoute au padding de la pilule et la déséquilibre. */
.libelle--pilule .libelle__mot { padding-inline: 0; }

/* Les largeurs de mesure sont posées sur chaque enfant, dans SON corps : un
   max-width en ch sur le conteneur se calculerait sur la fonte du conteneur,
   pas sur celle du titre, et écraserait le H2 à deux fois rien. */
.tete {
  display: flex;
  flex-direction: column;
  gap: var(--e5);
}
.tete .h2 { max-width: 22ch; }
.tete .corps, .tete .petit { max-width: 56ch; }

/* Bloc à largeur ajustée plutôt qu'inline-flex : quand le libellé passe sur
   deux lignes, la flèche reste collée au dernier mot au lieu de partir seule
   au bord droit. L'équilibrage empêche la flèche de passer seule à la ligne
   (relevé le 01/10 : 8 cas de 360 à 768 px, dont l'accueil et /solutions/). */
.lien-fleche {
  display: block;
  width: fit-content;
  max-width: 100%;
  text-wrap: balance;
  font-size: var(--t-interface);
  font-weight: var(--graisse-moyenne);
  color: var(--accent);
  text-decoration: none;
}

/* ------------------------------------------------------------- survols */
/* Une seule grammaire pour toute la page : l'élément survolé descend à .8
   d'opacité, son libellé interne se contracte à .98, en 265 ms. Le fond n'est
   jamais touché, aucune couleur ne change, rien ne se déplace.
   Deux familles y échappent : les appels à l'action, dont la nappe et le
   retournement de lettres sont un geste à part, et les entrées de Solutions,
   qui ne doivent pas s'éteindre quand on les désigne. */
.lien-fleche,
.nav__liens a,
.nav__secondaire,
.nav__declencheur,
.nav__bascule,
.nav__marque,
.pied__lien,
.faq-carte__mail a,
.faq__question,
.etape__titre a { transition: opacity var(--duree-survol) var(--courbe-survol); }

/* Corrigé le 22/09 : les sélecteurs au repos partageaient la déclaration
   `opacity: .8` des sélecteurs au survol. Tous les liens de la page étaient
   donc éteints en permanence et le survol ne changeait rien. */
.lien-fleche:hover,
.nav__liens a:hover,
.nav__secondaire:hover,
.nav__declencheur:hover,
.nav__bascule:hover,
.nav__marque:hover,
.pied__lien:hover,
.faq-carte__mail a:hover,
.faq__question:hover,
.etape__titre a:hover { opacity: var(--opacite-survol); }

.lien-fleche .fleche {
  display: inline-block;
  width: 15px;
  height: 15px;
  margin-left: var(--e2);
  vertical-align: -2px;
}

/* ------------------------------------------------------------- photographie */

.photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--rayon-carte);
  background: var(--fond-fonce);
}

.photo > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter:
    grayscale(var(--photo-gris))
    saturate(var(--photo-satur))
    contrast(var(--photo-contraste));
}

.photo--carre { aspect-ratio: 1 / 1; }

/* --------------------------------------------------------------- 00. nav */

/* Entête relevée sur le modèle : fixe, 72 px de haut, aucune bordure, aucune
   ombre, fond transparent. Elle est hors du flux, et c'est le héros qui
   réserve sa hauteur en padding : le cadre vidéo démarre donc exactement à
   y = 72.

   Une seule chose s'écarte du relevé, et pour une raison mesurable : une
   entête transparente qui reste fixe passe ensuite au-dessus des sections
   ardoise, où des liens en #0e1b2d deviennent illisibles. Le fond clair
   revient donc dès les premiers pixels de défilement. En haut de page, là où
   le relevé a été pris, les valeurs calculées sont bien celles du modèle. */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--h-entete);
  z-index: var(--z-entete);
  background: transparent;
  transition: background-color var(--duree-geste) var(--courbe-geste);
}

.nav[data-defile="oui"] {
  background: var(--fond-entete);
  -webkit-backdrop-filter: var(--flou-entete);
  backdrop-filter: var(--flou-entete);
}

.nav__barre {
  width: 100%;
  height: 100%;
  max-width: var(--largeur-page);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e5);
}

.nav__marque {
  display: inline-flex;
  align-items: center;
  gap: var(--e3);
  text-decoration: none;
  color: var(--texte-marque);
}

/* Le logo du 24/09 (proposition de l'associé, redessinée) est plus haut que
   large ne l'était l'écu : 579 x 413, soit un rapport de 1.402:1. La boîte
   suit ce rapport, sinon le symbole se recentre et laisse des bandes de vide.
   44 px de haut : en dessous, le contour du cavalier blanc s'efface. */
.nav__ecu {
  width: 62px;
  height: 44px;
  display: inline-flex;
  flex: 0 0 auto;
}
.nav__ecu svg { width: 100%; height: 100%; fill: var(--texte-marque); stroke: none; }

.nav__nom {
  display: flex;
  flex-direction: column;
  font-family: var(--police);
  font-size: var(--t-surtitre);
  font-weight: var(--graisse-moyenne);
  line-height: var(--lh-nom-nav);
  letter-spacing: var(--ls-nom-nav);
  text-transform: uppercase;
}

/* Au-dessus de 941 px, le conteneur du panneau s'efface : ses enfants
   remontent comme enfants directs de la barre. Un seul jeu de liens dans le
   HTML, jamais dupliqué entre un menu de bureau et un menu de téléphone. */
.nav__deploie { display: contents; }

.nav__liens {
  display: flex;
  align-items: center;
  gap: var(--e6);
}

.nav__liens a,
.nav__secondaire {
  font-size: var(--t-interface);
  font-weight: var(--graisse-normale);
  color: var(--texte);
  text-decoration: none;
}

/* « Comptes clients » sort du menu le 04/10 : un lien de la même facture que
   ceux du menu, posé juste à gauche du bouton, qui garde seul le poids d'une
   action. Au-dessus de 1024 px, les deux forment le groupe de droite de la
   barre. */
.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--e6);
}

/* ------------------------------------------------- méga menu « Solutions » */
/* La barre ne porte plus d'ancres : une navigation de site pointe sur des
   pages, pas sur des morceaux de la page courante. « Solutions » est la seule
   entrée qui en cache d'autres, et elle les montre toutes d'un coup plutôt que
   de les enfouir dans une cascade.
   Un seul jeu de liens dans le document, comme pour le reste de la barre :
   au-dessus de 941 px il flotte sous la barre, en dessous il se déplie en
   accordéon dans le menu du téléphone. */

.nav__entree { display: inline-flex; }

/* Le déclencheur se fond dans la rangée : même corps, même graisse, même
   couleur qu'un lien. Il reste un <button> parce qu'il commande un panneau et
   ne mène nulle part : sans JavaScript, il ne fait rien, et les quatre autres
   entrées restent des liens. */
.nav__declencheur {
  padding: 0;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: var(--t-interface);
  font-weight: var(--graisse-normale);
  line-height: inherit;
  letter-spacing: inherit;
  color: var(--texte);
  cursor: pointer;
}

/* Le panneau se cale sur la barre, pas sur son entrée : c'est --largeur-page qui tient
   l'alignement de la page, et un panneau accroché au mot « Solutions » aurait
   dérivé avec lui d'une largeur à l'autre. `.nav` est le seul ancêtre
   positionné, donc `top: 100%` tombe exactement sous la barre. */
.megamenu {
  position: absolute;
  top: 100%;
  left: 50%;
  width: min(1000px, calc(100vw - 2 * var(--gouttiere)));
  --carte-marge: 32px 36px;
  padding: var(--carte-marge);
  border-radius: var(--rayon-carte);
  background: var(--fond-carte);
  box-shadow: var(--ombre-flottante);
  /* Jamais en hauteur : animer `height` recalculerait la mise en page à chaque
     image, sur le premier élément que l'œil suit. Opacité et déplacement
     seulement, et la visibilité bascule d'un coup pour sortir les onze liens
     repliés du parcours de tabulation. */
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -8px);
  transition:
    opacity var(--duree-geste) var(--courbe-geste),
    transform var(--duree-geste) var(--courbe-geste),
    visibility 0s linear var(--duree-geste);
}

.nav__entree[data-ouvert="oui"] .megamenu {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s, 0s, 0s;
}

.megamenu__grille {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--e6);
}

.megamenu__colonne {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e4);
}

.megamenu__liste {
  display: flex;
  flex-direction: column;
  gap: var(--e4);
  width: 100%;
}

/* Le libellé et son accroche forment une seule cible : un lien dont la moitié
   basse ne serait pas cliquable se lit comme un défaut de calage. */
.megamenu__lien {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.megamenu__nom { font-weight: var(--graisse-moyenne); line-height: var(--lh-serre); }

.megamenu__accroche {
  font-size: var(--t-interface);
  line-height: var(--lh-compact);
  color: var(--texte-attenue);
}

/* Le déroulant des Solutions (29/09) : une seule colonne, les quatre titres
   des modules numérotés comme sur la page, puis le lien vers la page entière. */
.megamenu--solutions { width: min(560px, calc(100vw - 2 * var(--gouttiere))); }
.megamenu__lien--numerote {
  display: grid;
  grid-template-columns: var(--e6) minmax(0, 1fr);
  align-items: baseline;
}
.megamenu__numero { font-size: var(--t-etiquette); color: var(--accent); }
.megamenu__tout {
  padding-top: var(--e4);
  border-top: 1px solid var(--filet);
}

.nav__bascule {
  display: none;
  width: 42px;
  height: 42px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 1px solid var(--filet);
  border-radius: var(--rayon-pilule);
  color: var(--texte-marque);
  cursor: pointer;
}

.nav__traits {
  position: relative;
  display: block;
  width: 18px;
  height: 12px;
}
.nav__traits i {
  position: absolute;
  left: 0;
  right: 0;
  height: 1.5px;
  background: currentColor;
  transition:
    transform var(--duree-geste) var(--courbe-geste),
    opacity var(--duree-micro) var(--courbe-survol);
}
.nav__traits i:nth-child(1) { top: 0; }
.nav__traits i:nth-child(2) { top: 5.25px; }
.nav__traits i:nth-child(3) { top: 10.5px; }
.nav[data-ouvert="oui"] .nav__traits i:nth-child(1) { transform: translateY(5.25px) rotate(45deg); }
.nav[data-ouvert="oui"] .nav__traits i:nth-child(2) { opacity: 0; }
.nav[data-ouvert="oui"] .nav__traits i:nth-child(3) { transform: translateY(-5.25px) rotate(-45deg); }

/* Sous 1024 px : barre compacte à 59 px, liens et appel à l'action dans un
   panneau qui se déplie. Il s'anime en transform et en opacité, jamais en
   hauteur, et sa visibilité bascule d'un coup pour sortir les liens repliés
   du parcours de tabulation. Seuil passé de 941 à 1024 px le 29/09 : avec
   cinq entrées, « Comptes clients » se cassait sur deux lignes jusqu'à 995 px. */
@media (max-width: 1023.98px) {
  .nav__ecu { width: 56px; height: 40px; }
  .nav__bascule { display: inline-flex; }

  .nav__deploie {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: var(--e5);
    padding: var(--e5) var(--gouttiere) var(--e6);
    background: var(--fond-carte);
    border-bottom: 1px solid var(--filet);
    box-shadow: var(--ombre-flottante);
    /* Le panneau porte maintenant les onze liens de Solutions en plus des
       siens : déplié en entier sur un écran de 390 px, il dépasse le bas de
       l'écran, et rien ne peut l'y rattraper puisqu'il est absolu dans une
       entête fixe. Il se borne donc à la hauteur visible et défile chez lui.
       Sa mécanique d'ouverture, elle, ne change pas. */
    max-height: calc(100svh - var(--h-entete));
    overflow-y: auto;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition:
      opacity var(--duree-geste) var(--courbe-geste),
      transform var(--duree-geste) var(--courbe-geste),
      visibility 0s linear var(--duree-geste);
  }
  .nav[data-ouvert="oui"] .nav__deploie {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition-delay: 0s, 0s, 0s;
  }

  .nav__liens {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--e4);
  }
  .nav__liens a,
  .nav__secondaire { font-size: var(--t-nav-mobile); }
  .nav__deploie .cta { justify-content: center; }
  /* Dans le panneau, le groupe s'efface : le lien suit les entrées du menu,
     le bouton reste en dernier, sur toute la largeur. */
  .nav__actions { display: contents; }
  .nav__secondaire { align-self: flex-start; }

  /* Sous 1024 px, le méga menu cesse de flotter : il devient l'accordéon de
     l'entrée « Solutions », dans le flux, replié par défaut. Il se retire de
     la mise en page quand il est fermé, sinon il réserverait la hauteur de
     onze liens sous le bouton. */
  .nav__entree {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--e4);
    width: 100%;
  }
  .nav__declencheur { font-size: var(--t-nav-mobile); }

  .megamenu {
    display: none;
    position: static;
    width: 100%;
    padding: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
  }
  .nav__entree[data-ouvert="oui"] .megamenu { display: block; transform: none; }

  .megamenu__grille { grid-template-columns: minmax(0, 1fr); gap: var(--e5); }
}

/* L'entête du modèle ne fait 72 px qu'à partir de 1440 px. En dessous elle
   reste à 64 px, alors que le cadre vidéo, lui, commence toujours à y = 72 :
   les 8 px qui les séparent laissent voir le fond de la page, et c'est
   voulu. */
@media (max-width: 1439.98px) {
  .nav { height: var(--h-entete); }
}

/* Sous 768 px, la gouttière disparaît et la barre passe au-dessus de la
   vidéo. Elle garde donc son fond clair même en haut de page : des liens
   sombres sur une image sombre ne se lisent pas. C'est le seul écart assumé
   au relevé, et il ne porte que sur cette largeur. */
@media (max-width: 767.98px) {
  .nav {
    background: var(--fond-entete);
    -webkit-backdrop-filter: var(--flou-entete);
    backdrop-filter: var(--flou-entete);
  }
}

/* --------------------------------------------------------------- 01. héros */
/* L'entête est fixe et transparente au-dessus du cadre : l'image est une
   pièce posée sur la page, pas un fond qui déborde. Une seule photographie
   derrière le titre.

   Le cadre commence à y = 72 quelle que soit la largeur, et laisse 24 px en
   bas. La gouttière latérale, elle, a deux paliers relevés : 20 px de 768 à
   1380, 24 px à partir de 1440. Aucune n'est fluide, donc aucune ne suit
   --gouttiere, qui sert au contenu. */
/* Le cadre est collé en haut et recule au défilement : la section suivante
   remonte par-dessus. C'est le premier geste que l'œil enregistre, et il est
   invisible sur une capture. L'échelle suit 1 - 0,05 × min(scrollY / 900, 1),
   plancher à 0,95, posée par le script sur --recul. */
.hero {
  position: sticky;
  top: 0;
  z-index: var(--z-base);
  background: var(--fond-carte);
  padding: 72px var(--e5) var(--e5);
}

@media (max-width: 1439.98px) {
  .hero { padding: 72px 20px var(--e5); }
}

.hero__scene {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--rayon-carte);
  /* Hauteur du cadre sur le modèle : la fenêtre moins les 72 px qui la
     séparent du haut de l'écran et les 24 px de gouttière basse. Elle tombe
     au pixel près de 768 à 1920 px de fenêtre. `svh` plutôt que `vh` : sur
     mobile, `100vh` compte la barre d'adresse rétractée et fait déborder le
     cadre sous l'écran. Sur un poste fixe, les deux unités donnent exactement
     la même valeur.
     Une hauteur plancher, jamais une hauteur fixe : le 24/09, un iPhone en
     paysage rognait le titre (cadre de 284 px pour 545 px de contenu), et
     tout écran de moins de 641 px de haut en faisait autant. */
  min-height: calc(100svh - 96px);
  display: flex;
  align-items: flex-end;
  background: var(--fond-fonce);
  color: var(--texte-sur-fonce);
  transform: scale(var(--recul, 1));
  transform-origin: center center;
  will-change: transform;
}

/* La piste du héros. Depuis le 22/09 c'est une photographie fixe et non plus
   une vidéo : le plan de réunion porte le premier écran, donc le LCP, et rien
   d'autre n'est téléchargé pour le héros. */
.hero__piste {
  position: absolute;
  inset: 0;
  z-index: var(--z-base);
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Le cadre porte déjà le rayon et rogne ce qui dépasse, mais c'est
     l'élément média qui se mesure : sans rayon propre il rend `0px` en
     styles calculés, alors que le modèle le pose sur la piste. */
  border-radius: var(--rayon-carte);
  /* Depuis le 24/09, Jean-Marc veut un premier écran lumineux : la
     photographie n'est plus assombrie en bloc (elle était à `brightness(.42)`).
     Seul l'étalonnage froid de la page reste, et c'est le voile qui porte le
     titre blanc, là où il se pose et nulle part ailleurs. */
  filter: grayscale(var(--photo-heros-gris)) saturate(var(--photo-heros-satur)) contrast(var(--photo-heros-contraste));
}

/* Voile neutre, jamais teinté : l'ardoise est la couleur des sections, pas
   celle d'une image. Depuis le 24/09 il ne couvre plus le cadre entier : il
   monte du bord inférieur et s'éteint aux trois quarts de la hauteur. Les
   visages, entre 10 et 22 % du haut de l'image, restent à pleine lumière.
   Le titre, lui, se pose sur le sol de pierre sombre de la photographie. */
.hero__voile {
  position: absolute;
  inset: 0;
  z-index: var(--z-section);
  pointer-events: none;
  background: var(--voile-heros);
}

.hero__contenu {
  position: relative;
  z-index: var(--z-contenu-heros);
  width: 100%;
  padding-block: var(--e9) var(--e8);
  display: flex;
  flex-direction: column;
  /* Titre, sous-titre et appel à l'action sont centrés et posés dans le bas
     du cadre, comme sur le modèle. Le centrage vaut pour la boîte et pour le
     texte à l'intérieur. */
  align-items: center;
  text-align: center;
  gap: var(--e5);
}

.hero__titre {
  margin: 0;
  max-width: 18ch;
  font-family: var(--police);
  font-weight: var(--graisse-legere);
  font-size: var(--t-heros);
  line-height: var(--lh-titre-page);
  letter-spacing: var(--ls-affiche);
  color: var(--texte-sur-fonce);
  /* Une ombre large et douce, qui épouse les lettres : sur l'image claire du
     24/09, c'est elle qui porte la pêche de l'accent quand le titre remonte
     sur la verrière (fenêtres de 800 px de haut et moins). Un voile assez
     dense pour le faire aurait réassombri toute la photographie. */
  text-shadow: var(--ombre-titre-heros);
}

/* Le geste signature sans italique : la phrase détachée garde la fonte du
   titre et ne se distingue plus que par la teinte claire de l'accent,
   mesurée à 5,1:1 sur l'ardoise. */
.hero__titre em {
  font-style: normal;
  color: var(--accent-sur-fonce);
}

/* La marge qui sépare l'appel à l'action du chapeau appartient au héros, pas
   au composant : ailleurs, c'est la grille qui place le bouton. */
.hero__contenu .cta { margin-top: var(--e2); }

.hero__sous {
  max-width: 52ch;
  font-size: var(--t-chapo-heros);
  line-height: var(--lh-corps);
  font-weight: var(--graisse-normale);
  color: var(--texte-sur-fonce-88);
}

/* ------------------------------------------------------- appel à l'action */
/* Un seul composant pour tous les appels à l'action principaux de la page.
   Le mot reste à gauche, le disque à flèche part à l'autre bout de la pilule
   au survol. Le déplacement se joue sur le jeu (`flex-grow`) des deux
   entretoises, pas sur une position absolue : la flèche reste dans le flux et
   la pilule garde la même largeur d'un état à l'autre.
   L'entretoise avant garde 12 px de base : sans eux, la flèche touchait la
   dernière lettre au repos, mesuré à 0 px d'écart à toutes les largeurs. */
/* La pilule ne porte plus de réserve de course : le rond se colle au bout,
   à la distance du padding, et la largeur suit le contenu. Les 107 px de vide
   qui restaient derrière le rond au repos se lisaient comme un défaut de
   calage, pas comme une intention.

   Au survol, c'est la couleur du rond qui inonde la pilule : la nappe part du
   centre du rond et grandit jusqu'à la couvrir, en s'arrêtant à 4 px du bord.
   Il reste donc un liséré de la couleur de repos tout autour, et le libellé
   bascule sur la couleur contrastante. Le rond ne disparaît pas, il devient
   la pilule.

   Deux variantes, deux jetons locaux, aucune règle recopiée :
   --nappe, la couleur qui inonde, et --mot-survol, celle que prend le mot. */
.cta {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  --cta-ecart: 12px;
  max-width: 100%;
  height: 60px;
  --cta-marge: 8px 8px 8px 28px;
  gap: var(--cta-ecart);
  padding: var(--cta-marge);
  border-radius: var(--rayon-pilule);
  background: var(--action);
  color: var(--texte-sur-fonce);
  font-size: var(--t-interface);
  font-weight: var(--graisse-moyenne);
  line-height: var(--lh-plein);
  text-decoration: none;
  overflow: hidden;
  --nappe: var(--fond-blanc);
  --mot-survol: var(--action);
}

/* La nappe est insérée de 4 px sur les quatre côtés : c'est ce retrait qui
   fait le liséré. Elle est découpée en cercle centré sur le rond, à 30 px du
   bord droit (8 de padding plus 22 de demi-rond). Le rayon de 140 % couvre le
   coin opposé quelle que soit la longueur du libellé : à 100 %, la référence
   CSS vaut sqrt(l²+h²)/sqrt(2), soit moins que la diagonale réelle depuis un
   centre excentré. */
.cta__nappe {
  position: absolute;
  inset: var(--e1);
  z-index: var(--z-dessous);
  border-radius: var(--rayon-pilule);
  background: var(--nappe);
  clip-path: circle(0 at calc(100% - 30px) 50%);
  transition: clip-path var(--duree-nappe) var(--courbe-geste);
  pointer-events: none;
}
.cta:hover .cta__nappe,
.cta:focus-visible .cta__nappe { clip-path: circle(140% at calc(100% - 30px) 50%); }

.cta:hover .cta__mot,
.cta:focus-visible .cta__mot { color: var(--mot-survol); }

.cta__disque {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--rayon-pilule);
  background: var(--nappe);
  color: var(--action);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.cta__disque svg { width: 16px; height: 16px; }

/* Le mot avant découpe : une seule ligne, jamais coupée, jamais rétrécie
   sous sa largeur naturelle. Après découpe, il est fait de piles qui montent
   d'une demi-hauteur pour révéler leur seconde copie.
   La seconde copie est un `::after` alimenté par `data-lettre`, et non un
   second <span> : un doublon dans le document rendrait « RRééss... » à la
   sélection, à la recherche dans la page et à tout outil qui lit le texte. */
.cta__mot { display: inline-flex; flex: 0 0 auto; white-space: nowrap; transition: color var(--duree-nappe) var(--courbe-geste); }

.cta__lettre {
  display: inline-block;
  overflow: hidden;
  height: 1.2em;
  line-height: var(--lh-etiquette);
}
.cta__pile { display: block; }
.cta__pile::after { content: attr(data-lettre); display: block; }

/* Variante claire, pour les fonds ardoise et les cartes claires : la pilule
   passe au blanc, le rond au cuivre. Les deux jetons s'inversent, et le
   survol devient symétrique de celui de la variante sombre. */
.cta--clair {
  background: var(--fond-blanc);
  color: var(--texte-marque);
  --nappe: var(--action);
  --mot-survol: var(--texte-sur-fonce);
}
.cta--clair .cta__disque { color: var(--texte-sur-fonce); }

/* Variante compacte, pour l'entête : un CTA de 60 px ne tient pas dans une
   barre de 72 px, et encore moins dans les 64 px des largeurs intermédiaires.
   Seules les mesures changent, la mécanique est la même. */
.cta--compact {
  height: 44px;
  --cta-marge: 6px 6px 6px 20px;
  --cta-ecart: 10px;
  font-size: var(--t-bouton-compact);
}
.cta--compact .cta__disque { width: 32px; height: 32px; }
.cta--compact .cta__disque svg { width: 14px; height: 14px; }
.cta--compact .cta__nappe { clip-path: circle(0 at calc(100% - 22px) 50%); }
.cta--compact:hover .cta__nappe,
.cta--compact:focus-visible .cta__nappe { clip-path: circle(140% at calc(100% - 22px) 50%); }

/* Palier intermédiaire du titre : 64 px de 768 à 1380, relevé sur le modèle
   à sept largeurs. */

/* Sous 768 px, le modèle abandonne la gouttière et le rayon : la vidéo occupe
   toute la largeur et toute la hauteur visible, et l'entête se pose dessus.
   Le titre descend à 48 px, toujours en Geist 300, centré, avec le même
   interlettrage. */
@media (max-width: 767.98px) {
  .hero { padding: 0; }
  .hero__scene, .hero__piste { border-radius: 0; }
  .hero__scene { min-height: 100svh; }
  .cta { width: min(100%, 320px); }
  /* Le contenu est calé en bas : les 64 px d'entête posée sur la vidéo ne le
     recouvrent jamais, seul le haut de l'image passe dessous. */
  .hero__contenu { padding-block: var(--e8) var(--e7); }
  .hero__titre { max-width: none; }
  .hero__sous { font-size: var(--t-chapo-heros-mobile); }
}

/* Fenêtre basse : téléphone en paysage, petit iPhone, portable à écran
   court. Le contenu du héros ne tient plus dans la fenêtre et le cadre
   grandit avec lui. Il cesse alors de se coller : collé en haut et plus haut
   que l'écran, son bas ne serait jamais découvert, appel à l'action compris.
   Seuils mesurés le 24/09 : 601 px de contenu au plus sous 768 px de large,
   598 px plus 96 px de marges au-dessus. Un titre ou un sous-titre plus long
   les rend faux : les remesurer. */
@media (max-width: 767.98px) and (max-height: 620px),
       (min-width: 768px) and (max-height: 700px) {
  .hero { position: relative; }
  .hero__scene { transform: none; }
}

/* Sous 768 px, l'entête est posée sur le cadre : quand le contenu le remplit
   jusqu'en haut, le titre ne doit pas venir la toucher. */
@media (max-width: 767.98px) and (max-height: 620px) {
  .hero__contenu { padding-top: calc(var(--e8) + var(--e5)); }
}

/* ------------------------------------------------------------ 02. repères */
/* Une carte dans une carte : c'est ce double niveau qui fait la profondeur,
   pas une ombre. L'aplat ardoise pleine largeur de la V2.2 tombe. La section
   est blanche, l'enveloppante est un blanc cassé à rayon 16, les trois cartes
   sont blanches à rayon 16, et aucune des trois n'a d'ombre ni de bordure :
   mesuré carte par carte sur le modèle. */

.reperes {
  background: var(--fond-blanc);
  padding-block: 0 var(--e5);
}

.reperes__enveloppe {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Les deux écarts du modèle : 80 px de l'étiquette à la citation, 120 px de
   la citation à la bande. Ils ne passent pas par `gap`, qui les rendrait
   égaux. */
.reperes__citation {
  margin-top: 80px;
  font-family: var(--police);
  font-size: var(--t-titre-section);
  line-height: var(--lh-titre-section);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-affiche);
  max-width: 26ch;
}

/* La seconde phrase de la citation, en corps courant. Elle suit la citation
   à --e5 ; les 120 px jusqu'à la bande partent désormais d'elle. */
.reperes__suite {
  margin-top: var(--e5);
  max-width: 60ch;
  color: var(--texte-attenue);
}

.reperes__bande {
  margin-top: 120px;
  display: flex;
  flex-wrap: wrap;
  gap: var(--e5);
  width: 100%;
}

.repere {
  flex: 1 1 260px;
  min-width: 0;
  min-height: 250px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--e5);
  padding: var(--e5);
  background: var(--fond-blanc);
  border-radius: var(--rayon-carte);
  text-decoration: none;
  color: inherit;
}

/* L'énoncé est borné sur une carte qui fait près de 500 px : il tient sur deux
   lignes courtes et laisse le reste vide. C'est ce vide qui fait le rapport
   d'échelle avec le chiffre.
   Relevé le 22/09 : c'est la phrase que Matthis a pointée en premier sur la
   lisibilité. Elle passe du petit corps au corps courant, la mesure s'élargit
   d'autant pour garder les deux lignes, et le gris tiède du relevé cède au
   texte de la page. */
.repere__enonce {
  max-width: 280px;
  font-size: var(--t-enonce);
  font-weight: var(--graisse-normale);
  line-height: var(--lh-enonce);
  letter-spacing: var(--ls-enonce);
  color: var(--texte);
}

/* Le chiffre et son signe sont deux éléments, pas une chaîne : le signe a son
   propre interlettrage, plus lâche que celui du chiffre. */
.repere__valeur {
  display: flex;
  align-items: baseline;
  gap: var(--e1);
}

.repere__chiffre,
.repere__signe {
  font-family: var(--police);
  font-size: var(--t-chiffre-cle);
  line-height: var(--lh-plein);
  font-weight: var(--graisse-normale);
  color: var(--chiffre);
}
.repere__chiffre { letter-spacing: var(--ls-affiche); }
.repere__signe { letter-spacing: var(--ls-signe); }

/* `rouleau` : chaque chiffre défile sur sa propre colonne, comme un compteur
   mécanique. Ces règles ne mordent que si le script a construit la structure :
   sur la page brute, `.repere__chiffre` reste un texte et rien ne s'applique.
   La valeur bascule de `baseline` à `flex-end` le temps du roulement : une
   colonne qui rogne n'a pas la même ligne de base qu'un texte, et le « + »
   se décalerait. Les chiffres et le « + » n'ont pas de jambage, donc aligner
   leurs cadratins revient au même que les aligner sur la ligne de base.
   Aucun flex ici, et c'est volontaire : en conteneur flex, la piste devient un
   élément flex étiré à la hauteur de sa colonne, soit 1 em au lieu de 11, et le
   roulement ne parcourt plus qu'un rang. Mesuré le 22/09. En blocs, la piste
   fait la hauteur de son contenu et déborde d'une colonne qui rogne. */
.rouleau { display: inline-block; overflow: hidden; height: 1em; vertical-align: bottom; }
.rouleau__piste { display: block; }
.rouleau__piste span { display: block; height: 1em; line-height: var(--lh-plein); }

@media (max-width: 767.98px) {
  .reperes { padding-bottom: 0; }
  .reperes__citation { margin-top: var(--e7); }
  .reperes__bande { margin-top: var(--e8); }
  .repere { min-height: 0; }
}

/* --------------------------------------------------- carte enveloppante */
/* La carte dans une carte, une seule fois pour les cinq sections qui en
   portent une : repères, constat, solutions, méthode et FAQ.

   Les deux cartes qui existaient ne s'accordaient pas : 1612 px de large et
   64 / 40 de padding pour les repères, 1580 et 56 pour le constat. Les deux
   valeurs retenues sont les mesurées, pas les inventées.

   La largeur vient de `.enveloppe`, donc de --largeur-page : 1580 px à 1660 px de
   fenêtre. C'est ce jeton qui tient l'alignement du bord gauche de toutes les
   sections, et une carte qui s'en écarterait de 16 px le casserait. Les
   repères, qui flottaient à 1612 sur une gouttière de 24 px héritée du cadre
   vidéo, rentrent dans le rang.

   Le padding vient du relevé sur le modèle : 64 en haut et en bas, 40 sur les
   côtés. Le 56 uniforme du constat était une valeur de circonstance.

   Le fond se choisit en contraste de celui de la section : deux modificateurs
   suffisent, un clair pour les sections bleutées, un bleuté pour les sections
   crème. */
.panneau {
  border-radius: var(--rayon-carte);
  --carte-marge: clamp(28px, 4vw, 64px) clamp(20px, 2.5vw, 40px);
  padding: var(--carte-marge);
}

.panneau--papier { background: var(--fond-carte); }
.panneau--secondaire { background: var(--fond-alterne); }

@media (max-width: 767.98px) {
  .panneau { border-radius: 0; margin-inline: calc(var(--gouttiere) * -1); }
}

/* ------------------------------------------------------------ 03. constat */
/* Le propos ne bouge pas : un budget, deux chemins, deux nets. Ce qui change,
   c'est le contenant. Le bloc entier devient un panneau à rayon 16 posé sur
   le vélin, la démonstration chiffrée une carte claire à l'intérieur, et
   chaque libellé de ligne une étiquette Chivo Mono sur pilule.
   Depuis le 24/09, la section porte TROIS démonstrations, sur la simulation
   2026 du cabinet : le coût comparé d'un même net, le même cas après impôt
   sur les sociétés, puis le sort d'une prime de 35 000 €. Chacune s'annonce
   à gauche et se démontre à droite. */

.constat__texte {
  display: flex;
  flex-direction: column;
  gap: var(--e5);
}

.constat__blocs {
  margin-top: var(--e8);
  display: flex;
  flex-direction: column;
  gap: var(--e8);
}

.constat__bloc {
  display: grid;
  gap: var(--e5);
  align-items: start;
}

/* L'introduction dit ce que le schéma démontre, avant qu'on le lise. Sans
   elle, la carte n'est qu'une suite de montants. */
.constat__intro {
  display: flex;
  flex-direction: column;
  gap: var(--e3);
}

.constat__num {
  font-family: var(--police-mono);
  font-size: var(--t-etiquette);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-etiquette);
  color: var(--accent);
}

/* La carte qui porte un schéma. Elle remplace `.barres` du round 6 : mêmes
   fond, rayon et padding, un nom qui ne parle plus de barres puisqu'il n'y en
   a plus. */
.constat__carte {
  background: var(--fond-carte);
  border-radius: var(--rayon-carte);
  --carte-marge: clamp(24px, 2.4vw, 36px);
  padding: var(--carte-marge);
  display: flex;
  flex-direction: column;
  gap: var(--e6);
}

.constat__mention {
  font-size: var(--t-mention);
  line-height: var(--lh-mention);
  color: var(--texte-attenue);
  border-top: 1px solid var(--filet);
  padding-top: var(--e4);
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  font-weight: var(--graisse-normale);
}

/* ------------------------------------------- schéma 01, l'entonnoir */
/* La descente de la slide 1 du cabinet, rendue telle quelle : trois
   dispositifs côte à côte, une accolade qui les réunit en un total, une
   seconde vers le net, une flèche vers l'équivalent en salaire. Le vert, le
   magenta et l'orange de la plaquette cèdent à l'échelle tonale marine →
   marine-doux → marine-brume : trois parts d'un même ensemble, pas trois
   couleurs sans lien. Le cuivre reste réservé au résultat.

   Les deux grilles partagent le même gabarit de colonnes : sans ça, les
   accolades ne couvriraient pas exactement la largeur des trois cartes. */
.entonnoir {
  display: flex;
  flex-direction: column;
  gap: var(--e5);
  /* L'écart entre les cartes et leur marge intérieure se resserrent avec la
     fenêtre : à 941 px, chaque dispositif ne dispose que de 93 px. */
  --ecart: clamp(6px, .8vw, 14px);
  --pad-disp: clamp(8px, .9vw, 14px);
}

.entonnoir__cas,
.entonnoir__suite {
  display: grid;
  /* La colonne de libellés vaut un quart de plus qu'une carte : c'est le
     rapport de la slide, et c'est aussi le minimum pour que la pilule
     « PAR MANAGER » tienne à 941 px, où la carte ne fait plus que 93 px. */
  grid-template-columns: minmax(0, 1.25fr) repeat(3, minmax(0, 1fr));
  column-gap: var(--ecart);
}

.entonnoir__cas {
  /* Trois rangées : le nom, le plafond, le montant. Aucun écart vertical,
     les cartes doivent rester d'un seul tenant. */
  grid-template-rows: auto auto auto;
  row-gap: 0;
}

.entonnoir__suite { row-gap: var(--e4); align-items: center; }

/* La colonne de libellés et les trois cartes s'accrochent aux MÊMES trois
   rangées : c'est `subgrid` qui aligne « Plafond légal annuel » sur
   « 75 % du PASS » sans qu'aucune hauteur ne soit posée à la main.
   Les cartes ne portent donc aucun padding, ce sont leurs cellules qui le
   portent : un padding sur un conteneur en subgrid rogne sa première et sa
   dernière rangée, et l'alignement se décale d'autant. */
.entonnoir__libelles,
.dispositif {
  grid-row: 1 / -1;
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0;
  /* `minmax(0, …)` borne la piste, pas l'élément : sans cette remise à zéro,
     le `min-width: auto` d'un élément de grille l'empêche de descendre sous
     sa largeur min-content et il déborde de sa colonne. */
  min-width: 0;
}

.entonnoir__libelles { grid-column: 1; }

.entonnoir__cadre {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e2);
  padding-bottom: var(--e4);
}

.entonnoir__precision {
  font-size: var(--t-interface);
  line-height: var(--lh-enonce);
  color: var(--texte-attenue);
}

.entonnoir__rangee {
  align-self: center;
  padding-right: var(--e3);
  font-size: var(--t-interface);
  line-height: var(--lh-serre);
}

.dispositif {
  border-radius: var(--rayon-carte);
  overflow: hidden;
  background: var(--echelle-1);
  color: var(--texte-sur-accent);
  text-align: center;
}

.dispositif--derogatoire { background: var(--echelle-2); }
.dispositif--abondement { background: var(--echelle-3); color: var(--texte); }

.dispositif__nom {
  padding: var(--e4) var(--pad-disp) var(--e3);
  border-bottom: 1px solid var(--filet);
  font-size: var(--t-dispositif-nom);
  line-height: var(--lh-dispositif-nom);
  font-weight: var(--graisse-moyenne);
  /* « Participation volontaire dérogatoire » dans une colonne de 93 px à
     941 px : sans césure, « dérogatoire » sortirait de sa carte. La limite
     empêche le coupeur glouton de détacher « vo- » là où il reste la place
     de passer le mot entier à la ligne. */
  hyphens: auto;
  hyphenate-limit-chars: 8 4 4;
}

/* Le filet clair du relevé disparaîtrait sur la carte la plus pâle. */
.dispositif--abondement .dispositif__nom { border-bottom-color: var(--echelle-2); }

/* Sur écran large, la colonne de libellés porte l'intitulé de chaque rangée :
   celui des cartes reste dans le document pour les lecteurs d'écran, qui
   n'ont pas la colonne sous les yeux. Sous 941 px, la colonne s'efface et
   c'est lui qui titre la rangée. */
.dispositif__intitule {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.dispositif__plafond {
  padding: var(--e3) var(--pad-disp) var(--e1);
  font-size: var(--t-interface);
  line-height: var(--lh-serre);
}

.dispositif__montant {
  padding: 0 var(--pad-disp) var(--e4);
  font-family: var(--police);
  font-size: var(--t-dispositif-montant);
  line-height: var(--lh-dispositif-montant);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre-reset);
  white-space: nowrap;
}

/* L'accolade : un trait droit qui couvre la largeur des trois cartes, un
   retour vertical court à chaque extrémité, une tige centrale vers la
   pastille. Pas de boucle : le trait droit est dans la DA, la boucle ne
   l'est pas. Le tracé s'étire en largeur, `non-scaling-stroke` garde son
   épaisseur constante. */
.accolade {
  grid-column: 2 / -1;
  display: block;
  width: 100%;
  height: 30px;
}
.accolade--courte { height: 22px; }
.accolade svg { display: block; width: 100%; height: 100%; }
.accolade path {
  fill: none;
  stroke: var(--echelle-3);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

.entonnoir__palier {
  grid-column: 2 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e2);
  text-align: center;
}

.pastille {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  padding: var(--e3) clamp(16px, 2.2vw, 36px);
  border-radius: var(--rayon-pilule);
  background: var(--fond-alterne);
  font-family: var(--police);
  font-size: var(--t-pastille);
  line-height: var(--lh-titre-page);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre);
  color: var(--texte-marque);
  white-space: nowrap;
}

/* Le net est le résultat : c'est lui, et lui seul, qui porte l'accent. */
.pastille--net {
  background: var(--fond-carte);
  box-shadow: var(--ombre-flottante);
  color: var(--action);
}

.entonnoir__legende {
  font-size: var(--t-interface);
  line-height: var(--lh-compact);
  color: var(--texte-attenue);
  max-width: 46ch;
}

.entonnoir__bascule {
  grid-column: 2 / -1;
  display: flex;
  justify-content: center;
}

/* La flèche du lien resservie comme signe de passage, tournée vers le bas :
   le même dessin partout où la page fait descendre d'un montant à un autre. */
.entonnoir__bascule .fleche {
  width: 26px;
  height: 26px;
  color: var(--texte-attenue);
  transform: rotate(90deg);
}

/* Sur le MÊME axe que les accolades, les paliers et la flèche : en `1 / -1` et
   aligné à gauche, la dernière ligne de l'entonnoir partait seule sous la
   colonne de libellés, décalée de tout ce qu'elle conclut. */
.entonnoir__equivalence {
  grid-column: 2 / -1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--e4);
  text-align: center;
}

.pastille--salaire {
  background: var(--fond-neutre);
  color: var(--texte-sur-accent);
  font-size: var(--t-pastille-secondaire);
  padding: var(--e3) var(--e5);
}

.entonnoir__egal {
  font-size: var(--t-signe-egal);
  line-height: var(--lh-plein);
  color: var(--texte-attenue);
}

/* Le « = » voyage avec ce qu'il introduit : quand la ligne passe à la ligne,
   le laisser seul en bout de première ligne en faisait un signe sans second
   membre. */
.entonnoir__lien {
  display: flex;
  align-items: center;
  gap: var(--e4);
}

.entonnoir__salaire {
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  font-size: var(--t-corps);
  line-height: var(--lh-enonce);
}
.entonnoir__salaire b { font-weight: var(--graisse-moyenne); }
.entonnoir__salaire span { font-size: var(--t-interface); color: var(--texte-attenue); }

/* Retiré le 22/09 : `.legende*` servait la barre segmentée du round 6. Les trois
   dispositifs portent maintenant leur nom et leur montant dans leur propre carte,
   il n'y a plus de couleur à légender. */

/* ------------------------------------ schéma 02, le tableau comparatif */
/* La slide 2 est un tableau, et c'est un tableau qu'on rend : en-têtes de
   colonne et de rangée balisés, une colonne mise en avant, deux pastilles de
   gain en marge. Les montants sont alignés sur leur bord droit, faute de quoi
   la comparaison ligne à ligne demande de relire chaque chiffre. */
.calcul {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-interface);
  line-height: var(--lh-compact);
}

.calcul th,
.calcul td {
  padding: var(--e3) var(--e2);
  border-bottom: 1px solid var(--filet);
  text-align: right;
  vertical-align: middle;
  font-weight: var(--graisse-normale);
}

.calcul th:first-child,
.calcul td:first-child {
  text-align: left;
  padding-left: 0;
  padding-right: var(--e4);
  color: var(--texte-attenue);
}

/* Une colonne de tableau se dimensionne sur la largeur min-content de ses
   cellules. À 390 px, « ACCORD D'INTÉRESSEMENT » réclamait à lui seul 167 des
   302 px disponibles et poussait la page à 403 px de large. La césure rend
   ces mots sécables et ramène la colonne dans le rang. Elle dépend du
   dictionnaire du navigateur, que Chrome n'a pas toujours : la pilule porte
   donc aussi une césure conditionnelle écrite (`&shy;`), qui ne dépend de
   rien. Mesuré le 23/09. Elle ne joue que sous 768 px : au-dessus, la
   colonne a la place de couper à l'espace, et la ligne gourmande préférait
   « D'INTÉRES- / SEMENT » à « ACCORD / D'INTÉRESSEMENT ». */
.calcul th { hyphens: auto; hyphenate-limit-chars: 8 4 4; }
.calcul th .calcul__pilule { hyphens: none; }
@media (max-width: 767.98px) {
  .calcul th .calcul__pilule { hyphens: manual; }
}

.calcul thead th,
.calcul thead td {
  border-bottom: 0;
  padding-bottom: var(--e4);
  text-align: center;
}

.calcul b { font-weight: var(--graisse-moyenne); }
.calcul th b { color: var(--texte); }

/* Les deux étiquettes de colonne. Celle de l'accord prend le cuivre : c'est
   ce que fait l'orange de la slide. */
.calcul__pilule {
  display: inline-block;
  max-width: 100%;
  --pilule-marge: 7px 14px;
  padding: var(--pilule-marge);
  border-radius: var(--rayon-pilule);
  background: var(--fond-alterne);
  color: var(--texte);
  font-family: var(--police-mono);
  font-size: var(--t-etiquette);
  line-height: var(--lh-serre);
  letter-spacing: var(--ls-etiquette);
  text-transform: uppercase;
  font-weight: var(--graisse-normale);
}
.calcul__pilule--accord { background: var(--action); color: var(--texte-sur-accent); }

/* La colonne mise en avant. Le filet cuivré et les montants en cuivre 500 ne
   suffisaient pas : mesuré au pixel le 22/09, les deux colonnes avaient le même
   fond que la carte, donc rien ne soulevait la bonne réponse. La surface la
   porte maintenant, et c'est elle que l'œil trouve avant de lire un chiffre.
   Le premier et le dernier bord sont arrondis pour que la colonne se lise comme
   un bloc et non comme une suite de cellules teintées. */
.calcul__accord {
  background: var(--fond-alterne);
  color: var(--action);
}
.calcul thead .calcul__accord {
  border-top: 2px solid var(--action);
  padding-top: var(--e4);
  border-radius: var(--rayon-carte) var(--rayon-carte) 0 0;
}
.calcul tbody tr:last-child .calcul__accord {
  border-radius: 0 0 var(--rayon-carte) var(--rayon-carte);
}

/* La quatrième colonne n'existe que pour les deux pastilles de gain : elle
   se réduit à leur largeur et ne porte aucun filet. */
.calcul__marge {
  width: 1px;
  border-bottom: 0;
  padding-right: 0;
  padding-left: var(--e4);
  text-align: left;
  white-space: nowrap;
}

.gain {
  display: inline-flex;
  align-items: center;
  --gain-marge: 5px 12px;
  padding: var(--gain-marge);
  border-radius: var(--rayon-pilule);
  background: var(--action);
  color: var(--texte-sur-accent);
  font-family: var(--police-mono);
  font-size: var(--t-etiquette);
  line-height: var(--lh-etiquette);
  letter-spacing: var(--ls-etiquette);
  white-space: nowrap;
}
/* Sous 941 px la quatrième colonne disparaît : la pastille se replie en fin
   de cellule de la colonne intéressement. Une seule des deux copies est
   rendue à chaque largeur, donc une seule est lue.
   Elle prend sa propre ligne, et non la suite du montant : collée derrière un
   montant lui-même insécable, elle portait la largeur min-content de la
   cellule à 131 px et le tableau débordait de la page à 390 px. */
.gain--cellule { display: none; width: fit-content; margin: var(--e2) 0 0 auto; }

.avantage {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e3);
  padding: var(--e5);
  border-radius: var(--rayon-carte);
  background: var(--fond-alterne);
}

@media (min-width: 1024px) {
  /* Deux cinquièmes pour l'introduction, trois pour la carte : l'introduction fait
     trois lignes, la carte en fait vingt. À parts égales, la colonne de gauche
     n'était qu'un vide, et la ligne de résultat du schéma 01 se coupait.
     Seuil à 1024 et non 941 depuis le 24/09 : entre les deux, la carte à trois
     cinquièmes était trop étroite pour les tableaux 02 et 03, qui sortaient de
     9 et 17 px. L'introduction passe au-dessus de sa carte jusqu'à 1023 px. */
  .constat__bloc { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--e8); }
}

/* Sous 941 px : les trois cartes s'empilent, la colonne de libellés passe
   au-dessus et ses deux libellés de rangée redeviennent les intitulés
   internes de chaque carte. Les accolades tombent à une simple tige
   verticale centrée, tracée en fond plutôt qu'en SVG : le dessin à deux
   retours n'a plus de sens sur une colonne unique. */
@media (max-width: 940.98px) {
  .entonnoir__cas,
  .entonnoir__suite { grid-template-columns: minmax(0, 1fr); }

  .entonnoir__cas { grid-template-rows: none; row-gap: var(--e4); }

  .entonnoir__libelles,
  .dispositif {
    grid-column: 1;
    grid-row: auto;
    display: flex;
    flex-direction: column;
  }

  .entonnoir__cadre { padding-bottom: 0; }
  .entonnoir__rangee { display: none; }

  .dispositif { text-align: left; }
  .dispositif__nom,
  .dispositif__plafond,
  .dispositif__montant { padding-inline: var(--e4); }
  .dispositif__nom { font-size: var(--t-corps); }
  .dispositif__montant { font-size: var(--t-dispositif-montant-mobile); }

  .dispositif__intitule {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    display: block;
    /* La marge, pas du padding : l'intitulé vit dans la cellule, qui porte
       déjà le retrait latéral de la carte. */
    margin: var(--e3) 0 var(--e1);
    font-family: var(--police-mono);
    font-size: var(--t-etiquette);
    line-height: var(--lh-etiquette);
    letter-spacing: var(--ls-etiquette);
    text-transform: uppercase;
    opacity: .72;
  }
  /* Sur l'ardoise moyenne, .72 laissait l'intitulé à 3,44:1. Premier
     centième qui passe 4,5:1 (.92 donne 4,498). */
  .dispositif--derogatoire .dispositif__intitule { opacity: .93; }

  .accolade,
  .entonnoir__palier,
  .entonnoir__bascule,
  .entonnoir__equivalence { grid-column: 1; }

  .accolade {
    height: 24px;
    background: linear-gradient(var(--echelle-3), var(--echelle-3)) center / 1.5px 100% no-repeat;
  }
  .accolade svg { display: none; }

  .calcul__marge { display: none; }
  .gain--cellule { display: flex; }
}

@media (max-width: 767.98px) {
  .calcul th,
  .calcul td { padding: var(--e3) var(--e1); }
  .calcul th:first-child,
  .calcul td:first-child { padding-right: var(--e2); }
  .calcul__pilule { --pilule-marge: 6px 10px; }
}

/* Les montants qui comptent (`compte`) sont en chiffres tabulaires. En chasse
   proportionnelle, « 111 111 € » et « 888 888 € » diffèrent de 50 px à 34 px :
   la valeur changeait de largeur à chaque image de la course et le chiffre
   tremblait de gauche à droite jusqu'à l'arrêt. À nombre de chiffres égal, la
   largeur ne bouge plus. Mesuré le 24/09. */
#constat [data-anim="compte"] { font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------- 04. ruptures */

.ruptures__grille {
  display: grid;
  gap: var(--e7);
  align-items: start;
}

.ruptures__liste {
  display: flex;
  flex-direction: column;
  margin-top: var(--e6);
}

.rupture {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e3) var(--e5);
  padding-block: var(--e5);
  border-top: 1px solid var(--filet);
}
.rupture:last-child { border-bottom: 1px solid var(--filet); }

.rupture__num {
  font-family: var(--police-mono);
  font-size: var(--t-etiquette);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-etiquette);
  color: var(--accent-sur-fonce);
  padding-top: 5px;
}

.rupture__corps { display: flex; flex-direction: column; gap: var(--e3); }
.rupture__corps .h3 { color: var(--texte-sur-fonce); }
/* Le sous-titre d'une rupture est un `.petit` : même couleur que le corps,
   droit, puisque l'italique est sorti de la page. */
.rupture__corps .corps,
.rupture__corps .petit { color: var(--texte-sur-fonce-attenue); }
/* Les libellés de Jean-Marc (« Le constat : ») en blanc dans la phrase. 500 et
   non le `bolder` par défaut : Geist n'est chargée qu'en 300, 400 et 500. */
.rupture__corps b { color: var(--texte-sur-fonce); font-weight: var(--graisse-moyenne); }

/* Les photographies grandissent pendant qu'elles traversent l'écran, en
   continu et sans jamais basculer : le script écrit --grossit image par
   image, entre 1 et 1,10. Le cadre rogne, donc rien ne pousse la mise en
   page. Même grammaire pour les ruptures et pour la méthode. */
.ruptures__grille > .photo > img,
.methode__images > .photo > img {
  transform: scale(var(--grossit, 1));
  transform-origin: center center;
  will-change: transform;
}

/* La grille des ruptures ne passe à deux colonnes qu'à 1200 px. À 941, la
   photographie prenait 620 px et il restait 280 px au texte : le titre y
   tombait sur quatre lignes, dont deux d'un seul mot. Ce n'est pas un
   problème de typographie, c'est une colonne trop étroite. */
@media (min-width: 1200px) {
  .ruptures__grille {
    grid-template-columns: minmax(0, 620px) minmax(0, 1fr);
    gap: var(--e8);
  }
  /* Depuis le round 8, la colonne de texte fait 2,5 à 2,8 fois la hauteur de
     l'image (mesuré à 1660 et 1440 px) : sans ça, la moitié gauche de la
     section reste un aplat marine vide au défilement. */
  .ruptures__grille > .photo { position: sticky; top: var(--haut-colle); }
  .rupture { grid-template-columns: 56px 1fr; gap: var(--e3) var(--e6); }
}

/* ---------------------------------------------------------- 05. solutions */
/* « Le Sommaire ». Les cinq dispositifs ne sont pas cinq boîtes équivalentes :
   ils se rangent en deux familles, et c'est le choix de famille qui se fait en
   premier. Chaque rubrique garde sa barre sous les yeux pendant tout son
   chapitre, grâce à `position: sticky` sur la colonne de gauche.
   La tête de chaque famille est traitée plus grand que ses voisines : elle
   porte le cas le plus fréquent, les autres se lisent en diagonale.
   Aucun mécanisme neuf, aucun clic requis pour voir les cinq. */

/* La mesure du titre vaut à toutes les largeurs : les 22ch de `.tete .h2`
   laissaient « structure » seul sur sa ligne à 768 px. */
.solutions__tete .h2 { max-width: 30ch; }

/* La tête de section prend deux colonnes, mais la seconde est vide : le tiers
   droit est laissé nu, il ne borne plus que la largeur du titre. */
.solutions__tete {
  display: grid;
  gap: var(--e5);
}

.sommaire {
  margin-top: var(--e8);
  display: flex;
  flex-direction: column;
  gap: var(--e8);
}

.rubrique {
  display: grid;
  gap: var(--e5);
  border-top: 1px solid var(--filet);
  padding-top: var(--e6);
}

.rubrique__barre {
  display: flex;
  flex-direction: column;
  gap: var(--e3);
  align-self: start;
}

.rubrique__num {
  font-family: var(--police-mono);
  font-size: var(--t-etiquette);
  letter-spacing: var(--ls-etiquette);
  color: var(--accent);
}

.rubrique__titre {
  font-family: var(--police);
  font-size: var(--t-titre-rubrique);
  line-height: var(--lh-titre-section);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre-bloc);
  /* 14ch faisaient 224 px à 32 px de corps : « Ce qui se distribue chaque
     année » y tenait sur trois lignes dont une ne portait qu'un mot. */
  max-width: 20ch;
}

.rubrique__compte { font-size: var(--t-interface); color: var(--texte-attenue); }

/* Une image par famille, pas une par dispositif. Cinq vignettes sur cinq
   dispositifs auraient ramené la section à la grille d'illustrations que le
   concept « Le Sommaire » avait justement écartée, et auraient fait reposer
   la section sur la réussite de cinq images au lieu de deux.
   Elle vit dans la barre de rubrique, qui était la partie creuse de la
   section : une colonne de 360 px pour un ordinal, un titre et un compte.
   Collée au défilement avec elle, elle reste sous les yeux pendant tout le
   chapitre. Elle ne grandit pas au défilement : une image épinglée qui
   bouge quand rien d'autre ne bouge attire l'œil pour rien. */
.rubrique__image {
  margin-top: var(--e5);
  width: 100%;
  aspect-ratio: 4 / 3;
}

.rubrique__corps {
  display: grid;
  gap: var(--e5);
}

.disp {
  display: flex;
  flex-direction: column;
  gap: var(--e3);
  --carte-marge: clamp(20px, 1.8vw, 32px);
  padding: var(--carte-marge);
  border-radius: var(--rayon-carte);
  background: var(--fond-carte);
  text-decoration: none;
  color: inherit;
}
/* Pas de baisse d'opacité sur ces entrées : éteindre une carte qu'on vient
   de désigner est contre-intuitif. C'est la flèche qui avance, la carte reste
   pleinement lue. C'est le seul survol de la page qui déroge à la grammaire
   relevée sur le modèle. */
.disp .fleche { transition: transform var(--duree-geste) var(--courbe-geste); }
.disp:hover .fleche { transform: translateX(6px); }

.disp__nom {
  font-family: var(--police-mono);
  font-size: var(--t-etiquette);
  line-height: var(--lh-etiquette);
  letter-spacing: var(--ls-etiquette);
  text-transform: uppercase;
  font-weight: var(--graisse-normale);
  color: var(--accent);
}

.disp .h3 { font-size: var(--t-titre-carte); }
.disp .corps { font-size: var(--t-interface); }
.disp .lien-fleche { margin-top: var(--e1); }

/* La tête de famille : plus de place, un titre au calibre des cartes de
   fonctionnalités du modèle, et le seul aplat ardoise de la section. */
.disp--tete {
  background: var(--fond-fonce);
  color: var(--texte-sur-fonce);
  --accent: var(--accent-sur-fonce);
  --texte-attenue: var(--texte-sur-fonce-attenue);
  gap: var(--e4);
}
.disp--tete .h3 { color: var(--texte-sur-fonce); font-size: var(--t-titre-carte-large); }
.disp--tete .corps { color: var(--texte-sur-fonce-attenue); font-size: var(--t-corps); }

/* Les amorces de Jean-Marc (« Le principe managérial : »), round 8. 500 et non
   le `bolder` par défaut, que Geist ne charge pas ; en blanc sur l'ardoise de
   la tête de famille, comme les libellés des ruptures. */
.disp b { font-weight: var(--graisse-moyenne); }
.disp--tete b { color: var(--texte-sur-fonce); }

@media (min-width: 761px) {
  .rubrique__corps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .disp--tete { grid-column: 1 / -1; }
  /* Une carte seule derrière la tête de famille (le capital n'en a qu'une)
     prend toute la ligne : en demi-largeur, elle laissait une moitié vide
     à côté d'une colonne étroite, que le texte du round 8 a doublée. */
  .disp--tete + .disp:last-child { grid-column: 1 / -1; }
}

@media (min-width: 1024px) {
  .solutions__tete {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    align-items: end;
    gap: var(--e8);
  }

  .rubrique {
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
    gap: var(--e8);
  }
  /* La barre reste sous les yeux pendant son chapitre. 96 px : les 72 px de
     l'entête fixe, plus une respiration. */
  .rubrique__barre { position: sticky; top: var(--haut-colle); }
}

/* ------------------------------------------------------------ 06. méthode */

.methode__images {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e4);
  margin-top: var(--e7);
}

@media (min-width: 641px) {
  .methode__images { grid-template-columns: 1fr 1fr; gap: var(--e5); }
}

.methode__liste {
  margin-top: var(--e7);
  border-top: 1px solid var(--filet);
}

.etape {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--e2) var(--e5);
  padding-block: var(--e5);
  border-bottom: 1px solid var(--filet);
}

.etape__num {
  font-family: var(--police-mono);
  font-size: var(--t-etiquette);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-etiquette);
  color: var(--action);
  padding-top: 6px;
}

.etape__corps { display: flex; flex-direction: column; gap: var(--e2); }

/* Titre et sous-titre font un seul enfant de grille : sans ce bloc, le
   sous-titre serait un troisième enfant de `.etape__corps`, qui s'efface
   au-dessus de 941 px, et tomberait dans une rangée orpheline. Sa première
   ligne de base est celle du titre, c'est elle que la grille aligne. */
.etape__tete { display: flex; flex-direction: column; gap: var(--e2); }
.etape__sous { color: var(--texte-attenue); }

.etape__titre a { text-decoration: none; }

@media (min-width: 941px) {
  .etape {
    grid-template-columns: 56px minmax(0, 300px) minmax(0, 1fr);
    align-items: baseline;
    gap: var(--e6);
  }
  .etape__corps { display: contents; }
}

/* ---------------------------------------------------------------- 09. FAQ */
/* Deux colonnes : la carte ardoise de prise de rendez-vous à gauche, la pile
   d'accordéons à droite. La carte reste accrochée au défilement, la pile est
   trois fois plus haute qu'elle. La mécanique des accordéons ne change pas :
   des <details>, qui fonctionnent sans JavaScript. */

.faq__grille {
  display: grid;
  gap: var(--e6);
  align-items: start;
  margin-top: var(--e7);
}

/* L'ecart general de la carte est a 22 px, pas aux 16 px du pas d'espacement :
   c'est une valeur demandee a l'oeil, elle ne se range pas dans l'echelle. */
.faq-carte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
  --carte-marge: clamp(24px, 2.6vw, 40px);
  padding: var(--carte-marge);
  border-radius: var(--rayon-carte);
  background: var(--fond-fonce);
  color: var(--texte-sur-fonce);
  --texte-attenue: var(--texte-sur-fonce-attenue);
  /* Le focus lit --accent : sans cette ligne, l'anneau cuivre tombait à
     1,13:1 sur l'ardoise. */
  --accent: var(--accent-sur-fonce);
}
.faq-carte .h3 { color: var(--texte-sur-fonce); }
.faq-carte .corps { color: var(--texte-sur-fonce-attenue); }

/* Le portrait est un carré à coins arrondis, au rayon de la page, pas un
   rond. La section « Qui vous reçoit » ayant disparu, c'est ici et dans le
   bloc de rendez-vous que Jean-Marc est identifié. */
/* La carte change de registre a cet endroit : on passe de l'action a
   l'identite de celui qui recoit. Les 22 px de l'ecart general ne marquaient
   pas ce passage. 10 px de plus le portent a 32. */
.faq-carte__qui {
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin-top: 10px;
}
.faq-carte__qui img {
  width: 48px;
  height: 48px;
  flex: 0 0 auto;
  border-radius: var(--rayon-carte);
  object-fit: cover;
}

/* Le lien LinkedIn descend ici : c'est la seule preuve extérieure de la
   personne sur toute la page, et sa section d'origine est supprimée. */
/* Le logo seul, sans étiquette visible. Le libellé reste sur le lien en
   `aria-label` : il disparaît de l'écran, pas de la lecture.
   Le padding n'est pas décoratif : un logo de 18 px laisserait une cible de
   18 px, sous le minimum utilisable. Avec 9 px tout autour, la cible fait
   36 px de côté, et la marge négative la remet dans l'alignement du texte. */
.faq-carte__lkd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start;
  width: 36px;
  height: 36px;
  margin-left: -9px;
  color: var(--accent-sur-fonce);
  text-decoration: none;
}
.faq-carte__lkd svg { width: 18px; height: 18px; fill: currentColor; flex: 0 0 auto; }
.faq-carte__qui p { font-size: var(--t-interface); color: var(--texte-sur-fonce-attenue); }
.faq-carte__qui b { color: var(--texte-sur-fonce); font-weight: var(--graisse-moyenne); }

.faq-carte__mail {
  font-size: var(--t-interface);
  color: var(--texte-sur-fonce-attenue);
  padding-top: var(--e4);
  border-top: 1px solid var(--filet-sur-fonce);
  width: 100%;
}
.faq-carte__mail a {
  color: var(--accent-sur-fonce);
  text-decoration: none;
}

.faq__liste { border-top: 1px solid var(--filet); }

.faq__item { border-bottom: 1px solid var(--filet); }

.faq__question {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e5);
  padding-block: var(--e5);
  font-family: var(--police);
  font-size: var(--t-question);
  line-height: var(--lh-question);
  font-weight: var(--graisse-normale);
  letter-spacing: var(--ls-titre-bloc);
}
.faq__question::-webkit-details-marker { display: none; }

.faq__signe::before { content: "+"; }
.faq__item[open] .faq__signe { background: var(--action); color: var(--texte-sur-fonce); }
.faq__item[open] .faq__signe::before { content: "\2212"; }

/* La hauteur est écrite par le script, donc le panneau doit pouvoir être
   rogné pendant la course. `height` n'est jamais posée ici : elle est mise à
   `auto` dès que la course est finie, pour que le texte reste redimensionnable. */
.faq__reponse { overflow: hidden; }

.faq__reponse > div {
  display: flex;
  flex-direction: column;
  gap: var(--e3);
  padding-bottom: var(--e6);
  max-width: 78ch;
}

/* Les listes des réponses de Jean-Marc. Même corps et même mesure que les
   paragraphes voisins, puces et numéros en gris, retrait sobre. La remise à
   zéro globale des listes est levée ici seulement. */
.faq__points {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  max-width: 64ch;
  padding-left: 1.25em;
  font-size: var(--t-corps);
  line-height: var(--lh-corps);
}
ul.faq__points { list-style: disc; }
ol.faq__points { list-style: decimal; }
.faq__points li::marker { color: var(--texte-attenue); }

/* Ses amorces en gras : 500, la graisse la plus forte que la page charge. */
.faq__reponse b { font-weight: var(--graisse-moyenne); }

/* Le signe fait un demi-tour pendant la course, sur la même courbe que la
   hauteur : le passage du plus au moins se fait sous la rotation. */
.faq__signe {
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border-radius: var(--rayon-pilule);
  border: 1px solid var(--action);
  color: var(--action);
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--police);
  font-size: var(--t-signe);
  line-height: var(--lh-plein);
  font-weight: var(--graisse-normale);
  transition: background-color var(--duree-geste) var(--courbe-geste), color var(--duree-geste) var(--courbe-geste);
  transform: rotate(calc(var(--tour, 0) * 1deg));
}

@media (min-width: 1024px) {
  .faq__grille {
    grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
    gap: var(--e8);
  }
  .faq-carte { position: sticky; top: 120px; }
}

/* --------------------------------------------------------- 10. appel final */
/* Photographie pleine hauteur à gauche, panneau ardoise à droite. Les deux
   pièces font la même hauteur : c'est la grille qui les étire, pas une
   hauteur posée à la main sur chacune. */

.rdv__grille {
  display: grid;
  gap: var(--e5);
  align-items: stretch;
}

.rdv__photo {
  position: relative;
  overflow: hidden;
  border-radius: var(--rayon-carte);
  min-height: 320px;
  background: var(--fond-fonce);
}
.rdv__photo > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 24%;
  border-radius: 0;
  filter: grayscale(var(--photo-portrait-gris)) saturate(var(--photo-portrait-satur)) contrast(var(--photo-portrait-contraste));
}

.rdv__panneau {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e5);
  --carte-marge: clamp(28px, 3vw, 56px);
  padding: var(--carte-marge);
  border-radius: var(--rayon-carte);
  background: var(--fond-fonce);
  color: var(--texte-sur-fonce);
  --accent: var(--accent-sur-fonce);
  --texte-attenue: var(--texte-sur-fonce-attenue);
}

.rdv__titre { color: var(--texte-sur-fonce); max-width: 15ch; }
.rdv__chapo { color: var(--texte-sur-fonce-attenue); max-width: 54ch; }

/* Les six leviers que l'appel permet de trancher, depuis le 24/09. Chacun
   sous un filet, comme les deux points de réassurance qu'ils remplacent :
   une colonne sur téléphone, deux dès que le panneau a la place. */
.rdv__leviers {
  display: grid;
  gap: 0 var(--e5);
  width: 100%;
  margin: calc(var(--e2) * -1) 0 0;
}

.rdv__leviers li {
  padding: var(--e3) 0;
  border-bottom: 1px solid var(--filet-sur-fonce);
  font-size: var(--t-corps);
  line-height: var(--lh-compact);
}

@media (min-width: 641px) {
  .rdv__leviers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.rdv__garantie { color: var(--texte-sur-fonce-attenue); margin-top: calc(var(--e2) * -1); }

@media (min-width: 941px) {
  /* La colonne du portrait est bornée à 440 px. Le fichier source fait 400 px
     de côté : sans ce plafond, la colonne montait à 760 px et l'image était
     agrandie 1,9 fois. Mesuré après plafonnement, le cadre fait 440 x 628 et
     le facteur retombe à 1,57. C'est mieux, ce n'est pas bon : sur un écran
     à deux pixels par point, l'agrandissement réel est de 3,14. Il faut un
     fichier d'au moins 1257 px de côté pour que le cadre soit net. */
  .rdv__grille { grid-template-columns: minmax(0, 440px) minmax(0, 1fr); }
  .rdv__photo { min-height: 520px; }
}

/* ----------------------------------------------------------------- 11. pied */

.pied {
  background: var(--fond-pied);
  color: var(--texte-sur-fonce);
  /* Même raison que la carte de la FAQ : anneau cuivre à 2,82:1 sur le pied. */
  --accent: var(--accent-sur-fonce);
  padding-block: var(--e9) var(--e7);
  font-size: var(--t-interface);
}

.pied__haut { display: grid; gap: var(--e7); }

.pied__filiation { max-width: 40ch; color: var(--texte-sur-fonce-82); font-weight: var(--graisse-normale); }

.pied__adresse {
  font-style: normal;
  margin-top: var(--e4);
  color: var(--texte-sur-fonce-attenue);
  display: flex;
  flex-direction: column;
  gap: var(--e1);
}

.pied__colonnes {
  display: grid;
  gap: var(--e6);
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

.pied__colonnes h3 {
  font-family: var(--police);
  font-size: var(--t-surtitre);
  line-height: var(--lh-etiquette);
  letter-spacing: var(--ls-surtitre);
  text-transform: uppercase;
  color: var(--texte-sur-fonce-attenue);
  margin: 0 0 var(--e4);
  font-weight: var(--graisse-moyenne);
}

.pied__colonnes li + li { margin-top: var(--e2); }

.pied__lien {
  color: var(--texte-sur-fonce-86);
  text-decoration: none;
  font-weight: var(--graisse-legere);
}

.pied__statut {
  margin-top: var(--e7);
  padding-top: var(--e5);
  border-top: 1px solid var(--filet-pied);
  color: var(--texte-sur-fonce-attenue);
  font-size: var(--t-mention);
  line-height: var(--lh-mention);
  font-weight: var(--graisse-normale);
}

@media (min-width: 941px) {
  .pied__haut { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: var(--e8); }
  .pied__colonnes { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--e5); }
}

/* -------------------------------------------------------------- mouvement */

/* Le découpage des titres. Trois niveaux, et chacun a sa raison :

   `.ligne` est le masque. Il est en `block`, donc il ne touche pas à la ligne
   de base du titre, là où un `overflow: hidden` posé sur un `inline-block`
   déplacerait la sienne sur son bord inférieur et décalerait tout le texte.
   Il porte aussi la perspective : posée sur la ligne, tous les caractères
   partagent le même point de fuite et la rotation se lit comme un seul
   mouvement. Posée sur chaque caractère, chacun aurait le sien.

   `.mot` est insécable. Ce sont les espaces entre les mots, restés des nœuds
   de texte, qui portent les occasions de retour à la ligne : la coupure du
   titre est donc exactement celle du texte non découpé.

   `.car` tourne autour de son bord inférieur, c'est ce qui le fait sortir de
   sous la ligne au lieu de pivoter sur son milieu.

   Rien ici ne masque : l'état de départ est posé par GSAP. Sans lui, aucun
   titre n'est découpé et tous restent lisibles. */
.ligne {
  display: block;
  overflow: hidden;
  perspective: 600px;
}

/* -------------------------------------------------- aucun mot orphelin */
/* Règle de page : aucun titre, aucun chapeau, aucun corps ne laisse un mot
   seul sur sa dernière ligne, à aucune largeur.

   `balance` égalise les lignes d'un bloc court : c'est le bon outil pour un
   titre de une à trois lignes, et il supprime l'orphelin en répartissant le
   texte au lieu de le coller. Les moteurs le plafonnent à quelques lignes,
   d'où `pretty` sur les paragraphes longs, qui ne rééquilibre pas tout mais
   interdit la dernière ligne trop courte.

   Ce n'est pas une garantie à lui seul : les blocs qui résistent reçoivent
   une insécable entre leurs deux derniers mots, et la mesure dit lesquels. */
.h1,
.h2,
.h3,
.hero__titre,
.reperes__citation,
.rubrique__titre,
.repere__enonce,
.tete .petit,
.sol__sous,
.faq__question {
  text-wrap: balance;
}

.corps,
.petit,
.hero__sous,
.rdv__chapo,
.constat__mention,
.entonnoir__legende,
.faq__reponse p,
.pied__filiation,
.pied__statut p {
  text-wrap: pretty;
}
.mot { display: inline-block; white-space: nowrap; }
.car {
  display: inline-block;
  transform-origin: 50% 100%;
  will-change: transform, opacity;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
  }
  /* Le héros ne se colle plus et ne recule plus : le modèle ignore la
     préférence, pas nous. */
  .hero { position: static; }
  .hero__scene { transform: none !important; }
  /* Ceinture : aucune révélation n'est armée en mouvement réduit, mais si la
     préférence changeait après l'armement, rien ne resterait caché. */
  .car { transform: none !important; opacity: 1 !important; }
  .ligne { overflow: visible; }
}

/* ----------------------------------------------- garde anti-FOUC */
/* Mesuré le 22/09 sur la page en ligne : le premier bloc à révéler était peint
   à `opacity: 1` dès 152 ms, et GSAP l'effaçait à 238 ms. 86 ms de contenu
   peint puis retiré, en local, sans la latence du CDN qui sert GSAP. Le CSS
   n'avait aucun état initial : la page s'affichait entière, et c'est le
   `gsap.set` du `DOMContentLoaded` qui masquait après coup.

   L'attribut `data-reveal` est posé par un script en ligne placé juste après
   cette feuille, donc avant tout contenu, et retiré par le script des frames
   une fois les `gsap.set` posés. S'il n'y a pas de GSAP, ou en mouvement
   réduit, il est retiré tout de suite : sans ce filet, un CDN muet laisserait
   la page vide pour toujours.

   Cette liste de sélecteurs est la COPIE EXACTE de celle de `frames`, dans le
   script. Les deux se modifient ensemble. */
html[data-reveal="arme"] .panneau,
html[data-reveal="arme"] .repere,
html[data-reveal="arme"] .constat__carte,
html[data-reveal="arme"] .dispositif,
html[data-reveal="arme"] .entonnoir__palier,
html[data-reveal="arme"] .calcul tbody tr,
html[data-reveal="arme"] .gain,
html[data-reveal="arme"] .disp,
html[data-reveal="arme"] .rubrique__barre,
html[data-reveal="arme"] .etape,
html[data-reveal="arme"] .rupture,
html[data-reveal="arme"] .faq__item,
html[data-reveal="arme"] .faq-carte,
html[data-reveal="arme"] .rdv__photo,
html[data-reveal="arme"] .rdv__panneau,
html[data-reveal="arme"] .methode__images > .photo,
html[data-reveal="arme"] .ruptures__grille > .photo,
html[data-reveal="arme"] .liste-edito__item,
html[data-reveal="arme"] .carte,
html[data-reveal="arme"] [data-revele] { opacity: 0; }
