/* ═══════════════════════════════════════════════════════════════════════════
   LA PAGE D'ACCUEIL — une feuille à elle, chargée par elle seule.

   ⚠️ POURQUOI PAS DANS app.css. Cette feuille sert TOUTE l'application, sur
   chaque écran, à chaque chargement. Y verser une page vue une fois — la
   première — c'est faire payer son poids à tous les autres écrans, pour rien.
   Et l'inverse est vrai : une règle d'accueil posée dans app.css finirait par
   toucher un écran de l'app le jour où quelqu'un réemploie un nom de classe.
   D'où le préfixe `v-` partout : aucune collision possible, dans aucun sens.

   ⚠️ AUCUN SCRIPT, PAR CONSTRUCTION. La CSP est `script-src 'self'` : tout ce
   qui bouge ici bouge en CSS. Ce n'est pas subi — une page d'accueil qui attend
   du JavaScript pour s'afficher paraît lente, et la lenteur est exactement ce
   qu'on ne peut pas se permettre sur la première impression.
   ═══════════════════════════════════════════════════════════════════════════ */

.vitrine{
  --v-encre:#12101c;      /* presque noir, teinté du violet de la marque */
  --v-encre-2:#3b3752;
  --v-doux:#6a6584;
  --v-trait:#e8e5f0;
  --v-fond:#ffffff;
  --v-fond-2:#faf9fd;
  --v-accent:#5f6fc9;
  --v-accent-fonce:#4451ab;
  --v-accent-pale:#eef0fb;
  --v-nuit:#171430;       /* le fond du héros */
  --v-nuit-2:#241f45;
  /* ⚠️ LA LARGEUR EST CELLE DE L'APPLICATION, PAS D'UN SITE (Paul, 21/08 :
     « je veux une page conçue pour l'affichage mobile, pas en desktop »).
     Gestineo se tient dans la main : une page d'accueil étalée sur 1080 px
     promettrait un produit de bureau, et la première impression serait fausse
     avant même la première capture d'écran. Sur grand écran, la page reste
     donc une colonne — celle qu'on verra sur un téléphone. */
  /* ⚠️ LA MÊME LARGEUR QUE L'APPLICATION (`--app-large:480px`). Elle était à
     520 : quarante pixels d'écart, invisibles sur une page mais très visibles
     quand on passe de l'accueil aux tarifs - la colonne entière se décale, et
     avec elle la barre, les cartes, tout. Deux colonnes voisines de largeurs
     différentes se remarquent plus qu'une couleur qui change. */
  --v-max:480px;
  /* ⚠️ LA HAUTEUR DE LA BARRE EST UNE VARIABLE, ET C'EST UN CORRECTIF.
     Le héros remonte sous la barre par une marge NÉGATIVE, et son rembourrage
     haut doit rendre exactement ce que la marge a pris. Écrits en dur, ces deux
     nombres devaient s'accorder sans que rien ne les lie : j'ai changé le
     rembourrage sans toucher la marge, et le titre s'est posé SUR le logo —
     23 px de recouvrement, mesurés. Liés à une variable, ils ne peuvent plus
     diverger. */
  --v-barre:56px;

  margin:0; background:var(--v-fond); color:var(--v-encre);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,system-ui,sans-serif;
  -webkit-font-smoothing:antialiased;
}
.vitrine *{box-sizing:border-box}
.vitrine main{display:block}

/* ── L'EN-TÊTE ──────────────────────────────────────────────────────────── */
/* ⚠️ LA BARRE EST POSÉE SUR LE HÉROS, pas au-dessus (Paul, 21/08 : « on ajoute
   uniquement les 2 boutons sur le fond violet en haut à droite »). Elle est donc
   transparente, sans trait et sans flou : le dégradé passe dessous.

   ⚠️ ET ELLE N'EST PLUS COLLANTE. Une barre transparente qui suit le défilement
   se retrouve sur fond blanc dès qu'on quitte le héros : les boutons clairs y
   deviennent illisibles, et la seule façon de le rattraper serait de repeindre
   la barre au défilement — donc un script, sur une page qui n'en a pas besoin.
   Elle part avec le héros ; l'appel à l'action, lui, reste dans le flux. */
/* ⚠️ CLAIRE, COLLANTE, ET COMME CELLE DE LA PAGE D'ABONNEMENT (Paul, 21/08 :
   « le header était clair avant, comme pour la page de l'abonnement »). J'étais
   passé par deux extrêmes en une journée — transparente sur le violet, puis
   sombre pour rester lisible au défilement — alors que la forme qui marchait
   existait déjà ailleurs dans le produit. Deux pages voisines qui ne portent
   pas la même barre donnent l'impression de changer de site en cliquant. */
.v-entete{
  position:sticky; top:0; z-index:30;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  /* ⚠️ OPAQUE, COMME LES DEUX AUTRES. La transparence à 88 % ne se voit pas au
     repos sur un fond blanc, mais laisse le contenu transparaître au
     défilement : trois pages qui se suivent, et une seule qui se comporte
     autrement. Le flou coûtait en prime une couche de composition au navigateur
     pour un effet que personne ne peut nommer. */
  /* ⚠️ LE BANDEAU BLANC TRAVERSE, SON CONTENU EST CALÉ SUR LA COLONNE. Paul,
     22/08 : « garde le bandeau blanc sur toute la longueur, c'est juste le
     positionnement du logo et du nom et des boutons qui était à harmoniser ».

     J'étais allé trop loin : en bornant la barre ENTIÈRE à la colonne, elle
     devenait une carte blanche flottant au milieu d'un écran large - pas la même
     page, un autre défaut. Ce qui devait s'aligner, c'était le CONTENU ; le fond,
     lui, doit tenir le haut de l'écran.

     `max()` sur le rembourrage fait les deux : la bande reste pleine largeur, et
     son contenu se pose sur la même colonne que le héros. Sur téléphone, c'est
     le plancher de 20 px qui l'emporte. */
  padding:11px max(20px, calc((100% - var(--v-max)) / 2));
  background:var(--v-fond); border-bottom:1px solid var(--v-trait);
}
/* ⚠️ PLUS GRAND (Paul, 21/08 : « le logo et nom GESTINEO peuvent être
   légèrement agrandi ») ET EN CLAIR, puisque le fond est devenu sombre. */
