/* ============================================================
   SYSTÈME DE SECTIONS — le vocabulaire commun de tout le site.

   ⚠️⚠️ POURQUOI CE FICHIER EXISTE. L'accueil a été refait avec ses propres
   classes (`v-hero`, `v-sec`, `v-grille`, `v-offres`…) et les 11 autres pages
   sont restées sur le vocabulaire historique (`.section`, `.section-head`,
   `.card`, `.plans`). Résultat : pour aligner les deux, j'avais empilé des
   `!important` dans 15 feuilles.

   Ici, on donne un VOCABULAIRE UNIQUE, repris de l'accueil, que toutes les
   pages peuvent utiliser :

     .s-sec          une section (padding vertical unique)
     .s-tete         l'en-tête d'une section : titre + numéro
     .s-num          le numéro « 01 — La prestation »
     .s-grille       une grille de blocs (2, 3 ou 4 colonnes selon data-col)
     .s-bloc         un bloc de la grille : numéro, titre, texte
     .s-liste        une liste de bénéfices (filet fin entre les items)
     .s-offres       la grille des offres
     .s-offre        une carte d'offre
     .s-encadre      un encadré (bordé, aplat clair)
     .s-duo          deux colonnes : argument à gauche, action à droite

   ⚠️ CE VOCABULAIRE EST IDENTIQUE A L'ACCUEIL : mêmes valeurs de padding,
   mêmes tailles, mêmes filets. C'est ce qui fait qu'une page refaite avec
   ces classes est AUTOMATIQUEMENT cohérente, sans `!important`.

   ⚠️ RÈGLE : une page refaite n'utilise QUE ces classes. Si une page a besoin
   d'une variante, on l'ajoute ICI, pas dans un fichier séparé.
   ============================================================ */

/* ---------- section ---------- */
.s-sec {
  padding: 88px 28px;
  border-top: 1px solid var(--line);
}
.s-sec:first-of-type { border-top: 0; }
.s-sec > * { max-width: 1120px; margin-left: auto; margin-right: auto; }

/* ---------- en-tête de section ---------- */
.s-tete {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 40px; flex-wrap: wrap; margin-bottom: 56px;
}
.s-tete h2 { max-width: 22ch; }
.s-tete p { max-width: 62ch; margin: 16px 0 0; color: var(--muted); font-size: 16px; }
.s-num {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink); white-space: nowrap;
}

/* ---------- grille ---------- */
.s-grille {
  display: grid; gap: 0; border-top: 1px solid var(--line);
  grid-template-columns: repeat(2, 1fr);
}
.s-grille[data-col="3"] { grid-template-columns: repeat(3, 1fr); }
.s-grille[data-col="4"] { grid-template-columns: repeat(4, 1fr); }

.s-bloc {
  padding: 34px 30px 34px 0;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  min-width: 0;
}
.s-bloc:last-child { border-right: 0; }
/* la grille a 2 colonnes : un filet a droite des impairs */
.s-grille[data-col="2"] .s-bloc:nth-child(2n) { border-right: 0; padding-right: 0; }
.s-grille[data-col="3"] .s-bloc:nth-child(3n) { border-right: 0; }
.s-grille[data-col="4"] .s-bloc:nth-child(4n) { border-right: 0; }
.s-bloc:nth-child(2) { padding-left: 30px; }
.s-grille[data-col="3"] .s-bloc:nth-child(3n+2) { padding-left: 30px; }
.s-grille[data-col="4"] .s-bloc:nth-child(4n+3) { padding-left: 30px; }

.s-bloc .n {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .18em;
  display: block; margin-bottom: 18px; color: var(--ink);
}
.s-bloc h3 { margin: 0 0 12px; }
.s-bloc p { margin: 0; color: var(--muted); font-size: 15px; max-width: 46ch; }

/* ---------- liste de bénéfices ---------- */
.s-liste { list-style: none; margin: 0; padding: 0; }
.s-liste li {
  padding: 12px 0; border-bottom: 1px solid var(--line);
  font-size: 15px; color: var(--ink);
}
.s-liste li:last-child { border-bottom: 0; }

/* ---------- offres ---------- */
.s-offres {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line);
}
.s-offre {
  background: var(--card); padding: 40px 34px 44px;
  display: flex; flex-direction: column; min-width: 0;
}
.s-offre.mise { background: var(--paper-2); }
.s-offre .nom {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink); margin: 0;
}
/* ⚠️⚠️ LINE-HEIGHT ET PADDING POUR ANTON.
   Bug mesuré : a `line-height: 1.05` le prix faisait `scrollHeight=58` dans une
   boite de `48` — le haut des chiffres etait COUPE de 10 px (« 14,99 » perdait
   son sommet). Anton a une hauteur de glyphe superieure a l'interligne. */
