/* Feuille de l'accueil (index.html), sortie de la page le 11/10/2026 (audit
   SEO/GEO : le contenu commencait a 185 Ko dans le HTML). Meme contenu, meme
   ordre ; chargee par un <link> bloquant au meme endroit du <head>, donc
   aucun affichage avant elle. Empreinte ?v= posee par tools/versionne.py. */
/* =============================================================================
   Page de vente — direction artistique SOMBRE
   -----------------------------------------------------------------------------
   Noir teinté violet et lavande #9670ff, presque pas de blanc. Les halos sont
   des dégradés radiaux et des ombres portées colorées, jamais des filtres :
   un `filter: blur` sur un grand bloc coûte une frame entière sur mobile.

   Les noms de variables sont conservés depuis la version claire pour que le
   balisage n'ait pas à changer — seules leurs valeurs sont inversées.
   ============================================================================= */
:root{
  --lav:#9670ff; --lav-2:#bca3ff; --lav-3:#8b64f7;
  --lav-pale:#0a0811;          /* fond de page */
  --lav-voile:#100d1b;         /* sections alternées */
  --creme:#fffdf8;
  --encre:#eceaf6;             /* texte principal */
  --encre-2:#15121f;           /* cartes */
  --gris:#9b95ae; --gris-2:#6d6684; --trait:#241f36;
  /* LA LUMIÈRE. `--halo` est la couleur de toute lueur de la page ; `--halo-fort`
     la même au contact d'une surface ; `--lav-chaud` le violet qui tire vers le
     magenta (268° contre 256°). Ce décalage de teinte est l'ingrédient : une
     lueur d'une SEULE teinte se lit comme un aplat transparent, deux teintes se
     lisent comme une source. Encre sombre sur `--lav-chaud` : 5,84:1. */
  --halo:rgba(150,112,255,.62);
  --halo-fort:rgba(150,112,255,.85);
  --lav-chaud:#b06bff;
  /* Le vert de la maquette — rgb(13,234,80) sur les hausses de jetons —
     rabaissé pour du texte de page : le néon d'un badge de 9px devient criard
     sur un montant de 27px. Même famille, donc la page et le produit parlent la
     même langue, et le vert garde son sens : ce qu'on gagne, ce qu'on obtient. */
  --vert:#4fd47c; --vert-voile:rgba(79,212,124,.13); --vert-trait:rgba(79,212,124,.32);
  --max:1160px;
}
*{margin:0;padding:0;box-sizing:border-box}
/* Le fond est posé sur `html`, PAS seulement sur `body`. Ce que le navigateur
   peint en dehors du document — rebond élastique en bout de course, bande
   laissée par une barre d'outils qui se rétracte, zone sous l'encoche — vient
   du canevas, et le canevas ne reprend le fond du `body` que si `html` n'a rien
   ET que la propagation n'est pas rompue. Or `body` porte `overflow-x:hidden`,
   qui la rompt sur Safari iOS : d'où une bande blanche en bas du téléphone.
   `color-scheme:dark` complète le tableau, en disant au navigateur de peindre
   SES surfaces (barres de défilement, zones de rebond) en sombre au lieu du
   blanc par défaut. */
html{
  scroll-behavior:smooth;
  background:var(--lav-pale);
  color-scheme:dark;
  min-height:100%;
}
body{
  background:var(--lav-pale);color:var(--encre);
  min-height:100%;
  font:16px/1.65 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
img,svg{display:block;max-width:100%}
.wrap{max-width:var(--max);margin:0 auto;padding:0 22px;position:relative}

h1,h2,h3{letter-spacing:-.03em;line-height:1.1;font-weight:800;color:var(--creme)}
h1{font-size:clamp(36px,6vw,66px)}
h2{font-size:clamp(28px,4.2vw,46px)}
h3{font-size:19.5px;line-height:1.28;letter-spacing:-.02em}
p.lead{font-size:clamp(17px,2vw,20.5px);line-height:1.58;color:var(--gris)}
.eyebrow{
  font-size:12.5px;font-weight:800;letter-spacing:2.4px;text-transform:uppercase;
  margin-bottom:16px;color:var(--lav-2)
}
/* La pastille « #1 » du hero (11/10/2026, l'operateur : choix 11 « pastille
   lueur » sur 14 propositions, apres avoir ecarte la lavande pleine) : fond
   lavande transparent, filet clair, lueur courte, texte blanc en casse normale ; le « #1 » aussi en blanc (11/10/2026). */
.hero .eyebrow-n1{display:inline-flex;align-items:center;gap:7px;width:fit-content;max-width:100%;
  padding:8px 18px;border-radius:999px;background:rgba(150,112,255,.18);
  border:1px solid rgba(201,184,255,.55);box-shadow:0 0 22px -6px rgba(150,112,255,.75);
  color:#fff;font-size:15px;font-weight:800;letter-spacing:normal;text-transform:none}
.hero .eyebrow-n1 b{font-weight:900;color:#fff}
/* segment coloré dans un titre — même rôle que le <em> du hero, mais utilisable
   dans un h2 où <em> n'a pas de sens sémantique */
.hl{color:var(--lav)}

/* --------------------------------------------------------------- boutons */
/* UN LIBELLE QUI PORTE UN PRIX TIENT DANS UN SEUL <span> (test de prix). Ce
   bouton est un conteneur flex avec un `gap` : l'enveloppe du prix et le texte
   autour y deviendraient trois elements, ecartes de 9px (« Only for  $19  /month »). */
.btn{
  display:inline-flex;align-items:center;gap:9px;justify-content:center;
  padding:14px 24px;border-radius:999px;font-weight:700;font-size:15.5px;
  border:1.5px solid transparent;cursor:pointer;letter-spacing:-.01em;
  transition:transform .15s ease, box-shadow .2s, background .15s, border-color .15s;
}
.btn:hover{transform:translateY(-2px)}
/* le bouton principal EST la source de lumière de la page
   ---------------------------------------------------------------------------
   Recette reprise du bouton de paiement (login.html, .pay-offre) plutôt que
   réinventée, pour que la page et la caisse parlent la même langue : un
   DÉGRADÉ, et une ombre de SA couleur. Une ombre noire sous un bouton violet le
   POSE sur la page ; une ombre violette le fait RAYONNER.

   Quatre couches, chacune avec un rôle distinct — c'est l'empilement qui fait
   la lueur, pas l'opacité d'une seule :
     1. liseré clair de 1px   → l'arête éclairée, d'où vient le relief ;
     2. lueur proche (18px)   → le contact avec la page ;
     3. bloom large (44px)    → ce qu'on perçoit du coin de l'oeil ;
     4. reflet intérieur haut → la surface bombée.
   Le dégradé va du violet froid au violet chaud : encre sombre à 5,53:1 sur le
   premier point, 5,84:1 sur le second — lisible d'un bout à l'autre du bouton. */
.btn-encre{
  background:linear-gradient(135deg,var(--lav) 0%,var(--lav-chaud) 100%);
  color:#0b0814;
  box-shadow:
    0 0 0 1px rgba(188,163,255,.5),
    0 6px 18px -6px rgba(150,112,255,.7),
    0 16px 44px -14px rgba(150,112,255,.5),
    inset 0 1px 0 rgba(255,255,255,.3)
}
.btn-encre:hover{
  background:linear-gradient(135deg,#a888ff 0%,#c084ff 100%);
  box-shadow:
    0 0 0 1px rgba(188,163,255,.75),
    0 8px 24px -6px var(--halo-fort),
    0 24px 64px -16px rgba(150,112,255,.66),
    inset 0 1px 0 rgba(255,255,255,.36)
}
/* La bordure est ce qui fait lire ce bouton COMME un bouton : il n'a pas de
   fond. Elle doit donc tenir 3:1 contre la surface derrière (WCAG 2.2, 1.4.11).
   Elle ne les tenait déjà pas avant — 2,26:1 avec l'ancienne lavande — et le
   passage au violet saturé l'a descendue à 1,86:1, parce qu'à alpha égal ce
   violet est plus sombre. Reprise dans la teinte CLAIRE #bca3ff à .54, soit
   3,3:1 mesuré sur les quatre fonds où ce bouton apparaît. On s'arrête là et
   pas plus haut : ce bouton est le SECONDAIRE, il ne doit pas disputer
   l'attention au bouton principal, qui, lui, rayonne. */
.btn-vide{border-color:rgba(188,163,255,.54);color:var(--lav-2)}
.btn-vide:hover{border-color:var(--lav);background:rgba(150,112,255,.1)}
.btn.lg{padding:16px 30px;font-size:17px}

/* ------------------------------------------------------------------- entête */
header{
  position:sticky;top:0;z-index:60;
  background:rgba(10,8,17,.72);backdrop-filter:blur(18px) saturate(140%);
  border-bottom:1px solid var(--trait)
}
header .wrap{display:flex;align-items:center;gap:26px;height:68px}
.logo{display:flex;align-items:center;gap:11px;font-weight:800;letter-spacing:-.035em;
  font-size:18px;color:var(--creme)}
header nav{display:flex;gap:26px;margin-left:16px;font-size:15px;color:var(--gris);font-weight:500}
/* Un intitulé de navigation ne se coupe jamais : « Clip library » sur deux
   lignes double la hauteur de la barre et casse l'alignement de tout ce qui
   s'y trouve. S'il ne tient pas, c'est le tiroir qui prend le relais. */
header nav a{white-space:nowrap}
header nav a:hover{color:var(--creme)}
header .sp{flex:1}
/* Le bouton pleine taille (padding 14px, 15.5px) fait ~50px dans une barre de
   68 : il ne restait que 9px de part et d'autre et il touchait presque les
   bords. Version compacte, réservée à l'en-tête. */
header .btn{padding:10px 20px;font-size:14.5px}
/* Ni la marque ni le bouton ne doivent se casser : comprimés par flexbox, ils
   passaient tous deux sur deux lignes et la barre gonflait à 69px. */
.logo,header .btn{white-space:nowrap}
.logo>span:last-child{white-space:nowrap}
/* trois barres -> croix. Transformations seules : aucune propriété qui
   redéclenche une mise en page. */
.burger{display:none;width:38px;height:38px;padding:0;flex:0 0 auto;
  background:transparent;border:1px solid var(--trait);border-radius:11px;
  cursor:pointer;position:relative}
.burger:hover{border-color:rgba(150,112,255,.42)}
.burger span{position:absolute;left:50%;width:16px;height:1.5px;border-radius:2px;
  background:var(--encre);transform:translateX(-50%);
  transition:transform .22s ease,opacity .16s ease}
.burger span:nth-child(1){top:13px}
.burger span:nth-child(2){top:18.5px}
.burger span:nth-child(3){top:24px}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateX(-50%) translateY(5.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateX(-50%) translateY(-5.5px) rotate(-45deg)}

/* Le tiroir est décrit en fin de feuille : il est désormais fixé à la fenêtre
   et n'a plus rien à voir avec le flux de la barre. */

/* 900 et non 820 : la barre porte six intitulés depuis que la page a six
   sections, et à 830px les deux intitulés de deux mots se coupaient — mesuré.
   1100 DEPUIS LE 27/09/2026 : « Free demo », septième intitulé, porte la
   largeur minimale de la barre à 1070 px (mesuré dans Chrome : à 1024 px le
   bouton « Open my wallet » finissait à 1041 px, rogné de 17 px par
   `body{overflow-x:hidden}` ; à 960 px, de 81 px). Elle débordait déjà entre
   901 et 968 px avant l'ajout. 1100 laisse 30 px de marge pour une police
   système plus large (Segoe UI). Seul l'en-tête passe à 1100 : les grilles
   gardent leur seuil de 900. Le script qui referme le menu en repassant en
   grand écran suit ce nombre (matchMedia plus bas). */
@media(max-width:1100px){
  header nav{display:none}
  .burger{display:block}
}
@media(max-width:420px){
  /* le bouton du menu prend 38px : on récupère la place sur les trois autres */
  header .wrap{gap:10px}
  .logo{font-size:15.5px}
  header > .wrap > .btn{padding:8px 14px;font-size:12.5px}
  .burger{width:36px;height:36px}
  .burger span{left:50%;width:15px}
  .burger span:nth-child(1){top:12px}
  .burger span:nth-child(2){top:17.5px}
  .burger span:nth-child(3){top:23px}
}
@media(max-width:355px){
  /* En dessous, les trois ne rentrent plus. L'appel à l'action descend dans le
     menu, où il est de toute façon plus gros et plus lisible qu'écrasé ici. */
  header > .wrap > .btn{display:none}
}
/* ---------------------------------------------------------------- mobile
   Tout se centre sous 760px. Sur une colonne unique, un texte aligné à gauche
   laisse une marge droite irrégulière qui donne l'impression que la mise en
   page a cassé. Les listes gardent leur alignement à gauche à l'intérieur d'un
   bloc centré : une puce centrée est illisible. */
@media(max-width:760px){
  .hero .wrap{text-align:center;justify-items:center}
  .hero p.lead,.hero .micro{margin-left:auto;margin-right:auto}
  .cta-row{justify-content:center}

  .vit-tete,.vit-tete > div{text-align:center;justify-items:center}
  .vit-tete p{margin-left:auto;margin-right:auto}
  .vit-pied{justify-content:center;text-align:center}

  #pricing{text-align:center}
  .tar-chapo,.tar-argu > p{margin-left:auto;margin-right:auto}
  /* l'icône passe au-dessus du texte plutôt qu'à côté : à côté, elle force le
     bloc à rester aligné à gauche */
  .tar-rang{grid-template-columns:1fr;justify-items:center;gap:10px;padding:20px 0}
  .tar-rang i{margin:0 auto}
  .tar-rang span{max-width:40ch;margin:0 auto}

  /* les avantages de la carte restent lisibles : puce à gauche, bloc centré */
  .plan li{max-width:30ch}
}

@media(max-width:520px){
  /* mesuré à 375px : 331px de contenu utile, il faut y loger 150 + 128 + le
     jeu. On resserre les trois, pas un seul, sinon on repousse la casse. */
  header .wrap{gap:12px;height:60px}
  .wrap{padding:0 16px}
  .logo{font-size:16px;gap:9px}
  header .btn{padding:9px 16px;font-size:13.5px}
}
@media(max-width:380px){
  /* À 320px il ne reste que 288px utiles. `nowrap` ne fait pas disparaître le
     problème : il le change en débordement horizontal de toute la page. Il faut
     donc que ça RENTRE. Mesuré : 140 + 10 + 118 = 268. */
  .wrap{padding:0 14px}
  header .wrap{gap:10px}
  .logo{font-size:15px;gap:8px}
  .logo .mark svg,.logo .mark img{width:24px;height:24px}
  header .btn{padding:8px 14px;font-size:12.5px}
}

/* --------------------------------------------------------------------- hero */
.hero{position:relative;overflow:hidden;background:var(--lav-pale)}
/* TROIS halos superposés, du plus serré au plus large — l'ordre compte, le
   premier dégradé est celui du dessus. Un coeur chaud et petit posé sur un halo
   froid et large : c'est ce que fait une vraie source lumineuse, et c'est ce qui
   évite l'aplat violet uniforme qu'on obtient en montant simplement l'opacité
   d'un seul dégradé. */
.hero::before{
  content:"";position:absolute;inset:-320px 0 auto;height:1000px;pointer-events:none;
  background:
    radial-gradient(520px 320px at 30% 28%, rgba(176,107,255,.22), transparent 62%),
    radial-gradient(880px 520px at 26% 24%, rgba(150,112,255,.34), transparent 68%),
    radial-gradient(720px 460px at 80% 10%, rgba(139,100,247,.24), transparent 66%);
}
.hero::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(150,112,255,.38),transparent)
}
.hero .wrap{
  display:grid;grid-template-columns:1fr 370px;gap:60px;
  /* Le texte se cale EN HAUT, pas au centre. Centré, il était poussé de 103px
     vers le bas par le téléphone qui est bien plus haut que lui (746 contre
     541) — d'où l'impression qu'il flottait trop bas. */
  align-items:start;padding-top:64px;padding-bottom:82px;z-index:1
}
.demo{align-self:center}
@media(max-width:960px){.hero .wrap{grid-template-columns:minmax(0,1fr);gap:44px;padding-top:60px}}
.hero h1 em{
  font-style:normal;color:var(--lav)
}
.hero p.lead{margin-top:22px;max-width:54ch}
.cta-row{display:flex;gap:12px;margin-top:32px;flex-wrap:wrap}
.micro{font-size:13.5px;color:var(--gris-2);margin-top:18px;font-weight:500}


/* SUR MOBILE, UN RAIL PLUTOT QU'UNE PILE. Empilees, les trois cartes faisaient
   defiler 390px de page pour trois phrases qu'on lit en cinq secondes. En rail
   elles tiennent sur un geste, comme les six cartes de fonctionnalites juste
   au-dessus — meme convention, meme accrochage, meme barre masquee : deux
   mecaniques differentes pour deux rangees voisines se remarqueraient.
   Le debord negatif fait toucher le bord de l'ecran, ce qui est ce qui dit
   « ca defile » sans avoir a l'ecrire. */
/* SUR MOBILE, LES TROIS ETAPES PASSENT AVANT LE BOUTON. Le bouton arrivait
   entre la promesse et le mode d'emploi : on demandait de cliquer avant d'avoir
   dit ce qui se passe apres le clic. Les trois lignes repondent en une seconde,
   et le bouton se lit ensuite comme la conclusion plutot que comme une
   interruption. Sur grand ecran l'ordre du document convient : la colonne est
   large, les deux se voient d'un seul regard, et rien ne s'intercale. */
@media(max-width:760px){
  .final .box{display:flex;flex-direction:column}
  .final .fin-oeil{order:1}
  .final h2{order:2}
  .final .fin-lead{order:3}
  .final .fin-suite{order:4;margin-top:4px}
  .final .btn{order:5;margin-top:22px}
  .final .fin-micro{order:6}
}


/* --- LES TROIS ETAPES -------------------------------------------------------
   Numerotees parce que c'est une VRAIE suite : on ne peut pas composer avant
   d'avoir un compte, ni exporter avant d'avoir un abonnement. Un numero sur une
   liste dont l'ordre ne compte pas serait de la decoration ; ici il informe. */
/* Trois CARTES centrées, et plus une liste à gauche avec un trait vertical.
   La suite reste une suite — les numéros informent, ils ne décorent pas — mais
   elle se lit maintenant de gauche à droite, ce qui laisse les trois étapes
   tenir dans un seul regard au lieu de trois hauteurs d'écran.

   LA COULEUR PORTE LA PROGRESSION. Chaque étape a sa teinte, posée en `--c` sur
   la carte : violet, violet chaud, puis vert. Le vert n'est pas un ornement, il
   dit « c'est fini » — et c'est la seule étape où l'on obtient quelque chose.
   Le liseré du haut, la pastille du numéro et la bordure au survol prennent
   tous cette teinte, donc la progression se voit avant d'être lue. */
/* UNE SEULE COLONNE, de haut en bas. Trois cartes côte à côte imposaient la
   même hauteur à des textes de trois à sept lignes : les numéros se retrouvaient
   à trois hauteurs différentes et la suite ne se lisait plus. Empilées, chaque
   carte prend la hauteur de son contenu, et 1-2-3 se lit dans le sens où on lit.
   Bornée à 620px et centrée : au-delà, les lignes deviennent trop longues pour
   un texte centré, qui se lit mal dès qu'il dépasse une cinquantaine de signes. */
.etapes{
  list-style:none;margin:0 auto;padding:0;max-width:620px;
  display:grid;gap:30px;grid-template-columns:minmax(0,1fr);
}
.etapes li{
  --c:var(--lav);
  position:relative;overflow:hidden;text-align:center;
  background:linear-gradient(168deg,#191430,#131020 72%);
  border:1px solid var(--trait);border-radius:22px;
  padding:30px 24px 26px;
}
.etapes li:nth-child(2){--c:var(--lav-chaud)}
.etapes li:nth-child(3){--c:var(--vert)}
/* Le liseré est RENTRÉ de 26px de chaque côté. La carte ne rogne plus rien
   (`overflow:visible`, pour laisser passer le trait de liaison), donc un liseré
   qui irait d'un bord à l'autre dépasserait des coins arrondis en deux petites
   cornes. Rentré, il s'arrête avant la courbe et ça se lit comme un choix. */
.etapes li::before{
  content:"";position:absolute;inset:0 26px auto;height:2px;border-radius:0 0 2px 2px;
  background:var(--c);opacity:.85;
}
.etapes li:hover{transform:translateY(-4px);border-color:var(--c)}
/* LE TRAIT DE LIAISON, dans la gouttière. Il tient dans un `::after` posé
   au-dessous de la carte, donc hors de son `overflow:hidden` — c'est pour ça
   qu'il est sur `li` et pas dans la carte.
   LE DÉGRADÉ VA VERS LE BAS, et ce n'est pas indifférent : l'oeil suit
   l'intensité. Parti vif en haut, il se lirait comme une remontée vers l'étape
   précédente. Il tire donc vers le numéro SUIVANT, qui est le sens de lecture
   d'une suite. Et il emprunte la couleur de l'étape qu'il quitte, ce qui
   prolonge la progression violet → magenta → vert jusque dans l'intervalle. */
.etapes li:not(:last-child)::after{
  content:"";position:absolute;left:50%;bottom:-30px;
  width:1px;height:30px;transform:translateX(-50%);pointer-events:none;
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--c) 8%, transparent),
    color-mix(in srgb, var(--c) 55%, transparent));
}
/* `overflow:hidden` rognerait le trait : la carte n'en a plus besoin, son
   liseré du haut tient dans ses bords arrondis tout seul. */