.v-marque{
  /* ⚠️ LA MÊME DISPOSITION QUE SUR /formules (Paul, 22/08). Là-bas la marque
     s'écrit « Gestineo » à 15 px, en casse normale, collée au logo de 28 px ;
     ici elle criait « GESTINEO » en capitales espacées à 16,5 px. Le nom d'un
     produit ne change pas de graphie d'un écran à l'autre - c'est ce qui fait
     qu'on le reconnaît. */
  /* ⚠️ LE MÊME `clamp` QUE LES DEUX AUTRES BARRES, même si « Gestineo » seul
     tiendrait à 17 px partout. Les voisines portent « Gestineo · Immobilia » et
     doivent se réduire sur téléphone : à taille fixe ici, le nom du produit
     s'affichait à 17 px sur l'accueil et 13,9 sur les tarifs. Harmoniser des
     barres, ce n'est pas leur donner la même RÈGLE, c'est leur faire rendre la
     même CHOSE - et une règle plus permissive suffit à les séparer. */
  display:flex; align-items:center; gap:9px; text-decoration:none;
  color:var(--v-encre); font-weight:700; letter-spacing:normal;
  font-size:clamp(13px,3.6vw,17px); white-space:nowrap;
}
.v-marque .logo{width:28px;height:28px;color:var(--v-accent);flex-shrink:0}
/* Alignement vertical logo ↔ marque (Paul, 01/09) : rogne la boîte du texte aux
   capitales pour la centrer sur le logo, indépendamment de la police. Sur le span
   enveloppant, jamais sur le conteneur flex `.v-marque`. */
.v-marque span{text-box:trim-both cap alphabetic}
.v-actions{display:flex;align-items:center;gap:8px}

/* ⚠️ DEUX COULEURS, ET LA HIÉRARCHIE EST DÉLIBÉRÉE : le plein appelle, le creux
   attend. Deux boutons pleins côte à côte ne disent pas lequel est le geste
   principal, et celui qui hésite clique sur celui de gauche — au hasard. */
.v-btn{
  display:inline-flex; align-items:center; justify-content:center;
  /* ⚠️ 44 px, PARCE QUE C'EST LA RÈGLE DU DÉPÔT — `--tap:44px` est déclaré en
     tête d'app.css comme « cible tactile minimale ». À 38 px, mesurés sur la
     page servie, ces deux boutons la violaient : ce sont les seules actions de
     la barre, sur un produit conçu pour le téléphone. La règle existait, elle
     n'était simplement pas appliquée ici. */
  min-height:44px; padding:0 16px; border-radius:11px; white-space:nowrap;
  font-size:13.5px; font-weight:650; text-decoration:none; border:1px solid transparent;
  transition:background .14s, border-color .14s, color .14s, transform .1s;
}
.v-btn:active{transform:translateY(1px)}
/* ⚠️ MÊME BOUTON SUR LES DEUX PAGES (Paul, 21/08 : « le bouton s'abonner ne
   doit pas changer sur la landing page et ensuite sur la page d'abonnement »).
   C'est le MÊME geste, et un bouton qui change de taille ou de teinte entre
   deux écrans donne l'impression d'avoir changé de site en cliquant - c'est
   exactement ce qu'on vient de corriger sur la barre. Ces valeurs sont celles
   de `.btn-pub.plein` d'app.css, qui sert /formules. */