.s-offre .prix {
  font-family: var(--font-serif); font-size: 46px;
  margin: 18px 0 4px; line-height: 1.18; padding: .04em 0; color: var(--ink);
}
.s-offre .prix small {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .12em;
  color: var(--muted); margin-left: 6px;
}
.s-offre .cond { font-size: 14.5px; color: var(--muted); margin: 10px 0 0; }
.s-offre .s-liste { margin: 24px 0 30px; flex: 1; }
.s-offre .tag {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .16em;
  border: 1px solid var(--ink); padding: 4px 9px; display: inline-block;
  margin-bottom: 18px; text-transform: uppercase; align-self: flex-start;
  color: var(--ink);
}

/* ---------- encadré ---------- */
.s-encadre {
  border: 1px solid var(--line); background: var(--paper-2);
  padding: 48px 44px;
}
.s-encadre h2 { max-width: 24ch; margin-bottom: 24px; }

/* ---------- duo argument / action ---------- */
.s-duo {
  display: grid; grid-template-columns: 1.3fr .8fr; gap: 1px;
  background: var(--line); border: 1px solid var(--line);
}
.s-duo > div { background: var(--card); padding: 40px 38px; min-width: 0; }
.s-duo > div:last-child { background: var(--paper-2); display: flex; flex-direction: column; justify-content: center; }
.s-duo .accroche {
  font-family: var(--font-serif); font-size: 26px; line-height: 1.08;
  margin: 0 0 22px; color: var(--ink);
}

/* ---------- adaptation ---------- */
@media (max-width: 1000px) {
  .s-grille[data-col="4"] { grid-template-columns: repeat(2, 1fr); }
  .s-offres { grid-template-columns: 1fr; }
  .s-duo { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .s-sec { padding: 56px 20px; }
  .s-tete { margin-bottom: 36px; }
  .s-grille, .s-grille[data-col="3"] { grid-template-columns: 1fr; }
  .s-bloc, .s-bloc:nth-child(2) { padding: 28px 0; border-right: 0; }
  .s-encadre { padding: 30px 22px; }
  .s-duo > div { padding: 28px 22px; }
  .s-offre { padding: 30px 24px 34px; }
  .s-offre .prix { font-size: 38px; }
}

/* ============================================================
   TUNNEL DE L'OFFRE (/visibilite)
   ⚠️ Meme langage que le reste : angles droits, filets fins, aucun aplat
   colore, et l'echelle de titres unique. Les classes `visi-*` sont
   conservees (elles portent la logique du tunnel) mais leur STYLE est
   ramene au langage commun.
   ============================================================ */
/* ⚠️⚠️ LE PADDING ETAIT COMPTE DEUX FOIS. `.s-sec` porte deja `padding: 88px 28px`
   et `.s-tunnel` ajoutait `padding: 0 28px` : le contenu cadrait a 244 px au lieu
   de 216, soit 28 px de decalage avec /pricing. Meme piege que le hero de
   l'accueil. Un seul endroit porte la gouttiere : la SECTION. */
.s-tunnel { max-width: 1120px; margin: 0 auto; padding: 0; }

/* le hero du tunnel : titre + preuve, deux colonnes */
.visi-hero { padding: 64px 0 48px; border-bottom: 1px solid var(--line); }
.visi-eyebrow {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink); display: block; margin-bottom: 20px;
}
.visi-hero h1 { max-width: 20ch; margin: 0 0 24px; }
.visi-hero p { max-width: 62ch; color: var(--muted); font-size: 17px; margin: 0; }
.visi-whats-included {
  display: flex; flex-wrap: wrap; gap: 12px 32px; margin-top: 28px;
  padding-top: 24px; border-top: 1px solid var(--line);
}
.visi-item { display: flex; align-items: center; gap: 10px; font-size: 15px; color: var(--ink); }
.visi-item svg { flex: none; }

/* les exemples de sites : trois colonnes, filets */
.visi-proof-head { margin-bottom: 34px; }
.visi-proof-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.proof-card { background: var(--card); padding: 24px; margin: 0; min-width: 0; }
.proof-card img { width: 100%; height: auto; display: block; border: 1px solid var(--line); }
.proof-card figcaption { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .1em; color: var(--muted); margin-top: 14px; }
.visi-proof-note { font-size: 14.5px; color: var(--muted); margin-top: 24px; max-width: 78ch; }