.etapes li{overflow:visible}
.etapes .n{
  display:grid;place-items:center;width:52px;height:52px;border-radius:50%;
  margin:0 auto 16px;font-weight:800;font-size:19px;
  color:var(--c);
  background:color-mix(in srgb, var(--c) 13%, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--c) 36%, transparent),
             0 0 0 0 color-mix(in srgb, var(--c) 30%, transparent);
  transition:transform .22s cubic-bezier(.22,.9,.28,1), box-shadow .3s;
}
.etapes li:hover .n{
  transform:scale(1.07);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--c) 52%, transparent),
             0 0 0 7px color-mix(in srgb, var(--c) 9%, transparent);
}
.etapes h3{font-size:19.5px;margin:0 0 9px;letter-spacing:-.02em}
.etapes p{color:var(--gris);font-size:15px;line-height:1.66;margin:0}
.etapes strong{color:var(--encre);font-weight:650}
.etapes code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em;
  color:var(--lav-2);word-break:break-word}
@media(max-width:640px){
  .etapes li{padding:26px 20px 24px}
  .etapes .n{width:46px;height:46px;font-size:17px;margin-bottom:13px}
  .etapes h3{font-size:18px}
}

/* ── L'ENTREE DES TROIS ETAPES ────────────────────────────────────────────────
   L'ETAT VISIBLE EST LE DEFAUT. L'etat cache n'existe que sous la conjonction
   `html.etapes-attente` + carte sans `.vu`. Une `animation` avec `fill-mode`
   laisserait l'element sur son image de depart tant qu'elle n'a pas avance :
   dans un moteur qui n'execute pas les animations — j'en ai rencontre deux en
   verifiant cette page — les cartes resteraient invisibles POUR TOUJOURS. Ici,
   au pire, l'effet ne se joue pas. C'est la seule construction ou « pas d'effet »
   et « pas de contenu » ne peuvent pas se confondre.

   LE SEUIL PORTE SUR CHAQUE CARTE, PAS SUR LA SECTION. C'etait le defaut :
   mesure sur la page publiee, le haut de `#how` est 626 px au-dessus de la
   premiere carte et 1488 px au-dessus de la troisieme. Un seuil pose sur la
   section declenchait donc toute la cascade pendant que les cartes etaient
   encore a 546 px sous le bas de l'ecran. L'animation existait depuis toujours
   et personne ne l'avait jamais vue.

   `translate` ET `scale` SONT DES PROPRIETES A PART, pas `transform`, et c'est
   deliberé : `transform` est deja pris par le survol (`translateY(-4px)` sur la
   carte, `scale(1.07)` sur la pastille). Les trois se composent, chacune avec
   sa duree — l'entree peut durer 0,6 s sans rendre le survol pateux. La ou
   `translate`/`scale` ne sont pas connus, le decalage ne se fait pas et la carte
   se contente d'apparaitre en fondu : une degradation, jamais une disparition. */
.etapes li{opacity:1;translate:none}
.etapes li .n{scale:none}
.etapes li::before{transform:scaleX(1)}
.etapes li:not(:last-child)::after{transform:translateX(-50%) scaleY(1)}

html.etapes-attente .etapes li:not(.vu){opacity:0;translate:0 26px}
html.etapes-attente .etapes li:not(.vu) .n{scale:.78}
html.etapes-attente .etapes li:not(.vu)::before{transform:scaleX(0)}
html.etapes-attente .etapes li:not(.vu):not(:last-child)::after{transform:translateX(-50%) scaleY(0)}

/* QUATRE TEMPS DANS LA CARTE, et non un decalage d'une carte a l'autre : les
   cartes sont a 468 px l'une de l'autre, donc sur la plupart des ecrans elles
   entrent UNE PAR UNE. Un decalage entre elles ne se verrait jamais ; un
   mouvement interne se voit a chaque fois. La carte monte, la pastille se pose
   avec un rebond, le lisere se trace, puis le trait descend vers la suivante. */
.etapes li{
  transition:opacity .5s cubic-bezier(.22,.9,.28,1),
             translate .62s cubic-bezier(.22,.9,.28,1),
             transform .2s cubic-bezier(.22,.9,.28,1),
             border-color .2s;
}
.etapes li .n{
  transition:transform .22s cubic-bezier(.22,.9,.28,1),
             scale .52s cubic-bezier(.34,1.42,.5,1) .1s,
             box-shadow .3s;
}
.etapes li::before{transform-origin:50% 50%;transition:transform .5s cubic-bezier(.22,.9,.28,1) .2s}
.etapes li::after{transform-origin:50% 0;transition:transform .45s cubic-bezier(.22,.9,.28,1) .34s}

@media (prefers-reduced-motion: reduce){
  html.etapes-attente .etapes li:not(.vu){opacity:1;translate:none}
  html.etapes-attente .etapes li:not(.vu) .n{scale:none}
  html.etapes-attente .etapes li:not(.vu)::before{transform:scaleX(1)}
  html.etapes-attente .etapes li:not(.vu):not(:last-child)::after{transform:translateX(-50%) scaleY(1)}
  .etapes li,.etapes li .n,.etapes li::before,.etapes li::after{transition:none}
}

/* A L'IMPRESSION, TOUT EST POSE. Sans cette regle, un visiteur qui fait Cmd+P
   sans etre descendu jusqu'aux etapes imprime le titre au-dessus de trois cartes
   VIDES : l'etat cache ne vit dans aucune media query, il s'applique donc aussi
   au media pagine, et le navigateur imprime depuis un clone du DOM vivant, qui
   porte la classe d'attente. Le filet global a 6 s couvrait ce chemin par
   accident jusqu'au 15/09/2026 ; en le retirant — a raison, il revelait les
   cartes 2 et 3 sous le nez du lecteur — je l'ai decouvert. Une feuille
   d'impression est de toute facon le bon endroit pour ca : la question n'a
   jamais ete une histoire de delai. */
@media print{
  html.etapes-attente .etapes li:not(.vu){opacity:1;translate:none}
  html.etapes-attente .etapes li:not(.vu) .n{scale:none}
  html.etapes-attente .etapes li:not(.vu)::before{transform:scaleX(1)}
  html.etapes-attente .etapes li:not(.vu):not(:last-child)::after{transform:translateX(-50%) scaleY(1)}
  .etapes li,.etapes li .n,.etapes li::before,.etapes li::after{transition:none}
}

/* LE FILET PASSE PAR UNE CLASSE, PAS PAR UN STYLE EN LIGNE. L'entree anime
   QUATRE surfaces : la carte, la pastille, le lisere et le trait. Un style en
   ligne pose sur le <li> n'atteint ni son enfant `.n` ni ses pseudo-elements,
   et `transition` ne s'herite pas : le filet d'origine ne sauvait donc que la
   carte et laissait la pastille a 78 %, le lisere a zero et le trait a zero —
   une carte a demi habillee, ce qui est exactement le « pas de contenu » qu'il
   devait empecher. Avec `.vu` deja pose, couper la transition suffit : les
   valeurs cibles sont celles de l'etat visible. */
.etapes li.pose,.etapes li.pose .n,
.etapes li.pose::before,.etapes li.pose::after{transition:none}

/* LA MISE EN PLACE NE S'ANIME PAS. Mesure au banc : le script pose l'etat cache
   APRES le premier calcul de style, donc les cartes partaient de l'etat visible
   et s'EFFACAIENT en fondu — a 400 ms elles etaient a 1 % d'opacite et le lisere
   a 17 %. Sous la ligne de flottaison personne ne le voit, mais sur un lien
   direct vers /#how c'est un clignotement. Le script coupe donc les transitions
   pendant qu'il pose l'etat, force le calcul, puis les rend : la mise en place
   est instantanee, l'entree reste animee. */
html.etapes-froid .etapes li,html.etapes-froid .etapes li .n,
html.etapes-froid .etapes li::before,html.etapes-froid .etapes li::after{transition:none}


/* démo vivante */
.demo{justify-self:center;position:relative}
/* Le halo DERRIÈRE le téléphone — jamais dessus. L'écran, lui, reste lavande
   #b3a5f8 : c'est le produit, il ne suit pas la palette de la page. Le violet
   saturé l'entoure et le fait ressortir, au lieu de le recolorer. */