.v-btn.plein{background:var(--brand,#5f6fc9);color:#fff;border-color:var(--brand,#5f6fc9)}
.v-btn.plein:hover{background:var(--v-accent-fonce);border-color:var(--v-accent-fonce)}
/* ⚠️ DANS LA BARRE, « creux » SE LIT SUR DU SOMBRE. Le fond de la page est
   blanc, mais la barre est posée sur le héros : un bouton à fond blanc et texte
   sombre y ferait une pastille qui crie plus fort que le bouton principal juste
   à côté. Ailleurs (page des tarifs), il garde sa forme claire. */
.v-btn.creux{color:var(--v-encre-2);border-color:var(--v-trait);background:var(--v-fond)}
.v-btn.creux:hover{border-color:var(--v-accent);color:var(--v-accent)}
.v-btn.nu{color:#cfc9ee;border-color:rgba(255,255,255,.22);background:transparent}
.v-btn.nu:hover{border-color:rgba(255,255,255,.5);color:#fff}
.v-btn.grand{min-height:48px;padding:0 22px;font-size:15px;border-radius:12px}
.v-btn:focus-visible{outline:2px solid var(--v-accent);outline-offset:3px}

/* ── LE HÉROS ───────────────────────────────────────────────────────────── */
/* ⚠️ LE DÉGRADÉ EST LA SEULE LICENCE DE LA PAGE, et il est retenu : deux tons
   voisins du même violet, pas un arc-en-ciel. Un fond sombre en tête donne la
   profondeur qu'on attend d'un produit technique ; en mettre partout la
   retirerait, parce que le contraste vient de l'alternance. */
.v-hero{
  background:
    radial-gradient(1100px 420px at 78% -10%, rgba(120,104,220,.42), transparent 62%),
    linear-gradient(168deg, var(--v-nuit) 0%, var(--v-nuit-2) 100%);
  color:#fff;
  /* ⚠️ PLUS DE MARGE NÉGATIVE. La barre est redevenue collante et porte son
     propre fond : elle occupe sa place dans le flux, le héros commence en
     dessous. C'est ce couple marge-négative / rembourrage qui avait fait passer
     le titre SUR le logo — deux nombres à accorder, et un de trop. Le plus sûr
     des couplages est celui qu'on supprime. */
  /* ⚠️ LE BAS DU HÉROS EST RESSERRÉ (Paul, 21/08 : « réduis la hauteur du
     grand fond violet pour remonter l'encart vidéo »). Ces 62 px dataient d'un
     héros qui portait une double promesse et deux boutons ; il n'a plus que son
     titre, sa phrase et sa parenthèse. Un fond coloré ne se dimensionne pas à
     l'ambiance, il se dimensionne à ce qu'il contient. */
  /* ⚠️ 10 px EN BAS, ET C'EST LA RÈGLE DE BASE - celle qui sert AU-DESSUS de
     520 px. J'avais réduit le bandeau deux fois, mais dans le seul bloc mobile :
     mesuré à 390 px l'écart texte→vidéo faisait 12 px, à 660 et au-delà il en
     faisait 84 (40 de violet sous le texte, 44 de blanc au-dessus de la vidéo).
     Corriger un point de rupture n'est pas corriger la règle, et c'est sur grand
     écran que Paul regardait. */
  padding:22px 20px 16px;
}
.v-hero-in{max-width:var(--v-max);margin:0 auto}

/* ═══ LES DEUX PUBLICS ═════════════════════════════════════════════════════
   EN TÊTE DU HÉROS, EMPILÉES, « Gestionnaires de biens » AU-DESSUS DE
   « Particuliers » (Paul, 22/08). Elles disent À QUI la page parle avant de
   dire ce qu'elle propose.

   ⚠️ ET LE TITRE MONTE À LEUR HAUTEUR PAR UN FLOTTANT, jamais par un calage.
   Le navigateur raccourcit les lignes que le bloc CROISE au lieu de passer
   dessous : la superposition n'est donc pas évitée par des nombres bien
   choisis, elle est IMPOSSIBLE. C'est ce qui compte, parce qu'un nombre bien
   choisi cesse de l'être dès que le texte change.

   ⚠️ L'EMPILEMENT COÛTE DEUX LIGNES DE TITRE, PAS UNE. À 53 px de haut, le
   bloc croise les deux premières lignes du titre : chacune doit tenir dans ce
   qui reste (colonne - 134 px de pastilles - 12 de gouttière). C'était
   intenable tant que le héros portait aussi le sous-titre et la parenthèse ;
   depuis leur retrait, le titre est seul et il passe.

   ⚠️ SOUS 340 px LE FLOTTANT SE RETIRE - et le seuil est MESURÉ, pas calculé.
   Le piège est silencieux : quand « Gérer son » (118,5 px) ne rentre plus mais
   que « Gérer » seul (68 px) rentre encore, le navigateur garde la ligne à côté
   du flottant et le titre gagne une ligne sans que rien ne le signale. Vérifié
   de 326 à 1196 px de fenêtre RÉELLE : trois lignes partout, aucun
   chevauchement.

   ⚠️ ET « FENÊTRE RÉELLE » N'EST PAS LA LARGEUR QU'ON DEMANDE. Mes iframes de
   mesure portaient une barre de défilement de 19 px que le téléphone n'a pas -
   et seulement aux largeurs où la page dépasse en hauteur, donc pas partout.
   « 390 » testait 371. Lire documentElement.clientWidth, toujours. */
.v-cibles{
  float:right; display:flex; flex-direction:column; align-items:flex-end;
  gap:5px; margin:0 0 6px 12px;
}
.v-cibles span{
  display:inline-block; padding:4px 8px;
  border:1px solid rgba(255,255,255,.26); border-radius:999px;
  font-size:11px; font-weight:650; line-height:1.3;
  color:rgba(255,255,255,.82); white-space:nowrap;
}
/* Le flottant est refermé ici : sans quoi il déborderait du héros sur la vidéo
   les jours où le titre serait plus court que lui. */
.v-hero-in::after{content:"";display:block;clear:both}

@media (max-width:339px){
  /* Elles reprennent leur propre rangée : le titre descend, mais il garde
     ses trois lignes. */
  .v-cibles{float:none; align-items:flex-end; margin:0 0 12px}
}
.v-hero h1{
  margin:0; font-size:clamp(30px,8vw,40px); line-height:1.08;
  letter-spacing:-.028em; font-weight:800; text-wrap:balance;
  /* ⚠️ LA BORNE REVIENT (Paul, 22/08 : « le titre sur 3 lignes était bien »).
     Je l'avais retirée en lui rendant la colonne entière : il tombait alors à
     une ou deux lignes selon la largeur, et changeait de forme d'un écran à
     l'autre. Bornée en `ch`, la coupure suit la POLICE et non la fenêtre : le
     titre garde ses trois lignes partout, ce qui était l'état qu'il a validé. */
  max-width:15ch;
}
.v-hero h1 span{color:#b7a9f5}
/* Les deux mots restent solidaires : voir le commentaire de la vue. */
.v-hero h1 .v-ensemble{white-space:nowrap;color:inherit}

/* ── LES QUATRE CHIFFRES ────────────────────────────────────────────────── */
/* Ils chevauchent le héros : c'est ce qui fait qu'on les lit AVANT de décider
   de faire défiler. Posés dessous, ils seraient déjà hors de l'écran. */
.v-kpis{
  /* ⚠️ PLUS DE MARGE NÉGATIVE ICI NON PLUS, et c'est une régression que j'ai
     posée. Ces -34 px servaient à faire chevaucher les tuiles sur le héros,
     quand elles le suivaient immédiatement. Depuis que le bouton d'appel passe
     AVANT elles (Paul, 21/08), la marge ne mord plus sur le héros : elle mord
     sur le BOUTON, qu'on voyait dépasser en violet derrière les tuiles —
     34 px de recouvrement, mesurés. Une marge négative désigne son voisin, pas
     un décor : elle devient fausse dès qu'on change l'ordre. */
  max-width:var(--v-max); margin:14px auto 0; padding:0 20px;
  /* ⚠️ DEUX COLONNES, TOUJOURS — jamais quatre, jamais une. À quatre, chaque
     chiffre devient illisible dès qu'on quitte le bureau ; à une, ils
     deviennent une liste qu'on fait défiler, et un chiffre qu'on atteint en
     défilant a cessé d'être une accroche. */
  display:grid; grid-template-columns:1fr 1fr; gap:10px;
}
/* ⚠️ TOUTES DE LA MÊME HAUTEUR, ET CENTRÉES (Paul, 21/08 : « harmonise les
   hauteurs pour qu'ils soient tous alignés, centre en largeur les KPI »).
   `align-items:stretch` de la grille égalise déjà les hauteurs d'une MÊME
   ligne ; ce qui manquait, c'est que le contenu se pose au même endroit dedans
   quand les légendes n'ont pas le même nombre de lignes. D'où le centrage
   vertical ET horizontal : les trois chiffres tombent sur la même ligne de
   regard, quelle que soit la longueur du texte sous eux. */
.v-kpi{
  background:var(--v-fond); border:1px solid var(--v-trait); border-radius:15px;
  padding:19px 17px; box-shadow:0 8px 28px rgba(23,20,48,.09);
  display:flex; flex-direction:column; justify-content:center; text-align:center;
}
/* ⚠️ `> b`, ENFANT DIRECT — ET C'EST LA CORRECTION DE FOND. Écrite `.v-kpi b`,
   cette règle atteignait TOUS les `<b>` de la tuile, y compris ceux d'une
   phrase : le « IA » de « Analyse via IA des dossiers » sortait à 26 px, en
   bloc, seul sur sa ligne. Je l'avais rustiné une première fois en surchargeant
   `.v-kpi span b` ; le mot a changé de parent (span → li) et le défaut est
   revenu à l'identique. Une rustine par emplacement ne tient pas - il faut que
   la règle ne DÉBORDE PAS, et le combinateur enfant est ce qui l'en empêche.
   Les grands nombres sont des enfants directs de la tuile ; le gras d'un texte
   ne l'est jamais. */
.v-kpi > b{
  display:block; font-size:clamp(26px,3.6vw,36px); font-weight:800;
  letter-spacing:-.035em; line-height:1; color:var(--v-accent);
  font-variant-numeric:tabular-nums;
}
.v-kpi > b i{font-style:normal;font-size:.5em;font-weight:700;letter-spacing:0}

/* ⚠️ LA TUILE « INCLUS » PREND LES DEUX COLONNES. Ce qui est inclus est une
   PHRASE, pas un nombre : serrée dans une demi-largeur elle sortirait sur
   quatre lignes à côté de chiffres qui en tiennent une, et la grille perdrait
   son alignement — c'est-à-dire la seule chose qui fait lire quatre chiffres
   d'un coup d'œil. */
/* ⚠️ ELLE PREND LA LIGNE ENTIÈRE, ET ELLE EST MAINTENANT DESSOUS (Paul,
   21/08 : « inverse les 3 et celui tout seul en dessous »). Les trois chiffres
   ouvrent — ce sont eux qu'on compare —, la phrase ferme. */
.v-kpi-large{ grid-column:1 / -1; }
/* ⚠️ ELLE COULE, elle n'empile pas : le libellé et la phrase sont un seul
   texte. D'où le `display:inline` sur les deux — la règle générique
   `.v-kpi b{display:block}` les aurait séparés. */
/* ⚠️ `display:block` LÈVE LE FLEX DE `.v-kpi`, et c'est ce qui manquait. La
   tuile hérite de `display:flex; flex-direction:column` (le centrage vertical
   des trois chiffres) : dans un conteneur flex en colonne, un enfant en
   `display:inline` devient un ITEM FLEX et s'empile quand même — la déclaration
   est ignorée sans que rien ne le signale. Mesuré : le libellé finissait à
   621 px et la phrase démarrait à 629, l'une sous l'autre. Pour faire couler
   deux éléments dans la même ligne, il faut d'abord que leur parent soit un
   conteneur de LIGNES. */
/* ⚠️ `>` N'AJOUTE RIEN À LA SPÉCIFICITÉ, et c'est ce qui m'a eu. J'avais écrit
   `.v-kpi-large > span` en croyant battre `.v-kpi span` : les DEUX valent
   (0,1,1) — une classe, un élément — le combinateur ne compte pas. À égalité,
   c'est la dernière déclaration du fichier qui gagne, et la générique est plus
   bas. Le span restait donc en `display:block`, la phrase sur sa propre ligne,
   sans que rien ne le signale : les deux règles s'appliquaient, l'une écrasait
   l'autre. `.v-kpis` en tête ajoute la classe qui manquait (0,2,1).

   ⚠️ ET LE `display:block` SUR LA TUILE RESTE NÉCESSAIRE. Elle hérite du
   `display:flex; flex-direction:column` de `.v-kpi` : dans un conteneur flex,
   un enfant en `display:inline` est « blockifié » par la spécification et
   s'empile quand même. Il fallait les DEUX corrections — l'une sans l'autre ne
   fait rien, ce qui rend le défaut d'autant plus long à cerner. */
.v-kpis .v-kpi-large{ display:block; text-align:left; position:relative; }
.v-kpis .v-kpi-large .v-inclus{ display:inline; margin-right:5px; }

/* ═══ LES TROIS PUCES ══════════════════════════════════════════════════════
   ⚠️ DES PUCES, PLUS UNE PHRASE À POINTS MÉDIANS (Paul, 21/08). Trois éléments
   séparés par des « · » se lisent comme une seule chose longue ; empilés, on
   en compte trois d'un coup d'œil - et c'est le nombre qui compte ici. */
.v-inclus-liste{
  margin:9px 0 0; padding:0; list-style:none;
  display:flex; flex-direction:column; gap:5px;
}
.v-inclus-liste li{
  position:relative; padding-left:15px;
  font-size:12.5px; line-height:1.4; color:var(--v-encre-2);
}
.v-inclus-liste li::before{
  content:""; position:absolute; left:2px; top:7px;
  width:5px; height:5px; border-radius:50%; background:var(--v-accent);
}
.v-inclus-liste li b{ font-weight:750; color:var(--v-encre); }
/* Les exemples entre parenthèses : plus petits que la promesse. */
.v-inclus-liste li i{ font-style:normal; font-size:.88em; color:var(--v-doux); }

/* ═══ LE « + » QUI DÉPLIE TOUT ═════════════════════════════════════════════
   ⚠️ SANS UNE LIGNE DE SCRIPT : une case masquée, un label, et `:has()`. La CSP
   est `script-src 'self'` sans nonce, et c'est déjà le mécanisme des cartes de
   /formules - deux façons de déplier dans le même produit seraient une de trop. */
.v-tout-case{ position:absolute; width:1px; height:1px; opacity:0; margin:0; }
.v-tout-plus{
  /* ⚠️ LE « + » EST DESSINÉ, PAS ÉCRIT - et c'est la seule façon qu'il soit
     centré une fois TOURNÉ. Écrit en texte, il se pose sur sa boîte de ligne,
     qui n'est pas symétrique : j'avais compensé d'un `padding-top:2px`, mesuré
     et juste au repos… mais la rotation du « × » tourne AUSSI ce décalage, et
     la croix repartait de travers. Deux barres en `::before`/`::after`, centrées
     par translation depuis le milieu exact, n'ont pas de métrique de fonte :
     elles sont symétriques au repos comme à 45°. */
  position:absolute; top:10px; right:10px;
  width:30px; height:30px;
  border:1px solid var(--v-trait); border-radius:9px;
  background:var(--v-fond); cursor:pointer;
  transition:transform .18s, background .14s;
}
.v-tout-plus::before,
.v-tout-plus::after{
  content:""; position:absolute; left:50%; top:50%;
  background:var(--v-accent); border-radius:1px;
}
.v-tout-plus::before{ width:13px; height:2px; transform:translate(-50%,-50%); }
.v-tout-plus::after{ width:2px; height:13px; transform:translate(-50%,-50%); }
.v-tout-plus:hover{ background:var(--v-accent-pale); }
/* Le focus se voit : la case porte le clavier, le label porte le dessin. */
.v-tout-case:focus-visible + .v-inclus + .v-tout-plus{
  outline:2px solid var(--v-accent); outline-offset:2px;
}
/* Ouvert, le « + » devient un « × » par une rotation - un seul caractère, deux
   états, aucune image à charger. */
.v-kpi-large:has(.v-tout-case:checked) .v-tout-plus{ transform:rotate(45deg); }

.v-tout{ display:none; margin-top:12px; padding-top:12px; border-top:1px solid var(--v-trait); }
.v-kpi-large:has(.v-tout-case:checked) .v-tout{ display:block; }
.v-tout-titre{
  margin:0 0 8px; font-size:10.5px; font-weight:800; letter-spacing:.07em;
  text-transform:uppercase; color:var(--v-doux);
}
.v-tout ul{ margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:4px; }
.v-tout li{
  position:relative; padding-left:15px;
  font-size:12px; line-height:1.4; color:var(--v-encre-2);
}
.v-tout li::before{
  content:""; position:absolute; left:3px; top:6px;
  width:4px; height:4px; border-radius:50%; background:var(--v-doux);
}
/* ⚠️ TROIS COLONNES POUR LES TROIS CHIFFRES, et c'est une conséquence, pas un
   revirement. La règle « deux colonnes toujours » valait pour QUATRE tuiles
   équivalentes ; depuis que « INCLUS » prend la ligne entière, il en reste
   trois — et trois dans une grille de deux laisse la dernière ORPHELINE, seule
   sur sa ligne à mi-largeur (mesuré en ligne : 168 px contre 345). Une tuile
   esseulée se lit comme un gabarit cassé. Les trois disent le PRIX : les
   réunir sur une ligne, c'est aussi les donner à lire ensemble. */
.v-kpis{ grid-template-columns:repeat(3, 1fr); }
.v-kpi-large{ grid-column:1 / -1; }
.v-kpis .v-kpi:not(.v-kpi-large) b{ font-size:clamp(19px,5.4vw,26px); }
/* ⚠️ CENTRÉS EN HAUTEUR (Paul, 21/08). Les trois tuiles font la même hauteur —
   c'est la grille qui l'impose — mais leurs contenus n'ont pas la même longueur :
   « pour 1 logement » tient sur une ligne là où « des montants encaissés » peut
   passer à deux selon la largeur. Alignés en haut, les chiffres restaient au
   même niveau mais les légendes flottaient, et la ligne du bas semblait bancale.
   Centrer le bloc entier fait tenir les trois ensemble quelle que soit la
   longueur du texte — ce qui vaut mieux qu'un calage qui marche à 375 px et se
   défait à 320. */
.v-kpis .v-kpi:not(.v-kpi-large){
  padding:15px 11px;
  display:flex; flex-direction:column; justify-content:center;
}
/* ⚠️ 11,5 px, PAS 10,5. Je les avais serrées en passant à trois colonnes, et
   mesurées sur la page servie c'était le plus petit texte de l'accueil — or ce
   sont ces trois légendes qui DISENT ce que le chiffre au-dessus veut dire.
   « dès 190 € » sans « par an, tout compris » n'est pas une accroche, c'est un
   nombre. Vérifié après coup : rien ne déborde à 375 ni à 320. */
.v-kpis .v-kpi:not(.v-kpi-large) > span{ font-size:11.5px; line-height:1.35; }
/* Le mot lui-même reste un CHIFFRE de la grille : même graisse, même couleur,
   même interligne que les trois autres. Il est juste plus petit — un mot de
   six lettres à 36 px déborderait. */
.v-inclus{ font-size:clamp(22px,3vw,28px) !important; }

/* Le bouton d'appel prend toute la largeur : posé sous la vidéo, il ferme la
   séquence « on montre, puis on propose ». Centré et court, il flotterait. */
.v-btn-large{ display:flex; width:100%; }
/* ⚠️ « dès » SE LIT AVANT LE CHIFFRE, DONC IL DOIT S'EFFACER DEVANT LUI
   (Paul, 21/08 : « indique à partir de 0,9 % »). À la même taille, il vole
   l'œil au nombre — or c'est le nombre qu'on retient. */
.v-kpi > b i:first-child{font-size:.42em;font-weight:650;opacity:.62;margin-right:2px}
/* ⚠️ PLUS DE GRAS SOUS LE CHIFFRE (Paul, 21/08). Deux graisses fortes l'une
   au-dessus de l'autre se disputent l'œil : le chiffre cesse d'être ce qu'on
   lit en premier, et c'est pourtant tout ce qu'une tuile a à dire. La légende
   explique, elle n'annonce pas. */
/* ⚠️ `> span`, ENFANT DIRECT - MÊME CORRECTION QUE POUR `> b`, ET POUR LA MÊME
   RAISON. Écrite `.v-kpi span`, cette règle atteignait TOUS les `<span>` de la
   tuile : le « Immobilia » du panneau y prenait la couleur et la graisse de la
   légende, et battait `.nom-immo` (0,1,1 contre 0,1,0). C'est la deuxième fois
   qu'un sélecteur d'élément déborde dans cette tuile - le `<b>` d'abord, le
   `<span>` ensuite. La légende est un enfant DIRECT ; rien de ce qu'on écrira
   plus tard dans le texte ne l'est. */
.v-kpi > span{display:block;margin-top:8px;font-size:13.5px;font-weight:450;
  color:var(--v-encre-2);line-height:1.4}
.v-kpi > span b{font-weight:750;color:var(--v-encre)}
/* « (à vie) » se détache en bleu de marque : ce n'est pas une précision, c'est
   la promesse elle-même - gratuit trois mois et gratuit pour toujours ne sont
   pas la même offre. */
.v-kpi > span i{font-style:normal;font-weight:700;color:var(--v-accent)}
.v-kpi em{display:block;margin-top:3px;font-style:normal;font-size:11.5px;line-height:1.4;color:var(--v-doux)}

/* ── LA VIDÉO ───────────────────────────────────────────────────────────── */
/* ⚠️ 12 px, PAS 44. Cette marge datait d'un héros qui portait une double
   promesse et deux boutons ; il n'a plus que son titre, sa phrase et sa
   parenthèse. Additionnée au rembourrage du bandeau, elle éloignait la vidéo de
   84 px du dernier mot. Le lecteur remonte d'autant. */
.v-video{max-width:var(--v-max);margin:12px auto 0;padding:0 20px}
.v-video video{
  width:100%; display:block; border-radius:18px; background:#000;
  border:1px solid var(--v-trait); box-shadow:0 18px 50px rgba(23,20,48,.14);
}
/* ⚠️ L'ATTENTE SE DIT, elle ne se montre pas en cadre noir : un lecteur qui ne
   lit rien passe pour une panne, sur la première page que voit un visiteur. */
.v-video-attente{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:9px; aspect-ratio:16/9; border-radius:18px; text-align:center; padding:22px;
  background:linear-gradient(150deg,var(--v-accent-pale),var(--v-fond-2));
  border:1px dashed #c3bce9;
}
.vva-pastille{
  display:grid; place-items:center; width:52px; height:52px; border-radius:50%;
  background:var(--v-fond); border:1px solid var(--v-trait); color:var(--v-accent);
  box-shadow:0 6px 18px rgba(23,20,48,.08);
}
.vva-pastille svg{width:22px;height:22px;margin-left:3px;fill:currentColor;stroke:none}
.vva-titre{font-size:15px;font-weight:700;color:var(--v-encre)}
.vva-note{font-size:12.5px;line-height:1.45;color:var(--v-doux);max-width:34ch}

/* ── LES PREUVES ────────────────────────────────────────────────────────── */
.v-preuves{max-width:var(--v-max);margin:56px auto 0;padding:0 20px}
.v-notes{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-bottom:18px}
.v-note{
  font-size:13px; color:var(--v-encre-2); background:var(--v-accent-pale);
  border-radius:999px; padding:7px 14px;
}
.v-note b{color:var(--v-accent-fonce);font-weight:800}

/* ⚠️ L'ATTENTE NE RESSEMBLE PAS À UNE NOTE, et c'est tout l'enjeu de ces
   trois lignes. Une pastille de même poids que « 4,8 sur Trustpilot » se lit
   comme un chiffre qu'on n'arrive pas à déchiffrer ; en creux et en gris, elle
   se lit pour ce qu'elle est — une place réservée, pas un résultat caché. */
.v-note-attente{
  background:transparent; border:1px dashed #cdc7e4; color:var(--v-doux);
  font-size:12.5px;
}
.v-note-attente b{color:var(--v-encre-2);font-weight:700}


/* ── LE PIED ────────────────────────────────────────────────────────────── */
.v-pied{background:var(--v-fond-2);border-top:1px solid var(--v-trait);margin-top:8px}
.v-pied-in{
  max-width:var(--v-max); margin:0 auto; padding:22px 20px;
  display:flex; align-items:center; justify-content:space-between;
  gap:14px; flex-wrap:wrap; font-size:12.5px; color:var(--v-doux);
}
.v-pied-marque{display:flex;align-items:center;gap:7px;font-weight:700;color:var(--v-encre-2)}
.v-pied-marque .logo{width:20px;height:20px;color:var(--v-accent)}
.v-pied-marque span{text-box:trim-both cap alphabetic}
.v-pied nav{display:flex;gap:16px}
/* ⚠️ UNE HAUTEUR DE DOIGT, PAS UNE HAUTEUR DE TEXTE. Mesurés à 18 px de haut
   et 28 px de large pour « Tarifs » : sur un téléphone, on vise à côté. Le
   rembourrage grandit la CIBLE sans grandir le texte — la marge négative
   compense pour que le pied ne s'écarte pas. */
.v-pied nav a{
  color:var(--v-doux); text-decoration:none;
  display:inline-flex; align-items:center; min-height:40px; padding:0 2px;
}
.v-pied nav{margin:-9px 0}
.v-pied nav a:hover{color:var(--v-accent)}

/* ── LE TÉLÉPHONE ───────────────────────────────────────────────────────── */
/* ⚠️ QUATRE COLONNES DEVIENNENT DEUX, PAS UNE. À une seule, les chiffres
   deviennent une liste qu'on fait défiler — et un chiffre qu'on atteint en
   défilant a cessé d'être une accroche. */
/* ⚠️ PLUS DE COUPURE À 820 px : la page est la MÊME partout depuis qu'elle
   est conçue pour le téléphone. Une grille qui se réorganise au-delà d'un
   seuil produit deux mises en page à vérifier, et c'est toujours la seconde
   qu'on oublie de regarder. */
/* ═══════════════════════════════════════════════════════════════════════════
   ⚠️ TOUTES LES RÈGLES DE BASE VIVENT AU-DESSUS DES REQUÊTES MÉDIA, et c'est
   une contrainte, pas une préférence. À spécificité égale, c'est la DERNIÈRE
   déclaration qui gagne : une règle de base écrite sous un `@media` l'emporte
   sur lui à toutes les largeurs, et le point de rupture cesse silencieusement
   d'exister. C'est ce qui venait d'arriver — `.v-pour`, `.v-retour` et
   `.v-legal` avaient été ajoutées en fin de fichier, et la compression mobile
   ne mordait pas sur elles. Rien ne le signale : le fichier se charge, les
   règles sont justes, elles s'appliquent simplement au mauvais moment.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Le bouton d'appel, seul dans sa section : il ferme la page. */
.v-appel{ max-width:var(--v-max); margin:12px auto 0; padding:0 20px; }

/* ═══ LE CHEVRON DE RETOUR ═════════════════════════════════════════════════
   Un carré de la taille d'un doigt, à gauche du logo. Pas de libellé : la page
   d'où l'on vient change, un mot fixe finirait par mentir. */
.v-retour{
  display:grid; place-items:center; width:40px; height:40px; flex-shrink:0;
  margin-left:-6px; border-radius:10px; color:var(--v-encre-2);
}
.v-retour svg{ width:21px; height:21px; }
.v-retour:hover{ background:var(--v-doux-fond, rgba(0,0,0,.05)); color:var(--v-accent); }
.v-retour:focus-visible{ outline:2px solid var(--v-accent); outline-offset:2px; }

/* ═══ LES MENTIONS LÉGALES, SUR LEUR PAGE ══════════════════════════════════ */
.v-legal{
  max-width:var(--v-max); margin:0 auto; padding:22px 20px 8px;
  color:var(--v-encre-2); font-size:14px; line-height:1.6;
}
.v-legal h1{ margin:0 0 18px; font-size:24px; letter-spacing:-.02em; color:var(--v-encre); }
.v-legal h2{
  margin:22px 0 6px; font-size:11.5px; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--v-doux);
}
.v-legal p{ margin:0; }
.v-legal a{ color:var(--v-accent); }

.v-cible{
  display:inline-block; padding:5px 10px;
  border:1px solid var(--v-trait); border-radius:8px;
  background:var(--v-fond); color:var(--v-encre-2);
  font-size:11.5px; font-weight:650; line-height:1.2;
}

@media (max-width:520px){
  /* ⚠️ UNE SEULE `.v-hero{padding}` DANS CE BLOC. Il y en avait DEUX : celle-ci
     à 52/62 - l'ancienne valeur, d'avant la compression du pli - et la vraie,
     soixante lignes plus bas. La seconde gagnait, donc rien ne paraissait
     cassé ; mais une déclaration morte dans le même bloc est un piège à retard,
     qui reprend la main au premier réordonnancement. Retirée. */
  .v-entete{padding:9px 13px;gap:8px}
  /* Le nom de la marque s'efface avant les boutons : il est décoratif ici,
     eux sont les actions. Mieux vaut un logo seul qu'une barre qui déborde. */
  .v-entete:has(.v-retour) .v-marque span{display:none}
  .v-marque .logo{width:30px;height:30px}
  /* ⚠️ CE POINT DE RUPTURE RAPETISSAIT LA CIBLE TACTILE — à l'envers de ce qu'il
     faut. Sous 520 px, on est sur un TÉLÉPHONE : c'est la seule largeur où ces
     boutons sont touchés au doigt et non cliqués à la souris, donc la seule où
     44 px comptent vraiment. La règle de base était déjà passée à 44 ; celle-ci
     la ramenait à 36 sans qu'on le voie, parce qu'on mesure rarement une page
     dans le point de rupture qu'on vient d'écrire.
     ⚠️ ET LE REMBOURRAGE SE RESSERRE, LUI. La barre porte un chevron, un logo et
     deux boutons : à 16 px de rembourrage elle débordait de 7 px sur
     /mentions-legales. On gagne la hauteur sans perdre la largeur. */
  .v-btn{min-height:44px;padding:0 11px;font-size:12.5px}
  .v-btn.grand{min-height:46px;font-size:14.5px;width:100%}
  .v-kpis{margin-top:-26px;gap:9px;padding:0 15px}
  .v-kpi{padding:15px 13px;border-radius:13px}
  .v-video,.v-cap,.v-preuves{padding:0 15px}
  .v-pied-in{flex-direction:column;align-items:flex-start;gap:10px}

  /* ═══ LE BUDGET DE HAUTEUR — Paul, 21/08 : titre, vidéo, bouton et chiffres
     doivent tenir SANS DÉFILER sur un téléphone.

     ⚠️ CE N'EST PAS UNE QUESTION DE GOÛT, C'EST UNE SOUSTRACTION. Un écran de
     812 px n'en montre que ~620 dans un navigateur mobile : la barre d'adresse
     et la barre d'outils prennent le reste. C'est contre 620 qu'on mesure, pas
     contre la taille de l'appareil — sinon tout « tient » au banc et rien ne
     tient dans la main.

     ⚠️ ET C'EST LE VIDE QU'ON COUPE, PAS LE CONTENU. Le héros portait 114 px de
     rembourrage pour 119 px de texte : il payait sa respiration au prix du
     bouton, qui tombait à 813 px — un pixel sous la ligne, donc invisible. */
  /* Le détail du budget, bloc par bloc — mesuré à 375 px, la largeur de
     référence.

     ⚠️ CE QUI TIENT ET CE QUI NE TIENT PAS, mesuré en ligne le 21/08 :
       · iPhone 12/13, 14 Pro, 15 Pro Max, Pixel 7 → tout est visible ✓
       · iPhone 12 mini (683 px utiles) → ~12 px de trop
       · iPhone SE 2/3 (553) et petit Android (640) → ~145 px de trop
     Ces 145 px ne se grattent PAS sur des marges : la vidéo en 16/9 fait 190 px
     et les quatre tuiles 165. Les faire entrer demanderait de réduire la vidéo
     à une vignette — donc de montrer une forme que le vrai film n'aura pas — ou
     de retirer des chiffres. C'est un arbitrage produit, pas un réglage CSS ;
     il attend Paul. En attendant, sur ces écrans, la dernière ligne de chiffres
     se découvre d'un petit défilement, et rien n'est coupé. */
  .v-entete{padding:11px 20px;gap:8px}

  .v-pour{padding:6px 16px 0}
  .v-pour p{gap:4px}
  .v-cible{padding:3px 7px;font-size:10.5px;border-radius:7px}
  .v-pour-mot{font-size:10.5px}

  /* ⚠️ LE HÉROS REND ENCORE DE LA HAUTEUR, pour que le lecteur remonte (Paul,
     22/08 : « qu'un iPhone 12 ait jusqu'aux 3 KPI et voie juste Les vrais + »).
     C'est le dernier vide compressible avant le titre lui-même. */
  .v-hero{padding:9px 18px 12px}
  .v-hero h1{font-size:25px;line-height:1.12}

  /* ⚠️ LA VIDÉO GARDE SON 16/9 — c'est le seul bloc qu'on ne comprime pas.
     Le cadre annonce la FORME du film qui viendra s'y mettre : l'aplatir
     montrerait une vidéo que le fichier ne rendra pas, et il faudrait tout
     reprendre le jour où Paul livre `presentation.mp4`. On gagne ailleurs. */
  .v-video{margin-top:6px}
  .v-video-attente{padding:12px 16px}
  .vva-pastille{width:38px;height:38px}
  .vva-note{font-size:11.5px}

  .v-appel{margin-top:7px}
  .v-kpis{margin-top:7px;gap:5px}
  /* ⚠️ LE SÉLECTEUR ÉGALE CELUI DE BASE, sans quoi il perd. Les tuiles sont
     posées par `.v-kpis .v-kpi:not(.v-kpi-large)` (spécificité 0,3,0) : un
     `.v-kpi` seul (0,1,0) dans une requête média ne les touche pas, quel que
     soit l'ordre du fichier. Une requête média ne gagne RIEN par elle-même —
     elle ne change ni la spécificité ni la cascade. */
  /* ⚠️ LE MÊME REMBOURRAGE POUR LES QUATRE (Paul, 21/08 : « harmonise les
     hauteurs pour qu'ils soient tous alignés »). Trois valeurs différentes
     donnaient trois hauteurs à deux pixels près — invisibles une par une,
     visibles quand les tuiles se touchent. */
  .v-kpis .v-kpi{padding:8px 11px;border-radius:11px}
  .v-kpis .v-kpi-large .v-inclus{font-size:19px !important}
  .v-kpis .v-kpi-large span{font-size:11.5px;line-height:1.32}
  .v-preuves{margin-top:26px}
}

/* ⚠️ SOUS 360 px, LE NOM DE LA MARQUE S'EFFACE TOUJOURS — chevron ou pas.
   Mesuré à 320 px (iPhone SE, toujours en service) : la barre de l'accueil
   débordait de 2 px, parce que la règle du bloc ci-dessus ne visait que le cas
   du chevron. Deux pixels ne se voient pas sur une capture, mais ils font
   apparaître un défilement HORIZONTAL sur toute la page — et une page d'accueil
   qui glisse latéralement sous le pouce donne l'impression d'un site cassé
   avant même qu'on l'ait lue. Le logo seul reste reconnaissable, et il reste le
   lien vers l'accueil.

   ⚠️ CE BLOC VIENT APRÈS LE 520, JAMAIS DEDANS. Je l'y avais glissé d'abord :
   les accolades restaient équilibrées, le fichier se chargeait sans erreur, et
   toutes les règles du 520 situées plus bas se retrouvaient enfermées dans le
   360 — la mise en page mobile aurait été juste à 320 et cassée à 400. Une
   requête média mal refermée ne rougit nulle part. */
@media (max-width:360px){
  /* ⚠️ LE NOM S'EFFACE SOUS 360 px, MAIS PAS LE REMBOURRAGE. Il était à 9/11
     ici contre 11/20 partout : quatre pixels de moins, donc une barre de 63 au
     lieu de 67 - la landing redevenait l'exception sur les deux plus petits
     écrans, exactement ce qu'on vient de fermer. Seule la GOUTTIÈRE se resserre,
     et elle ne change pas la hauteur. */
  .v-marque span{display:none}
  .v-entete{padding:11px 12px;gap:6px}
  .v-btn{padding:0 10px}
}

/* ── LE MOUVEMENT, POUR CEUX QUI EN VEULENT ─────────────────────────────── */
/* Une seule animation, à l'arrivée, et elle se coupe si le système le demande.
   Ce qui donne l'impression d'un produit abouti n'est pas le nombre d'effets :
   c'est qu'aucun ne soit gratuit. */
@media (prefers-reduced-motion:no-preference){
  .v-hero-in>*{animation:v-monte .5s cubic-bezier(.22,1,.36,1) backwards}
  .v-hero-in>*:nth-child(2){animation-delay:.06s}
  .v-hero-in>*:nth-child(3){animation-delay:.12s}
  .v-hero-in>*:nth-child(4){animation-delay:.18s}
  @keyframes v-monte{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
}