/* le calculateur : deux colonnes */
.visi-calc { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.visi-calc-copy h2 { max-width: 20ch; margin-bottom: 20px; }
.visi-calc-points { list-style: none; margin: 0 0 28px; padding: 0; }
.visi-calc-points li { padding: 11px 0; border-bottom: 1px solid var(--line); font-size: 15px; color: var(--ink); }
.visi-calc-shot { border: 1px solid var(--line); background: var(--card); }
.vcs-bar { display: flex; align-items: center; gap: 7px; padding: 12px 15px; border-bottom: 1px solid var(--line); background: var(--paper-2); }
.vcs-bar span { width: 9px; height: 9px; background: var(--line); display: block; }
.vcs-bar em { font-family: var(--font-mono); font-size: 11px; color: var(--muted); font-style: normal; margin-left: 8px; }
.vcs-body { padding: 22px; }
.vcs-t { font-family: var(--font-serif); font-size: 20px; margin-bottom: 16px; color: var(--ink); }
.vcs-l { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14px; color: var(--ink); }
.vcs-l i { display: none; }
.vcs-tot { display: flex; justify-content: space-between; padding-top: 16px; font-size: 15px; color: var(--ink); }

/* la mise en page guide + carte de paiement */
.visi-layout { display: grid; grid-template-columns: 1.15fr .85fr; gap: 64px; align-items: start; }
.visi-guide-block { margin-bottom: 44px; }
.visi-guide-title { font-size: 25px; margin: 0 0 18px; }
.visi-steps-guide { list-style: none; margin: 0; padding: 0; counter-reset: vg; }
.visi-steps-guide li { display: flex; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--line); font-size: 15px; counter-increment: vg; }
.visi-steps-guide li strong { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .14em; color: var(--ink); min-width: 26px; }
.visi-steps-guide li p { margin: 4px 0 0; color: var(--muted); }
/* la FAQ */
.visi-q { border-bottom: 1px solid var(--line); }
.visi-q summary { cursor: pointer; padding: 16px 0; font-family: var(--font-serif); font-size: 17px; color: var(--ink); list-style: none; }
.visi-q summary::-webkit-details-marker { display: none; }
.visi-q p { margin: 0 0 16px; font-size: 14.5px; color: var(--muted); }
.visi-guide-reassure ul { list-style: none; margin: 0; padding: 0; }
.visi-guide-reassure li { padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 15px; color: var(--ink); }

/* la carte de paiement : aplat clair, filet, angles droits */
.visi-card { border: 1px solid var(--ink); background: var(--card); padding: 32px 30px; position: sticky; top: 90px; }
.visi-summary { display: block; }
.visi-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.visi-plan-name { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink); }
.visi-price { font-family: var(--font-serif); font-size: 44px; line-height: 1.18; padding: .04em 0; margin: 12px 0 0; color: var(--ink); }
.visi-price-major { }
.visi-price small { font-family: var(--font-mono); font-size: 12px; color: var(--muted); margin-left: 5px; }
.visi-badge { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; border: 1px solid var(--ink); padding: 4px 9px; color: var(--ink); }
.visi-badges { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.visi-list { list-style: none; margin: 24px 0; padding: 0; }
.visi-list li { padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14.5px; color: var(--ink); }
.visi-separator { height: 1px; background: var(--line); margin: 24px 0; }
.visi-pay-title { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink); }
.visi-note { font-size: 14px; color: var(--muted); margin: 8px 0 18px; }
.visi-pay label { display: block; font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin: 14px 0 7px; }
.visi-pay input[type=email] { width: 100%; padding: 14px 15px; border: 1px solid var(--line); background: var(--card); color: var(--ink); font-size: 15px; }
.visi-consent { display: flex; gap: 12px; align-items: flex-start; margin: 18px 0; font-size: 13.5px; color: var(--muted); text-transform: none; letter-spacing: 0; }
.visi-consent input { margin-top: 3px; flex: none; }
.visi-consent a { color: var(--ink); }
.visi-tiny { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em; color: var(--muted); text-align: center; margin-top: 14px; }
.visi-alt { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line); font-size: 14px; color: var(--muted); }
.visi-alt a { color: var(--ink); }

@media (max-width: 1000px) {
  .visi-proof-grid, .visi-calc, .visi-layout { grid-template-columns: 1fr; gap: 28px; }
  .visi-card { position: static; }
}
@media (max-width: 900px) {
  /* ⚠️ MEME DOUBLE PADDING QUE SUR DESKTOP (corrige 2026-10-05) : `.s-sec` porte
     deja la gouttiere, le `20px` ici la comptait une 2e fois -> texte a 38 px au
     lieu de l'axe (18 px) sur /visibilite mobile. */
  .s-tunnel { padding: 0; }
  .visi-hero { padding: 40px 0 32px; }
  .visi-guide-title { font-size: 20px; }
  .visi-price { font-size: 36px; }
}