.demo::before{
  content:"";position:absolute;inset:-18% -28%;border-radius:50%;pointer-events:none;
  background:
    radial-gradient(closest-side, rgba(176,107,255,.20), transparent 58%),
    radial-gradient(closest-side, rgba(150,112,255,.46), transparent 76%)
}
.device{
  /* Largeur FIXE à l'origine : sur un écran de 320px la colonne du hero prenait
     les 330px du téléphone, forçait le texte à déborder, et overflow:hidden le
     coupait en plein mot. On plafonne sur la FENÊTRE et non sur 100% : ce
     dernier se résout sur le conteneur, dont la largeur dépend justement du
     téléphone — une définition circulaire qui renvoyait toujours 330px. */
  --w:min(330px,calc(100vw - 56px));width:var(--w);position:relative;
  border-radius:calc(var(--w)*.132);padding:calc(var(--w)*.0295);
  background:linear-gradient(160deg,#3b3552,#141020 44%,#332c4a);
  box-shadow:
    0 0 0 1px rgba(150,112,255,.16),
    0 30px 70px -26px rgba(53,27,126,.6)
}
.device .screen-frame{border-radius:calc(var(--w)*.105);overflow:hidden;background:#000;position:relative}
.device .island{
  position:absolute;left:50%;top:calc(var(--w)*.033);transform:translateX(-50%);
  width:calc(var(--w)*.32);height:calc(var(--w)*.0925);background:#000;border-radius:999px;z-index:20
}

/* ------------------------------------------------------------------ bandeau */
/* Bande défilante. Deux lots identiques côte à côte, la piste glisse de -50% :
   quand elle se réinitialise, le second lot est exactement là où était le
   premier, donc aucun saut visible. */
.bande{
  background:linear-gradient(180deg,#0d0a16,#100d1b);
  border-bottom:1px solid var(--trait);
  overflow:hidden;position:relative;padding:30px 0
}
/* les bords s'estompent au lieu d'être tranchés net */
.bande::before,.bande::after{
  content:"";position:absolute;top:0;bottom:0;width:90px;z-index:2;pointer-events:none
}
.bande::before{left:0;background:linear-gradient(90deg,#0d0a16,transparent)}
.bande::after{right:0;background:linear-gradient(270deg,#100d1b,transparent)}
.bd-piste{display:flex;width:max-content;animation:defile 26s linear infinite}
/* Pas de pause au survol : la bande passe sous le curseur pendant qu'on
   descend la page, et s'arrêter là attirait l'œil sur un arrêt involontaire. */
.bd-lot{display:flex}
.bd-item{
  display:flex;flex-direction:column;justify-content:center;text-align:center;
  padding:0 34px;white-space:nowrap;position:relative
}
/* séparateur discret entre deux arguments */
.bd-item::after{content:"";position:absolute;right:0;top:50%;transform:translateY(-50%);
  width:1px;height:26px;background:var(--trait)}
.bd-item b{display:block;font-size:23px;letter-spacing:-.03em;font-weight:800;color:var(--lav-2)}
/* `>` : le prix du <b> est une enveloppe du test de prix (des <span>), qui
   prendrait sinon la taille et la couleur du libelle. */
.bd-item > span{font-size:13px;color:var(--gris-2);margin-top:3px}
@keyframes defile{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media(max-width:760px){
  .bande{padding:24px 0}
  .bd-item{padding:0 24px}
  .bd-item b{font-size:20px}
  .bd-item > span{font-size:12.5px}
  .bande::before,.bande::after{width:48px}
}
@media (prefers-reduced-motion: reduce){
  /* on n'immobilise pas la bande sur une frame arbitraire : on rend la main,
     le contenu reste atteignable au doigt */
  .bd-piste{animation:none}
  .bande{overflow-x:auto;scrollbar-width:none}
  .bande::-webkit-scrollbar{display:none}
}

/* ---------------------------------------------------------------- sections */
section{padding:92px 0;position:relative}
/* Entêtes de section centrées : le bandeau de chiffres l'étant aussi, tout
   l'axe central de la page est aligné. */
.head{max-width:58ch;margin:0 auto 46px;text-align:center}
.head p{color:var(--gris);margin-top:15px;font-size:17.5px}

.grid{display:grid;gap:18px}
.g3{grid-template-columns:repeat(3,1fr)}
.g2{grid-template-columns:repeat(2,1fr)}
@media(max-width:920px){.g3{grid-template-columns:1fr 1fr}}
@media(max-width:660px){.g3,.g2{grid-template-columns:1fr}}

.card{
  background:var(--encre-2);border:1px solid var(--trait);border-radius:20px;padding:28px 26px;
  position:relative;text-align:center;
  transition:transform .18s, box-shadow .18s, border-color .18s
}
/* liseré clair en haut, comme sur les cartes de la maquette */
.card::before{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.01) 60%,transparent);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;padding:1px
}
.card:hover{
  transform:translateY(-3px);border-color:rgba(150,112,255,.42);
  box-shadow:0 18px 38px -28px rgba(53,27,126,.8)
}
.card p{color:var(--gris);font-size:15px;margin:10px auto 0;line-height:1.6;max-width:34ch}

/* `will-change` n'est déclaré que hors de la pause : douze couches GPU promues
   en permanence coûteraient plus cher que l'animation elle-même. */
/* Six teintes à luminance équivalente et saturation modérée : trop vives,
   cette carte crierait au milieu des cinq autres ; trop éteintes, la
   fonctionnalité ne se lirait plus. */
/* vitrine : cinq écrans réels */
.vit-tete{display:grid;grid-template-columns:1fr 420px;gap:60px;align-items:end;margin-bottom:44px}
.vit-tete h2{margin:20px 0 0}
.vit-tete p{color:var(--gris);margin:0;font-size:16.5px}
.vit-oeil{display:inline-flex;align-items:center;gap:9px;font-size:11.5px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--lav-2);
  background:rgba(150,112,255,.1);border:1px solid rgba(150,112,255,.28);
  padding:7px 15px;border-radius:999px}
.vit-oeil i{width:6px;height:6px;border-radius:50%;background:var(--lav);display:block}
/* défile au doigt : jamais de débordement du corps de page */
.vit-rangee{display:grid;grid-auto-flow:column;grid-auto-columns:232px;gap:18px;
  overflow-x:auto;padding-bottom:10px;scroll-snap-type:x mandatory;scrollbar-width:none;
  --fondu:20px;--f-g:var(--fondu);--f-d:var(--fondu)}
.vit-rangee::-webkit-scrollbar{display:none}
/* margin:0 indispensable : <figure> porte 40px de marge par défaut du
   navigateur, qui rétrécissait les cartes et faussait l'échelle du rendu. */
.vitre{margin:0;position:relative;border-radius:22px;overflow:hidden;scroll-snap-align:start;
  border:1px solid var(--trait);background:#000;
  box-shadow:0 22px 50px -34px rgba(53,27,126,.85);transition:transform .2s,border-color .2s}
.vitre:hover{transform:translateY(-4px);border-color:rgba(150,112,255,.4)}
.vitre .ecran{overflow:hidden;position:relative}
/* Une carte de la bibliotheque : la video remplit le cadre, format du post. Pas
   de legende — le nom d'un fichier ne decrit pas ce qu'on voit. */
.vitre-clip{aspect-ratio:9/16}
.vitre-clip video{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none}
/* La derniere carte : la video reste, floutee, et le chiffre passe devant. Le
   `scale` masque les bords que le flou rendrait transparents. */
.vitre-plus video{filter:blur(14px) saturate(.75) brightness(.55);transform:scale(1.12)}
.vit-plus{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:4px;color:#fff;text-align:center;padding:12px}
.vit-plus b{font-size:34px;font-weight:800;letter-spacing:-1.4px;line-height:1;
  text-shadow:0 2px 18px rgba(0,0,0,.6)}
.vit-plus span{font-size:12.5px;color:rgba(255,255,255,.82)}
/* La carte « 100+ » est un lien vers le wallet (10/10/2026) : la pastille dit
   où il mène, la carte entière est cliquable. */
a.vit-plus{text-decoration:none;cursor:pointer}
.vit-plus i{margin-top:12px;padding:8px 14px;border-radius:999px;font-style:normal;
  font-size:12.5px;font-weight:800;color:#140d2a;background:var(--lav-2);
  box-shadow:0 8px 20px -10px rgba(150,112,255,.8)}
.vit-plus i span{font-size:inherit;color:inherit}
a.vit-plus:focus-visible{outline:2px solid var(--lav-2);outline-offset:-4px;border-radius:22px}
.vitre figcaption{position:absolute;left:0;right:0;bottom:0;padding:76px 16px 16px;
  font-weight:700;font-size:14.5px;color:var(--creme);
  background:linear-gradient(to top,rgba(10,8,17,.97) 0%,rgba(10,8,17,.93) 38%,
    rgba(10,8,17,.65) 68%,transparent)}
.vitre figcaption small{display:block;font-weight:400;font-size:12.5px;color:var(--gris);margin-top:3px}
.vit-pied{display:flex;align-items:center;gap:34px;flex-wrap:wrap;margin-top:38px;
  padding-top:28px;border-top:1px solid var(--trait)}
.vit-fait{color:var(--gris-2);font-size:14.5px}
.vit-fait b{color:var(--creme);font-weight:700}
.vit-sp{flex:1}
@media(max-width:860px){
  .vit-tete{grid-template-columns:1fr;gap:18px;align-items:start}
  .vit-rangee{grid-auto-columns:196px}
}
/* masqué par défaut ; le média ci-dessous le montre. Posé APRÈS, il
   l'emporterait sur lui : à spécificité égale, c'est l'ordre qui tranche. */
.vit-cta-mob{display:none}

@media(max-width:760px){
  /* Les trois faits tiennent sur UNE ligne, qui défile. Empilés, ils prenaient
     trois hauteurs pour trois demi-phrases ; raccourcis, ils auraient perdu ce
     qu'ils disent. La ligne défile donc, comme les rails au-dessus, et le
     bouton passe dessous où il reste pleinement cliquable. */
  .vit-pied{
    display:flex;flex-wrap:nowrap;gap:26px;overflow-x:auto;
    /* CENTRER UN CONTENU QUI DEBORDE LE REND INATTEIGNABLE D'UN COTE.
       Une règle plus haut centre cette ligne ; dès qu'elle ne tient plus, le
       centrage pousse le débordement des DEUX côtés à parts égales — et la
       partie gauche est perdue, parce que `scrollLeft` ne descend pas sous
       zéro. Mesuré : le premier fait commençait à −60px d'un conteneur qui
       commence à 16, et aucun geste ne pouvait aller le chercher.

       `safe center` centre tant que ça tient et se rabat sur le début dès que
       ça déborde. La première déclaration est le repli des moteurs qui ne
       connaissent pas le mot-clé : ils gardent flex-start, qui est le
       comportement correct dans le cas qui pose problème. */
    justify-content:flex-start;
    justify-content:safe center;
    scrollbar-width:none;padding-bottom:4px;
    --fondu:22px;--f-g:var(--fondu);--f-d:var(--fondu);
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--f-g),
      #000 calc(100% - var(--f-d)),transparent 100%);
    mask-image:linear-gradient(90deg,transparent 0,#000 var(--f-g),
      #000 calc(100% - var(--f-d)),transparent 100%)
  }
  .vit-pied::-webkit-scrollbar{display:none}
  .vit-fait{white-space:nowrap;flex:0 0 auto;font-size:13.5px}
  .vit-sp{display:none}
  /* le bouton sort de la ligne défilante : un appel à l'action qu'il faut
     aller chercher en faisant glisser n'est plus un appel à l'action */
  .vit-pied .btn{display:none}
  .vit-cta-mob{display:flex;justify-content:center;margin-top:22px}
}

/* étapes */
.steps{counter-reset:s}
.step{display:flex;gap:20px;padding:24px 0;border-top:1px solid var(--trait)}
.step:first-child{border-top:0;padding-top:0}
.step .n{
  counter-increment:s;flex:0 0 40px;height:40px;border-radius:50%;
  background:rgba(150,112,255,.15);display:grid;place-items:center;
  font-weight:800;font-size:15px;color:var(--lav-2);
  box-shadow:inset 0 0 0 1px rgba(150,112,255,.26)
}
.step .n::before{content:counter(s)}
.step p{color:var(--gris);margin-top:7px;font-size:15.5px}

/* tarifs — la carte de prix. Son ancien conteneur `.plans` a disparu du balisage
   quand le bloc est passé à deux colonnes (`.tar-duo`) : les deux règles qui le
   visaient ne peignaient plus rien et ont été retirées. Le halo qu'elles
   portaient est maintenant la seconde box-shadow de `.plan` ci-dessous — une
   ombre extérieure, que `overflow:hidden` ne rogne pas, contrairement à un
   pseudo-élément. */
.plan{
  position:relative;overflow:hidden;
  /* Deux couches : un halo TRÈS discret qui vient éclairer le prix par le haut,
     puis le fond. Sans lui la carte est un rectangle plat. */
  background:
    radial-gradient(130% 68% at 50% -12%, rgba(176,107,255,.10), transparent 46%),
    radial-gradient(130% 68% at 50% -12%, rgba(150,112,255,.22), transparent 60%),
    linear-gradient(168deg,#1c1733,#121020 64%);
  border:1px solid rgba(150,112,255,.36);border-radius:30px;
  padding:34px 44px 40px;display:flex;flex-direction:column;text-align:center;
  /* deux ombres : la portée, qui pose la carte, et un bloom de sa couleur, qui
     la fait exister dans le noir. Sans le second la carte est un rectangle. */
  box-shadow:0 30px 70px -42px rgba(53,27,126,.9),
             0 0 90px -34px rgba(150,112,255,.42)
}
/* Filet clair sur l'arête haute. C'est ce détail qui fait lire la carte comme
   une surface éclairée plutôt qu'un aplat — le même que sur les sections. */
.plan::before{content:"";position:absolute;inset:0 0 auto;height:1px;
  background:linear-gradient(90deg,transparent,rgba(188,163,255,.45),transparent)}
.plan > *{position:relative}

/* La pastille était pleine et à cheval sur la bordure : elle criait plus fort
   que le prix. Elle rentre dans la carte, en contour. */
.plan .tag{
  align-self:center;background:rgba(150,112,255,.12);color:var(--lav-2);
  border:1px solid rgba(150,112,255,.3);white-space:nowrap;
  font-size:10.5px;font-weight:700;letter-spacing:1.5px;padding:6px 14px;
  border-radius:999px;text-transform:uppercase;margin-bottom:22px
}
.plan h3{font-size:17px;font-weight:650;color:var(--gris);letter-spacing:.2px}
.plan .sous{font-size:14px;color:var(--gris-2);margin-top:10px}
.price{font-size:72px;font-weight:800;letter-spacing:-.05em;margin:10px 0 0;
  line-height:1;color:var(--creme);display:flex;align-items:baseline;
  justify-content:center;gap:8px}
.price small{font-size:17px;font-weight:600;color:var(--gris);letter-spacing:0}

.plan ul{list-style:none;margin:30px 0 32px;padding-top:28px;
  border-top:1px solid var(--trait);display:grid;gap:15px}
.plan li{display:flex;gap:13px;align-items:flex-start;font-size:15px;
  color:var(--encre);line-height:1.5;text-align:left;max-width:33ch;
  margin:0 auto;width:100%}
/* La coche était tracée en #111 : du noir sur un fond noir, invisible. */
.plan li .ck{flex:0 0 21px;height:21px;border-radius:50%;margin-top:1px;
  background:rgba(150,112,255,.14);border:1px solid rgba(150,112,255,.26);
  display:grid;place-items:center}
.plan li .ck svg{display:block}
.plan li strong{color:var(--creme);font-weight:650}
.plan li.off{color:var(--gris-2)}
.plan .btn{margin-top:auto;width:100%}

/* tarifs : la carte et, à côté, ce qui remplit le vide */
.tar-titre{font-size:clamp(30px,4.2vw,44px);line-height:1.1;letter-spacing:-.035em;
  font-weight:800;margin:14px 0 0;color:var(--creme);text-wrap:balance}
.tar-chapo{color:var(--gris);margin:16px 0 0;max-width:52ch;font-size:16.5px}
/* Calées en HAUT : centrées, la colonne la plus courte flottait au milieu et
   rouvrait le vide qu'on venait de combler. */
/* La carte est CENTRÉE en hauteur face à la colonne d'arguments. L'étirement
   précédent alignait bien les deux bas, mais il écartait les quatre lignes pour
   combler la différence : elles flottaient loin les unes des autres. */
.tar-duo{display:grid;grid-template-columns:1fr 400px;gap:64px;align-items:center;
  margin-top:8px;position:relative}
.tar-argu{display:flex;flex-direction:column}
.tar-rassure{display:grid;gap:2px}

.tar-argu h3{font-size:21px;line-height:1.3;letter-spacing:-.02em;font-weight:700;
  color:var(--creme);margin:0 0 12px}
.tar-argu .tar-titre{margin-top:14px}
/* le chapô ferme l'entête, le bloc « pourquoi » ouvre la suite : sans cet
   écart les deux se touchent et le titre du second se lit comme un
   sous-titre du premier */
.tar-argu .tar-chapo{margin-bottom:0}
.tar-pourquoi{margin-top:40px}
/* le paragraphe du « pourquoi » n'est plus enfant direct de .tar-argu depuis
   qu'il vit dans .tar-pourquoi : la règle générale ne l'atteignait plus */
.tar-pourquoi > p{margin:0 0 26px;max-width:46ch}
.tar-argu > p{color:var(--gris);margin:0 0 30px;max-width:46ch}
.tar-rassure{display:grid;gap:2px}
.tar-rang{display:grid;grid-template-columns:38px 1fr;gap:16px;align-items:start;
  padding:17px 0;border-top:1px solid var(--trait)}
.tar-rang:first-child{border-top:0;padding-top:0}
.tar-rang:last-child{border-bottom:1px solid var(--trait)}
.tar-rang i{width:38px;height:38px;border-radius:12px;display:grid;place-items:center;
  background:rgba(150,112,255,.12);border:1px solid rgba(150,112,255,.22);
  font-style:normal;font-size:16px;color:var(--lav-2)}
.tar-rang b{display:block;color:var(--creme);font-size:15.5px;font-weight:650}
.tar-rang span{display:block;color:var(--gris);font-size:14.5px;margin-top:3px;line-height:1.55}
.tar-apres{text-align:center;color:var(--gris-2);font-size:12.5px;margin:14px 0 0}
@media(max-width:900px){
  .tar-duo{grid-template-columns:1fr;gap:40px}
  .tar-rassure{grid-auto-rows:auto}
  /* PAS de `order` ici. La règle d'origine passait `.tar-argu` sous la carte
     pour donner le prix en premier — « on ne fait pas lire un plaidoyer à
     quelqu'un qui descend chercher un chiffre ». L'intention était juste, mais
     `.tar-argu` porte AUSSI l'intitulé de la section, et le plaidoyer lui-même
     (`.tar-pourquoi`) est déjà masqué sur téléphone : il ne restait donc que le
     titre à faire passer sous la carte. Un titre de section sous ce qu'il
     annonce ne se lit pas comme un titre.
     Ordre naturel, donc : intitulé, puis carte. */
}

/* FAQ */
.faq{max-width:800px;margin:0 auto}
.faq details{border-bottom:1px solid var(--trait)}
.faq summary{
  list-style:none;cursor:pointer;padding:21px 0;font-weight:700;font-size:17px;
  display:flex;align-items:center;gap:14px;letter-spacing:-.02em;color:var(--creme)
}
.faq summary:hover{color:var(--lav-2)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";margin-left:auto;flex:0 0 9px;width:9px;height:9px;
  border-right:2.4px solid var(--lav-3);border-bottom:2.4px solid var(--lav-3);
  transform:rotate(45deg) translateY(-3px);transition:transform .2s
}
.faq details[open] summary::after{transform:rotate(-135deg) translateY(-2px)}
.faq .a{padding:0 0 22px;color:var(--gris);font-size:15.5px;max-width:70ch}

/* --------------------------------------------------------- app installable */
.mob-cta{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin-top:40px}
/* Les deux téléphones REPRENNENT le .device du hero : seule --w change, tout
   le reste (rayons, bordure, ombre, encoche) s'en déduit déjà.
   L'écran d'accueil est dessiné en CSS et calé sur le ratio du canevas de la
   maquette (923 × 2000) — c'est ce qui garantit que les deux cadres tombent
   exactement à la même hauteur, sans hauteur codée en dur. */
.apps{display:flex;justify-content:center;align-items:flex-start;gap:44px;flex-wrap:wrap}
.apps .device{--w:238px}
.app-tel{display:flex;flex-direction:column;align-items:center;gap:16px}
.app-tel figcaption{
  font-size:13.5px;line-height:1.5;color:var(--gris-2);font-weight:600;
  max-width:24ch;text-align:center
}
.accueil{
  aspect-ratio:923/2000;display:flex;flex-direction:column;
  padding:calc(var(--w)*.033) calc(var(--w)*.045) calc(var(--w)*.028);
  background:
    radial-gradient(115% 62% at 50% 0%, #2b2249, transparent 72%),
    linear-gradient(168deg,#191233,#0b0817 56%,#160f2a)
}
/* hauteur = celle de l'encoche, pour que l'heure s'aligne dessus */
.accueil .barre{
  display:flex;align-items:center;height:calc(var(--w)*.0925);
  padding:0 calc(var(--w)*.028);font-size:calc(var(--w)*.04);
  font-weight:700;color:#fff;letter-spacing:-.01em
}
.accueil .barre .sp{flex:1}
.accueil .pile{
  width:calc(var(--w)*.062);height:calc(var(--w)*.029);
  border-radius:2px;background:rgba(255,255,255,.92)
}
.accueil .grille{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:calc(var(--w)*.05) calc(var(--w)*.036);margin-top:calc(var(--w)*.07)
}
.accueil .app{text-align:center;min-width:0}
.accueil .app img,.accueil .ic{
  display:block;width:100%;height:auto;aspect-ratio:1;border-radius:22%
}
.accueil .ic{background:rgba(255,255,255,.07);box-shadow:inset 0 0 0 1px rgba(255,255,255,.05)}
.accueil .app img{box-shadow:0 5px 14px -6px rgba(0,0,0,.85),0 0 0 1px rgba(150,112,255,.28)}
.accueil .nom{
  /* Le nom porte par le manifeste fait 14 caracteres la ou l'ancienne etiquette
     en faisait 7. Sans coupure, `nowrap` le laissait deborder sur la cellule
     voisine. Un telephone tronque, donc tronquer est la representation JUSTE. */
  max-width:100%;overflow:hidden;text-overflow:ellipsis;
  display:block;margin-top:calc(var(--w)*.024);white-space:nowrap;line-height:1.25;
  font-size:calc(var(--w)*.035);font-weight:600;color:#fff;letter-spacing:-.02em;
  text-shadow:0 1px 3px rgba(0,0,0,.55)
}
/* étiquettes muettes des icônes de remplissage : elles ne servent qu'à donner
   aux cellules la même hauteur que celle de l'app */
.accueil .vide{
  display:block;width:64%;height:calc(var(--w)*.019);border-radius:99px;
  margin:calc(var(--w)*.028) auto 0;background:rgba(255,255,255,.10)
}
.accueil .dock{
  margin-top:auto;display:grid;grid-template-columns:repeat(4,1fr);
  gap:calc(var(--w)*.036);padding:calc(var(--w)*.036);
  border-radius:calc(var(--w)*.08);background:rgba(255,255,255,.09);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.06)
}
.accueil .poignee{
  width:34%;height:calc(var(--w)*.014);border-radius:99px;
  margin:calc(var(--w)*.03) auto 0;background:rgba(255,255,255,.5)
}
/* En dessous de 640 px les deux téléphones ne tiennent plus côte à côte. Ils
   passaient l'un sous l'autre ; ils restent désormais SUR UNE LIGNE et se
   parcourent au doigt (demande du 25/09/2026). Deux points sous le rail disent
   lequel on regarde.
   L'ÉCRAN SÉLECTIONNÉ EST CENTRÉ (demande du 25/09/2026, le premier était calé
   sur la gouttière de gauche) : accroche `center`, et le rail va de bord à bord
   de la FENÊTRE (`50% - 50vw`, indépendant de la gouttière de `.wrap`, qui vaut
   22, 16 ou 14 px selon la largeur). Pour que le PREMIER et le DERNIER puissent
   se centrer, il faut une demi-fenêtre de vide à chaque bout : ce sont deux
   pseudo-éléments et non un `padding`, parce que Safari a longtemps ignoré le
   padding de fin d'un conteneur défilant, et le dernier téléphone restait alors
   collé au bord droit. Leur largeur retire le `gap`, qui s'ajoute entre eux et
   le téléphone. Le voisin dépasse de chaque côté : il dit qu'il y a une suite. */
@media(max-width:640px){
  .apps{--tel:min(238px,64vw);
    flex-wrap:nowrap;justify-content:flex-start;gap:18px;
    overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;
    overscroll-behavior-x:contain;
    margin:0 calc(50% - 50vw);padding:6px 0 14px;scroll-padding:0}
  .apps::before,.apps::after{content:"";flex:0 0 calc(50vw - var(--tel) / 2 - 18px)}
  /* LA LUEUR DE FOND (demande du 25/09/2026). Une fois l'écran centré, le vide
     de chaque côté restait noir, surtout à gauche où rien ne dépasse quand le
     premier téléphone est sélectionné. Elle est peinte sur le RAIL lui-même :
     le fond d'un conteneur défilant reste attaché à sa boîte (attachment
     `scroll`), il ne glisse donc pas avec les téléphones. Chaque ellipse s'éteint
     avant le haut et le bas du rail, pour ne laisser aucun bord franc. */
  .apps{background:
    radial-gradient(52% 40% at 6% 44%, rgba(150,112,255,.34), rgba(150,112,255,0)),
    radial-gradient(34% 30% at 96% 58%, rgba(176,107,255,.17), rgba(176,107,255,0)),
    radial-gradient(52% 26% at 50% 70%, rgba(150,112,255,.10), rgba(150,112,255,0))}
  .apps::-webkit-scrollbar{display:none}
  .app-tel{flex:0 0 var(--tel);width:var(--tel);scroll-snap-align:center;scroll-snap-stop:always}
  .apps .device{--w:var(--tel)}
}
.apps-points{display:none}
@media(max-width:640px){
  .apps-points{display:flex;justify-content:center;gap:8px;margin-top:6px}
  .apps-points i{width:7px;height:7px;border-radius:99px;
    background:rgba(188,163,255,.3);transition:width .25s,background .25s}
  .apps-points i.on{width:20px;background:var(--lav)}
}

/* avertissement, désormais en pied de page */
.avert{margin-top:22px;padding-top:20px;border-top:1px solid var(--trait)}
.avert p{font-size:13px;line-height:1.7;color:var(--gris-2)}
.avert p+p{margin-top:9px}
.avert strong{color:var(--gris)}
.avert a{color:var(--lav-3)}
.avert a:hover{color:var(--lav-2)}

/* CTA final */
/* le bloc final collait à la section précédente : il lui faut le même air
   qu'entre deux sections */
.final{padding:92px 0 96px}
.final .box{
  background:linear-gradient(165deg,#1d1734,#120e1e);
  border:1px solid rgba(150,112,255,.42);
  border-radius:30px;padding:70px 30px 56px;text-align:center;
  position:relative;overflow:hidden;
  box-shadow:0 30px 70px -44px rgba(53,27,126,.9),
             0 0 110px -40px rgba(150,112,255,.5)
}
/* filet clair sur l'arête haute : la même signature que les autres surfaces */
.final .box::before{content:"";position:absolute;inset:0 0 auto;height:1px;z-index:1;
  background:linear-gradient(90deg,transparent,rgba(188,163,255,.55),transparent)}
.fin-oeil{display:inline-block;font-size:11.5px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--lav-2);background:rgba(150,112,255,.1);
  border:1px solid rgba(150,112,255,.28);padding:7px 15px;border-radius:999px}
.final h2{margin:22px 0 0;font-size:clamp(30px,4.6vw,48px);line-height:1.08;
  letter-spacing:-.035em}
.fin-lead{color:var(--gris);max-width:52ch;margin:18px auto 32px;font-size:16.5px}
/* Les trois étapes qui suivent le clic. Numérotées parce que c'est une vraie
   séquence, pas trois arguments qu'on aurait rangés en ligne. */
.fin-suite{list-style:none;display:flex;justify-content:center;gap:10px;
  flex-wrap:wrap;margin:34px 0 0;padding:0}
/* Le texte de l'etape tient dans un <span> : il porte un prix (enveloppe du test
   de prix), et chaque morceau deviendrait sinon un element flex ecarte de 10px. */
.fin-suite li{display:flex;align-items:center;gap:10px;font-size:14.5px;
  color:var(--encre);background:rgba(255,255,255,.035);
  border:1px solid var(--trait);border-radius:999px;padding:9px 18px 9px 9px}
.fin-suite b{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
  background:rgba(150,112,255,.16);color:var(--lav-2);font-size:12px;font-weight:700}
.fin-micro{color:var(--gris-2);font-size:13.5px;margin:26px 0 0}
@media(max-width:620px){
  .final .box{padding:52px 22px 44px}
  .fin-suite{flex-direction:column;align-items:stretch;gap:8px}
  .fin-suite li{justify-content:flex-start}
}
.final .box::after{
  content:"";position:absolute;left:50%;top:-40%;width:760px;height:520px;
  transform:translateX(-50%);pointer-events:none;
  background:
    radial-gradient(closest-side, rgba(176,107,255,.19), transparent 56%),
    radial-gradient(closest-side, rgba(150,112,255,.40), transparent 74%)
}
/* Le halo du bloc est un `::after` : dans l'ordre de peinture, un pseudo-élément
   positionné en `z-index:auto` passe APRÈS ses frères de même niveau, parce que
   l'arbre le place en dernier. `position:relative` seul ne suffit donc pas à
   faire passer le contenu devant — il le met au même niveau, et l'arbre
   tranche en faveur du halo. Il faut un z-index explicite.
   Ça ne se voyait pas tant que le halo était à .16 ; il est passé à .40. */
.final .box > *{position:relative;z-index:2}
.final p{color:var(--gris)}

footer{background:#07050d;color:var(--gris-2);padding:48px 0;font-size:14.5px;
  border-top:1px solid var(--trait)}
footer .wrap{display:flex;gap:28px;flex-wrap:wrap;align-items:center}
footer .logo{color:var(--creme)}
footer a:hover{color:var(--lav-2)}
footer .sp{flex:1}
/* La maquette se gouverne elle-même : le centrage mobile des sections
   descendait par héritage jusque dans l'écran du wallet et centrait le solde,
   les lignes de jetons et les titres de section. Une réplique d'app ne se
   centre pas — c'est le premier détail qui trahit une fausse capture. */
.mw{text-align:left}

/* Bords fondus des rails horizontaux.
   Un masque agit sur le CONTENU, pas en calque par-dessus : il fonctionne donc
   quelle que soit la couleur derrière — et les deux rails n'ont pas le même
   fond. Un calque aurait exigé de connaître la couleur et de la corriger à
   chaque changement de section.
   Le fondu est RETIRÉ du côté où l'on est déjà en butée : sinon le premier
   élément apparaît rongé alors qu'il n'y a rien à faire défiler à gauche. */
/* « Réduis le blur sur les côtés, il est vraiment trop puissant et propagé »
   (10/10/2026) : fondu court et le bord ne s'efface qu'à moitié (35 %), au
   lieu de 46 px (22 au téléphone) jusqu'à la transparence. */
.vit-rangee{
  -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,.35) 0,#000 var(--f-g),
    #000 calc(100% - var(--f-d)),rgba(0,0,0,.35) 100%);
  mask-image:linear-gradient(90deg,rgba(0,0,0,.35) 0,#000 var(--f-g),
    #000 calc(100% - var(--f-d)),rgba(0,0,0,.35) 100%)
}
[data-bord~="debut"]{--f-g:0px}
[data-bord~="fin"]{--f-d:0px}

/* ------------------------------------------------------------- rail de cartes */
/* les points ne servent pas qu'à décorer : sans eux on ignore combien de
   cartes existent et où l'on se trouve */
/* Sur grand écran trois cartes sont visibles à la fois : un point « courant »
   n'a plus de sens. Ils n'apparaissent que là où une seule carte s'affiche. */
@media(max-width:760px){
  /* fondu plus court au téléphone (10/10/2026 : 22 px y étaient encore trop) */
  .vit-rangee{--fondu:10px}
}

/* ------------------------------------------------- hero mobile : ordre et taille
   Placé en FIN de feuille à dessein : `.device{--w:…}` est défini plus haut, et
   à spécificité égale c'est la dernière règle qui gagne. Posé avant, le plafond
   de largeur ne s'appliquait pas. */
@media(max-width:760px){
  /* L'aperçu remonte ENTRE le chapô et les boutons : il montre le produit avant
     qu'on demande de cliquer. `display:contents` dissout la colonne de texte
     pour que ses enfants deviennent des éléments de la grille et puissent
     s'ordonner avec l'aperçu, sans toucher au balisage. */
  .hero .wrap{gap:18px}
  .hero .wrap > div:first-child{display:contents}
  .hero .eyebrow{order:1}
  .hero h1{order:2;margin-top:2px}
  .hero p.lead{order:3;margin-top:0}
  .hero .demo{order:4;margin:10px auto 6px}
  .hero .cta-row{order:5;margin-top:0}
  /* LE PRIX ETAIT REMONTE EN TETE DE SECTION. Ce bloc reordonne les enfants du
     hero un par un (`display:contents` sur la colonne), et un element sans
     `order` vaut 0 : mon prix, ajoute apres coup, passait donc AVANT le titre.
     Il se lisait avant meme qu'on sache de quoi il s'agissait. Sa place est
     sous le bouton, la ou la question du prix se pose. */
  .hero .hero-forts{order:6;margin-top:2px}
  .hero .micro{order:7;margin-top:0}
  .device{--w:min(250px,calc(100vw - 110px))}
  /* LES ESPACES DU HAUT, UN PEU RESSERRÉS (07/10/2026, l'opérateur sur sa capture
     du haut de page : « diminue juste un petit peu les espaces ici »). Des px
     fixes, rien d'autre : la taille du téléphone ne dépend que de la largeur et
     le premier écran ne bouge pas au défilé (un téléphone taillé sur la hauteur
     de l'écran grandissait sous le doigt dans l'appli Google). Avant → après :
     marge du haut 60 → 44, bandeau → titre 36 → 26, titre → chapô 18 → 14,
     chapô → téléphone 28 → 20. Sous le téléphone, rien ne change. */
  .hero .wrap{padding-top:44px}
  .hero .eyebrow{margin-bottom:6px}
  .hero .eyebrow-n1{justify-self:center;margin-left:auto;margin-right:auto}
  .hero p.lead{margin-top:-4px}
  .hero .demo{margin-top:2px}
}
/* ------------------------------------------- tarifs : colonne d'arguments
   Réservée au grand écran. Sur mobile elle ajoutait quatre pavés entre le
   titre et le prix, alors que la carte porte déjà l'essentiel de ce qu'ils
   disent (« Cancel anytime »).
   Posé en FIN de feuille à dessein : la grille des tarifs passe à une colonne
   à 900px, et une règle écrite plus haut serait écrasée par elle. */
@media(max-width:900px){
  /* seule la partie « pourquoi » disparaît : le titre et le chapô restent */
  .tar-pourquoi{display:none}
  .tar-duo{grid-template-columns:minmax(0,1fr);gap:34px}
}
/* ----------------------------------- section « app mobile » : l'installation
   L'icône se pose sur la grille, tient une bonne partie du cycle, puis
   recommence : c'est exactement ce que la légende annonce. En pause tant que
   la section n'est pas à l'écran — pas de cycle qui tourne dans le vide. */
.accueil .grille > .app:first-child > img,
.accueil .grille > .app:first-child > .nom{
  animation:pose 7s cubic-bezier(.22,1,.36,1) infinite
}
.accueil .grille > .app:first-child > .nom{animation-delay:.14s}
#mobile.hors-champ .accueil .grille > .app:first-child > img,
#mobile.hors-champ .accueil .grille > .app:first-child > .nom{animation-play-state:paused}
@keyframes pose{
  0%,4%   {opacity:0;transform:scale(.55)}
  16%     {opacity:1;transform:scale(1.06)}
  22%,88% {opacity:1;transform:scale(1)}
  96%,100%{opacity:0;transform:scale(.55)}
}
@media (prefers-reduced-motion: reduce){
  /* état FINI, pas une image arbitraire du cycle */
  .accueil .grille > .app:first-child > img,
  .accueil .grille > .app:first-child > .nom{animation:none;opacity:1;transform:none}
}
/* --------------------------------------------------- pied de page sur mobile
   La marque, les six liens et l'avertissement partageaient la même rangée
   flexible : les liens se cassaient sur deux lignes irrégulières et le tout
   occupait presque un écran. Trois blocs empilés et centrés, plus serrés.
   Posé en FIN de feuille : `footer .wrap{display:flex}` est déclaré plus haut. */
@media(max-width:760px){
  footer{padding:34px 0 30px;font-size:13.5px}
  footer .wrap{
    flex-direction:column;align-items:center;justify-content:center;
    gap:16px;text-align:center
  }
  /* l'espaceur ne sert qu'à pousser les liens à droite sur grand écran */
  footer .sp{display:none}
  footer .logo{font-size:16px;gap:9px}
  /* les six liens forment leur propre bloc, centré et resserré */
  footer .wrap > a:not(.logo){
    display:inline-block;font-size:13px;padding:2px 0
  }
  footer .wrap:first-of-type{
    display:flex;flex-flow:row wrap;gap:9px 15px;
    align-items:center;justify-content:center
  }
  footer .wrap:first-of-type > .logo{flex:0 0 100%;justify-content:center}
  .avert{margin-top:20px;padding-top:18px}
  .avert p{font-size:12px;line-height:1.6;max-width:46ch;margin-left:auto;margin-right:auto}
  .avert p+p{margin-top:8px}
}

/* ------------------------------------------- respiration des rails au survol */
/* `overflow-x:auto` fait d'un conteneur un cadre de défilement, et un cadre de
   défilement CLIPPE LES DEUX AXES — la spécification ne permet pas de laisser
   l'un visible pendant que l'autre défile. Les cartes se soulèvent au survol
   (-3px et -4px) : sans marge intérieure, ce soulèvement passait sous le bord
   supérieur et la carte apparaissait coupée net en haut.
   On ouvre donc l'espace À L'INTÉRIEUR du cadre, et on le reprend par une
   marge négative de la même valeur : le rail respire, la page ne bouge pas.
   Posé en fin de feuille à dessein : ces deux sélecteurs sont déjà réglés à
   quatre endroits plus haut, et à spécificité égale c'est la dernière règle
   du fichier qui gagne. */

/* Le chapô du hero occupait cinq lignes sur un téléphone : la promesse se
   perdait avant d'être lue. La liste d'usages passe donc à la trappe sur petit
   écran, et seule la promesse reste. Un seul texte source — on masque une
   partie, on ne duplique pas une variante qui divergerait à la première
   retouche. */
/* La règle ne valait que dans .lead alors que le nom de la classe promet
   davantage. Elle vaut partout, et restreindre la portée n'aurait fait
   qu'inviter une deuxième règle. `.sur-mobile`, son inverse, avait disparu le
   24/09/2026 ; il revient le 04/10/2026 pour le chapô du hero, que l'opérateur
   veut « plus simple et catchy sur mobile » : une autre phrase, pas un extrait. */
.sur-mobile{display:none}
@media(max-width:760px){
  .hors-mobile{display:none}
  .sur-mobile{display:inline}
}

/* Atterrissage des liens du menu sur téléphone. La barre collante y mesure
   61 px et le haut de plusieurs sections n'en laisse que 56 à 57 avant leur
   premier texte : « Mobile app », « Affiliates » et « FAQ » arrivaient avec
   leur sur-titre rogné de 4 à 5 px sous la barre (mesuré le 24/09/2026). Sur
   grand écran la marge des sections suffit déjà (92 px pour 69). */
@media(max-width:820px){
  section[id]{scroll-margin-top:16px}
}

/* --------------------------------------- liens du pied de page : deux lignes */
/* HISTORIQUE. Les six liens tenaient sur UNE ligne, à l'arraché : 366px pour
   358 utiles à 390px de large, d'où un écart ramené à 6px et une taille fluide
   pour récupérer les huit pixels manquants. Le but était d'éviter que
   « Contact » retombe seul sur une deuxième ligne, où il se lisait comme s'il
   n'appartenait pas au même groupe.
   Ce budget est mort avec le septième lien (« Affiliates ») : ~371px à 360px
   de large pour 316 utiles, et `nowrap` aurait transformé le débordement en
   défaut visible sur toute la page — ce qui était l'intention de l'époque, pas
   une fatalité à conserver.
   On replie donc EXPRÈS, sur deux lignes centrées, et la taille revient à 13px :
   une fois le repli assumé, la compression n'a plus de raison d'être. Relevé le
   05/10/2026, lien de la démo retiré : cinq liens puis trois à 320 et 360 px
   de large, six puis deux à 390 px — jamais d'orphelin : c'était le seul
   défaut que la ligne unique cherchait à éviter. */
@media(max-width:760px){
  footer .wrap:first-of-type{gap:10px 14px;flex-wrap:wrap;justify-content:center}
  footer .wrap:first-of-type > a:not(.logo){
    font-size:13px;white-space:nowrap
  }
  /* le logo garde sa ligne à lui : c'est lui qui autorise les six liens à
     partager la suivante */
  footer .wrap:first-of-type > .logo{flex:0 0 100%}
}

/* ------------------------------------------------------ tiroir latéral droit */
/* Le menu glisse depuis la DROITE, il ne tombe plus du haut. Un panneau qui
   descend pousse le regard vers le bas alors que le geste vient d'un bouton
   situé en haut à droite ; un tiroir arrive du côté où l'on a appuyé.

   Il n'est jamais retiré du flux par [hidden] : un élément caché ainsi ne peut
   pas s'animer. On le sort de l'écran et on le rend invisible — `visibility`
   suffit à l'ôter du parcours clavier, et sa transition est retardée à la
   fermeture pour que le glissement ait le temps de se jouer. */
.menu-mob{
  position:fixed;top:0;right:0;z-index:70;
  width:min(320px,82vw);height:100dvh;
  display:flex;flex-direction:column;gap:2px;
  padding:78px 22px calc(22px + env(safe-area-inset-bottom));
  background:rgba(10,8,17,.98);
  backdrop-filter:blur(18px) saturate(140%);
  border-left:1px solid var(--trait);
  box-shadow:-24px 0 60px -30px rgba(0,0,0,.9);
  overflow-y:auto;overscroll-behavior:contain;
  visibility:hidden;transform:translateX(100%);
  transition:transform .28s cubic-bezier(.32,.72,0,1),visibility 0s .28s;
}
.menu-mob.ouvert{visibility:visible;transform:none;transition:transform .28s cubic-bezier(.32,.72,0,1),visibility 0s}
.menu-mob a{padding:14px 2px;font-size:16.5px;color:var(--encre);font-weight:500;
  border-bottom:1px solid var(--trait)}
.menu-mob a:last-of-type{border-bottom:0}
.menu-mob .menu-cta{display:inline-flex;margin-top:18px;justify-content:center;
  border-bottom:0;color:#100d1b;font-weight:700}
.menu-fermer{
  position:absolute;top:16px;right:18px;
  display:grid;place-items:center;width:38px;height:38px;padding:0;
  background:transparent;border:1px solid var(--trait);border-radius:11px;
  color:var(--gris);cursor:pointer;transition:color .18s,border-color .18s
}
.menu-fermer:hover{color:var(--creme);border-color:rgba(150,112,255,.42)}
/* Le tiroir recouvre le burger : sans cette croix, on ouvrirait sans pouvoir
   refermer autrement qu'en tapant à côté. */

/* Le voile passe SOUS le tiroir mais AU-DESSUS de la page : il assombrit ce
   qu'on quitte et absorbe le clic de fermeture. */
.menu-voile{
  position:fixed;inset:0;z-index:65;background:rgba(6,4,12,.62);
  opacity:0;visibility:hidden;transition:opacity .28s ease,visibility 0s .28s
}
.menu-voile.ouvert{opacity:1;visibility:visible;transition:opacity .28s ease,visibility 0s}
/* le fond ne défile plus derrière le tiroir ouvert */
body.menu-ouvert{overflow:hidden}

@media (prefers-reduced-motion: reduce){
  .menu-mob,.menu-voile{transition:none}
}

/* Un seul appel à l'action sur téléphone. Deux boutons côte à côte se
   partageaient la largeur : aucun des deux ne dominait, et « See pricing »
   captait des clics qui auraient dû aller au premier. La section tarifs reste
   atteignable par le menu et par le simple défilement — on ne perd donc pas un
   chemin, on en supprime un concurrent. Le bouton restant s'étire : sur un
   écran étroit, un bouton large est la cible la plus sûre au pouce.

   MAIS IL NE VA PAS JUSQU'AUX BORDS. Il s'étirait à la largeur entière du
   contenu, soit 18px de l'écran sur un téléphone de 375px — c'est-à-dire
   exactement la marge du texte courant, ce qui se lit comme un bouton collé
   aux bords plutôt que comme un bouton pleine largeur assumé. Il était aussi
   nettement plus large que le téléphone posé juste au-dessus, qui, lui, garde
   55px de marge (`.device`). Le retrait ci-dessous le pose entre les deux :
   plus large que la maquette, franchement à l'intérieur de la colonne de
   texte. `box-sizing: border-box` est global (l.64), donc ce padding se prend
   sur la largeur du bouton et non en plus. */
@media(max-width:760px){
  .hero .cta-row .btn-vide{display:none}
  .hero .cta-row{width:100%;padding-inline:26px}
  .hero .cta-row .btn-encre{flex:1 1 auto;max-width:340px}
  /* Le format `lg` a été dessiné pour un bouton posé dans une rangée de deux,
     sur grand écran. Seul et pleine largeur sur un téléphone, il devenait un
     pavé de 66px de haut : la cible tactile n'y gagne plus rien passé 48-52px,
     et le bouton finissait par peser plus lourd que le titre au-dessus. */
  .hero .cta-row .btn.lg{padding:14px 26px;font-size:16px}
}

/* ------------------------------------------------ titre du hero sur mobile */
/* Il tenait sur TROIS lignes : la coupure tombait au hasard et la proposition
   en violet se retrouvait éclatée sur deux lignes. On force donc la coupure
   entre les deux propositions — le changement de couleur épouse alors le
   changement de ligne — et on taille le texte sur la LIGNE LA PLUS LONGUE
   (« A believable wallet app, », 401px à 36px) pour que les deux tiennent,
   y compris sur un écran de 320px.
   Le facteur .089 vient de la mesure : 358px disponibles à 390px de large
   autorisent 31,9px, soit (100vw - 32px) × .089.
   En fin de feuille à dessein : `.hero h1` est déjà réglé plus haut dans un
   @media, et à spécificité égale c'est la dernière règle qui gagne. */
@media(max-width:760px){
  .hero h1{font-size:min(36px, calc((100vw - 32px) * .089))}
  .hero h1 em{display:block}
}

/* -------------------------------------------------------- commandes du rail */
/* Les points ne s'affichaient que sous 760px : sur grand écran, rien n'indiquait
   qu'il y avait d'autres cartes, et rien ne permettait d'y aller à la souris —
   la barre de défilement est masquée et une molette verticale ne fait pas
   avancer un conteneur horizontal. Deux flèches règlent les deux problèmes. */
.vit-rangee{padding-top:12px;padding-bottom:16px;margin-top:-12px;margin-bottom:-6px}

/* ------------------------------------------- les vignettes prennent la place
   Elles vivaient dans un cadre de 104px de haut, centré au milieu d'une carte
   qui en fait 360 de large : une scène de 200x88 flottant dans du vide, avec
   des marges au-dessus et en dessous. À cette taille, la finesse du dessin ne
   se voit pas — on lit « un pictogramme », pas « un écran ».

   La scène garde ses coordonnées (tout y est posé au pixel sur un canevas de
   200x88) et c'est le CANEVAS ENTIER qu'on agrandit : rien ne se déplace, rien
   ne se réaligne, et les six animations continuent de tomber juste.

   Le cadre, lui, va d'un bord à l'autre de la carte et se colle en haut, comme
   la capture d'un écran plutôt qu'une illustration posée dessus. */
#features .card{padding-top:0;overflow:hidden}

/* ------------------------------------------------- du vert, la ou il dit quelque chose
   Posé en fin de feuille : les règles d'origine de `.plan .tag` et `.ck` sont
   plus haut à la même spécificité, et c'est la dernière qui gagne.

   Le vert ne décore pas, il affirme. Sur la carte de prix il porte ce qu'on
   OBTIENT — la pastille « everything included » et les six coches — pendant que
   le lavande reste la marque et que le prix reste crème : ce qu'on paie n'est
   pas un gain, et le colorer en vert serait un compliment qu'on se fait à
   soi-même. Sur le calculateur d'affiliation il porte ce qu'on ENCAISSE, ce qui
   est exactement le même sens. */
.plan .tag{
  background:var(--vert-voile);color:var(--vert);border-color:var(--vert-trait)
}
.plan li .ck{background:var(--vert-voile);border-color:var(--vert-trait)}
/* La coche est tracée en dur dans le balisage (stroke="#bca3ff") : on la reprend
   ici plutôt que de la réécrire six fois. */
.plan li .ck svg path{stroke:var(--vert)}
/* Les quatre pastilles de la colonne de gauche étaient en lavande à 12 % de
   fond et 22 % de contour : à cette dose, sur ce noir, le lavande se lit gris.
   La couleur était là, elle ne se voyait pas. */
.tar-rang i{background:rgba(150,112,255,.17);border-color:rgba(150,112,255,.36)}

/* ----------------------------------- le rail montre ses deux voisins, sur mobile
   La carte courante était collée au bord gauche : on voyait la suivante dépasser
   à droite et rien à gauche, si bien que le rail se lisait comme une colonne qui
   déborde plutôt que comme une file qu'on parcourt. Une gouttière des DEUX côtés
   dit d'un coup d'œil qu'il y a quelque chose avant et quelque chose après.

   Trois valeurs liées, et c'est pour ça qu'elles sont écrites ensemble :
     - la carte rétrécit pour laisser la place aux gouttières ;
     - le rail sort des 22px de l'enveloppe pour occuper toute la largeur, sans
       quoi la gouttière de gauche serait celle du .wrap et pas la sienne ;
     - le rembourrage vaut exactement la moitié de ce qui reste, ce qui permet à
       la PREMIÈRE et à la DERNIÈRE carte de se centrer elles aussi. Sans lui
       elles restaient calées contre leur bord — le défaut d'origine, déplacé. */
@media(max-width:899px){
}
/* -------------------------------------- le bloc final : la couleur dit l'issue
   Posé en fin de feuille : les règles d'origine visent les mêmes sélecteurs à la
   même spécificité, et c'est la dernière qui gagne.

   Trois étapes numérotées sont une progression, et la troisième n'est pas une
   étape de plus : c'est ce qu'on obtient. Elle passe donc au vert, le même que
   celui des coches de la carte de prix — il y porte déjà « ce qu'on obtient »,
   et le reprendre ici n'ajoute pas une couleur, il en prolonge une. Les deux
   premières restent lavande : ce sont des démarches, pas des résultats.

   La pastille du haut, elle, gagne un fond un peu plus dense. À 10 % sur ce
   noir, le lavande se lisait gris — la couleur était là sans se voir, exactement
   comme les quatre pastilles de la colonne des tarifs. */
.fin-oeil{background:rgba(150,112,255,.15);border-color:rgba(150,112,255,.36)}
.fin-suite li:last-child{
  border-color:var(--vert-trait);background:var(--vert-voile)
}
.fin-suite li:last-child b{background:rgba(79,212,124,.2);color:var(--vert)}
/* ------------------------------------------- passerelle du pied vers les guides */
/* L'accueil ne liait AUCUN guide ni article : la page la mieux dotée du site ne
   transmettait rien aux quatre pages qui, elles, peuvent être citées. Un bloc en
   pleine page avait été essayé, puis retiré — il pesait trop lourd pour ce qu'il
   disait. La même information tient ici en une ligne de pied, sans rien coûter à
   la lecture. Posé en FIN de feuille comme toute règle ajoutée : au milieu, une
   déclaration plus bas à spécificité égale la reprendrait. */
footer .pied-ref{
  gap:8px 18px;margin-top:24px;padding-top:14px;padding-bottom:14px;
  border-top:1px solid var(--trait);font-size:13px
}
/* L'ENCART YOUTUBE (10/10/2026) : une carte sobre au fond du pied, le logo
   rouge et le bouton blanc « Subscribe » de YouTube pour qu'on le reconnaisse
   d'un coup d'oeil. Un peu plus petit le soir meme (« un tout petit peu plus
   petit »). Deux liens dans la carte : la chaine, et « Subscribe » qui ouvre
   la confirmation d'abonnement de YouTube (tools/comptes.py). Les liens ne
   sont pas enfants directs de `.wrap` : `footer .wrap > a:not(.logo)` ne les
   touche pas ; `footer a:hover` (0,1,2) teinterait la pastille, d'ou (0,2,1). */
footer .pied-ref:not(:has(a)){display:none}
/* LE MEME PETIT ESPACE au-dessus et au-dessous de la carte, entre les deux
   filets (10/10/2026, l'operateur). Le filet du haut est la bordure de
   `.pied-ref`, celui du bas la bordure de `.avert` : la marge de `.avert`
   passe dans le bas de `.pied-ref` (14 px, 12 sur mobile), egal a son haut. */
footer .pied-ref + .avert{margin-top:0}
footer .pied-ref:not(:has(a)) + .avert{margin-top:22px}
.pied-yt{
  display:inline-flex;align-items:center;gap:10px;max-width:100%;
  padding:7px 7px 7px 11px;border-radius:12px;
  background:rgba(255,255,255,.04);border:1px solid var(--trait);
  text-align:left;line-height:1.25;transition:border-color .2s,background-color .2s
}
.pied-yt:hover{background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.18)}
footer .pied-yt-chaine,footer .pied-yt-chaine:hover{display:flex;align-items:center;gap:10px;min-width:0;color:var(--creme)}
.pied-yt a:focus-visible{outline:2px solid var(--lav-2);outline-offset:3px;border-radius:8px}
.pied-yt-logo{flex:none;display:block}
.pied-yt-txt{display:flex;flex-direction:column;gap:1px;min-width:0}
.pied-yt-txt b{font-size:13px;font-weight:700;color:var(--creme)}
.pied-yt-txt span{font-size:11px;color:rgba(237,233,245,.55)}
footer .pied-yt-abo,footer .pied-yt-abo:hover{flex:none;margin-left:4px;padding:6px 11px;border-radius:999px;
  background:#f1f1f1;color:#0f0f0f;font-size:12px;font-weight:700;line-height:1.25}
footer .pied-yt-abo:hover{background:#fff}

/* Sur mobile, `footer .wrap` passe en colonne avec 16px d'écart — et cette
   rangée porte la classe `wrap`. Chaque lien prenait donc une ligne à lui, et
   les cinq liens plus leur intitulé occupaient six lignes, soit près de 200px
   pour une note de bas de page.
   On revient à une rangée qui se replie, centrée. Depuis le 10/10/2026 elle ne
   porte plus que l'encart YouTube. */
@media(max-width:760px){
  footer .pied-ref{
    flex-flow:row wrap;align-items:center;justify-content:center;
    gap:5px 13px;margin-top:16px;padding-top:12px;padding-bottom:12px;font-size:12px
  }
}
/* Petits telephones (320 px) : le titre ne passe jamais sur deux lignes. */
@media(max-width:360px){
  .pied-yt{gap:8px;padding:7px 6px 7px 10px}
  footer .pied-yt-chaine,footer .pied-yt-chaine:hover{gap:8px}
  .pied-yt-txt b{font-size:12.5px;white-space:nowrap}
  footer .pied-yt-abo,footer .pied-yt-abo:hover{margin-left:2px;padding:5px 9px;font-size:11.5px}
}
/* La reference mesuree, tout en bas : une ligne en petit, sans filet.
   `footer .wrap` en fait une rangee flex (et une colonne sous 760px) : on la
   remet en rangee qui se replie, centree sur mobile comme le reste du pied.
   PETIT, PAS ILLISIBLE (27/09/2026). Les liens etaient en 10,5 px a
   rgba(237,233,245,.3) sur #07050d : 2,31:1, sous le minimum WCAG AA (4,5:1)
   et le motif « liens presque invisibles » des regles anti-spam de Google.
   Desormais 12 px a .55 : 5,39:1 (calcule), toujours plus petits et plus
   pales que les liens du pied au-dessus, donc toujours discrets, mais lus par
   quiconque les regarde. Ces rangees servent les visiteurs qui cherchent le
   mot, pas seulement les moteurs. */
footer .pied-mesure{
  flex-flow:row wrap;align-items:center;gap:2px 12px;margin-top:18px;
  font-size:12px;line-height:1.5
}
footer .pied-mesure span,
footer .pied-mesure a{color:rgba(237,233,245,.55)}
footer .pied-mesure span{letter-spacing:.06em;text-transform:uppercase;font-size:10px}
footer .pied-mesure a:hover{color:var(--gris)}
@media(max-width:760px){
  /* RESSERREES SUR MOBILE (30/09/2026, « sur mobile réduis un peu la taille de
     cette section ») : les quatre rangées prenaient 194px. 11px au lieu de 12,
     intitulés en 9px, interlignes et écarts réduits ; la couleur ne change
     pas, le contraste reste 5,39:1. */
  footer .pied-mesure{justify-content:center;gap:0 8px;margin-top:8px;line-height:1.4}
  footer .pied-mesure span{font-size:9px}
  /* `footer .wrap > a:not(.logo)` (13px) passe devant un simple
     `.pied-mesure > a` : il faut au moins sa specificite. */
  footer .wrap.pied-mesure > a:not(.logo){font-size:11px;padding:0;line-height:1.4}
}

/* ------------------------------------------ le bas de la colonne du hero */
/* Le téléphone fait 693px de haut, le texte 469 : 224px de vide sous la colonne
   de gauche. Le CENTRAGE vertical avait été essayé puis rejeté — le commentaire
   de `.hero .wrap` le raconte : centré, le texte descendait de 103px d'un coup
   et flottait. On descend donc de 48px seulement, ce qui laisse le titre commencer
   près du haut du téléphone, et on comble le reste avec un repère de défilement
   plutôt qu'avec du vide.
   Les deux ne valent qu'au-dessus de 960px : en dessous, le téléphone passe SOUS
   le texte, il n'y a plus de vide à combler et plus rien à annoncer. */
.hero-bas{display:none}
@media(min-width:961px){
  .hero .wrap > div:first-child{margin-top:48px}

  .hero-bas{
    display:inline-flex;align-items:center;gap:10px;margin-top:38px;
    color:var(--gris-2);text-decoration:none;font-size:13px;font-weight:600;
    letter-spacing:.02em;transition:color .2s
  }
  .hero-bas-r{
    display:grid;place-items:center;width:30px;height:30px;flex:0 0 auto;
    border:1px solid var(--trait);border-radius:50%;
    transition:border-color .2s,background .2s,transform .2s
  }
  .hero-bas svg{animation:heroBas 2.4s ease-in-out infinite}
  @keyframes heroBas{
    0%,62%,100%{transform:translateY(0)}
    78%{transform:translateY(3px)}
  }
  .hero-bas:hover{color:var(--creme)}
  .hero-bas:hover .hero-bas-r{
    border-color:var(--lav);background:rgba(150,112,255,.12);transform:translateY(2px)
  }
  .hero-bas:focus-visible{outline:2px solid var(--lav);outline-offset:4px;border-radius:999px}
  @media(prefers-reduced-motion:reduce){
    .hero-bas svg{animation:none}
    .hero-bas:hover .hero-bas-r{transform:none}
  }
}

/* ------------------------------------------- le doigt de la démo du wallet */
/* Deux éléments plutôt qu'un : le parent porte le DÉPLACEMENT, l'enfant porte
   l'APPUI. Sur un seul, la mise à l'échelle de l'appui se composait avec la
   translation et le point partait en biais à chaque touche.
   Le parent n'a pas de dimensions : seule sa translation compte, et l'enfant
   est centré dessus par ses décalages négatifs. Il vit DANS `.mw`, qui est en
   position relative et mesure 923 px de large — donc ces pixels sont ceux du
   canevas, et le scale() du cadre les réduit avec le reste. */
.mw-doigt{
  /* z-index au-dessus du menu (110) et du panneau (120) : le doigt doit se voir
     PENDANT qu'il touche une de leurs entrées. */
  position:absolute;left:0;top:0;width:0;height:0;z-index:200;
  pointer-events:none;opacity:0;
  transition:transform var(--d,.5s) cubic-bezier(.4,0,.2,1),opacity .34s ease
}
.mw-doigt.est-la{opacity:1}
.mw-doigt i{
  /* 18px d'ÉCRAN. Avant, la bulle vivait dans le canevas et ses 46px étaient
     réduits par le scale du cadre — environ 16px à l'écran. Sortie du canevas,
     elle n'est plus mise à l'échelle : les mêmes 46px auraient fait une tache
     trois fois trop grosse. */
  position:absolute;left:-9px;top:-9px;width:18px;height:18px;border-radius:50%;
  background:rgba(255,253,248,.2);
  box-shadow:inset 0 0 0 1.6px rgba(255,253,248,.62), 0 0 12px rgba(255,253,248,.18);
  transition:transform .19s ease,background .19s ease
}
.mw-doigt.est-pose i{transform:scale(.62);background:rgba(255,253,248,.5)}
/* Le menu du « + » n'est plus ecrit ici. Il fait partie de la maquette
   (mockup.css), en pixels de canevas, et la demonstration guidee l'ouvre en
   posant `data-fab` sur `.mw` — le meme attribut que le studio et /demo.
   `--brand` disparait avec lui : il ne peignait que ses pastilles, et la
   maquette prend desormais `--mw-accent`, c'est-a-dire le lavande du produit.
   C'est la fin d'un pont qui laissait la couleur de la PAGE entrer dans
   l'ecran du telephone — il donnait deja deux lavandes differentes a deux
   centimetres l'une de l'autre, #ab9ff2 pour le menu et #b3a5f8 pour le « + »
   du dock juste en dessous. */

/* ------------------------------ extrait des réglages, pour la démonstration */
/* Dimensions en pixels d'ÉCRAN, comme le menu du « + » : ce bloc vit dans le
   cadre du téléphone, pas dans le canevas de 923 px. Il ne cherche pas à être
   le panneau du studio — il en a l'allure, ce qui suffit à une animation vue
   à 330 px de large. */
.dem-reg{
  /* `.mw` porte déjà `text-align:left` pour la même raison : le centrage des
     sections descend par héritage jusque dans l'écran du téléphone. Ces deux
     surfaces vivent dans le CADRE, hors du canevas, donc la protection de `.mw`
     ne les couvrait pas — les étiquettes et les valeurs arrivaient centrées,
     là où le studio les aligne à gauche. */
  text-align:left;
  position:absolute;inset:0;z-index:120;display:flex;flex-direction:column;
  background:#0d0b14;color:#f2effa;
  font:400 12px/1.45 -apple-system,BlinkMacSystemFont,"SF Pro Text",Helvetica,Arial,sans-serif;
  transform:translateY(100%);visibility:hidden;
  transition:transform .34s cubic-bezier(.32,.72,0,1),visibility 0s .34s;
}
.device .dem-reg.est-ouvert{transform:none;visibility:visible;transition:transform .34s cubic-bezier(.32,.72,0,1),visibility 0s}
.dem-tete{
  position:relative;flex:0 0 auto;display:flex;align-items:center;
  padding:22px 16px 12px;border-bottom:1px solid #241f36
}
.dem-poi{position:absolute;left:50%;top:8px;transform:translateX(-50%);width:30px;height:4px;border-radius:99px;background:#2f2947}
.dem-tete b{font-size:16px;font-weight:800;letter-spacing:-.3px}
.dem-x{
  margin-left:auto;display:grid;place-items:center;width:26px;height:26px;
  border-radius:50%;background:#1a1626;color:#b9b1cf;font-size:11px
}
.dem-corps{flex:1 1 auto;overflow-y:auto;scrollbar-width:none;padding:12px 14px 0}
.dem-corps::-webkit-scrollbar{display:none}
.dem-bloc{
  display:flex;align-items:center;border:1px solid #241f36;border-radius:12px;
  background:#141020;padding:10px 12px;margin-bottom:8px;font-weight:650;font-size:12.5px
}
.dem-bloc i{margin-left:auto;width:6px;height:6px;border-right:1.6px solid #6d6684;border-bottom:1.6px solid #6d6684;transform:rotate(45deg) translateY(-1px)}
.dem-bloc--on i{transform:rotate(-135deg) translateY(-1px)}
.dem-champ{margin:2px 0 10px}
.dem-champ label,.dem-carte label{display:block;color:#8d85a6;font-size:10.5px;margin:8px 0 4px}
.dem-in{
  border:1px solid #241f36;border-radius:10px;background:#141020;
  padding:8px 10px;font-size:12.5px;color:#f2effa;min-height:32px;
  display:flex;align-items:center
}
.dem-in--sel::after{content:"";margin-left:auto;width:5px;height:5px;border-right:1.5px solid #6d6684;border-bottom:1.5px solid #6d6684;transform:rotate(45deg)}
.dem-in--qte{border-color:#5b3fb8;box-shadow:0 0 0 2px rgba(150,112,255,.14)}
.dem-caret{width:1.5px;height:14px;background:#9670ff;margin-left:1px;animation:dem-clign 1s steps(2) infinite}
@keyframes dem-clign{0%,50%{opacity:1}51%,100%{opacity:0}}
.dem-carte{border:1px solid #241f36;border-radius:12px;background:#141020;padding:10px 12px;margin-bottom:10px}
.dem-carte--pale{opacity:.45}
.dem-carte-t{font-weight:800;font-size:13px;letter-spacing:-.2px}
.dem-prix{font-size:12px;color:#f2effa}
.dem-barre{
  flex:0 0 auto;display:flex;justify-content:flex-end;align-items:center;
  padding:8px 14px calc(10px + env(safe-area-inset-bottom));
  border-top:1px solid #241f36;background:#0d0b14
}
.dem-ok{
  display:grid;place-items:center;width:34px;height:34px;border-radius:50%;
  background:var(--lav);color:#100d1b;font-size:15px;font-weight:800;
  transition:transform .18s ease
}
.dem-ok.est-pris{transform:scale(.88)}


/* --------------------------------------------------- le second palier, à vie */
/* En fin de feuille, comme toutes les règles ajoutées après coup dans ce
   fichier : les @media empilés plus haut gagneraient à spécificité égale. */
.plan-vie{
  margin:10px auto 0;padding:7px 12px;
  border:1px solid rgba(150,112,255,.3);border-radius:999px;
  background:rgba(150,112,255,.12);
  color:#c3bdd6;font-size:13px;line-height:1.5;text-align:center;
  width:fit-content;max-width:100%;
}
.plan-vie b{color:var(--creme);font-weight:700}
/* Un cran plus visible le 11/10/2026 (l'opérateur : « rends le un petit peu
   plus visible ») : texte, bordure et fond lavande plus nets, sans lueur ni
   aplat plein, pour rester une précision et pas un second bouton. */
/* Plus discrète que la pastille du dessus : elle la précise, elle ne fait pas
   une troisième offre. */
.plan-crypto{margin:7px 0 0;text-align:center;color:var(--gris-2);font-size:12.5px;line-height:1.5}
/* Les deux sont des liens depuis le 05/10/2026 (voir la carte) : en bloc pour
   garder le centrage de la `<div>` qu'ils étaient, et le survol les éclaircit
   à peine — l'allure reste celle d'une précision, pas d'un second bouton. */
a.plan-vie,a.plan-crypto{display:block;transition:color .15s,border-color .15s,background-color .15s}
a.plan-crypto{width:fit-content;margin-left:auto;margin-right:auto}
a.plan-vie:hover{border-color:rgba(150,112,255,.5);background:rgba(150,112,255,.17);color:var(--creme)}
a.plan-crypto:hover{color:var(--gris)}


/* ============================================================== la respiration
   Une SEULE propriété animée : `opacity`, qui se compose sur le GPU. Aucun
   `filter`, aucune box-shadow animée, aucun redimensionnement — la règle que la
   page se donne ailleurs (voir le bloc des vignettes) tient ici aussi.

   9 s et 11 s, amplitude .18 : à ce rythme et à cette amplitude on ne voit pas
   une animation, on voit une surface vivante. Deux durées PREMIÈRES l'une par
   rapport à l'autre, pour que les deux halos ne se synchronisent jamais — deux
   lueurs qui pulsent à l'unisson se lisent comme un clignotant.

   La bascule est en `no-preference`, pas en `reduce` : par défaut on n'anime
   rien, on n'anime QUE si le système a dit qu'il acceptait le mouvement.
   ========================================================================== */
@keyframes souffle{0%,100%{opacity:.82}50%{opacity:1}}
@media (prefers-reduced-motion: no-preference){
  .demo::before{animation:souffle 9s ease-in-out infinite}
  .final .box::after{animation:souffle 11s ease-in-out infinite}
}

/* ------------------------------------------------ la pastille « tout inclus »
   UN REFLET QUI PASSE, ET NON UNE TROISIEME RESPIRATION. `souffle` tient deja
   deux surfaces de la page ; une pastille qui respirerait au meme rythme
   ajouterait un troisieme battement dans le meme ecran, et trois battements
   concurrents ne se lisent plus comme un rythme mais comme du bruit. Un reflet
   qui traverse est un autre geste : il dit « regarde ici » une fois, puis se
   tait.

   LE RAPPORT FAIT TOUT. Le balayage occupe 22 % du cycle de sept secondes, soit
   1,5 s ; les cinq secondes et demie restantes sont une pause, reflet hors
   champ. C'est ce rapport qui separe un accent d'une enseigne lumineuse — un
   reflet qui repasse toutes les deux secondes serait le second.

   `overflow:hidden` sur un rayon de 999px suffit a tailler le reflet en
   pastille : aucun masque, aucun filtre, rien qui coute une image sur telephone.
   Et `translate` plutot que `transform`, pour que le jour ou cette pastille
   prendra un survol, les deux ne se marchent pas dessus. */
.plan .tag{position:relative;overflow:hidden}
@keyframes tag-reflet{0%,78%{translate:-135% 0}100%{translate:135% 0}}
@media (prefers-reduced-motion: no-preference){
  .plan .tag::after{
    content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(104deg,transparent 40%,rgba(79,212,124,.3) 50%,transparent 60%);
    animation:tag-reflet 7s ease-in-out infinite
  }
}
/* Le rythme de la page est une alternance : un fond « voile » ne touche jamais
   un autre fond « voile », il y a toujours un fond « sol » entre les deux.
   Ces trois-la etaient poses en attribut `style`, ce qui les rendait
   insurchargeables sans `!important` — or c'est exactement ce dont le bloc
   suivant a besoin. Ils passent donc dans la feuille. */
#vitrine,#pricing,#faq{background:var(--lav-voile)}

/* ================================================= l'air entre les sections, sur mobile
   `section{padding:92px 0}` n'avait AUCUNE surcharge mobile — c'était la seule
   grande valeur de la feuille dans ce cas. Mesuré sur un 390x844 : sept sections
   à 92/92, donc 184 px de vide à chaque jointure, soit 22 % de la hauteur de
   l'écran sans rien dedans, et 1404 px de padding cumulé sur une page de 9348 —
   15 % de la page. Sur un grand écran ces 92 px respirent, parce que la mise en
   page est large et que l'oeil a de quoi se poser à côté. Sur un téléphone il
   n'y a qu'une colonne : le vide occupe toute la largeur et se lit comme une fin
   de page, pas comme une respiration.

   56 px, soit 112 px à la jointure. Le repère est la rythmique interne de la
   page, qui tourne autour de 20 px (`.step` 24, `.faq summary` 21, `.tar-rang`
   17) : une frontière de section doit se lire nettement plus large qu'une ligne
   interne, et 56 contre 21 fait ce rapport de 2,7. En descendant plus bas les
   sections commenceraient à se toucher.

   Le bas du hero suit la même logique : 82 px le séparaient de la bande, alors
   que son haut avait déjà été ramené à 60 sur cette largeur. Il descend à 52.
   `.bande` (24) et le pied (34/30) sont déjà réduits ailleurs, on n'y touche pas. */
@media(max-width:760px){
  section{padding:56px 0}
  .final{padding:56px 0 60px}
  .hero .wrap{padding-bottom:52px}
}

/* ================================================ l'appel final, en bas, sur mobile
   Sur grand écran l'ordre est : tarifs → appel final → FAQ. L'appel arrive
   pendant qu'on décide, la FAQ lève les dernières objections juste après, et
   l'œil fait l'aller-retour sans effort parce que tout tient dans un écran et
   demi.

   Sur un téléphone il n'y a pas d'aller-retour : on descend, et ce qu'on voit
   en dernier est ce sur quoi on agit. Un appel à l'action suivi de mille pixels
   de questions se lit comme une page qui n'en finit pas. On le renvoie donc
   APRÈS la FAQ — répondre, puis demander.

   Fait par `order` et non en déplaçant le balisage : le DOM reste l'ordre de
   lecture et l'ordre déclaré aux moteurs, identique sur les deux affichages.
   `order` exige un parent en flex ou en grid, et ici le parent est `body`.
   D'où les précautions :
     - `grid-template-columns:minmax(0,1fr)` — un item de grille vaut
       `min-width:auto` par défaut, ce qui l'empêche de rétrécir sous son
       contenu ; le `minmax(0,…)` lève ce plancher et évite un débordement
       horizontal sur les sections qui portent un tableau ou un rail ;
     - `align-content:start` — `body` a `min-height:100%`, sans quoi les rangées
       se répartiraient l'espace restant sur une page courte ;
     - `order:2` sur le pied : sans lui, `order:1` ferait passer l'appel APRÈS
       le pied, puisque tout le reste est à 0.
   Les menus (`.menu-voile`, `.menu-mob`) sont en `position:fixed` : ils ne sont
   pas des items de grille et ne bougent pas. Le `<header>` reste collant — un
   item de grille peut l'être. Mesuré à 320, 390 et 760 px : header, hero,
   bande, tarifs et pied sont au pixel près là où ils étaient. */
@media(max-width:760px){
  body{display:grid;grid-template-columns:minmax(0,1fr);align-content:start}
  body > .final{order:1}
  body > footer{order:2}
  /* Les deux echangent leur fond en meme temps qu'elles echangent leur place,
     sinon les tarifs et la FAQ — deux « voiles » — se retrouveraient collees et
     la page perdrait sa respiration a cet endroit precis. Une fois echangees,
     l'alternance est intacte : mobile(sol) > tarifs(voile) > FAQ(sol) >
     appel(voile) > pied. L'appel final y gagne meme une surface legerement
     relevee, ce qui va bien a un bloc de cloture. */
  #faq{background:var(--lav-pale)}
  .final{background:var(--lav-voile)}
}

/* ==================================================== programme d'affiliation
   POSÉ EN FIN DE FEUILLE, et c'est obligatoire : la section réemploie `.head`,
   `.steps`, `.step` et `.tar-rang`, tous réglés plus haut ET repris dans des
   @media situés après eux. À spécificité égale c'est la dernière règle qui
   gagne — une surcharge écrite au milieu du fichier serait silencieusement
   annulée par un @media plus bas.

   AUCUN `padding` SUR `#affiliate`. Un sélecteur d'id (1-0-0) battrait
   `section{padding:92px 0}` (0-0-1) à TOUTES les largeurs, y compris sous le
   @media 760px qui ramène les sections à 56 px — la section serait la seule de
   la page à garder 92 px de vide sur un téléphone. L'espacement vient donc de
   `section`, comme partout ailleurs.

   LE FOND EST UNE DALLE PROPRE, ni « sol » ni « voilé ». #pricing, juste
   au-dessus, est voilé : deux dalles voilées qui se touchent effacent la
   frontière entre elles. La dalle s'allume par le haut, se sépare de #pricing
   par un filet, et se referme sur --lav-voile.
   ORDRE DES SECTIONS, à relire quand on en déplace une :
     bureau  #mobile(sol) #vitrine(voilé) #how(sol) #pricing(voilé)
             #affiliate(dalle) .final(sol) #faq(voilé)
     mobile  … #pricing(voilé) #affiliate(dalle) #faq(sol) .final(voilé) pied
   — sous 760px `body` devient une grille et `.final` remonte en `order:1` ;
   #faq et .final échangent alors leur fond (plus bas dans cette feuille), ce
   qui reste indispensable ICI pour une raison nouvelle : la dalle se referme
   sur --lav-voile, exactement la couleur du voile de #faq. Sans cet échange,
   deux #100d1b se toucheraient bord à bord et la frontière disparaîtrait. */
#affiliate{
  border-top:1px solid var(--trait);
  background:
    radial-gradient(120% 66% at 50% 0%, rgba(171,159,242,.13), transparent 62%),
    linear-gradient(180deg,#110e20,#0c0917 46%,var(--lav-voile))
}
/* TEST DE PRIX, cellules à 29 $/mois : le titre y dit « Three referrals »,
   plus long que « Two », et à 1280 px « ahead. » tombait SEUL sur une
   troisième ligne. Lignes équilibrées dans ces cellules-là seulement : le
   témoin (19 $, et toute page sans bloc de tête) garde sa mise en page au
   pixel près (spec prix_v1, étape 5). Sans `text-wrap` (Safari < 17.5), le
   titre retombe sur la coupure d'avant, rien de pire. */
html[data-px-m="29"] #affiliate .head h2{text-wrap:balance}

.aff-duo{
  display:grid;gap:52px;align-items:center;
  /* minmax(0,…) et pas 1fr : une piste de grille prend par défaut la largeur
     MINIMALE de son contenu comme plancher, et l'adresse en <code> non sécable
     ferait déborder la colonne au lieu de la comprimer. */
  grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr)
}

/* ------------------------------------------------------------- la facture
   Même traitement que la carte de tarif — deux couches, un filet clair sur
   l'arête haute. Les deux blocs qui parlent d'argent sur cette page se
   ressemblent, ce n'est pas un hasard : c'est la même question posée deux
   fois, « combien ça me coûte », et la seconde y répond « rien ». */
.aff-compte{
  position:relative;overflow:hidden;
  background:
    radial-gradient(130% 68% at 50% -12%, rgba(171,159,242,.13), transparent 60%),
    linear-gradient(165deg,#1b1533,#120f1f);
  border:1px solid rgba(150,112,255,.34);
  border-radius:26px;padding:28px 28px 26px;
  box-shadow:0 26px 60px -44px rgba(53,27,126,.9)
}
.aff-compte::before{content:"";position:absolute;inset:0 0 auto;height:1px;
  background:linear-gradient(90deg,transparent,rgba(188,163,255,.5),transparent)}
.aff-compte > *{position:relative}

/* ------------------------------------------------------- la demonstration
   Elle a remplace trois paliers ecrits en dur. L'arithmetique n'a pas change —
   ~10,55 $ par filleul contre 19 $ d'abonnement — mais elle se manipule.

   `--part` EST DECLAREE, et c'est la meme lecon qu'au mois dernier sur la barre
   d'action de la maquette : une propriete personnalisee non declaree accepte
   n'importe quelle chaine, et une valeur qui n'est pas un pourcentage rendrait
   INVALIDE AU CALCUL la declaration qui la consomme. `width` retomberait a
   `auto`, donc a la largeur du contenu — une barre pleine annoncant un gain
   qu'on n'a pas. Declaree, une valeur mal formee est ignoree et c'est zero qui
   s'applique : le pire cas est une barre vide, jamais une barre menteuse. */
@property --part {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

.aff-tete{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding-bottom:19px;margin-bottom:22px;border-bottom:1px solid var(--trait)}
/* --gris et non --gris-2 : #6d6684 sur la dalle de la carte tombe sous le seuil
   de contraste pour une capitale de 12px, et ce libelle n'est pas decoratif. */
.aff-tete span{font-size:12px;font-weight:800;letter-spacing:2px;
  text-transform:uppercase;color:var(--gris)}
.aff-tete .aff-n{font-size:30px;font-weight:800;color:var(--creme);
  font-variant-numeric:tabular-nums;letter-spacing:-.03em;line-height:1}

.aff-corps{display:grid;gap:26px}

/* ----------------------------------------------------------- les personnes
   Six boutons, pas un curseur : au doigt on VISE un groupe, on ne glisse pas
   vers une valeur. `flex:1` pour qu'ils remplissent la carte a toutes les
   largeurs, et une hauteur qui reste au-dessus de la cible tactile de 44px
   recommandee par Apple comme par Google.

   UN GROUPE, ET NON UNE PERSONNE. Chaque bouton vaut dix filleuls depuis le
   20/09/2026 : dessiner une silhouette seule disait le contraire de ce que le
   bouton fait. Trois silhouettes — deux en retrait, une devant — se lisent comme
   « plusieurs » sans qu'on ait a les compter, ce qui serait faux aussi. Et le
   « +10 » sous chacune dit le pas en toutes lettres, la ou il ne se devinait
   qu'en cliquant.

   DEUX LIGNES DANS LE BOUTON, donc `grid-template-rows` et non `place-items` :
   le dessin et son libelle sont deux rangees, centrees ensemble. */
.aff-gens{display:flex;gap:10px}
.aff-gen{
  flex:1 1 0;min-width:0;height:56px;border-radius:14px;cursor:pointer;
  display:grid;grid-template-rows:auto auto;gap:1px;
  align-content:center;justify-items:center;
  background:rgba(255,255,255,.04);border:1px solid var(--trait);
  color:var(--gris-2);padding:0;
  transition:background .26s,border-color .26s,color .26s,scale .26s cubic-bezier(.22,.61,.36,1)
}
.aff-gen svg{fill:currentColor;display:block}
/* Les deux silhouettes du fond sont en retrait : l'oeil lit d'abord celle de
   devant, puis comprend qu'elles sont plusieurs. A opacite egale, les trois se
   confondaient en une tache. */
.aff-gen .aff-loin{opacity:.4}
.aff-gen.est-on .aff-loin{opacity:.6}
/* Le pas, ecrit sous chaque bouton. Tabulaire pour que les six « +10 » aient
   exactement la meme largeur : a chasse variable, la rangee respire. */
.aff-gen-n{font-size:10px;font-weight:800;line-height:1;letter-spacing:.01em;
  font-variant-numeric:tabular-nums}
.aff-gen.est-on{
  background:rgba(150,112,255,.16);border-color:rgba(150,112,255,.42);
  color:var(--lav-2)
}
/* Le survol ne PREVISUALISE pas : il dit seulement que c'est cliquable. Une
   previsualisation au survol ferait bouger les chiffres sans qu'on ait rien
   demande, et la moitie du public est au doigt, ou le survol n'existe pas. */
@media (hover:hover){ .aff-gen:hover{border-color:rgba(150,112,255,.5);color:var(--lav-2)} }
.aff-gen:active{scale:.92}
.aff-gen:focus-visible{outline:2px solid var(--lav);outline-offset:3px}
/* La derniere personne allumee se detache : c'est elle qu'on vient de poser. */
.aff-gen.est-on.est-tete{background:rgba(150,112,255,.3);border-color:var(--lav)}

/* ------------------------------------------------------------- la jauge */
.aff-somme{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:16px}
.aff-montant{font-size:34px;font-weight:800;color:var(--creme);
  font-variant-numeric:tabular-nums;letter-spacing:-.035em;
  transition:color .3s}
/* `>` : le montant (dans <output>) porte une enveloppe <span> du test de prix,
   qui prendrait sinon la taille du libelle. */
.aff-somme > span{font-size:14px;color:var(--gris)}

.aff-piste{
  position:relative;height:16px;border-radius:999px;
  background:rgba(255,255,255,.05);box-shadow:inset 0 0 0 1px var(--trait);
  margin-bottom:38px
}
.aff-barre{
  height:100%;width:var(--part,0%);border-radius:999px;
  background:linear-gradient(90deg,var(--lav-3),var(--lav));
  box-shadow:0 0 20px -7px var(--halo-fort);
  transition:width .58s cubic-bezier(.22,.61,.36,1),background .32s,box-shadow .32s
}
/* LE REPERE EST LA VERITE DE CETTE CARTE. La barre dit ce qui REVIENT, le trait
   dit ce qu'on PAIE, et les deux ne se confondent jamais. Sa place = le prix
   mensuel DU LECTEUR sur le maximum de la piste (MAX x PAS filleuls au
   plancher de commission) : 3,17 % = 1900 / 60000 au prix de controle, 4,83 %
   a 29 $. Elle n'est plus ecrite ici : `--px-seuil` est pose sur <html> par le
   bloc de tete du test de prix (spec prix_v1, §3.2), AVANT le premier
   affichage, depuis le meme calcul que tools/tarifs.py. Le repli 3,17 % sert
   sans bloc de tete (le controle). L'ancienne valeur, 2,78 %, etait fausse :
   elle datait d'un plancher a 11,40 $ (1900 / 68400), pas de celui du script.
   ⚠️ LE CALCUL SUIT LES CONSTANTES `PAS` ET `MAX` DU SCRIPT : tarifs.py les
   relit (invariant 5) et refuse un ecart avec affilie.calc_pas/calc_boutons.
   Mince et tout a gauche, c'est voulu : a cette echelle, ce qu'on paie EST ce
   petit trait-la a cote de ce qui rentre. */
.aff-seuil{
  position:absolute;left:var(--px-seuil,3.17%);top:-7px;bottom:-7px;width:2px;pointer-events:none;
  background:repeating-linear-gradient(180deg,var(--gris-2) 0 4px,transparent 4px 8px);
  transition:background .32s
}
/* Le libelle est cale a GAUCHE et non centre sur le trait : a 3 ou 5 % de la
   piste, un `translateX(-50%)` le ferait sortir de la carte par la gauche.
   ENFANT DIRECT (`>`) : le prix du libelle est une enveloppe de test de prix
   (des <span> dans le <b>), qu'un `.aff-seuil span` sortirait du flux. */
.aff-seuil > span{
  position:absolute;top:calc(100% + 9px);left:-2px;
  white-space:nowrap;font-size:12.5px;color:var(--gris-2);line-height:1
}
.aff-seuil b{color:var(--gris);font-weight:700}

.aff-dit{font-size:15.5px;color:var(--gris);line-height:1.5;margin:0}
.aff-dit b{color:var(--creme);font-weight:700;font-variant-numeric:tabular-nums}

/* ------------------------------------------------- l'etat « on est devant »
   Le vert de cette page ne decore pas, il dit « ce qu'on obtient ». Il ne tombe
   que lorsque ce qui revient a reellement depasse ce qu'on paie, et il tombe
   alors sur TOUT ce qui porte ce sens a la fois — le montant, la barre, la
   phrase. Un seul etat, lu d'un coup d'oeil. */
.aff-compte.est-devant .aff-montant{color:var(--vert)}
.aff-compte.est-devant .aff-barre{
  background:linear-gradient(90deg,rgba(79,212,124,.72),var(--vert));
  box-shadow:0 0 22px -7px var(--vert)}
.aff-compte.est-devant .aff-dit b{color:var(--vert)}
.aff-compte.est-devant .aff-seuil{
  background:repeating-linear-gradient(180deg,var(--vert-trait) 0 4px,transparent 4px 8px)}

/* LE FRANCHISSEMENT, une fois. Pose 900 ms au moment ou la barre passe le
   repere, jamais en boucle : le but est de faire remarquer l'instant, pas de
   fabriquer un clignotant. */
.aff-compte.aff-saute .aff-montant{animation:aff-bond .62s cubic-bezier(.22,.61,.36,1) 1}
.aff-compte.aff-saute .aff-seuil::after{
  content:"";position:absolute;inset:-4px -7px;border-radius:6px;
  background:var(--vert);animation:aff-eclair .62s ease-out 1 both}
@keyframes aff-bond{0%{scale:1}38%{scale:1.13}100%{scale:1}}
@keyframes aff-eclair{from{opacity:.5}to{opacity:0}}

/* Pose d'une valeur SANS animation — le retour a zero avant la demonstration.
   Meme geste que le filet des entrees : on coupe, on force le calcul, on rend. */
.aff-compte.aff-froid-carte .aff-barre,
.aff-compte.aff-froid-carte .aff-montant,
.aff-compte.aff-froid-carte .aff-gen{transition:none}

@media (prefers-reduced-motion: reduce){
  .aff-barre,.aff-gen,.aff-montant,.aff-seuil{transition:none}
  .aff-compte.aff-saute .aff-montant{animation:none}
  .aff-compte.aff-saute .aff-seuil::after{display:none}
}
@media print{
  .aff-gens{display:none}
  .aff-compte.aff-saute .aff-seuil::after{display:none}
}

/* L'adresse du lien, en filet de texte et non en <code> pleine largeur : elle
   sert d'exemple, pas de chose à copier.
   PRÉFIXÉES PAR `.tar-rang`, les deux règles qui suivent, et ce n'est pas du
   décor : `.tar-rang span` et `.tar-rang i` valent DEUX sélecteurs et battaient
   `.aff-lien` / `.aff-jours` qui n'en valent qu'un. Mesuré sur la page avant
   correction : l'adresse sortait en 14,5px grise et le « 60 » en 16px. */
.tar-rang .aff-lien{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:13.5px;color:var(--lav-2);white-space:nowrap;display:inline}
/* Le seul pictogramme chiffré de la rangée : 16px, la taille des glyphes
   voisins, rendrait « 60 » plus large que la boîte de 38px. */
.tar-rang .aff-jours{font-size:13.5px;font-weight:800;letter-spacing:-.02em}

.aff-pied{margin:38px auto 0;max-width:64ch;text-align:center;
  color:var(--gris);font-size:14.5px;line-height:1.62}
.aff-pied a{color:var(--lav-2);text-decoration:none;
  border-bottom:1px solid rgba(188,163,255,.34);white-space:nowrap}
.aff-pied a:hover{color:var(--creme);border-bottom-color:var(--lav)}
.aff-pied a:focus-visible{outline:2px solid var(--lav);outline-offset:3px;border-radius:3px}

@media(max-width:900px){
  .aff-duo{grid-template-columns:minmax(0,1fr);gap:34px}
}
@media(max-width:620px){
  .aff-compte{padding:22px 20px 20px;border-radius:22px}
  .aff-tete .aff-n{font-size:26px}
  .aff-montant{font-size:29px}
  /* Six cibles tactiles sur 335px de large : 45px chacune en largeur, la cote
     plancher d'Apple comme de Google, et 7px d'ecart. En dessous on toucherait le
     voisin. La hauteur reste bien au-dessus de 44 depuis que le libelle est la. */
  .aff-gens{gap:7px}
  .aff-gen{height:50px;border-radius:12px}
  .aff-gen svg{width:21px;height:21px}
  .aff-gen-n{font-size:9.5px}
  .tar-rang .aff-lien{white-space:normal}
}

/* ------------------------------------------------- l'entrée de la section
   Même moteur que les trois étapes de #how — un seul script, deux groupes —
   mais ses propres classes, parce que l'état caché ne porte pas sur les mêmes
   surfaces.

   L'ÉTAT VISIBLE EST LE DÉFAUT CSS. Rien n'est masqué tant que le script n'a
   pas posé `aff-attente` sur <html> : sans JavaScript, sur un moteur qui
   échoue, ou à l'impression, tout est simplement là. C'est la règle inverse qui
   a déjà coûté trois cartes blanches sur un Cmd+P.

   SIX LIGNES ET NON TROIS depuis le 20/09/2026. Les trois rangées de droite
   n'entraient pas du tout : la moitié gauche de la section se composait sous
   l'œil pendant que l'autre était posée là depuis toujours, et ce déséquilibre
   se remarquait plus que l'effet lui-même. Elles portent désormais la même
   classe, donc le même moteur les prend — `querySelectorAll` rend les six dans
   l'ordre du document, et chacune garde son propre seuil.

   DEUX SURFACES ANIMÉES PAR LIGNE : la ligne, et la boîte de pictogramme des
   rangées de droite. Le filet `.pose` DOIT citer les deux. C'est exactement la
   faute de la première version du filet de #how, qui ne sauvait que la carte et
   laissait sa pastille figée à mi-course : une ligne à demi habillée est pire
   qu'une ligne qui n'entre pas. Le garde `aSauver()` du script, lui, interroge
   déjà le sous-arbre entier.
   Les trois lignes de gauche sont désormais les trois morceaux de la
   démonstration — les personnes, la jauge, le verdict. */
.aff-pas{transition:opacity .62s cubic-bezier(.22,.61,.36,1),
                    translate .62s cubic-bezier(.22,.61,.36,1)}
.aff-pas i{transition:scale .62s cubic-bezier(.22,.61,.36,1)}
html.aff-attente .aff-pas:not(.vu){opacity:0;translate:0 20px}
html.aff-attente .aff-pas:not(.vu) i{scale:.72}

/* LE DÉCALAGE, PAS L'AMPLITUDE. Sur un grand écran les lignes d'une colonne
   franchissent leur seuil dans la même image : sans décalage elles entreraient
   ensemble, ce qui ne se lit pas comme une cascade mais comme un fondu. 70 ms
   suffisent à faire lire l'ordre. Sur téléphone elles arrivent déjà l'une après
   l'autre par le défilement, et ce délai s'y ajoute sans se voir.
   ⚠️ LE TOTAL RESTE SOUS 900 ms, qui est le premier passage du filet : 620 de
   transition + 140 de délai = 760. Allonger l'un ou l'autre ferait forcer une
   ligne encore légitimement en route, et l'entrée se verrait couper net. */
.aff-pas:nth-child(2),
.aff-pas:nth-child(2) i{transition-delay:.07s}
.aff-pas:nth-child(3),
.aff-pas:nth-child(3) i{transition-delay:.14s}

/* Pose de l'état transitions coupées, puis rendues : voir le script. */
html.aff-froid .aff-pas,
html.aff-froid .aff-pas i{transition:none}
.aff-pas.pose,.aff-pas.pose i{transition:none}

/* L'onde de la pastille du palier qui basculait est partie avec les paliers :
   la bascule se voit desormais sur la jauge, ou la barre franchit le repere du
   19 $, et elle y est bien plus lisible qu'un anneau autour d'un chiffre. */
/* ------------------------------- les rangees d'arguments sous 760px
   `@media(max-width:760px)` pose, ligne 247, `.tar-rang{justify-items:center}`
   et `.tar-rang span{margin:0 auto}`. Ce bloc est ecrit AVANT la regle de base
   de `.tar-rang` : celle-ci le rattrape sur tout ce qu'elle redeclare, mais pas
   sur ces deux-la. #pricing ne l'a jamais vu — ses rangees sont masquees sous
   900px par `.tar-pourquoi{display:none}`. #affiliate, lui, les affiche : entre
   620 et 760px le libelle restait cale a gauche pendant que sa description se
   centrait sous lui, decalee d'une dizaine de pixels. On rend la piste au texte
   et on ancre la mesure de 40ch a gauche. Mesure : `<b>` et `<span>` retombent
   au meme x a 700 et 760px, rien ne bouge a 375px. */
@media(max-width:760px){
  #affiliate .tar-rang{justify-items:stretch}
  #affiliate .tar-rang span{margin-left:0;margin-right:auto}
}

/* ------------------------------------------------- l'entrée de l'appel final
   Troisieme groupe du meme moteur, apres les trois etapes de #how et les six
   lignes de l'affiliation. Ses propres classes : l'etat cache ne porte pas sur
   les memes surfaces — ici c'est la pastille chiffree qui s'ouvre avec sa ligne.

   L'ETAT VISIBLE EST LE DEFAUT CSS. Rien n'est masque tant que le script n'a pas
   pose `fin-attente` sur <html> : sans JavaScript, sur un moteur qui echoue, ou
   a l'impression, le bloc de cloture est simplement la. Sur le DERNIER appel a
   l'action de la page, c'est la seule regle acceptable.

   HUIT MORCEAUX, SEPT RETARDS : la petite ligne du bas entre AVEC la troisieme
   demarche plutot qu'apres elle. Sans cela elle restait seule visible pendant que
   tout le reste montait — le seul element immobile d'un bloc en mouvement se
   remarque plus que le mouvement lui-meme.

   ⚠️ LE PLUS TARDIF DOIT FINIR AVANT 900 ms, premier passage du filet : 500 de
   transition + 320 de delai = 820. Ce n'est pas le gout qui fixe le pas de la
   cascade, c'est cette borne — un delai de plus et le filet couperait net une
   entree encore legitimement en route. */
.fin-pas{transition:opacity .5s cubic-bezier(.22,.61,.36,1),
                    translate .5s cubic-bezier(.22,.61,.36,1)}
.fin-pas b{transition:scale .5s cubic-bezier(.22,.61,.36,1)}
html.fin-attente .fin-pas:not(.vu){opacity:0;translate:0 16px}
html.fin-attente .fin-pas:not(.vu) b{scale:.6}

/* LE BOUTON GARDE SON SURVOL, et il a fallu l'ecrire. `.fin-pas` et `.btn` ont
   la meme specificite : la derniere ecrite gagne, et `transition` est un
   raccourci — il REMPLACE la liste, il ne s'y ajoute pas. Le bouton principal de
   la page aurait perdu le timing de son survol, sans le moindre symptome au
   chargement. Les deux listes sont donc reunies ici, a deux selecteurs.
   `translate` pour l'entree et `transform` pour le survol : deux proprietes
   INDEPENDANTES, qui ne se marchent jamais dessus. */
.btn.fin-pas{
  transition:opacity .5s cubic-bezier(.22,.61,.36,1),
             translate .5s cubic-bezier(.22,.61,.36,1),
             transform .15s ease, box-shadow .2s, background .15s, border-color .15s
}

.fin-pas[data-d="2"]{transition-delay:.05s}
.fin-pas[data-d="3"]{transition-delay:.10s}
.fin-pas[data-d="4"]{transition-delay:.15s}
.fin-pas[data-d="5"],.fin-pas[data-d="5"] b{transition-delay:.22s}
.fin-pas[data-d="6"],.fin-pas[data-d="6"] b{transition-delay:.27s}
.fin-pas[data-d="7"],.fin-pas[data-d="7"] b,
.fin-pas[data-d="8"]{transition-delay:.32s}

/* Sous 760px les trois demarches passent AVANT le bouton (`order`, plus haut
   dans cette feuille) : la cascade suit l'oeil, pas le document. */
@media(max-width:760px){
  .fin-pas[data-d="4"]{transition-delay:.32s}
  .fin-pas[data-d="5"],.fin-pas[data-d="5"] b{transition-delay:.15s}
  .fin-pas[data-d="6"],.fin-pas[data-d="6"] b{transition-delay:.20s}
  .fin-pas[data-d="7"],.fin-pas[data-d="7"] b{transition-delay:.25s}
  .fin-pas[data-d="8"]{transition-delay:.32s}
}

/* Pose de l'état transitions coupées, puis rendues : voir le script. Ces deux
   regles viennent APRES `.btn.fin-pas` a dessein — a specificite egale c'est la
   derniere qui gagne, et le filet doit pouvoir couper la transition du bouton
   comme celle des autres. */
html.fin-froid .fin-pas,html.fin-froid .fin-pas b{transition:none}
.fin-pas.pose,.fin-pas.pose b{transition:none}

@media (prefers-reduced-motion: reduce){
  html.aff-attente .aff-pas:not(.vu){opacity:1;translate:none}
  html.aff-attente .aff-pas:not(.vu) i{scale:none}
  html.fin-attente .fin-pas:not(.vu){opacity:1;translate:none}
  html.fin-attente .fin-pas:not(.vu) b{scale:none}
}
@media print{
  html.aff-attente .aff-pas:not(.vu){opacity:1;translate:none}
  html.aff-attente .aff-pas:not(.vu) i{scale:none}
  html.fin-attente .fin-pas:not(.vu){opacity:1;translate:none}
  html.fin-attente .fin-pas:not(.vu) b{scale:none}
}

/* ------------------------------------------- les trois démarches, en boucle
   1, 2, 3 se SIGNALENT l'une après l'autre — la pastille rebondit, un anneau
   part de la pilule —, puis la boucle se repose et recommence : c'est un ordre,
   et la boucle le raconte à qui hésite encore devant le bouton.

   LA BOUCLE ANIME L'ACCENT, JAMAIS LA PRÉSENCE (25/09/2026). Elle faisait
   s'effacer les trois démarches ensemble toutes les 5 s, et la troisième
   restait invisible 2 s par cycle : du texte lisible, à côté du dernier bouton
   de la page, qui disparaissait tout seul. Les trois restent désormais
   affichées en permanence, à pleine opacité et à leur place ; seules bougent la
   pastille (`scale`) et un anneau (`box-shadow`), qui ne cachent rien.

   La classe `boucle` n'est posée par le script qu'une fois les trois démarches
   ENTRÉES (classe `vu` du moteur d'entrée), et toutes ensemble : une seule
   horloge pour les trois. Le départ négatif (-2,5 s, la moitié du cycle) la
   prend dans sa phase de repos : poser la classe ne fait rien bouger d'un coup.
   Au repos, sans script, en mouvement réduit ou à l'impression, les trois sont
   simplement là, sans accent. */
.fin-suite.boucle li,
.fin-suite.boucle li b{animation:5s cubic-bezier(.22,.61,.36,1) -2.5s infinite both}
.fin-suite.boucle li:nth-child(1){animation-name:fin-b1}
.fin-suite.boucle li:nth-child(2){animation-name:fin-b2}
.fin-suite.boucle li:nth-child(3){animation-name:fin-b3}
.fin-suite.boucle li:nth-child(1) b{animation-name:fin-n1}
.fin-suite.boucle li:nth-child(2) b{animation-name:fin-n2}
.fin-suite.boucle li:nth-child(3) b{animation-name:fin-n3}
/* L'anneau part d'une ombre d'étalement nul, donc invisible sous la pilule :
   il n'y a aucun saut quand la boucle repart de 0 %. */
@keyframes fin-b1{0%{box-shadow:0 0 0 0 rgba(150,112,255,.5)}
  14%,100%{box-shadow:0 0 0 10px rgba(150,112,255,0)}}
@keyframes fin-b2{0%,12%{box-shadow:0 0 0 0 rgba(150,112,255,.5)}
  26%,100%{box-shadow:0 0 0 10px rgba(150,112,255,0)}}
/* la troisième est l'aboutissement (verte) : son anneau est vert, et plus large */
@keyframes fin-b3{0%,24%{box-shadow:0 0 0 0 rgba(79,212,124,.55)}
  42%,100%{box-shadow:0 0 0 12px rgba(79,212,124,0)}}
@keyframes fin-n1{0%{scale:1}6%{scale:1.22}12%,100%{scale:1}}
@keyframes fin-n2{0%,12%{scale:1}18%{scale:1.22}24%,100%{scale:1}}
@keyframes fin-n3{0%,24%{scale:1}30%{scale:1.22}36%,100%{scale:1}}
@media (prefers-reduced-motion: reduce){
  .fin-suite.boucle li,.fin-suite.boucle li b{animation:none}
}
@media print{
  .fin-suite li,.fin-suite li b{animation:none!important}
}

/* ------------------------------------------- l'entrée des quatre garanties
   Quatrième groupe du même moteur, après #how, #affiliate et l'appel final.
   Ces quatre rangées ne vivent QUE sur grand écran — `.tar-pourquoi` est en
   `display:none` sous 900px — donc ce bloc n'ajoute pas un octet d'animation au
   téléphone, d'où viennent 86 % des visites.

   L'ÉTAT VISIBLE EST LE DÉFAUT CSS : sans JavaScript, à l'impression ou sous
   mouvement réduit, les quatre pictogrammes sont dessinés, entiers, immobiles.

   ⚠️ CHAQUE GESTE FINIT AVANT 850 ms, et ce n'est pas un choix esthétique. Le
   filet du moteur passe à 900 ms et appelle `finish()` sur tout le sous-arbre de
   la ligne : une animation plus longue serait coupée net au milieu. Le pire
   retard est .18 s, la plus longue animation .62 s — 800 ms. */
.tar-pas{transition:opacity .5s cubic-bezier(.22,.61,.36,1),
                    translate .5s cubic-bezier(.22,.61,.36,1)}
html.tar-attente .tar-pas:not(.vu){opacity:0;translate:0 14px}
html.tar-froid .tar-pas{transition:none}
.tar-pas.pose{transition:none}
.tar-pas:nth-child(2){transition-delay:.06s}
.tar-pas:nth-child(3){transition-delay:.12s}
.tar-pas:nth-child(4){transition-delay:.18s}

/* Le trait suit la couleur de la boîte, comme le faisait le glyphe. */
#pricing .tar-rang i .ic{display:block}
/* La rotation porte sur le <svg> entier : `transform-origin` y vaut son centre
   sans avoir à poser `transform-box`, ce que réclame un <path>. */
#pricing .tar-rang i .ic-annule{transform-origin:50% 50%}

/* ---- 1. ANNULER : la flèche fait un tour complet en arrière. C'est le seul
        geste que « cancel » puisse faire — on revient d'où l'on vient. */
.tar-pas.vu .ic-annule{animation:ic-tour .62s cubic-bezier(.34,1.2,.5,1) both}
@keyframes ic-tour{from{rotate:-330deg}to{rotate:0deg}}

/* ---- 2. PRIVÉ : les murs sont déjà là, le TOIT descend se poser dessus. La
        maison se ferme au lieu d'apparaître, et c'est exactement ce que dit la
        ligne — rien ne sort de chez vous. */
.tar-pas.vu .ic-toit{animation:ic-toit .5s cubic-bezier(.22,.61,.36,1) .1s both}
@keyframes ic-toit{from{translate:0 -7px;opacity:0}to{translate:0 0;opacity:1}}

/* ---- 3. SANS LIMITE : le trait parcourt TOUTE la boucle et la referme.
        `pathLength="1"` normalise la longueur du chemin, donc le décalage va
        de 1 à 0 quelle que soit la géométrie : retoucher la courbe ne casse
        plus l'animation. Tiret de 1 et non plus de .55 (05/10/2026, signalé
        par l'opérateur) : le trait de .55 restait figé à mi-boucle à la fin
        du geste, et le pictogramme se lisait « ∽ », un logo cassé. */
.tar-pas.vu .ic-infini path{
  stroke-dasharray:1;
  animation:ic-trace .62s cubic-bezier(.4,0,.35,1) both}
@keyframes ic-trace{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}

/* ---- 4. INCLUS : la barre horizontale se trace, puis la verticale s'ajoute
        par-dessus. Un plus qui se construit, pas un plus qui apparaît. */
.tar-pas.vu .ic-plus path{stroke-dasharray:1;animation:ic-trace .32s ease-out both}
.tar-pas.vu .ic-plus .ic-v{animation-delay:.26s}

@media (prefers-reduced-motion: reduce){
  html.tar-attente .tar-pas:not(.vu){opacity:1;translate:none}
  .tar-pas.vu .ic-annule,
  .tar-pas.vu .ic-toit,
  .tar-pas.vu .ic-infini path,
  .tar-pas.vu .ic-plus path{animation:none}
  .tar-pas.vu .ic-infini path,
  .tar-pas.vu .ic-plus path{stroke-dasharray:none}
}
@media print{
  html.tar-attente .tar-pas:not(.vu){opacity:1;translate:none}
  .tar-pas.vu .ic-annule,
  .tar-pas.vu .ic-toit,
  .tar-pas.vu .ic-infini path,
  .tar-pas.vu .ic-plus path{animation:none}
  .tar-pas.vu .ic-infini path,
  .tar-pas.vu .ic-plus path{stroke-dasharray:none}
}

/* =============================================================================
   CE QUE LA PAGE RÉSERVE AVANT QUE LES SCRIPTS LE REMPLISSENT (25/09/2026)
   -----------------------------------------------------------------------------
   Posé en FIN de feuille à dessein : au milieu, une règle plus bas à
   spécificité égale le reprendrait (la feuille a des @media partout).
   ============================================================================= */

/* LES DEUX ÉCRANS DE MAQUETTE ONT LEUR HAUTEUR DÈS LE PREMIER PIXEL. #demo et
   #apercuApp sont vides dans le HTML, et le module ne les remplit qu'une fois
   mockup.js arrivé ; `fitMockup` pose alors une hauteur de 2000 × l / 923. Sans
   réservation, le téléphone du hero était une barre noire de 20 px, et sur
   téléphone le bouton « Unlock my wallet », le prix et la ligne Stripe étaient
   peints juste sous le texte puis poussés 500 px plus bas — souvent au moment
   où le pouce allait toucher le bouton. Le fond reste celui de l'écran (#000),
   qui est aussi celui du canevas de la maquette.

   ET C'EST CETTE HAUTEUR-CI QUI RESTE, pas celle du script. `fitMockup`
   (assets/mockup.js?v=9ba67629) écrit 2000 × clientWidth / 923 en style en ligne, et
   `clientWidth` est ARRONDI à l'entier : 311 px pour 310,53 px réels sur
   ordinateur (--w 330px), d'où 673,89 px écrits contre 672,87 px réservés, et
   le bouton, le prix et tout ce qui suit le téléphone du hero descendaient
   d'un pixel à l'arrivée du module (0,5 px vers le haut à 375 px de large).
   `height:auto!important` laisse donc le rapport décider, avant comme après
   le script, et aussi quand l'observateur de largeur de mockup.js réécrit la
   hauteur. Le canevas, lui, garde l'échelle arrondie : il dépasse ou manque
   d'au plus 1 px en bas, rogné par `.mw-frame{overflow:hidden}` ou posé sur
   le même noir — invisible, comme l'écart qu'il a déjà en largeur.
   Pas de hauteur minimale de contenu à craindre : `.mw-frame` est en
   `overflow:hidden`, et un conteneur de défilement n'a pas de minimum
   automatique sous `aspect-ratio`. */
#demo,#apercuApp{aspect-ratio:923/2000}
#demo,#apercuApp{height:auto!important}

/* LA RANGÉE DE CLIPS GARDE LA HAUTEUR D'UNE CARTE tant que /api/videos n'a pas
   répondu (`html.vit-attente`, posé par le script de tête, retiré seulement si
   l'appel échoue ou ne répond pas en 8 s, et jamais sous les yeux). Une
   PISTE de grille explicite, et non un min-height : une piste existe même
   vide, et sa hauteur ne dépend que
   de la largeur des colonnes — pas des marges internes de la rangée, qui sont
   redéfinies plus haut dans la feuille. La carte fait 9:16 de sa colonne. */
html.vit-attente .vit-rangee{grid-template-rows:calc(232px * 16 / 9)}
/* En attendant, l'emplacement des cartes se devine à peine : un vide de 400 px
   se lirait comme une section cassée, une rangée de cadres pleins comme une
   bibliothèque vide. Un voile lavande à 6 %, au pas exact des futures cartes
   (colonne + gouttière), sous le même fondu de bord que la rangée. */
html.vit-attente .vit-rangee:empty{
  background:linear-gradient(90deg,rgba(150,112,255,.06) 0 232px,transparent 232px) 0 0/250px 100% repeat-x;
  background-origin:content-box;background-clip:content-box
}
@media(max-width:860px){
  html.vit-attente .vit-rangee{grid-template-rows:calc(196px * 16 / 9)}
  html.vit-attente .vit-rangee:empty{
    background-image:linear-gradient(90deg,rgba(150,112,255,.06) 0 196px,transparent 196px);
    background-size:214px 100%
  }
}
/* ── LES TROIS ETAPES EN BOUCLE (25/09/2026, demande de l'operateur : « fais la
   tourner en boucle »). Toutes les 7 s, tant que la liste est a l'ecran, les
   DECORS de chaque carte rejouent leur arrivee, carte apres carte : la pastille
   se repose avec son rebond, le lisere se retrace, le trait redescend vers la
   suivante. La carte, son titre et son texte ne bougent pas : un contenu qui
   s'efface tout seul est exactement ce que tools/flash_check.py refuse.
   `eteint` ramene les decors a l'etat de depart de l'arrivee (0,35 s) ; quand
   la classe tombe, les transitions d'arrivee — celles de plus haut — les
   rejouent, decalees par carte avec `--dl`. */
.etapes.eteint li .n{scale:.78;transition:transform .22s, scale .35s ease, box-shadow .3s}
.etapes.eteint li::before{transform:scaleX(0);transition:transform .35s ease}
.etapes.eteint li:not(:last-child)::after{transform:translateX(-50%) scaleY(0);transition:transform .3s ease}
.etapes.relance li .n{transition-delay:0s, calc(var(--dl,0s) + .1s), 0s}
.etapes.relance li::before{transition-delay:calc(var(--dl,0s) + .2s)}
.etapes.relance li::after{transition-delay:calc(var(--dl,0s) + .34s)}
@media print{
  .etapes.eteint li .n{scale:none}
  .etapes.eteint li::before{transform:scaleX(1)}
  .etapes.eteint li:not(:last-child)::after{transform:translateX(-50%) scaleY(1)}
}
/* ── GLISSER LA RANGÉE DE CLIPS À LA SOURIS (05/10/2026, demande de
   l'operateur : « en restant appuyé sur un clip on devrait pouvoir défiler »).
   Au doigt, la rangée défile seule ; à la souris, seuls un pavé tactile ou
   Maj + molette la faisaient avancer. La main ouverte dit qu'on peut la saisir,
   pour une souris seulement : le doigt n'a pas de curseur.
   `vit-libre` coupe l'aimantation pendant le geste ET pendant le retour animé
   vers une carte (script de la rangée, en fin de page) : laissée en place
   pendant qu'on écrit `scrollLeft`, elle ramènerait la rangée sur une carte à
   chaque mouvement de la souris, par sauts de 250 px. */
@media (hover:hover) and (pointer:fine){
  .vit-rangee{cursor:grab}
}
.vit-rangee.vit-glisse{cursor:grabbing;-webkit-user-select:none;user-select:none}
.vit-rangee.vit-libre{scroll-snap-type:none}
.vit-glisse .vitre:hover{transform:none}

/* ── LES POINTS FORTS À LA PLACE DU PRIX (12/10/2026, l'opérateur : « les
   points forts mais sur un axe horizontal scrollable pas à la suite »).
   Du texte précédé d'une coche, sans fond ni contour : en pastilles, « ça se
   rapproche trop du style bouton ».
   ORDINATEUR : une ligne, les TROIS premiers seulement (« comme ça et tu
   gardes que les 3 first », sur la capture de la version A), sous les boutons.
   Elle se replie d'elle-même si la colonne est trop étroite (961-1000 px).
   TÉLÉPHONE : les six, sur UNE ligne jamais repliée qui défile au doigt. Elle
   sort de la gouttière du .wrap et touche les deux bords de l'écran : le
   point fort coupé à droite dit qu'il y a une suite ; le rembourrage rend la
   gouttière au premier et au dernier. `justify-self:stretch` et
   `min-width:0` : sinon la grille du haut (`justify-items:center`) lui donne
   sa largeur de contenu, 1 070 px mesurés sur un écran de 390, et rien ne
   défile. Bords fondus courts et à moitié seulement (« réduis le blur »,
   10/10), retirés du côté en butée : `data-bord`, écrit « debut » dans le
   HTML, tenu à jour par le script des rails ; les deux règles de bord sont
   redites ici avec la classe, sinon la déclaration des fondus, posée en fin
   de feuille, gagnerait contre `[data-bord~=…]` de même spécificité. */
.hero-forts{display:flex;flex-wrap:wrap;gap:12px 34px;list-style:none;margin:26px 0 0;padding:0}
.hero-forts li{
  display:inline-flex;align-items:center;gap:9px;white-space:nowrap;
  color:var(--gris);font-size:15px;font-weight:600;line-height:1.4
}
.hero-forts li:nth-child(n+4){display:none}
/* la coche : deux traits, pas un caractère (l'encre d'un glyphe déborde
   différemment sur iOS et macOS, cf. les emoji) */
.hero-forts li::before{
  content:"";flex:0 0 auto;width:10px;height:5.5px;margin-top:-3px;
  border-left:2px solid var(--lav-2);border-bottom:2px solid var(--lav-2);
  transform:rotate(-45deg)
}
@media(min-width:761px){
  .hero .micro{margin-top:22px}
}
@media(max-width:760px){
  .hero .hero-forts{
    --g:22px;--fondu:22px;--f-g:var(--fondu);--f-d:var(--fondu);
    flex-wrap:nowrap;gap:22px;
    justify-self:stretch;min-width:0;
    margin:2px calc(-1 * var(--g)) 0;padding:2px var(--g);scroll-padding:0 var(--g);
    overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;
    -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,.35) 0,#000 var(--f-g),
      #000 calc(100% - var(--f-d)),rgba(0,0,0,.35) 100%);
    mask-image:linear-gradient(90deg,rgba(0,0,0,.35) 0,#000 var(--f-g),
      #000 calc(100% - var(--f-d)),rgba(0,0,0,.35) 100%)
  }
  .hero .hero-forts::-webkit-scrollbar{display:none}
  .hero .hero-forts[data-bord~="debut"]{--f-g:0px}
  .hero .hero-forts[data-bord~="fin"]{--f-d:0px}
  .hero-forts li{flex:0 0 auto;gap:8px;font-size:14px}
  .hero-forts li:nth-child(n+4){display:inline-flex}
  .hero-forts li::before{width:9px;height:5px}
}
@media(max-width:520px){ .hero .hero-forts{--g:16px} }
@media(max-width:380px){ .hero .hero-forts{--g:14px} }