/* ⚠️ COHÉRENCE D'ALIGNEMENT sur /visibilite : le hero et les bénéfices étaient
   CENTRÉS, la suite ALIGNÉE À GAUCHE. Mesure : le passage était brusque.
   Tout le site est aligné à gauche — on aligne ce bloc comme le reste. */
.visi-hero { text-align: left; }
.visi-hero h1, .visi-hero p { margin-left: 0; margin-right: 0; }
.visi-whats-included { justify-content: flex-start; }

/* ============================================================
   ECRAN D'OUVERTURE — une seule regle, robuste partout.

   ⚠️⚠️ LEÇON DE MES DIX PALIERS. J'ai empilé des media queries par largeur ET
   par hauteur (`max-height: 860/780/760/700/680`, `max-width: 900/420`). Elles
   se combattaient : a 360x740 le hero faisait 818 px pour un ecran de 740, et
   corriger un palier cassait le precedent.

   LA REGLE JUSTE, en une ligne :
       min-height: min(100svh, 900px)
   → sur un grand ecran, le hero fait un plein ecran (l'effet de la reference) ;
   → sur un petit ecran, il s'arrete a 900 px et GRANDIT selon son contenu,
     sans jamais forcer un plein ecran qui deborderait.

   ⚠️ On ne cache JAMAIS le sous-titre pour gagner de la place : c'est du
   contenu de vente. On laisse la page defiler de quelques pixels si besoin —
   invisible pour le visiteur, contrairement a un texte rogne.
   ============================================================ */
body.v-page .v-hero {
  min-height: min(100svh, 900px);
  padding-top: 118px !important;
  padding-bottom: 56px !important;
  display: flex; flex-direction: column; justify-content: center;
}
@media (max-width: 900px) {
  body.v-page .v-hero { padding-top: 88px !important; padding-bottom: 40px !important; }
  /* ⚠️⚠️ LE TITRE ETAIT ECRASE (corrige 2026-10-05). Deux divergences mesurees
     avec la maquette VALIDEE (previews/accueil-blanc.html, 390px) :
       - taille : maquette 46,8px  ->  ici 30px (36 % plus petit) ;
       - largeur : maquette 350px (pleine colonne) -> ici 255px, bride par le
         `max-width: 17ch` de `vitrine.css` (17ch en Anton ~ 255px).
     Resultat : un titre de 30px en Anton, coince dans 65 % de la largeur, avec
     117px de vide a droite — c'est ce qui donne l'impression de casse.
     On revient a la maquette : titre plus grand et pleine largeur. */
  body.v-page .v-h1 { font-size: clamp(34px, 11vw, 50px) !important; max-width: none; }
  .v-hero-sub { margin-top: 18px; font-size: 15px; }
  .v-hero-cta { margin-top: 22px; }
  .v-hero-facts { margin-top: 26px; }
  .v-hero-facts > div { padding: 12px 0 0; }
  .v-hero-facts dd { font-size: 18px; }
}
@media (max-width: 900px) and (max-height: 860px) {
  /* ⚠️⚠️ LE HERO DEVENAIT PLUS HAUT QUE L'ECRAN sur petit telephone.
     Mesure : 840 px pour un ecran de 740, et 864 px pour un ecran de 568.
     Le sol en perspective tombait alors SOUS la ligne de flottaison.
     ⚠️ La cause n'est pas le texte mais les ESPACEMENTS : 88 px en haut,
     30 px entre chaque bloc, 162 px de bandeau. On les resserre par paliers,
     sans jamais reduire la lisibilite du texte au-dela du raisonnable. */
  body.v-page .v-hero { padding-top: 68px !important; padding-bottom: 26px !important; }
  body.v-page .v-h1 { font-size: clamp(32px, 10vw, 46px) !important; }
  .v-hero-sub { margin-top: 14px; font-size: 14.5px; }
  .v-hero-cta { margin-top: 16px; }
  .v-hero-facts { margin-top: 18px; }
  .v-hero-facts > div { padding: 8px 0 0; }
  .v-hero-facts dt { font-size: 10px; }
  .v-hero-facts dd { font-size: 15px; margin-top: 3px; }
}
@media (max-width: 900px) and (max-height: 700px) {
  body.v-page .v-hero { padding-top: 56px !important; padding-bottom: 20px !important; }
  body.v-page .v-h1 { font-size: clamp(30px, 9vw, 40px) !important; }
  .v-hero-sub { margin-top: 12px; font-size: 14px; }
  .v-hero-cta { margin-top: 14px; }
  .v-hero-cta .v-btn { padding: 13px 18px; font-size: 11px; }
  .v-hero-facts { margin-top: 14px; }
  .v-hero-facts dd { font-size: 14px; }
}
@media (max-width: 900px) and (max-height: 600px) {
  body.v-page .v-hero { padding-top: 48px !important; padding-bottom: 16px !important; }
  body.v-page .v-h1 { font-size: clamp(26px, 8vw, 34px) !important; }
  /* ⚠️⚠️ IL FALLAIT AUSSI LES ESPACEMENTS INTERNES ET LES BOUTONS.
     Mesure : sur un 320x568, le bloc CTA faisait 194 px — les trois elements
     (bouton plein, bouton vide, mention) s'empilaient sur 284 px de large, et
     le bouton principal faisait 75 px de haut. Les marges du sous-titre (30 px)
     et du bandeau (40 px) n'etaient pas couvertes non plus. Une regle de
     padding seul ne suffit pas : il faut TOUTE la chaine d'espacements. */
  body.v-page .v-hero-sub { margin-top: 10px !important; font-size: 13px !important; }
  body.v-page .v-hero-cta { margin-top: 12px !important; gap: 8px !important; }
  body.v-page .v-hero-cta .v-btn { padding: 11px 14px !important; font-size: 10.5px !important; width: 100%; }
  body.v-page .v-hero-note { font-size: 10px !important; margin-left: 0 !important; }
  body.v-page .v-hero-facts { margin-top: 12px !important; }
  body.v-page .v-hero-facts > div { padding: 7px 0 0 !important; }
  body.v-page .v-hero-facts dt { font-size: 9px !important; }
  body.v-page .v-hero-facts dd { font-size: 13px !important; margin-top: 2px !important; }
  body.v-page .v-kicker { margin-bottom: 14px !important; }
}

/* ============================================================
   PAGES DE CONTENU — /comment-ca-marche, /a-propos, /resultats,
   /logiciel-devis, et les pages legales.
   ⚠️ Meme langage : filets fins, angles droits, echelle unique, aucun aplat
   colore. Les classes historiques (steps, faq-item, valeur) sont ramenees au
   langage commun au lieu d'etre remplacees — moins de risque de casse.
   ============================================================ */

/* ⚠️⚠️ LA CARTE LEGALE ETAIT HORS AXE (corrige 2026-10-05).
   `.container.narrow` (840 px, CENTRE sur lui-meme) faisait demarrer le texte a
   328 px (/contact) et 381 px (/cgv) alors que TOUT le site est sur l'axe du
   conteneur standard : contenu a 188 px. Mesure : +140 px et +193 px — c'est le
   « decalage dans les ecritures » signale par l'utilisateur.
   Les 4 templates legaux utilisent desormais `.container` ; on garde ici une
   largeur de LECTURE confortable, mais ANCRÉE A GAUCHE du conteneur (donc sur
   l'axe), jamais centree sur elle-meme. */
/* les etapes numerotees */
.steps { list-style: none; margin: 0; padding: 0; display: grid;
         grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--line); }
.steps li { padding: 32px 28px 32px 0; border-bottom: 1px solid var(--line);
            border-right: 1px solid var(--line); min-width: 0; }
.steps li:last-child { border-right: 0; }
.steps .step-num, .steps .num { font-family: var(--font-mono); font-size: 11.5px;
            letter-spacing: .18em; color: var(--ink); display: block; margin-bottom: 16px; }
.steps h3 { margin: 0 0 10px; }
.steps p { margin: 0; font-size: 15px; color: var(--muted); }

/* la FAQ : meme traitement que le carrousel des offres */
.faq-item, .faq-acc { border-bottom: 1px solid var(--line); }
.faq-item h3, .faq-acc summary { font-family: var(--font-serif); font-size: 20px;
            padding: 18px 0; margin: 0; color: var(--ink); }
.faq-item p, .faq-acc-body p { margin: 0 0 18px; font-size: 15px; color: var(--muted);
            max-width: 78ch; }
details.faq-item summary, details.faq-acc summary {
            cursor: pointer; list-style: none; display: flex;
            justify-content: space-between; align-items: center; gap: 20px; }
details.faq-item summary::-webkit-details-marker,
details.faq-acc summary::-webkit-details-marker { display: none; }
details.faq-item summary::after, details.faq-acc summary::after {
            content: '+'; font-family: var(--font-mono); color: var(--ink); font-size: 18px; }
details[open].faq-item summary::after, details[open].faq-acc summary::after { content: '–'; }

/* les blocs de valeurs / arguments */
.value-card, .valeurs .card, .preuve-card {
            border: 1px solid var(--line); background: var(--card);
            padding: 28px 26px; }
.value-card h3, .preuve-card h3 { margin: 0 0 10px; }
.value-card p, .preuve-card p { margin: 0; font-size: 15px; color: var(--muted); }
.value-card svg, .preuve-card svg { color: var(--ink); margin-bottom: 16px; }

/* les chiffres / statistiques : police display, filet */
.stat, .kpi, .chiffre-cle {
            border-top: 1px solid var(--line); padding-top: 18px; }
.stat b, .kpi b, .chiffre-cle b {
            font-family: var(--font-serif); font-size: 40px; line-height: 1.18;
            padding: .04em 0; display: block; color: var(--ink); }
.stat span, .kpi span, .chiffre-cle span {
            font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .16em;
            text-transform: uppercase; color: var(--muted); }

/* le contenu long (pages legales) : lisibilite avant tout.
   ⚠️⚠️ DOUBLE DECALAGE CORRIGE (2026-10-05), c'etait le « decalage dans les
   ecritures » signale par l'utilisateur :
     1. `margin: 0 auto` CENTRAIT la carte -> texte a 353 px au lieu de 188.
     2. le `padding` horizontal de 52 px de la carte décalait ENCORE le texte de
        52 px (241 px au lieu de 188).
   On retire donc le cadre sur les pages legales : meme `max-width` de lecture
   (840 px), mais SANS bordure, fond ni padding horizontal -> le texte tombe
   exactement sur l'axe du site (188 px desktop / 18 px mobile), comme les autres
   pages. Un seul axe pour tout le site. */
.legal-card, .legal-page { border: 0; background: transparent;
            padding: 0; max-width: 840px; margin: 0; }
.legal-card h1, .legal-page h1 { margin-bottom: 12px; }
.legal-card h2, .legal-page h2 { margin: 40px 0 14px; }
.legal-card p, .legal-page p { font-size: 15px; line-height: 1.75;
            margin-bottom: 16px; color: var(--ink); max-width: 78ch; }
.legal-card .updated, .legal-page .updated {
            font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .14em;
            color: var(--muted); margin-bottom: 32px; }
.legal-card .back, .legal-page .back {
            display: inline-block; margin-top: 32px; font-family: var(--font-mono);
            font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase;
            color: var(--ink); text-decoration: none; }

@media (max-width: 900px) {
  .steps { grid-template-columns: 1fr; }
  .steps li { border-right: 0; padding-right: 0; }
  .legal-card, .legal-page { padding: 28px 20px; }
}

/* ============================================================
   HERO DES PAGES METIER (/services/<metier>) — alignement bas.

   ⚠️ MESURE : le hero est un grid 2 colonnes (529 px | 487 px). Le bouton
   (colonne gauche) finissait a y=429 et le bloc « trust » (colonne droite)
   a y=433 — 4 px d'ecart visibles comme un desequilibre. Les deux colonnes
   doivent se terminer sur la MEME ligne.
   ============================================================ */
.hero { align-items: end; }
.hero .cta-row, .hero .trust { align-self: end; }
@media (max-width: 900px) {
  .hero { align-items: start; }
}

/* ============================================================
   CANVAS 3D DU HERO — restaure (il avait disparu avec la refonte).

   ⚠️⚠️ CE QUI S'EST PASSE. En reecrivant l'accueil, j'ai supprime le canvas
   `atelier3d` ET son script. Le user l'a vu immediatement : « plus d'effet 3d,
   plus haut de gamme ». C'etait l'element qui donnait l'impression de qualite.
   ⚠️ C'est un FOND : position absolue, derriere le contenu, non cliquable.
   ⚠️ `atelier3d.js` gere lui-meme : arret apres 10 s (pas de cout CPU), gel
   hors ecran, `prefers-reduced-motion`, et repli Canvas 2D si WebGL manque.
   ============================================================ */
.v-hero-3d {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.v-hero-3d canvas {
  display: block;
  width: 100%;
  height: 100%;
}
/* le contenu reste AU-DESSUS du canvas */
.v-hero-inner, .v-hero-facts { position: relative; z-index: 2; }

/* ⚠️ Sur mobile, le canvas est plus couteux que sur desktop et le hero est
   court : on le desactive sous 700 px, comme le faisait la version d'origine. */
@media (max-width: 700px) {
  .v-hero-3d { display: none; }
}

/* ============================================================
   ANIMATIONS D'APPARITION — le contenu est VISIBLE PAR DEFAUT.

   ⚠️⚠️ REGLE ABSOLUE, apprise d'un bug reel : ne JAMAIS masquer le contenu avec
   `opacity: 0` par defaut. Si l'IntersectionObserver echoue, la page parait
   VIDE (le user l'avait signale : « c'est completement vide » sur mobile).
   L'animation ne s'applique QUE si le script a pose `js-anim` sur le body.
   ============================================================ */
.reveal, .v-sec, .s-sec, .v-sec-head, .s-tete { opacity: 1; }
body.js-anim .reveal,
body.js-anim .v-sec,
body.js-anim .s-sec,
body.js-anim .v-sec-head,
body.js-anim .s-tete {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .55s ease, transform .55s ease;
}
body.js-anim .reveal.visible,
body.js-anim .v-sec.visible,
body.js-anim .s-sec.visible,
body.js-anim .v-sec-head.visible,
body.js-anim .s-tete.visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  body.js-anim .reveal, body.js-anim .v-sec, body.js-anim .s-sec,
  body.js-anim .s-tete, body.js-anim .v-sec-head {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}

/* ============================================================
   PLAN TECHNIQUE EN PERSPECTIVE — CSS PUR (remplace le shader WebGL).

   ⚠️⚠️ POURQUOI CE CHANGEMENT. L'effet 3D de l'accueil etait un shader WebGL
   ecrit a la main (`atelier3d.js`, 20 Ko). Il a cesse de fonctionner quand le
   hero a change de classe, puis il s'est revele impossible a reparer : le
   shader compilait, `drawArrays` s'executait, et le canvas restait
   TRANSPARENT — sans aucune erreur. Un effet qui echoue en silence est pire
   qu'un effet absent : on croit qu'il marche.

   Le CSS donne le MEME resultat visuel, sans shader, sans canvas, sans
   dependance. Et si quelque chose casse, ca se VOIT.

   Les trois couches (empilees, toutes decoratives) :
     1. `.v-sol-grille`  la grille en perspective au sol (le plan d'atelier)
     2. `.v-sol-ligne`   le cordeau d'horizon, un trait plein
     3. `.v-sol-lueur`   un halo chaud au-dessus de l'horizon
   ============================================================ */
/* ⚠️⚠️ z-index 1, PAS 0. La cause du « sol invisible » etait un ORDRE
   D'EMPILEMENT : `.v-hero-cadre` (le degrade opaque blanc) vient APRES
   `.v-sol` dans le DOM et portait le meme `z-index: 0` — il recouvrait donc
   entierement la grille. Mesure : meme un fond ROUGE PUR ne produisait aucun
   pixel a l'ecran.
   Le sol passe au-dessus du cadre, sous le contenu (`.v-hero-inner` est a 2). */
.v-sol {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;      /* jamais cliquable : c'est un fond */
  overflow: hidden;
}
/* le cadre reste SOUS le sol */
.v-hero-cadre { z-index: 0; }
.v-sol > span { position: absolute; display: block; }

/* 1. la grille : un motif repete, incline en perspective.
   ⚠️ `perspective()` sur le PARENT et `rotateX` sur l'enfant : c'est ce qui
   donne la fuite vers l'horizon, exactement comme un plan vu de biais.
   ⚠️ `transform-origin: 50% 100%` : le point de fuite part du BAS de l'ecran
   (le spectateur), pas du centre. */
.v-sol-grille {
  /* HAUTEUR EN vh, PAS EN POURCENTAGE.
     Bug mesuré : `height: 78%` sur un parent sans hauteur définie retombait à
     150 px — la grille ne couvrait que le bas de l'écran, et son masque
     l'effaçait entièrement. La hauteur doit être liée à la FENÊTRE. */
  /* ⚠️⚠️ L'ANGLE ECRASE LA HAUTEUR PAR PROJECTION.
     Mesure : `height: 558px` avec `rotateX(64deg)` ne rend que 135 px a
     l'ecran (558 x cos 64 = 245, moins le masque). Une grille de 135 px de
     haut ne se voit presque pas. On REDUIT l'angle (45 au lieu de 64) et on
     AUGMENTE la hauteur pour compenser la projection. */
  /* ⚠️⚠️ POSITION VERTICALE. Mesure : avec `bottom: -20vh` la grille
     commencait a y=757 et finissait a 1128 — dans un ecran de 900 px, seuls
     143 px etaient visibles, et le masque les effacait. La grille doit
     demarrer dans la moitie basse de l'ecran, pas en dessous. */
  left: -40vw; right: -40vw; bottom: 4vh; height: 96vh;
  transform-origin: 50% 100%;
  transform: perspective(760px) rotateX(46deg);
  /* traits de 2 px — à 1 px le rendu sous-pixel les fait disparaître sur la
     plupart des écrans ; période de 64 px — plus dense, donc plus lisible */
  background-image:
    repeating-linear-gradient(to right,
      rgba(10,10,10,.34) 0 2px, transparent 2px 64px),
    repeating-linear-gradient(to bottom,
      rgba(10,10,10,.34) 0 2px, transparent 2px 64px);
  /* l'effacement au loin reste, mais on garde 55 % de la grille visible */
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 55%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0%, #000 55%, transparent 100%);
}

/* 2. le cordeau d'horizon */
.v-sol-ligne {
  left: 0; right: 0; bottom: 56vh; height: 1px;
  background: linear-gradient(to right, transparent, rgba(10,10,10,.30) 18%,
              rgba(10,10,10,.30) 82%, transparent);
}

/* 3. le halo chaud juste au-dessus de l'horizon */
.v-sol-lueur {
  left: 0; right: 0; bottom: 56vh; height: 26vh;
  background: radial-gradient(60% 100% at 50% 100%,
              rgba(10,10,10,.055), transparent 70%);
}

/* ⚠️ Sur mobile, le hero est court : la perspective prend trop de place et
   gene la lecture. On la reduit sans la supprimer. */
@media (max-width: 900px) {
  /* ⚠️⚠️ MEME BUG QUE SUR DESKTOP : `height: 42%` sur un parent sans hauteur
     definie retombe a la taille du contenu. Mesure : sur un 360x740 le sol
     etait a -28 px (HORS ECRAN), sur un 320x568 a -230 px. On passe en vh
     et on remonte la grille pour qu'elle soit visible sous le contenu. */
  .v-sol-grille {
    height: 46vh;
    bottom: 0;
    transform: perspective(420px) rotateX(54deg);
  }
  .v-sol-lueur, .v-sol-ligne { display: none; }
}

/* ⚠️ Animation TRES lente du sol : un glissement de 40 s, en boucle.
   `prefers-reduced-motion` la desactive completement. */
@media (prefers-reduced-motion: no-preference) {
  .v-sol-grille { animation: v-sol-defile 40s linear infinite; }
  @keyframes v-sol-defile {
    from { background-position: 0 0, 0 0; }
    to   { background-position: 0 0, 0 92px; }
  }
}

/* ============================================================
   PARALLAXE DU MOCKUP — CSS pur, au survol du hero.
   ⚠️ Le script JS faisait deja ca (avec perspective/rotate). On le garde en
   CSS pour ne PAS dependre d'un script : `:hover` suffit, et si le navigateur
   ne le fait pas, la maquette reste simplement droite.
   ============================================================ */
@media (hover: hover) and (pointer: fine) and (min-width: 1000px) {
  .v-fenetre {
    transition: transform .6s cubic-bezier(.22,.61,.36,1), box-shadow .6s ease;
  }
  .v-hero:hover .v-fenetre {
    transform: perspective(1500px) rotateY(-7deg) rotateX(3deg) translateZ(0);
    box-shadow: 0 30px 70px rgba(10,10,10,.13);
  }
}
@media (prefers-reduced-motion: reduce) {
  .v-fenetre { transition: none; }
  .v-hero:hover .v-fenetre { transform: none; }
}

/* ============================================================
   PAGE D'ERREUR — le vide au-dessus de la carte.

   ⚠️ MESURE : la carte de la 404 commencait a y=273 sur un ecran de 844 —
   273 px de vide en haut, signales par l'audit visuel. La cause :
   `.auth-body` est en `flex; justify-content: flex-start`, et le `topbar` en
   premiere position pousse la carte vers le bas. Le `margin: auto` de la carte
   ne peut pas la recentrer car la barre occupe deja de la place.

   ⚠️ On ne touche PAS a la barre de navigation : on centre la carte dans
   l'espace QUI RESTE, en la faisant grandir pour occulter la barre.
   ============================================================ */
.auth-body .auth-card {
  flex: 1 1 auto;         /* la carte occupe l'espace restant */
  margin: 0 auto;
  align-self: center;      /* et se centre verticalement dedans */
  max-height: none;
}
/* le conteneur de la carte : centre son contenu */
.auth-body > .auth-card,
.auth-body > div > .auth-card { align-self: center; }

@media (max-width: 900px) {
  /* ⚠️ SUR MOBILE. Mesure : la carte commencait a y=267 pour 365 px de haut —
     il restait 211 px de vide en bas et 267 en haut, donc un desequilibre.
     La barre est posee en absolu pour ne plus peser dans le flux, et la carte
     est centree dans ce qui reste. */
  .auth-body { justify-content: flex-start; padding-top: 0; }
  .auth-body .topbar { position: absolute; top: 0; left: 0; right: 0; z-index: 5; }
  .auth-body .auth-card { margin: auto 20px; flex: 0 0 auto; }
  .auth-body::before { content: none; }
}
