/* ==========================================================================
   MAQUETTE V2 — page d'accueil (06/10/2026, branche feat/maquette-v2)
   Système : maquettes/maquette-v2/sorties-agents/locus/da-accueil.md
   Mécanismes : …/schierke/mecanismes.md (mesures), …/guts/rapport.md
   (patron « une variable, deux moteurs, la valeur initiale est le repli »).
   La nav et le pied viennent de herite.css (copie exacte de wotg.css) : ici
   on ne change QUE leurs jetons de couleur.
   ========================================================================== */

/* MOUVEMENT FORCÉ (décision du 10/10, appliquée à la base le 11/10) : plus
   aucune garde prefers-reduced-motion dans cette feuille. Les blocs
   « no-preference » sont devenus « @media all » (ou ont perdu la condition),
   les blocs « reduce » sont retirés : la base se comporte comme les
   prototypes, quel que soit le réglage de l'appareil. Seuls restent les
   garde-fous contre les clignotements. Ancienne feuille : git, avant le 11/10. */

/* ---- 1. Jetons ----------------------------------------------------------- */
:root {
  /* La rampe neutre de Locus, R = G = B partout, aucune teinte. */
  --blanc:  #FFFFFF;
  --papier: #F5F5F5;   /* une seule section pleine largeur : les démos */
  --filet:  #E2E2E2;
  --gris:   #767676;   /* 4,54:1 sur blanc : le plancher AA */
  --gris-f: #4D4D4D;   /* texte secondaire confortable : 8,45:1 */
  --encre:  #1A1A1A;
  --noir:   #000000;
  --sur-noir: #A3A3A3; /* 8,33:1 sur noir */

  /* LES JETONS DE LA NAV ET DU PIED (noms historiques de wotg.css = des
     rôles) : passés au noir et blanc. Ombres et biseaux à zéro — pas d'ombre
     douce dans la nouvelle direction. */
  --bg-rgb: 255,255,255;
  --white: var(--noir);          /* le texte « allumé » */
  --dim: var(--gris-f);          /* le texte au repos */
  --faint: var(--gris);
  --hair: rgba(0,0,0,.115);      /* ≈ #E2E2E2 sur blanc */
  --hair-2: rgba(0,0,0,.06);
  --glass: rgba(255,255,255,.78);
  --glass-hover: rgba(0,0,0,.045);
  --nav-hover: rgba(0,0,0,.055);
  --nav-current: rgba(0,0,0,.075);
  --wash-hover-soft: rgba(0,0,0,.04);
  --surface: #FFFFFF;
  --surface-2: var(--papier);
  --surface-overlay: rgba(255,255,255,.97);
  --trait: var(--filet);
  --on-solid: #FFFFFF;
  --shadow-color: transparent;
  --shadow-color-cast: transparent;
  --bevel: transparent;
  --bevel-strong: transparent;
  /* Le halo du champ de recherche tournait sur le spectre : il tourne en gris. */
  --violet: #000000;
  --bleu: #767676;
  --cyan: #000000;
  --mx: .5;
  --my: .5;

  --font-display: "Archivo", -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-body: "Archivo", -apple-system, "Helvetica Neue", Arial, sans-serif;
  --ease: var(--ease-sortie);
  --wrap: 1240px;
  --pad: clamp(18px, 4vw, 56px);

  /* Géométrie : colonne 1080, deux rayons seulement (12 et la pilule). */
  --col: 1080px;
  --rayon: 12px;

  /* LE SYSTÈME COMMUN (revue du 11/10) : une seule source pour la base et
     les prototypes, qui redéclaraient chacun leurs colonnes, rayons, noirs,
     accent et courbes. Toute nouvelle section les consomme au lieu d'en
     inventer. Colonne : calc(var(--col) + 2 * var(--pad)), bord gauche à
     180 px à 1440 ; colonne de lecture centrée : --col-texte. */
  --col-texte: 760px;
  --r-surface: 24px;   /* tuiles, vitrines, cadres, cartes de démo, contact */
  --r-fenetre: 12px;   /* toute fenêtre de navigateur simulée */
  --r-champ: 8px;
  --r-pilule: 999px;
  --noir-surface: #0B0B0B;
  /* L'accent (provisoire, à confirmer par Théo) marque la sélection et
     l'avance (curseur, barre de progression, élément choisi), jamais une
     action. Le vert est réservé à l'état « en ligne ». */
  --accent: #992CFF;
  --accent-sur-noir: #C08AFF;
  --accent-voile: rgba(153, 44, 255, .08);
  --etat-ok: #22C55E;
  /* Deux courbes, trois durées, un pas de cascade. */
  --ease-sortie: cubic-bezier(.16, 1, .3, 1);
  --ease-bascule: cubic-bezier(.65, 0, .35, 1);
  --d-court: .2s;
  --d-moyen: .45s;
  --d-long: .8s;
  --cascade: 60ms;

  /* Titres : variante B (décision de Théo du 06/10), serif choisi par ?titres. */
  --f-titre: "Instrument Serif", "Instrument Serif repli", serif;
  --d1: clamp(50px, 7.5vw, 108px);  --d1-lh: .98; --d1-ls: -.012em;
  --d2: clamp(34px, 4.1vw, 60px);   --d2-lh: 1.04; --d2-ls: -.008em;
  --d3: clamp(24px, 2vw, 30px);     --d3-ls: 0;
  --manif: clamp(32px, 4.1vw, 60px); --manif-lh: 1.12;
  --titre-w: 400;
}
html.t-caslon {
  --f-titre: "Libre Caslon Text", "Libre Caslon repli", Georgia, serif;
  --d1: clamp(42px, 6.11vw, 88px);  --d1-lh: 1.02; --d1-ls: -.01em;
  --d2: clamp(28px, 3.61vw, 52px);  --d2-lh: 1.1;  --d2-ls: -.005em;
  --d3: clamp(21px, 1.81vw, 26px);
  --manif: clamp(26px, 3.3vw, 48px); --manif-lh: 1.22;
}
html.t-archivo {
  --f-titre: "Archivo", -apple-system, "Helvetica Neue", Arial, sans-serif;
  --d1: clamp(40px, 5.83vw, 84px);  --d1-lh: .94; --d1-ls: -.035em;
  --d2: clamp(30px, 3.89vw, 56px);  --d2-lh: 1.04; --d2-ls: -.025em;
  --d3: clamp(19px, 1.53vw, 22px);  --d3-ls: -.01em;
  --manif: clamp(26px, 3.2vw, 46px); --manif-lh: 1.18;
  --titre-w: 900;
}

@font-face { font-family: "Instrument Serif"; font-style: normal; font-weight: 400; font-display: swap;
  src: url(/assets/v2/fonts/instrument-serif-regular.woff2) format("woff2"); }
@font-face { font-family: "Instrument Serif"; font-style: italic; font-weight: 400; font-display: swap;
  src: url(/assets/v2/fonts/instrument-serif-italic.woff2) format("woff2"); }
/* Le repli calé sur Instrument Serif (métriques lues dans le fichier : chasse
   83 % de Times New Roman sur la phrase du hero, ascendante 0,99, descendante
   0,31) : la bascule de police au chargement ne déplace plus le hero. */
@font-face { font-family: "Instrument Serif repli"; src: local("Times New Roman"), local("TimesNewRomanPSMT");
  size-adjust: 83%; ascent-override: 119%; descent-override: 37%; line-gap-override: 0%; }
/* Le repli calé sur Libre Caslon Text (passe 2 : la bascule de police
   donnait un CLS de 0,0002 à 1440). Métriques lues dans le fichier : chasse
   108 % de Georgia sur la phrase du hero, ascendante 0,97, descendante 0,26 ;
   chasse ramenée à 106,5 % après mesure (CLS 0 de 106 à 107 %, > 0 au-delà). */
@font-face { font-family: "Libre Caslon repli"; src: local("Georgia");
  size-adjust: 106.5%; ascent-override: 91%; descent-override: 24.4%; line-gap-override: 0%; }
@font-face { font-family: "Libre Caslon Text"; font-style: normal; font-weight: 400; font-display: swap;
  src: url(/assets/v2/fonts/librecaslontext-400.woff2) format("woff2"); }
@font-face { font-family: "Libre Caslon Text"; font-style: italic; font-weight: 400; font-display: swap;
  src: url(/assets/v2/fonts/librecaslontext-400i.woff2) format("woff2"); }

/* Les trois propriétés pilotées par le scroll. VALEUR INITIALE = LE REPLI :
   un moteur sans animation-timeline (ou le mouvement réduit) voit l'état
   final, lisible. */
@property --p { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --t { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --z { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --v { syntax: "<number>"; inherits: true; initial-value: 1; }

/* ---- 2. Base ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--blanc); color: var(--encre);
  font-family: var(--font-body); font-size: clamp(16px, 1.25vw, 18px); line-height: 1.55;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; }
h1, h2, h3, p, ol, ul { margin: 0; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--noir); outline-offset: 3px; }
.wrap-v2 { width: 100%; max-width: calc(var(--col) + 2 * var(--pad)); margin-inline: auto; padding-inline: var(--pad); }

.d1, .d2, .carte-nom, .etape-t, .manif-p {
  font-family: var(--f-titre); font-weight: var(--titre-w); color: var(--noir);
  text-wrap: balance;
}
html.t-archivo :is(.d1, .d2, .carte-nom, .etape-t, .manif-p) { font-stretch: 125%; }
.d1 { font-size: var(--d1); line-height: var(--d1-lh); letter-spacing: var(--d1-ls); }
.d2 { font-size: var(--d2); line-height: var(--d2-lh); letter-spacing: var(--d2-ls); }
.d1 em, .d2 em { font-style: italic; }
html.t-archivo .d1 em { font-style: normal; }

/* PASSE 6 — LES TITRES DE SECTION AU TÉLÉPHONE (html.p6-titres ;
   ?titres-mobile=actuel rend l'ancien). Mesuré à 390 : H2 28 px contre un
   H1 de 42, H3 21 px : en Caslon fin, ça se fondait dans le corps de texte
   (Théo, 07/10). Sous 720 px : H2 de 40 à 50 px, interligne serré, et UN mot
   en italique par titre pour le rythme : accueil.php donne le titre en clair
   (.t-clair) et une copie avec l'italique (.t-mobile, aria-hidden), montrée
   seulement ici ; au-dessus, la copie n'existe pas à l'écran et le titre
   en clair est rendu comme avant. H3 à 30 px. Le titre de la FAQ n'est pas
   touché : la FAQ reste telle quelle (mission). */
.t-mobile { display: none; }
/* Revue du 11/10 : le titre qui garde son italique (.t-partout, celui des
   démos) le montre aussi au bureau. */
html.p6-titres .t-mobile.t-partout { display: inline; }
html.p6-titres .t-clair.t-partout { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (max-width: 720px) {
  html.p6-titres .d2 { font-size: clamp(40px, 11.6vw, 50px); line-height: 1.02; letter-spacing: -.015em; }   /* Théo, 09/10 : le titre de la FAQ aussi (B) ; il restait à 28 px */
  html.p6-titres .t-mobile { display: inline; }
  html.p6-titres .t-clair { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  html.p6-titres :is(.carte-nom, .etape-t) { font-size: 30px; line-height: 1.05; letter-spacing: -.01em; }
  html.p6-titres .demo-nom { font-size: 30px; line-height: 1.05; letter-spacing: -.01em; }
}

/* Boutons : des pilules (la pilule est l'élément conservé), deux tenues. */
.bt {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 0 26px; border-radius: 999px; border: 1px solid transparent;
  font: 500 15px/1 var(--font-body); text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color .35s var(--ease), color .35s var(--ease), border-color .35s var(--ease);
}
.bt--plein { background: var(--noir); color: var(--blanc); }
.bt--plein:hover { background: #2B2B2B; }
.bt--doux { background: #EDEDED; color: var(--noir); }
.bt--doux:hover { background: var(--filet); }
.bt--blanc { background: var(--blanc); color: var(--noir); }
.bt--blanc:hover { background: #D9D9D9; }

/* ---- 3. Emplacements d'image (tpl/v2/images.php) ------------------------- */
.slot {
  position: relative; overflow: hidden; aspect-ratio: var(--ratio, 1);
  border-radius: var(--rayon); background: var(--papier);
}
.slot img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); }
.slot-note { display: none; }
.slot--vide { background: #E9E9E9; display: grid; place-items: center; }
/* Revue du 11/10 : la note de chantier ne s'affiche plus que pour le
   repérage (?images=gris) ; un emplacement vide reste un aplat, sans texte. */
html.i-gris .slot-note {
  display: block; padding: 6px 10px; font-size: 11px; letter-spacing: .08em; color: var(--gris-f); text-align: center;
}
html.i-gris .slot-note::before { content: attr(data-note); }
html.i-gris .slot { background: #E9E9E9; display: grid; place-items: center; }
html.i-gris .slot img { display: none; }
html.i-nb .slot img { filter: grayscale(1); }

/* ---- 4. Hero ------------------------------------------------------------- */
.hero {
  position: relative; overflow: clip;
  min-height: max(760px, 100svh);
  display: grid; place-items: center;
}
.hero-cadres { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
/* Le curseur (écrit par wotg.js dans --mx/--my, inchangé) pousse chaque cadre
   à l'opposé, d'autant plus qu'il est grand : une profondeur, pas un défilé.
   Aucune parallaxe au scroll (mesuré chez la référence : 1:1). */
.cadre {
  position: absolute; left: var(--x); top: var(--y); width: calc(var(--w) * 1vw);
  translate: calc((.5 - var(--mx)) * var(--k)) calc((.5 - var(--my)) * var(--k));
  transition: translate 1.1s var(--ease);
}
.hero-texte {
  position: relative; z-index: 2; text-align: center;
  padding: 120px var(--pad) 96px; max-width: 980px;
}
.hero-sub { max-width: 30em; margin: 30px auto 0; color: var(--encre); font-size: clamp(16px, 1.25vw, 18px); line-height: 1.5; text-wrap: balance; }
.hero-acts { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 36px; }
@media (max-width: 720px) {
  .hero { min-height: max(700px, 100svh); }
  /* Revue du 11/10 : la rangée du haut se place sur la hauteur d'écran
     (--ym, en % de max(700px, 100svh)), celle du bas s'accroche au bas du
     hero (--bm, en vw). Le texte réserve les deux : en haut, 40vw = la plus
     haute image de la rangée (hero-3, 30vw en 3/4) ; en bas, 52vw = hero-8
     (6vw du bord + 26vw en 9/16). Le hero grandit au lieu de recouvrir. */
  .cadre { left: var(--xm); top: calc(max(700px, 100svh) * var(--ym) / 100); width: calc(var(--wm) * 1vw); translate: none; }
  .cadre--bas { top: auto; bottom: calc(var(--bm) * 1vw); }
  .cadre--bureau { display: none; }
  .hero-texte { padding-block: calc(max(700px, 100svh) * .12 + 40vw + 20px) calc(52vw + 20px); }
  .hero-acts { flex-direction: column; align-items: stretch; max-width: 320px; margin-inline: auto; }
}

/* ---- 5. Manifeste : le texte qui monte en s'allumant (passe 3) ----------- */
/* D'après la référence de Théo, MESURÉE (Conicorn, 1440×900, 07/10) : aucun
   épinglage, le paragraphe suit la page ; l'allumage court du moment où son
   haut est à 74 % de l'écran jusqu'à 13 % (550 px de scroll), lettre par
   lettre ; texte centré ; 120 px de marge. Notre code, pas le leur.

   LA PLAGE D'ALLUMAGE, À RÉGLER ICI (en % de la hauteur d'écran, position
   du HAUT du paragraphe) : --manif-debut (le premier gris s'allume) et
   --manif-fin (la dernière lettre est noire). Défaut 88 → 10 = 78 % de
   l'écran, soit 702 px de scroll à 1440×900 et 658 px à 390×844. Pourquoi
   plus large que la référence (74 → 13) : notre texte compte 213 lettres sur
   7 lignes contre 122 sur 3 ; à 75 → 15 le front traversait une ligne en
   77 px de scroll (183 px chez elle), ce qui redonnait le « ça passe très
   vite ». 75 → 15 reproduit la plage de la référence au pixel près. Plus
   long encore : écarter les deux nombres. v2.js lit les mêmes variables. */
.manif {
  --manif-debut: 88;
  --manif-fin: 10;
  /* La marge reste celle de la passe 3 (135 px à 1440) AU-DESSUS DU
     PARAGRAPHE : le label (16 px + 28 px) se loge dedans. */
  --manif-marge: clamp(96px, 15vh, 140px);
  --label-h: 44px;
  background: var(--blanc);
  padding: calc(var(--manif-marge) - var(--label-h)) var(--pad) var(--manif-marge);
}
/* Le label : même allumage, mêmes lettres, au style des numéros de la page
   (12 px, capitales, +0,14 em). Son gris de départ est #767676 (4,54:1, le
   seuil AA du petit texte) et non #8F8F8F : à 12 px, 3:1 ne suffit pas. */
.manif-label {
  --gris0: 118;
  margin: 0 auto 28px; line-height: 16px; height: 16px; text-align: center;
  font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
}
.manif-p {
  max-width: 1040px; margin: 0 auto; text-align: center; color: #1A1A1A;
  font-size: var(--manif); line-height: var(--manif-lh); letter-spacing: var(--d2-ls);
  text-wrap: balance;
}
/* La copie ne doit pas doubler le texte : la version en clair est pour les
   lecteurs d'écran seulement. */
.manif-clair { user-select: none; -webkit-user-select: none; }
.mot { white-space: nowrap; }
/* Une lettre : gris #8F8F8F (3,24:1 sur blanc, lisible) → #1A1A1A (17,4:1,
   le noir du texte courant de la charte V2, comme le rgb(26,26,26) de la
   référence). Le front d'allumage couvre trois lettres (--doux), pour que la
   bascule se lise comme un balayage et pas comme un clignotement. Repli
   (--t = 1) : tout est noir. */
.l {
  --doux: 3;
  --w: clamp(0, calc((var(--t) * (var(--n) + var(--doux)) - var(--i)) / var(--doux)), 1);
  --c: calc(var(--gris0, 143) - (var(--gris0, 143) - 26) * var(--w));
  color: rgb(var(--c) var(--c) var(--c));
}
@media all {
  @supports (animation-timeline: view()) {
    .manif-bloc {
      animation: v2-t linear both; animation-timeline: view();
      /* cover 0 = haut du paragraphe au bas de l'écran ; « cover 25vh » =
         son haut à 75 % de l'écran. */
      animation-range: cover calc((100 - var(--manif-debut)) * 1vh) cover calc((100 - var(--manif-fin)) * 1vh);
    }
    .l { transition: color .18s linear; }
  }
  html.js-driver .manif-bloc { animation: none; }
}
@keyframes v2-t { from { --t: 0; } to { --t: 1; } }
/* Téléphone : 22 px, 9 lignes. La consigne visait 5 à 7 lignes ; il
   faudrait ~18 px (la taille du corps de texte) pour y tenir les 45 mots,
   alors que la référence n'en compte que 19 (mesuré, voir RAPPORT-PASSE-3). */
@media (max-width: 720px) { .manif-p { font-size: 22px; line-height: 1.28; letter-spacing: -.015em; } }

/* ---- 6. Les trois paliers ------------------------------------------------- */
/* ÉTAT DE BASE = LE REPLI (téléphone, tablette, mouvement réduit, sans script,
   moteur sans timeline) : trois cartes à plat, face texte. */
/* PASSE 4 — LE VIDE SOUS LE MANIFESTE. --vide-vise = l'écart voulu entre
   la fin du texte du manifeste et le haut du titre des paliers (Théo : « un
   gros padding »). Il était de 372 px à 1440×900 (135 de marge du manifeste
   + 237 où le titre est centré dans l'écran épinglé) et de 245 px à 390.
   Version à plat (téléphone, mouvement réduit, sans script) : la marge haute
   des paliers absorbe l'écart. Version épinglée : voir plus bas. */
.paliers {
  --vide-vise: 165px;
  position: relative;
  padding: max(24px, calc(var(--vide-vise) - clamp(96px, 15vh, 140px))) 0 clamp(96px, 14vh, 160px);
}
.paliers-siege { width: 100%; max-width: calc(var(--col) + 2 * var(--pad)); margin-inline: auto; padding-inline: var(--pad); }
.paliers-tete { text-align: center; max-width: 720px; margin: 0 auto 48px; }
.paliers-sub { margin-top: 18px; color: var(--gris-f); }
.jeu { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 760px) { .jeu { grid-template-columns: repeat(3, 1fr); } }
.carte { position: relative; }
.carte-in { position: relative; height: 100%; }
.face--image { display: none; }
.face--texte {
  height: 100%; display: flex; flex-direction: column; gap: 12px;
  padding: 24px 22px 22px; border-radius: var(--rayon);
}
/* Le palier se lit aussi à la teinte : clair, moyen, noir. Aucune couleur. */
.carte--1 .face--texte { background: #EDEDED; color: var(--noir); }
.carte--2 .face--texte { background: #A1A1A1; color: var(--noir); }
.carte--3 .face--texte { background: var(--noir); color: var(--blanc); }
.carte--3 .carte-nom { color: var(--blanc); }
.carte-rang { font-size: 12px; letter-spacing: .14em; font-weight: 500; opacity: .7; }
.carte-nom { font-size: var(--d3); line-height: 1.05; letter-spacing: var(--d3-ls); margin-top: -4px; }
html.t-archivo .carte-nom { text-transform: uppercase; }
.carte-promesse { font-size: 15px; line-height: 1.4; font-weight: 500; }
.carte-puces { list-style: none; padding: 0; display: grid; gap: 7px; font-size: 13px; line-height: 1.4; }
.carte-puces li { padding-left: 14px; position: relative; }
.carte-puces li::before { content: ""; position: absolute; left: 0; top: .62em; width: 6px; height: 1px; background: currentColor; }
.carte-pied { margin-top: auto; padding-top: 14px; border-top: 1px solid currentColor; border-top-color: color-mix(in srgb, currentColor 22%, transparent); display: grid; gap: 6px; }
.carte-prix { display: flex; align-items: baseline; gap: 8px; }
.carte-montant { font-family: var(--f-titre); font-size: 34px; line-height: 1; }
html.t-archivo .carte-montant { font-weight: 800; font-size: 28px; }
.carte-paye, .carte-intro { font-size: 12px; line-height: 1.35; }
.carte-lien { margin-top: 4px; font-size: 13px; font-weight: 500; text-underline-offset: 3px; }
.carte--2 .carte-intro, .carte--1 .carte-intro { color: #2E2E2E; }
.carte--3 .carte-intro { color: var(--sur-noir); }

/* LE MÉCANISME : uniquement avec le script (il porte les bascules), assez de
   place pour lire une carte, et le droit de bouger. Mesures de Schierke :
   bannière 1080 × 540 → 900 × 450 (scale 1,2 → 1) sur 1 800 px de scroll,
   puis deux bascules ANIMÉES DANS LE TEMPS (pas au scroll) : la fente (30 px),
   puis le retournement à 180° (fente 14 px). Éventail ramené de ±12° (mesure)
   à ±6° : nos cartes portent du texte à lire, pas trois mots. */
@media (min-width: 1000px) {
  html.js .paliers {
    --course: 3000px;
    height: calc(100svh + var(--course)); padding: 0;
    /* Version épinglée : on ne touche NI à la piste (même hauteur), NI à ce
       qui se passe dans l'écran épinglé (même cadrage, même rythme). On
       remonte la section entière d'un bloc : --pal-x est la position du
       titre dans l'écran épinglé, recalculée comme la feuille la produit
       (64 px de haut, centrage vertical du titre + 30 px + la bannière, et
       les 24 px de montée du titre au repos). Le haut de la section, vide et
       transparent, passe alors sous la fin du texte : il ne capte pas la
       souris (pointer-events ci-dessous). */
    --pal-dw: min(900px, 62.5vw, calc((100svh - 300px) * 2 / 1.2));
    --pal-x: calc(64px + (100svh - 64px - (var(--d2) * var(--d2-lh) + 30px + var(--pal-dw) / 2)) / 2 + 24px);
    margin-top: calc(var(--vide-vise) - clamp(96px, 15vh, 140px) - var(--pal-x));
    /* k : le rétrécissement, de 300 à 2 100 px de course (linéaire). */
    --k: clamp(0, calc((var(--p) - .1) / .6), 1);
    /* Le titre arrive pendant le rétrécissement (fondu + montée de 24 px). */
    --ta: clamp(0, calc((var(--k) - .45) / .35), 1);
  }
  @supports (animation-timeline: view()) {
    html.js .paliers { animation: v2-p linear both; animation-timeline: view(); animation-range: contain 0% contain 100%; }
  }
  html.js.js-driver .paliers { animation: none; }

  html.js .paliers-siege {
    position: sticky; top: 0; height: 100svh; max-width: none;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 30px;
    padding-top: 64px;
  }
  html.js .paliers, html.js .paliers-siege { pointer-events: none; }
  html.js .paliers-siege > * { pointer-events: auto; }
  html.js .paliers-tete { margin: 0; opacity: var(--ta); translate: 0 calc((1 - var(--ta)) * 24px); }
  html.js .paliers-sub { display: none; }
  html.js .jeu {
    --dw: min(900px, 62.5vw, calc((100svh - 300px) * 2 / 1.2));
    display: flex; justify-content: center; gap: 0;
    height: calc(var(--dw) / 2);
    transform: scale(calc(1.2 - .2 * var(--k))); transform-origin: 50% 50%;
  }
  html.js .carte {
    flex: 0 0 calc(var(--dw) / 3); height: 100%;
    perspective: 1400px;
    transition: transform .8s var(--ease);
  }
  html.js .carte-in {
    transform-style: preserve-3d;
    /* Courbe presque symétrique : le passage à 90° tombe vers 0,32 s, là où
       les faces échangent leur opacité. ≈ 0,8 s (mesure de la référence). */
    --flip-t: .8s; --flip-mi: .32s;
    transition: transform var(--flip-t) cubic-bezier(.4, 0, .2, 1);
  }
  html.js .face {
    position: absolute; inset: 0; overflow: hidden;
    backface-visibility: hidden; -webkit-backface-visibility: hidden;
  }
  /* Safari n'applique backface-visibility qu'aux faces qui ont leur propre
     transformation 3D : la face avant reçoit donc un rotateY(0) explicite
     (sans lui, WebKit montrait la face texte en miroir — vu le 06/10). */
  html.js .face--image { display: block; transform: rotateY(0deg); transition: border-radius .6s var(--ease), opacity 0s linear .32s; }
  html.js .face--texte { transform: rotateY(180deg); padding: 20px 20px 18px; gap: 10px; opacity: 0; transition: opacity 0s linear .32s; }
  /* CEINTURE : WebKit 26.5 montrait quand même la face texte en miroir. Les
     faces s'échangent donc aussi par l'opacité, à mi-rotation (0,32 s). L'opacité, pas visibility : un lien à opacité 0
     reste atteignable au clavier, et son focus retourne la carte. */
  html.js .paliers[data-etat="retourne"] .face--image,
  html.js .paliers:focus-within .face--image { opacity: 0; }
  html.js .paliers[data-etat="retourne"] .face--texte,
  html.js .paliers:focus-within .face--texte { opacity: 1; }
  /* Une seule image, trois fenêtres : chaque face montre son tiers. */
  html.js .face--image .slot { position: absolute; top: 0; height: 100%; width: 300%; aspect-ratio: auto; border-radius: 0; }
  html.js .carte--2 .face--image .slot { left: -100%; }
  html.js .carte--3 .face--image .slot { left: -200%; }
  /* Bannière jointe : seuls les coins extérieurs sont arrondis. */
  html.js .carte--1 .face--image { border-radius: var(--rayon) 0 0 var(--rayon); }
  html.js .carte--2 .face--image { border-radius: 0; }
  html.js .carte--3 .face--image { border-radius: 0 var(--rayon) var(--rayon) 0; }

  /* Bascule 1 : la fente. */
  html.js .paliers:is([data-etat="fente"], [data-etat="retourne"]) .face--image { border-radius: var(--rayon); }
  /* La fente et ses écarts sont des translations, pas un `gap` animé : le
     compositeur seul, aucun recalcul de mise en page (CLS mesuré à 0). */
  html.js .paliers[data-etat="fente"] .carte--1 { transform: translateX(-30px); }
  html.js .paliers[data-etat="fente"] .carte--3 { transform: translateX(30px); }
  /* Bascule 2 : le retournement, en éventail. Au clavier, le focus dans une
     carte la retourne aussi : jamais un lien caché derrière une image. */
  html.js .paliers[data-etat="retourne"] .carte-in,
  html.js .paliers:focus-within .carte-in { transform: rotateY(180deg); }
  html.js .paliers[data-etat="retourne"] .carte--1 { transform: translateX(-14px) rotate(-6deg) translateY(12px); }
  html.js .paliers[data-etat="retourne"] .carte--3 { transform: translateX(14px) rotate(6deg) translateY(12px); }
}
@keyframes v2-p { from { --p: 0; } to { --p: 1; } }

/* PASSE 6 — LES PALIERS AU TÉLÉPHONE, DEUX GESTES À COMPARER (sous 1000 px).
   Le défaut ne change pas : les cartes à plat. ?paliers=a ou ?paliers=b pose
   html.p6-paliers-a|b. Les deux ne vivent qu'avec le script (html.js) et le
   droit de bouger : sans script, en mouvement réduit, au-dessus de 999 px,
   c'est le rendu d'avant. Le script (v2.js, « paliers au téléphone ») écrit
   une seule valeur par carte et par image, du transform et de l'opacité
   seulement, dans les deux moteurs (une seule mécanique : un view() natif ne
   ferait pas mieux, il anime ici des variables, pas le compositeur). Entre
   760 et 999 px les trois colonnes passent en une, centrée (560 px). */
@media (max-width: 999px) {
  html.js:is(.p6-paliers-a, .p6-paliers-b) .jeu { grid-template-columns: 1fr; max-width: 560px; margin-inline: auto; }

  /* A — UNE IMAGE, TROIS BANDES. L'image de la bannière se pose au-dessus de
     la première carte, en trois bandes jointes ; au fil du scroll, les deux
     bandes du haut descendent chacune vers SA carte (elles passent derrière
     les cartes qu'elles croisent : le texte n'est jamais recouvert) et
     deviennent l'en-tête de la carte. Carte 1 : le bas de l'image, carte 2 :
     le milieu, carte 3 : le haut. La place de l'image jointe est réservée
     au-dessus des cartes (deux bandes). */
  html.js.p6-paliers-a .jeu { --bande: clamp(84px, 24vw, 120px); padding-top: calc(2 * var(--bande) - 16px); gap: 16px; }
  html.js.p6-paliers-a .face--image {
    display: block; position: relative; z-index: 1; height: var(--bande); overflow: hidden;
    border-radius: var(--rayon) var(--rayon) 0 0; background: var(--papier);
    transform: translate3d(0, var(--ty, 0px), 0); will-change: transform;
  }
  html.js.p6-paliers-a .face--image .slot { position: absolute; left: 0; width: 100%; height: 300%; aspect-ratio: auto; border-radius: 0; }
  html.js.p6-paliers-a .carte--1 .face--image .slot { top: -200%; }
  html.js.p6-paliers-a .carte--2 .face--image .slot { top: -100%; }
  html.js.p6-paliers-a .carte--3 .face--image .slot { top: 0; }
  html.js.p6-paliers-a .face--texte { position: relative; z-index: 2; height: auto; border-radius: 0 0 var(--rayon) var(--rayon); }
  /* L'image jointe : seuls ses coins extérieurs sont arrondis tant que les
     bandes se touchent (--separe = 0), puis chaque bande prend ses coins. */
  html.js.p6-paliers-a .carte:not(.carte--3) .face--image { border-top-left-radius: calc(var(--rayon) * var(--separe, 1)); border-top-right-radius: calc(var(--rayon) * var(--separe, 1)); }

  /* B — LES CARTES S'EMPILENT. Chaque carte est collée sous la nav (64 px,
     puis 14 px de plus par rang) ; la suivante monte la recouvrir, la
     précédente recule (échelle 0,94, 16 px plus haut) et s'assombrit. Les
     trois rangées ont la même hauteur (celle de la plus longue) : la pile
     se ferme net sur GRID STUDIO. Un lien qui reçoit le focus ramène sa
     carte devant. */
  html.js.p6-paliers-b .jeu { gap: 0; grid-auto-rows: 1fr; }
  html.js.p6-paliers-b .carte { position: sticky; top: calc(64px + var(--rang) * 14px); margin-bottom: 26svh; }
  html.js.p6-paliers-b .carte--1 { --rang: 0; }
  html.js.p6-paliers-b .carte--2 { --rang: 1; }
  html.js.p6-paliers-b .carte--3 { --rang: 2; margin-bottom: 0; }
  html.js.p6-paliers-b .carte-in {
    transform-origin: 50% 0; will-change: transform;
    transform: translate3d(0, calc(var(--recul, 0) * -16px), 0) scale(calc(1 - .06 * var(--recul, 0)));
  }
  html.js.p6-paliers-b .carte-in::after {
    content: ""; position: absolute; inset: 0; border-radius: var(--rayon); pointer-events: none;
    background: var(--noir); opacity: calc(.3 * var(--recul, 0));
  }
  html.js.p6-paliers-b .carte:focus-within { z-index: 3; }
  html.js.p6-paliers-b .carte:focus-within .carte-in { transform: none; }
  html.js.p6-paliers-b .carte:focus-within .carte-in::after { opacity: 0; }

  /* PASSE 7 — L'ARRIVÉE EN PILE (B, sauf ?pile=p6). Mesuré sur la référence :
     la carte part 30° inclinée, à 0,8, invisible, et se pose en dépassant ;
     la précédente ne bouge pas. Ici, la carte monte avec le défilement (elle
     est dans le flux) : seule la transformation s'ajoute, écrite par v2.js
     (--arr, de 0 à ~1,05, lissé dans le temps comme la référence ; --arr-o,
     l'opacité). Inclinaison ramenée à 24° et dépassement à 4,5 % au plus : ce sont
     des cartes de prix, le texte doit se poser vite et sans rebond marqué.
     L'écart entre les cartes passe de la marge des cartes à l'écart de la
     grille : la 3e carte n'absorbe plus les 26svh (219 px de blanc à 390). */
  html.js.p6-paliers-b.p7-pile .jeu { row-gap: 26svh; }
  html.js.p6-paliers-b.p7-pile .carte { margin-bottom: 0; }
  html.js.p6-paliers-b.p7-pile .carte-in {
    transform-origin: 50% 100%; will-change: transform, opacity;
    transform: perspective(1200px) translate3d(0, calc((1 - var(--arr, 1)) * 56px), 0)
      rotateX(calc((1 - var(--arr, 1)) * 24deg)) scale(calc(.8 + .2 * var(--arr, 1)));
    opacity: var(--arr-o, 1);
  }
  html.js.p6-paliers-b.p7-pile .carte-in::after { content: none; }
  html.js.p6-paliers-b.p7-pile .carte:focus-within .carte-in { transform: none; opacity: 1; }
}

/* PASSE 7 — LES CARTES DE PRIX, TROIS VERSIONS À COMPARER (?cartes=a|b|c).
   Sans la classe p7-cartes, rien ici ne s'applique : les cartes d'avant.
   Même structure pour les trois (mesure d'Equiv, MESURES-REFERENCES-PASSE-7) :
   le nom, la promesse, ce que le palier ajoute, le prix de lancement en très
   grand (le prix plein barré à côté), un vrai bouton plein en bas. Les tailles
   suivent la largeur de la carte (cqi) : 300 px au bureau (1440), 354 à 390.
   Au bureau, la face texte reste la face arrière du retournement : seule
   sa mise en page change, ni sa taille ni sa place.
     A — fiche sobre : clair, filet noir, noir ; rien d'autre que le texte.
     B — une matière par palier, cumulative comme les paliers : la grille
         (GRID), la grille et ses blocs (CORE), la grille, les blocs et le
         contour prismatique de la V1 (STUDIO).
     C — une seule matière, le halo de la V1, qui monte : un souffle (GRID),
         le filet du haut (CORE), tout le contour et le prix (STUDIO).
   Le spectre ne vit que dans les traits et les chiffres (dossier d'identité),
   jamais en nappe. Rien ne boucle : les tracés partent une fois, au
   retournement (bureau) ou à l'entrée dans l'écran (téléphone, v2.js). */
html.p7-cartes .c7 {
  --c7-fond: #F5F5F5; --c7-encre: var(--noir); --c7-doux: #4D4D4D;
  --c7-filet: rgba(0, 0, 0, .14); --c7-trame: rgba(0, 0, 0, .085);
  --c7-btn: var(--noir); --c7-btn-txt: var(--blanc); --c7-btn-survol: #333333;
  /* Le prisme de la V1 (wotg.css, carte GRID STUDIO), en traits pleins. */
  --c7-violet: rgb(176, 92, 255); --c7-bleu: rgb(62, 138, 255); --c7-menthe: rgb(104, 255, 205);
  position: relative; container-type: inline-size;
  display: flex; flex-direction: column; gap: 0;
  padding: 22px 20px 20px;
  background: var(--c7-fond); color: var(--c7-encre);
  border: 1px solid var(--c7-filet); border-radius: var(--rayon);
}
html.p7-cartes .carte--2 .c7 { --c7-fond: var(--blanc); --c7-filet: var(--noir); }
html.p7-cartes .carte--3 .c7 {
  --c7-fond: var(--noir); --c7-encre: var(--blanc); --c7-doux: var(--sur-noir);
  --c7-filet: rgba(255, 255, 255, .22); --c7-trame: rgba(255, 255, 255, .11);
  --c7-btn: var(--blanc); --c7-btn-txt: var(--noir); --c7-btn-survol: #D6D6D6;
}
html.p7-cartes .c7 > :not(.c7-matiere) { position: relative; z-index: 1; }
html.p7-cartes .c7-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
html.p7-cartes .c7 .carte-nom { margin: 0; color: inherit; font-size: clamp(22px, 10.6cqi, 36px); line-height: 1.04; }
html.p7-cartes .c7 .carte-rang { font-size: 13px; letter-spacing: .14em; font-weight: 500; opacity: 1; color: var(--c7-doux); font-variant-numeric: tabular-nums; }
html.p7-cartes .c7 .carte-promesse { margin-top: clamp(6px, 3cqi, 12px); font-size: clamp(14px, 6.6cqi, 19px); line-height: 1.3; font-weight: 500; text-wrap: pretty; }
html.p7-cartes .c7-plus { margin-top: clamp(10px, 5cqi, 20px); font-size: 13px; line-height: 1.3; color: var(--c7-doux); }
html.p7-cartes .c7-puces { list-style: none; padding: 0; margin: 6px 0 clamp(12px, 5cqi, 20px); display: grid; gap: clamp(2px, 1.4cqi, 6px); font-size: clamp(12px, 5.8cqi, 17px); line-height: 1.35; }
html.p7-cartes .c7-puces li { position: relative; padding-left: 18px; }
/* La puce : un bloc du symbole (un seul coin arrondi), pas un tiret. */
html.p7-cartes .c7-puces li::before {
  content: ""; position: absolute; left: 0; top: .42em; width: 7px; height: 7px;
  background: currentColor; border-radius: 0 0 0 3.5px;
}
html.p7-cartes .c7-prix { margin-top: auto; padding-top: clamp(10px, 5cqi, 18px); }
html.p7-cartes .c7-prix::before { content: ""; position: absolute; left: 0; right: 0; top: 0; border-top: 1px solid var(--c7-filet); }
html.p7-cartes .carte--2 .c7-prix::before { border-top-color: rgba(0, 0, 0, .18); }
html.p7-cartes .c7-entete, html.p7-cartes .c7-lance, html.p7-cartes .c7-duree { font-size: 13px; line-height: 1.3; color: var(--c7-doux); }
html.p7-cartes .c7-ligne { display: flex; align-items: center; gap: 12px; margin-top: 4px; }
html.p7-cartes .c7-montant { font-family: var(--f-titre); font-size: clamp(36px, 21.5cqi, 64px); line-height: .95; letter-spacing: -.01em; font-variant-numeric: lining-nums; }
html.t-archivo.p7-cartes .c7-montant { font-weight: 800; }
html.p7-cartes .c7-cote { display: grid; gap: 1px; }
html.p7-cartes .c7-plein { font-size: clamp(14px, 6.8cqi, 20px); line-height: 1.1; color: var(--c7-doux); text-decoration-thickness: 1.5px; }
html.p7-cartes .c7-duree { margin-top: 6px; }
html.p7-cartes .c7-bouton {
  margin-top: clamp(10px, 5cqi, 18px); min-height: 48px; padding: 12px 20px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: 999px; background: var(--c7-btn); color: var(--c7-btn-txt);
  font-size: 15px; font-weight: 600; line-height: 1.2; text-decoration: none;
  transition: background-color .2s var(--ease);
}
html.p7-cartes .c7-bouton span { transition: transform .3s var(--ease); }
html.p7-cartes .c7-bouton:hover { background: var(--c7-btn-survol); }
html.p7-cartes .c7-bouton:hover span { transform: translateX(4px); }
html.p7-cartes .c7-bouton:focus-visible { outline: 2px solid var(--c7-encre); outline-offset: 3px; }
@media (forced-colors: active) {
  html.p7-cartes .c7-bouton { border: 2px solid ButtonText; }
  html.p7-cartes .c7-montant { color: CanvasText !important; background: none !important; }
}
/* A : au survol (bureau), le filet de la carte se fonce. Un téléphone ne
   survole pas : le geste est le bouton lui-même (état actif). */
html.p7-cartes-a .carte--1 .c7:hover { border-color: rgba(0, 0, 0, .45); }
html.p7-cartes-a .carte--3 .c7:hover { border-color: rgba(255, 255, 255, .6); }
html.p7-cartes .c7-bouton:active { background: var(--c7-btn-survol); }

/* Le centre du halo (B STUDIO, C) : --lx/--ly, de 0 à 1 dans la carte.
   Bureau : la souris (v2.js, au survol). Téléphone : le défilement, et le
   doigt quand il touche la carte. Repos, sans script, mouvement réduit :
   en haut à gauche, figé. */
@property --lx { syntax: "<number>"; inherits: true; initial-value: .22; }
@property --ly { syntax: "<number>"; inherits: true; initial-value: .08; }
html.p7-cartes .c7 {
  --hx: calc(var(--lx, .22) * 100%); --hy: calc(var(--ly, .08) * 100%);
  /* Le halo rejoint le point en 0,4 s : il suit, il ne saute pas (la
     référence lisse de même le défilement, ~0,6 s). */
  transition: --lx .4s var(--ease), --ly .4s var(--ease), border-color .3s var(--ease);
}

/* ---- B : la matière de chaque palier ---- */
html.p7-cartes-b .c7-matiere { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; z-index: 0; }
/* La grille : deux nappes de traits d'un pixel (pas de 20 px), horizontales
   puis verticales, qui se tracent par un rideau (clip-path). Elle s'efface
   vers le bas : le prix et le bouton restent sur un fond calme. */
html.p7-cartes-b .c7-grille { position: absolute; inset: 0; -webkit-mask: linear-gradient(#000 0 38%, transparent 82%); mask: linear-gradient(#000 0 38%, transparent 82%); }
html.p7-cartes-b .c7-grille::before, html.p7-cartes-b .c7-grille::after {
  content: ""; position: absolute; inset: 0; clip-path: inset(0);
  transition: clip-path 1.1s cubic-bezier(.6, 0, .2, 1);
}
html.p7-cartes-b .c7-grille::before { background: repeating-linear-gradient(to bottom, var(--c7-trame) 0 1px, transparent 1px 20px); background-position: 0 19px; }
html.p7-cartes-b .c7-grille::after { background: repeating-linear-gradient(to right, var(--c7-trame) 0 1px, transparent 1px 20px); background-position: 19px 0; transition-delay: .18s; }
/* Au survol (bureau) ou sous le doigt, la grille s'éclaire autour du point. */
html.p7-cartes-b .c7-matiere::before {
  content: ""; position: absolute; inset: 0; opacity: 0; transition: opacity .4s var(--ease);
  background:
    repeating-linear-gradient(to bottom, var(--c7-encre) 0 1px, transparent 1px 20px) 0 19px,
    repeating-linear-gradient(to right, var(--c7-encre) 0 1px, transparent 1px 20px) 19px 0;
  -webkit-mask: radial-gradient(circle 110px at var(--hx) var(--hy), rgba(0, 0, 0, .18), transparent);
  mask: radial-gradient(circle 110px at var(--hx) var(--hy), rgba(0, 0, 0, .18), transparent);
}
html.p7-cartes-b .c7:hover .c7-matiere::before, html.p7-cartes-b .c7.c7-doigt .c7-matiere::before { opacity: 1; }
/* Les blocs (CORE et STUDIO) : quatre cases de la grille, un coin arrondi
   chacune, tournées vers le centre comme le symbole. Elles arrivent de
   l'extérieur et s'assemblent en haut à droite. */
html.p7-cartes-b .c7-blocs { position: absolute; top: 20px; left: round(down, calc(100% - 58px), 20px); width: 40px; height: 40px; display: grid; grid-template-columns: 1fr 1fr; }
/* B : le coin haut droit porte les blocs (CORE, STUDIO) ; le numéro s'efface
   pour les trois cartes, le nom garde sa place. */
html.p7-cartes-b .c7 .carte-rang { display: none; }
html.p7-cartes-b :is(.carte--2, .carte--3) .c7-tete { padding-right: 50px; min-height: 42px; }
html.p7-cartes-b .c7-blocs i {
  display: block; margin: 1px 0 0 1px; background: color-mix(in srgb, var(--c7-encre) 24%, transparent);
  transition: transform .8s cubic-bezier(.2, .9, .25, 1.15), opacity .5s var(--ease);
}
html.p7-cartes-b .carte--3 .c7-blocs i { background: color-mix(in srgb, var(--c7-encre) 34%, transparent); }
html.p7-cartes-b .c7-blocs i:nth-child(1) { border-radius: 0 0 7px 0; --dx: -26px; --dy: -22px; }
html.p7-cartes-b .c7-blocs i:nth-child(2) { border-radius: 0 0 0 7px; --dx: 24px;  --dy: -30px; transition-delay: .08s; }
html.p7-cartes-b .c7-blocs i:nth-child(3) { border-radius: 0 7px 0 0; --dx: -30px; --dy: 26px;  transition-delay: .16s; }
html.p7-cartes-b .c7-blocs i:nth-child(4) { border-radius: 7px 0 0 0; --dx: 22px;  --dy: 24px;  transition-delay: .24s; }
/* Le contour prismatique (STUDIO) : un anneau de 1,5 px, découpé par un
   masque ; la lumière y tourne autour de --hx/--hy. Le chiffre du prix
   porte le même prisme, éclairci (≥ 9:1 sur noir). */
html.p7-cartes-b .carte--3 .c7-matiere::after,
html.p7-cartes-c .c7::after {
  content: ""; position: absolute; inset: -1px; border-radius: inherit; padding: 1.5px; pointer-events: none; z-index: 2;
  background: radial-gradient(130% 120% at var(--hx) var(--hy), var(--c7-violet) 0%, var(--c7-bleu) 30%, var(--c7-menthe) 52%, transparent 74%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  transition: opacity .4s var(--ease);
}
html.p7-cartes-b .carte--3 .c7-matiere { overflow: visible; }
html.p7-cartes-b .carte--3 .c7-montant,
html.p7-cartes-c .carte--3 .c7-montant {
  color: var(--blanc);
  background: radial-gradient(160% 220% at calc(var(--lx, .22) * 160% - 30%) 50%, #D7B8FF 0%, #A9C8FF 28%, #B5F7DF 48%, #FFFFFF 70%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}

/* ---- C : le halo qui monte en gamme ---- */
/* GRID : un souffle, presque rien au repos, un peu plus sous la souris. */
html.p7-cartes-c .carte--1 .c7::after { opacity: .16; }
html.p7-cartes-c .carte--1 .c7:hover::after, html.p7-cartes-c .carte--1 .c7.c7-doigt::after { opacity: .42; }
/* CORE : le halo vit dans le filet du haut seulement : l'anneau est coupé
   à 14 px de haut (le filet et le départ des deux arrondis). */
html.p7-cartes-c .carte--2 .c7::after {
  inset: -1px -1px auto -1px; height: 16px; padding: 3px 3px 0 3px;
  border-radius: var(--rayon) var(--rayon) 0 0;
  background: linear-gradient(90deg, var(--c7-violet) calc(var(--lx) * 100% - 45%), var(--c7-bleu) calc(var(--lx) * 100%), var(--c7-menthe) calc(var(--lx) * 100% + 45%));
}
/* STUDIO : tout le contour, et le prix. */
html.p7-cartes-c .carte--3 .c7::after {
  padding: 3px;
  background: conic-gradient(from calc(var(--lx) * 360deg - 90deg) at 50% 50%, var(--c7-violet), var(--c7-bleu), var(--c7-menthe), var(--c7-bleu), var(--c7-violet));
}

/* Les tracés et l'assemblage : l'état « pas encore là » n'existe qu'avec le
   script et le droit de bouger ; sans eux, tout est posé (le repli). */
@media all {
  @media (max-width: 999px) {
    html.js.p7-cartes-b .carte:not(.c7-vu) .c7-grille::before { clip-path: inset(0 100% 0 0); }
    html.js.p7-cartes-b .carte:not(.c7-vu) .c7-grille::after { clip-path: inset(0 0 100% 0); }
    html.js.p7-cartes-b .carte:not(.c7-vu) .c7-blocs i { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.5); }
    html.js.p7-cartes-c .carte:not(.c7-vu) .c7::after { opacity: 0; }
  }
  @media (min-width: 1000px) {
    html.js.p7-cartes-b .paliers:not([data-etat="retourne"]):not(:focus-within) .c7-grille::before { clip-path: inset(0 100% 0 0); transition-duration: 0s; }
    html.js.p7-cartes-b .paliers:not([data-etat="retourne"]):not(:focus-within) .c7-grille::after { clip-path: inset(0 0 100% 0); transition-duration: 0s; }
    html.js.p7-cartes-b .paliers:not([data-etat="retourne"]):not(:focus-within) .c7-blocs i { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.5); transition-duration: 0s; }
    /* Le tracé part quand la carte a fini de se retourner (0,8 s). */
    html.js.p7-cartes-b .paliers[data-etat="retourne"] .c7-grille::before { transition-delay: .55s; }
    html.js.p7-cartes-b .paliers[data-etat="retourne"] .c7-grille::after { transition-delay: .73s; }
    html.js.p7-cartes-b .paliers[data-etat="retourne"] .c7-blocs i { transition-delay: calc(.7s + var(--k7, 0s)); }
  }
}
html.p7-cartes-b .c7-blocs i:nth-child(2) { --k7: .08s; }
html.p7-cartes-b .c7-blocs i:nth-child(3) { --k7: .16s; }
html.p7-cartes-b .c7-blocs i:nth-child(4) { --k7: .24s; }

/* Entre 760 et 999 px, trois colonnes de 225 px ne portent pas ces cartes :
   une colonne centrée, comme les gestes A et B de la passe 6. */
@media (min-width: 760px) and (max-width: 999px) {
  html.p7-cartes .jeu { grid-template-columns: 1fr; max-width: 560px; margin-inline: auto; }
}
@media (max-width: 999px) {
  html.p7-cartes .c7 { padding: 24px 22px 22px; }
}
/* Au bureau, la face texte reste la face arrière : absolue, de la taille de
   la carte (300 × 450 à 1440 × 900). Elle devient un conteneur à deux
   dimensions : sur un écran plus bas, la carte rapetisse, et ce qui ne
   tient plus s'efface dans l'ordre (l'en-tête du prix, la ligne « plus »). */
@media (min-width: 1000px) {
  html.js.p7-cartes .c7 { position: absolute; container-type: size; padding: 18px 18px 18px; }
}
@container (max-height: 390px) {
  html.p7-cartes .c7-entete { display: none; }
}
@container (max-height: 340px) {
  html.p7-cartes .c7-plus { display: none; }
  html.p7-cartes .c7-duree { display: none; }
}

/* PASSE 7 BIS — LA CARTE D (?cartes=d), avenant 1 : la carte Equiv Pass est
   la SPÉCIFICATION. Mesures de la référence (MESURES-REFERENCES-PASSE-7.md) :
   carte 360 × 520, rayon 24, marges 24 / 22 ; sélecteur de devise en pilules ;
   titre 18 gras + sous-titre ; objet filaire dans une tuile à droite ; bloc
   prix 314 × 82, rayon 16, prix 56 ; libellé en capitales ; accordéon, un seul
   ouvert, rayon 12 ; pilule 48. Les surfaces sont des voiles du blanc (ou du
   noir en clair) aux mêmes taux que la référence : 2 à 5 %, filets 5 à 12 %.
   Écarts voulus (voir le rapport) : textes à 15 px au téléphone, texte
   secondaire en --sur-noir / --gris-f (les 35-45 % de la référence passent
   sous 4,5:1), tuile de 80 px (l'avenant), police Archivo (la nôtre). */
html.p7-cartes-d .c7d {
  --d-fond: var(--noir); --d-texte: var(--blanc); --d-doux: var(--sur-noir);
  --d-v2: rgba(255, 255, 255, .02); --d-v3: rgba(255, 255, 255, .03); --d-v4: rgba(255, 255, 255, .04); --d-v5: rgba(255, 255, 255, .06);
  --d-f5: rgba(255, 255, 255, .07); --d-f8: rgba(255, 255, 255, .1); --d-f12: rgba(255, 255, 255, .16);
  background: var(--d-fond); color: var(--d-texte); border: 1px solid var(--d-f5);
  border-radius: 24px; padding: 24px 22px; gap: 0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
}
html.p7-fond-clair .c7d,
html.p7-fond-mixte :is(.carte--1, .carte--2) .c7d {
  --d-fond: var(--blanc); --d-texte: var(--noir); --d-doux: var(--gris-f);
  --d-v2: rgba(0, 0, 0, .02); --d-v3: rgba(0, 0, 0, .03); --d-v4: rgba(0, 0, 0, .04); --d-v5: rgba(0, 0, 0, .05);
  --d-f5: rgba(0, 0, 0, .1); --d-f8: rgba(0, 0, 0, .1); --d-f12: rgba(0, 0, 0, .16);
  box-shadow: none;
}
/* &fond=mixte : la gamme monte du blanc au noir, franchement (Théo) :
   GRID blanc, GRID CORE blanc cassé (--papier, #F5F5F5), GRID STUDIO noir. */
html.p7-fond-mixte .carte--2 .c7d { --d-fond: var(--papier); }
/* Même taille pour les trois cartes : la hauteur commune vient de v2.js
   (--d-h, la plus haute de tous les états) ; le bouton est en bas. */
html.p7-cartes-d .c7d { min-height: var(--d-h, 0px); }
/* Sans script (ou avant lui) : les rangées de la grille ont toutes la hauteur
   de la plus haute, donc les trois cartes aussi. Au bureau, la grille est un
   flex : sans effet. */
html.p7-cartes-d .jeu { grid-auto-rows: 1fr; }
html.p7-cartes-d .d-mesure .d-acc::details-content, html.p7-cartes-d .d-mesure .d-acc { transition: none !important; }
/* Passe 8 — contraste des éléments (WCAG 1.4.11, 3:1 mesuré) : le filet du
   bouton et la pilule de devise active, des voiles à 16 % (1,45:1), passent
   en traits francs. Écart voulu avec la référence, pour l'accessibilité. */
html.p7-cartes-d .c7d { --d-ctrl: rgba(255, 255, 255, .5); --d-actif: var(--blanc); --d-actif-texte: var(--noir); }
html.p7-fond-clair .c7d, html.p7-fond-mixte :is(.carte--1, .carte--2) .c7d { --d-ctrl: var(--gris); --d-actif: var(--noir); --d-actif-texte: var(--blanc); }
/* 1. Le sélecteur de devise : deux pilules, USD active. Des radios : il
   marche sans script ; EUR ne change pas le prix (il n'y a pas de prix en
   euros), il dit que la facture est en dollars. */
html.p7-cartes-d .d-devises { align-self: flex-start; display: inline-flex; gap: 2px; margin: 0; padding: 3px; border: 1px solid var(--d-f8); border-radius: 999px; background: var(--d-v3); min-width: 0; }
html.p7-cartes-d .d-devises label { position: relative; display: block; cursor: pointer; }
html.p7-cartes-d .d-devises input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
html.p7-cartes-d .d-devises span { display: block; min-width: 44px; padding: 5px 10px; border-radius: 999px; font-size: 13px; line-height: 1.2; text-align: center; color: var(--d-doux); }
html.p7-cartes-d .d-devises input:checked + span { background: var(--d-actif); color: var(--d-actif-texte); }
html.p7-cartes-d .d-devises input:focus-visible + span { outline: 2px solid var(--d-texte); outline-offset: 1px; }
html.p7-cartes-d .d-si-eur { display: none; }
html.p7-cartes-d .c7d:has(input[value="eur"]:checked) .d-si-usd { display: none; }
html.p7-cartes-d .c7d:has(input[value="eur"]:checked) .d-si-eur { display: inline; }

/* 2. Titre, sous-titre ; la tuile de l'objet à droite. */
html.p7-cartes-d .d-tete { margin-top: 15px; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
html.p7-cartes-d .d-titres { min-width: 0; }
html.p7-cartes-d .c7d .d-nom {
  margin: 0; color: inherit; font-family: var(--font-body); font-weight: 700; font-stretch: 100%;
  font-size: 20px; line-height: 1.15; letter-spacing: -.01em; text-transform: none;
}
html.p7-cartes-d .d-sous { margin-top: 3px; font-size: 15px; line-height: 1.35; color: var(--d-doux); }
html.p7-cartes-d .d-tuile {
  flex: none; position: relative; width: 80px; aspect-ratio: 1; border-radius: 14px;
  background: var(--d-v4); border: 1px solid var(--d-f8); display: grid; place-items: center; perspective: 420px;
}
html.p7-cartes-d .d-solide { position: relative; width: 78%; aspect-ratio: 1; color: var(--d-texte); }
html.p7-cartes-d .d-solide svg, html.p7-cartes-d .d-solide canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
html.p7-cartes-d .d-solide line { stroke: currentColor; stroke-width: 1; vector-effect: non-scaling-stroke; stroke-linecap: round; }
html.p7-cartes-d .d-solide.anime svg { visibility: hidden; }

/* 3. Le prix : une ligne, comme la référence. Le prix plein barré ne doit
   pas grandir le bloc : a, petit et en exposant collé au prix ; b, la même
   place, visible au survol, au toucher ou au focus. */
html.p7-cartes-d .d-prix { margin-top: 14px; padding: 12px 16px; border-radius: 16px; background: var(--d-v2); border: 1px solid var(--d-f5); }
html.p7-cartes-d .d-ligne-prix { display: flex; align-items: center; gap: 0; min-height: 56px; }
html.p7-cartes-d .d-montant { font-family: var(--font-body); font-weight: 400; font-size: 56px; line-height: 1; letter-spacing: -.02em; font-variant-numeric: lining-nums; color: var(--d-texte); }
html.p7-cartes-d .d-devise { color: var(--d-doux); margin-right: 2px; }
html.p7-cartes-d .d-plein {
  align-self: flex-start; margin: 5px 0 0 6px; font-size: 15px; line-height: 1; color: var(--d-doux);
  text-decoration-thickness: 1.5px; transition: opacity .25s var(--ease), transform .25s var(--ease);
}
html.p7-barre-b .d-plein { opacity: 0; transform: translateX(-6px); }
html.p7-barre-b .d-prix:hover .d-plein, html.p7-barre-b .d-prix:focus-within .d-plein,
html.p7-barre-b .c7d.c7-doigt .d-plein { opacity: 1; transform: none; }
html.p7-cartes-d .d-pastille {
  margin-left: auto; padding: 4px 9px; border-radius: 999px; white-space: nowrap;
  font-size: 13px; line-height: 1.3; color: var(--d-doux); background: var(--d-v5);
}

/* 4. Le libellé, puis l'accordéon (<details name> : un seul ouvert). */
html.p7-cartes-d .d-label { margin-top: 14px; font-size: 12px; line-height: 1.3; letter-spacing: .04em; text-transform: uppercase; color: var(--d-doux); }
html.p7-cartes-d .d-liste { margin-top: 9px; display: grid; gap: 0; }
html.p7-cartes-d .d-acc { border: 1px solid transparent; border-radius: 12px; transition: background-color .25s var(--ease), border-color .25s var(--ease); }
html.p7-cartes-d .d-acc[open] { background: var(--d-v4); border-color: var(--d-f8); }
html.p7-cartes-d .d-acc summary {
  list-style: none; display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 12px; cursor: pointer;
  font-size: 15px; line-height: 1.3; color: var(--d-doux); border-radius: 12px;
}
html.p7-cartes-d .d-acc summary::-webkit-details-marker { display: none; }
html.p7-cartes-d .d-acc[open] summary { color: var(--d-texte); }
html.p7-cartes-d .d-acc summary:focus-visible { outline: 2px solid var(--d-texte); outline-offset: -2px; }
html.p7-cartes-d .d-coche { flex: none; width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
html.p7-cartes-d .d-acc-t { flex: 1; min-width: 0; }
html.p7-cartes-d .d-signe { flex: none; position: relative; width: 9px; height: 9px; transition: transform .25s var(--ease); }
html.p7-cartes-d .d-signe::before, html.p7-cartes-d .d-signe::after { content: ""; position: absolute; left: 0; top: 3.75px; width: 9px; height: 1.5px; background: currentColor; }
html.p7-cartes-d .d-signe::after { transform: rotate(90deg); }
html.p7-cartes-d .d-acc[open] .d-signe { transform: rotate(45deg); color: var(--d-texte); }
html.p7-cartes-d .d-acc-d { padding: 0 12px 12px 34px; font-size: 15px; line-height: 1.4; color: var(--d-doux); }
@supports (interpolate-size: allow-keywords) {
  html.p7-cartes-d .c7d { interpolate-size: allow-keywords; }
  html.p7-cartes-d .d-acc::details-content { height: 0; overflow: clip; transition: height .23s cubic-bezier(.16, 1, .3, 1), content-visibility .23s allow-discrete; }
  html.p7-cartes-d .d-acc[open]::details-content { height: auto; }
}

/* 5. La pilule, pleine largeur, 48 px, comme la référence (voile 3 %, filet). */
html.p7-cartes-d .d-bouton {
  margin-top: auto; min-height: 48px; padding: 12px 20px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: 999px; background: var(--d-v3); color: var(--d-texte); border: 1px solid var(--d-ctrl);
  font-size: 15px; font-weight: 600; line-height: 1.2; text-decoration: none;
  transition: background-color .25s var(--ease), border-color .25s var(--ease);
}
html.p7-cartes-d .d-liste { margin-bottom: 8px; }
html.p7-cartes-d .d-bouton span { transition: transform .3s var(--ease); }
html.p7-cartes-d .d-bouton:hover, html.p7-cartes-d .d-bouton:active { background: var(--d-v5); border-color: var(--d-texte); }
html.p7-cartes-d .d-bouton:hover span { transform: translateX(3px); }
html.p7-cartes-d .d-bouton:focus-visible { outline: 2px solid var(--d-texte); outline-offset: 3px; }
@media (forced-colors: active) { html.p7-cartes-d .d-bouton { border: 2px solid ButtonText; } }

/* La face du bureau (300 × 450 à 1440) : les mêmes blocs, à l'échelle de la
   carte (0,83 de la référence). Seule cette face est un conteneur en hauteur. */
@container (max-height: 470px) {
  html.p7-cartes-d .d-devises { padding: 2px; }
  html.p7-cartes-d .d-devises span { min-width: 36px; padding: 3px 8px; font-size: 11px; }
  html.p7-cartes-d .d-tete { margin-top: 11px; }
  html.p7-cartes-d .c7d .d-nom { font-size: 16px; }
  html.p7-cartes-d .d-sous { font-size: 12px; white-space: nowrap; }
  html.p7-cartes-d .d-tuile { width: 58px; border-radius: 11px; }
  html.p7-cartes-d .d-prix { margin-top: 11px; padding: 9px 12px; border-radius: 13px; }
  html.p7-cartes-d .d-ligne-prix { min-height: 46px; }
  html.p7-cartes-d .d-montant { font-size: 46px; }
  html.p7-cartes-d .d-plein { font-size: 12px; margin-top: 4px; }
  html.p7-cartes-d .d-pastille { font-size: 11px; padding: 3px 7px; }
  html.p7-cartes-d .d-label { margin-top: 11px; font-size: 11px; }
  html.p7-cartes-d .d-liste { margin-top: 6px; margin-bottom: 8px; }
  html.p7-cartes-d .d-acc summary { min-height: 32px; padding: 4px 10px; font-size: 13px; }
  html.p7-cartes-d .d-acc-d { padding: 0 10px 8px 32px; font-size: 12px; line-height: 1.35; }
}
/* Bureau plus bas. Les seuils portent sur la boîte de CONTENU de la face
   (sans ses marges) : 412 px à 1440 × 900, 362 à 1280 × 800, 282 à 1024 × 768. */
@container (max-height: 380px) {
  html.p7-cartes-d .d-acc-d, html.p7-cartes-d .d-signe { display: none; }
  html.p7-cartes-d .d-acc summary { pointer-events: none; }
  html.p7-cartes-d .d-acc[open] { background: none; border-color: transparent; }
  html.p7-cartes-d .d-acc[open] summary { color: var(--d-doux); }
  /* Chaque libellé tient sur une ligne (aucun texte coupé) : le bouton finit
     au même endroit sur les trois cartes. */
  html.p7-cartes-d .d-acc summary { padding-inline: 6px; gap: 8px; font-size: 12px; min-height: 30px; }
}
@container (max-height: 300px) {
  html.p7-cartes-d .d-tuile { width: 44px; border-radius: 10px; }
  /* 1024 × 768 seulement (face de 213 px) : sans la pastille ni le sélecteur. */
  html.p7-cartes-d .d-sous, html.p7-cartes-d .d-label, html.p7-cartes-d .d-pastille, html.p7-cartes-d .d-devises { display: none; }
  html.p7-cartes-d .d-tete { margin-top: 0; }
  html.p7-cartes-d .d-montant { font-size: 36px; }
  html.p7-cartes-d .d-ligne-prix { min-height: 36px; }
  html.p7-cartes-d .d-acc summary { min-height: 24px; padding: 2px 4px; gap: 6px; font-size: 11px; line-height: 1.25; }
  html.p7-cartes-d .d-coche { width: 10px; height: 10px; }
  html.p7-cartes-d .d-bouton { padding-inline: 10px; font-size: 13px; white-space: nowrap; }
}

/* ?logo=1 : le logo holographique de la première version (gardé, règle 12). */
html.p7-cartes-d .d-logo {
  --h: 70%; position: relative; height: var(--h); aspect-ratio: 172.28 / 247.41; transform-style: preserve-3d;
  transform: rotateY(calc((var(--lx, .5) - .5) * 50deg + var(--bal) * 28deg)) rotateX(calc((.5 - var(--ly, .5)) * 30deg));
}
html.p7-cartes-d .c7d { --lx: .5; --ly: .5; --h1: #F2F2F2; --h2: #C9A6FF; --h3: #8FB8FF; --h4: #9FF5D8; --h5: #FFE3A3; --h6: #F7B3E9; --d-tranche: #2B2B2B; --d-tranche-fond: #0D0D0D; }
html.p7-fond-clair .c7d, html.p7-fond-mixte :is(.carte--1, .carte--2) .c7d { --h1: #1A1A1A; --h2: #7A45F0; --h3: #2F6BEA; --h4: #14A88C; --h5: #D08A1C; --h6: #C445B6; --d-tranche: #8A8A8A; --d-tranche-fond: #3A3A3A; }
html.p7-cartes-d .carte--1 .c7d { --h2: #CFCFCF; --h3: #9E9E9E; --h4: #E6E6E6; --h5: #B8B8B8; --h6: #DADADA; }
html.p7-cartes-d .carte--2 .c7d { --h2: #B9AEDB; --h3: #9DB3D9; --h4: #B3E0D2; --h5: #DADADA; --h6: #C9C9C9; }
html.p7-cartes-d .d-logo i {
  position: absolute; inset: 0; display: block;
  -webkit-mask: url(/assets/v2/wotg-symbole.svg) center / contain no-repeat; mask: url(/assets/v2/wotg-symbole.svg) center / contain no-repeat;
  transform: translateZ(calc(var(--k) * -1.8px));
  background: color-mix(in srgb, var(--d-tranche) calc(100% - var(--k) * 8%), var(--d-tranche-fond));
}
html.p7-cartes-d .d-logo .d-face { overflow: hidden; background: #1A1A1A; }
html.p7-cartes-d .d-face b {
  position: absolute; top: 0; bottom: 0; left: 0; width: 300%;
  background: linear-gradient(105deg, var(--h1) 0%, var(--h2) 17%, var(--h3) 33%, var(--h4) 50%, var(--h5) 67%, var(--h6) 83%, var(--h1) 100%);
  transform: translateX(calc(var(--lx, .5) * -44% - 11% - var(--bal) * 11%));
}
@property --bal { syntax: "<number>"; inherits: true; initial-value: -.64; }
@keyframes d-tourne { from { --bal: -1; } to { --bal: 1; } }
@media all {
  html.js.p7-cartes-d .c7d.c7-visible .d-logo { animation: d-tourne 3.6s ease-in-out infinite alternate; }
}
@media (min-width: 1000px) {
  html.js.p7-cartes-d .paliers:not([data-etat="retourne"]):not(:focus-within) .d-logo { animation: none; }
}
@media (max-width: 999px) {
  html.p7-cartes-d .c7d { padding: 24px 22px; }
}

/* PASSE 8, CHANTIER 2 — COMPARER LES PALIERS AU TÉLÉPHONE (?cartes=d&mobile=a|b|c|d|e).
   Théo : « elles se superposent par le bas, on ne peut pas trop comparer ».
   Au bureau, rien de tout ceci : les commandes sont masquées, la bascule 3D
   reste. Sous 1000 px :
     a, c, e : un choix par radios (sans script, :has()) ; a et c empilent les
       trois cartes dans la même case de grille (même hauteur par construction)
       et n'en montrent qu'une ;
     b, d : un défilement horizontal à accroche, natif ; v2.js ne fait que
       suivre la position (pastilles). */
.m-choix, .m-points, .m-table, .m-ligne { display: none; }
@media (max-width: 999px) {
  html.p8-mobile .jeu { max-width: 560px; margin-inline: auto; }
  /* Le choix : un contrôle segmenté, collé sous la nav. */
  html:is(.p8-mobile-a, .p8-mobile-c) .m-choix {
    display: flex; position: sticky; top: 64px; z-index: 6; max-width: 560px; margin: 0 auto 14px; padding: 4px;
    border: 1px solid var(--gris); border-radius: 999px; background: var(--blanc);
  }
  html.p8-mobile .m-choix label { flex: 1; position: relative; cursor: pointer; }
  html.p8-mobile .m-choix input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
  html.p8-mobile .m-choix span { display: flex; align-items: center; justify-content: center; min-height: 44px; border-radius: 999px; font: 600 15px/1 var(--font-body); letter-spacing: .02em; color: var(--gris-f); transition: background-color .2s var(--ease), color .2s var(--ease); }
  html.p8-mobile .m-choix input:checked + span { background: var(--noir); color: var(--blanc); }
  html.p8-mobile .m-choix input:focus-visible + span { outline: 2px solid var(--noir); outline-offset: 2px; }
  /* e : les radios restent (les lignes compactes sont leurs étiquettes), le
     groupe segmenté est caché mais lisible au clavier. */
  html.p8-mobile-e .m-choix { display: flex; position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

  /* a et c : une carte à la fois, sur place. */
  html:is(.p8-mobile-a, .p8-mobile-c, .p8-mobile-e) .jeu { display: grid; grid-template-columns: 1fr; }
  html:is(.p8-mobile-a, .p8-mobile-c) .jeu > .carte { grid-area: 1 / 1; transition: opacity .2s var(--ease), visibility 0s linear .2s, transform .25s var(--ease); }
  html:is(.p8-mobile-a, .p8-mobile-c) .paliers-siege:not(:has(#m-t1:checked)) .carte--1,
  html:is(.p8-mobile-a, .p8-mobile-c) .paliers-siege:not(:has(#m-t2:checked)) .carte--2,
  html:is(.p8-mobile-a, .p8-mobile-c) .paliers-siege:not(:has(#m-t3:checked)) .carte--3 { opacity: 0; visibility: hidden; transform: translateY(6px); pointer-events: none; }

  /* b et d : la piste horizontale. */
  html:is(.p8-mobile-b, .p8-mobile-d) .jeu {
    display: flex; gap: 12px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
    margin-inline: calc(-1 * var(--pad)); padding: 2px var(--pad) 6px; scroll-padding-inline: var(--pad); max-width: none; scrollbar-width: none;
  }
  html:is(.p8-mobile-b, .p8-mobile-d) .jeu::-webkit-scrollbar { display: none; }
  html:is(.p8-mobile-b, .p8-mobile-d) .jeu > .carte { flex: 0 0 86%; scroll-snap-align: start; }
  html.p8-mobile-d .jeu > .carte { flex-basis: 100%; scroll-snap-stop: always; }
  html.p8-mobile-d .jeu { gap: 16px; }
  html:is(.p8-mobile-b, .p8-mobile-d) .m-points { display: flex; justify-content: center; gap: 4px; margin-top: 14px; }
  html:is(.p8-mobile-b, .p8-mobile-d) .m-points a { display: grid; place-items: center; width: 44px; height: 44px; }
  html:is(.p8-mobile-b, .p8-mobile-d) .m-points a::before { content: ""; width: 8px; height: 8px; border-radius: 999px; background: var(--gris); transition: width .25s var(--ease), background-color .25s var(--ease); }
  html:is(.p8-mobile-b, .p8-mobile-d) .m-points a[aria-current="true"]::before { width: 24px; background: var(--noir); }
  html:is(.p8-mobile-b, .p8-mobile-d) .m-points a:focus-visible { outline: 2px solid var(--noir); outline-offset: -6px; border-radius: 999px; }
  /* d : la pagination « à la Apple », dans une pastille, plus visible. */
  html.p8-mobile-d .m-points { width: max-content; margin: 16px auto 0; padding: 0 6px; border-radius: 999px; background: var(--papier); }

  /* c : le tableau de ce que chaque palier ajoute. */
  html.p8-mobile-c .m-table { display: table; width: 100%; max-width: 560px; margin: 22px auto 0; border-collapse: collapse; font-size: 15px; line-height: 1.3; }
  html.p8-mobile-c .m-table caption { text-align: left; padding-bottom: 8px; font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--gris-f); }
  html.p8-mobile-c .m-table th, html.p8-mobile-c .m-table td { padding: 9px 4px; border-bottom: 1px solid var(--filet); }
  html.p8-mobile-c .m-table thead th { font-size: 12px; font-weight: 600; letter-spacing: .04em; color: var(--noir); text-align: center; }
  html.p8-mobile-c .m-table tbody th { text-align: left; font-weight: 400; color: var(--noir); padding-right: 8px; }
  html.p8-mobile-c .m-table td { width: 60px; text-align: center; }
  html.p8-mobile-c .m-table .m-table-prix th, html.p8-mobile-c .m-table .m-table-prix td { font-weight: 600; color: var(--noir); }
  html.p8-mobile-c .m-oui { color: var(--noir); font-weight: 700; }
  html.p8-mobile-c .m-non { color: var(--gris); }
  /* La colonne du palier choisi se lit en premier. */
  html.p8-mobile-c .paliers-siege:has(#m-t1:checked) .m-table :is(th, td):nth-child(2),
  html.p8-mobile-c .paliers-siege:has(#m-t2:checked) .m-table :is(th, td):nth-child(3),
  html.p8-mobile-c .paliers-siege:has(#m-t3:checked) .m-table :is(th, td):nth-child(4) { background: var(--papier); }

  /* e : les paliers en lignes compactes, une seule ouverte. */
  html.p8-mobile-e .jeu { gap: 10px; grid-auto-rows: auto; }
  /* La carte ouverte garde sa propre hauteur (pas celle de l'article, qui
     contient aussi la ligne compacte). */
  html.p8-mobile-e .jeu > .carte > .carte-in, html.p8-mobile-e .jeu .face--texte { height: auto; }
  html.p8-mobile-e .m-ligne {
    display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; align-items: baseline; min-height: 64px; padding: 14px 18px;
    border: 1px solid var(--gris); border-radius: 18px; background: var(--blanc); cursor: pointer;
  }
  html.p8-mobile-e .m-ligne-nom { font: 700 18px/1.2 var(--font-body); color: var(--noir); }
  html.p8-mobile-e .m-ligne-prix { font: 400 24px/1 var(--font-body); color: var(--noir); }
  html.p8-mobile-e .m-ligne-promesse { grid-column: 1 / -1; font-size: 15px; line-height: 1.35; color: var(--gris-f); }
  html.p8-mobile-e .paliers-siege:has(#m-t1:checked) .carte--1 .m-ligne,
  html.p8-mobile-e .paliers-siege:has(#m-t2:checked) .carte--2 .m-ligne,
  html.p8-mobile-e .paliers-siege:has(#m-t3:checked) .carte--3 .m-ligne { display: none; }
  html.p8-mobile-e .paliers-siege:not(:has(#m-t1:checked)) .carte--1 > .carte-in,
  html.p8-mobile-e .paliers-siege:not(:has(#m-t2:checked)) .carte--2 > .carte-in,
  html.p8-mobile-e .paliers-siege:not(:has(#m-t3:checked)) .carte--3 > .carte-in { display: none; }
  html.p8-mobile-e .paliers-siege:has(#m-t1:focus-visible) .carte--1 .m-ligne,
  html.p8-mobile-e .paliers-siege:has(#m-t2:focus-visible) .carte--2 .m-ligne,
  html.p8-mobile-e .paliers-siege:has(#m-t3:focus-visible) .carte--3 .m-ligne { outline: 2px solid var(--noir); outline-offset: 2px; }
  /* Pendant la mesure des hauteurs (v2.js), toutes les cartes sont dépliées. */
  html.p8-mobile-e .jeu.d-mesure .carte > .carte-in { display: block !important; }
}

/* PASSE 8, CHANTIER 3 — L'ENTRÉE DES CARTES (?cartes=d&entree=a|b|c).
   700 ms au plus, transform et opacité seulement (CLS 0), une seule fois,
   déclenchée par v2.js quand la section entre à l'écran (.p8-vu sur .jeu).
   L'état « pas encore là » n'existe qu'avec le script : sans lui, tout est
   posé. Mouvement réduit : un fondu de 200 ms, sans déplacement.
     a  cascade : chaque carte monte de 16 px et apparaît, 120 ms d'écart ;
     b  chaque palier sort de derrière le précédent (le haut contient le bas) ;
     c  la gamme se construit : GRID, puis CORE posé dessus, puis STUDIO, et ce
        que chaque palier ajoute (son libellé, ses lignes) s'éclaire un instant.
   Au bureau, le retournement 3D est déjà l'entrée : sous ?entree, il passe en
   cascade et raccourcit (0,56 s, 70 ms d'écart, 0,70 s au total) ; c y ajoute
   l'éclairage. Le défaut garde le retournement de la passe 7 (0,8 s). */
@keyframes p8-monte { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes p8-sort { from { opacity: 0; transform: translateY(calc(-100% - 12px)) scale(.94); } 60% { opacity: 1; } to { opacity: 1; transform: none; } }
@keyframes p8-pose { from { opacity: 0; transform: translateY(-10px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes p8-eclat { 0% { background-color: transparent; } 35% { background-color: rgba(0, 0, 0, .07); } 100% { background-color: transparent; } }
@keyframes p8-fondu { from { opacity: 0; } to { opacity: 1; } }
/* PASSE 9 (Théo : « j'ai rien vu ») : la section entière se déclenchait dès
   que son haut passait 80 % de l'écran ; les cartes 2 et 3, encore sous le
   pli, finissaient leur entrée avant d'être vues (mesuré : 0 % visibles
   pendant leur animation), et la carte 1 n'en montrait qu'un tiers, 16 px
   en 340 ms. Désormais CHAQUE carte entre quand elle-même est au tiers à
   l'écran (.p8-vu sur la carte, v2.js), plus ample et plus lente (≤ 900 ms). */
@keyframes p9-monte { from { opacity: 0; transform: translateY(48px); } to { opacity: 1; transform: none; } }
@keyframes p9-pose { from { opacity: 0; transform: translateY(-28px) scale(.92); } to { opacity: 1; transform: none; } }
@keyframes p9-eclat { 0% { background-color: transparent; } 30% { background-color: rgba(0, 0, 0, .1); } 100% { background-color: transparent; } }
@media (max-width: 999px) {
  html.js.p8-entree .jeu > .carte:not(.p8-vu) { opacity: 0; }
}
@media (max-width: 999px) {
  html.js.p8-entree-a .jeu > .carte.p8-vu { animation: p9-monte .7s cubic-bezier(.33, 1, .68, 1) both; }
  /* b : la carte sort de derrière la précédente (dont elle part, 100 % de sa
     hauteur plus l'écart, au-dessus) ; la première monte simplement. */
  html.js.p8-entree-b .jeu > .carte.p8-vu { animation: p8-sort .8s cubic-bezier(.33, 1, .68, 1) both; }
  html.js.p8-entree-b .jeu > .carte { position: relative; }
  html.js.p8-entree-b .jeu > .carte--1 { z-index: 3; } html.js.p8-entree-b .jeu > .carte--2 { z-index: 2; } html.js.p8-entree-b .jeu > .carte--3 { z-index: 1; }
  html.js.p8-entree-b .jeu > .carte--1.p8-vu { animation-name: p9-monte; }
  /* c : la carte se pose, puis ce qu'elle ajoute (libellé, lignes) s'éclaire. */
  html.js.p8-entree-c .jeu > .carte.p8-vu { animation: p9-pose .6s cubic-bezier(.33, 1, .68, 1) both; }
  /* L'éclairage attend que la liste elle-même soit à l'écran (.p9-eclaire,
     v2.js) : à l'entrée de la carte, elle est souvent encore sous le pli. */
  html.js.p8-entree-c .jeu > :is(.carte--2, .carte--3).p9-eclaire :is(.d-label, .d-liste) { animation: p9-eclat .7s ease-out .1s both; border-radius: 10px; }
  /* Galeries (b, d de ?mobile) : les cartes hors champ entrent avec la
     première, la cascade se voit sur la pastille d'après. */
  html.js.p8-entree .jeu > .carte--2.p8-vu.p9-ensemble { animation-delay: .12s; }
  html.js.p8-entree .jeu > .carte--3.p8-vu.p9-ensemble { animation-delay: .24s; }
  /* Une carte déjà dépassée au chargement (page rendue défilée) : posée. */
  html.js.p8-entree .jeu > .carte.p9-deja { animation: none !important; }
}
/* Les cartes cachées des variantes mobiles (a, c, d, e) restent cachées. */
@media (max-width: 999px) {
  html.js.p8-entree:is(.p8-mobile-a, .p8-mobile-c) .jeu > .carte.p8-vu { animation-fill-mode: backwards; }
}
/* Le bouton de test « Replay » (&rejouer=1), en bas à gauche. */
.p9-rejouer { display: none; }
html.js .p9-rejouer { display: inline-flex; position: fixed; left: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); z-index: 60; align-items: center; min-height: 44px; padding: 0 18px; border: 0; border-radius: 999px; background: var(--noir); color: var(--blanc); font: 600 15px/1 var(--font-body); cursor: pointer; }
/* Au bureau : le retournement en cascade, raccourci. */
@media (min-width: 1000px) {
  html.js.p8-entree .carte-in { --flip-t: .56s; }
  html.js.p8-entree .carte { transition-duration: .56s; }
  html.js.p8-entree .carte--2 { --d8: 150ms; }
  html.js.p8-entree .carte--3 { --d8: 300ms; }
  html.js.p8-entree .carte-in { transition-delay: var(--d8, 0s); }
  html.js.p8-entree .face--image { transition: border-radius .6s var(--ease), opacity 0s linear calc(.22s + var(--d8, 0s)); }
  html.js.p8-entree .face--texte { transition: opacity 0s linear calc(.22s + var(--d8, 0s)); }
  html.js.p8-entree-c .paliers[data-etat="retourne"] :is(.carte--2, .carte--3) :is(.d-label, .d-liste) { animation: p9-eclat .45s ease-out calc(.15s + var(--d8, 0s)) both; border-radius: 8px; }
}


/* PASSE 8, CHANTIER 4 — L'EURO (?cartes=d&eur=indicatif|payer). Les deux prix
   sont dans le HTML ; la radio EUR montre les euros de vendable.php. En
   indicatif, un astérisque suit le prix et « * Billed in USD » se loge sous le
   prix, dans la marge basse du bloc : le bloc ne grandit pas (mesuré). La
   pastille garde « Lifetime updates » dans les deux modes (Théo). */
html.p8-eur .d-si-eur-prix, html.p8-eur .d-note-eur { display: none; }
html.p8-eur .c7d:has(input[value="eur"]:checked) .d-si-usd-prix { display: none; }
html.p8-eur .c7d:has(input[value="eur"]:checked) .d-si-eur-prix { display: inline; }
html.p8-eur .c7d:has(input[value="eur"]:checked) .d-si-usd { display: inline; }
html.p8-eur .c7d:has(input[value="eur"]:checked) .d-si-eur { display: none; }
html.p8-eur .d-ast { font-size: .42em; vertical-align: super; margin-left: 1px; color: var(--d-doux); }
html.p8-eur-indicatif .c7d:has(input[value="eur"]:checked) .d-note-eur {
  display: block; position: absolute; left: 16px; bottom: 3px; font-size: 12px; line-height: 12px; color: var(--d-doux);
}
/* De l'air entre les chiffres et la note, sans grandir le bloc : la ligne du
   prix remonte (transformation du montant et du barré seulement : sur la
   ligne entière, elle deviendrait le repère de la note, qui tomberait sur
   les chiffres, vu le 08/10). */
html.p8-eur-indicatif .c7d:has(input[value="eur"]:checked) :is(.d-montant, .d-plein) { transform: translateY(-5px); }
@container (max-height: 470px) {
  html.p8-eur-indicatif .c7d:has(input[value="eur"]:checked) .d-note-eur { left: 12px; bottom: 1px; }
  html.p8-eur-indicatif .c7d:has(input[value="eur"]:checked) :is(.d-montant, .d-plein) { transform: translateY(-7px); }
}


/* PASSE 8, CHANTIER 5 — LE BUREAU : SURVOL ET BOUTON DES DÉMOS.
   ?aura=a|b (avec cartes=d) : quand les cartes sont retournées, la carte
   survolée grandit (face texte à 1,04) et une aura neutre se pose derrière
   elle (a : centrée ; b : elle suit la souris, --ax/--ay posés par v2.js).
   L'aura vit dans la carte (.carte a son propre contexte d'empilement, celui
   de l'éventail) : rien ne passe devant une autre carte, la bascule 3D et
   l'éventail ne sont pas touchés. Passer d'une carte à l'autre : chacune
   fait sa transition (0,32 s), pas de saut. Mouvement réduit : pas de zoom,
   l'aura seule, sans transition. */
@media (hover: hover) and (min-width: 1000px) {
  html.p8-aura .carte::before {
    content: ""; position: absolute; inset: -34px; z-index: -1; pointer-events: none; border-radius: 48px;
    background: radial-gradient(closest-side at var(--ax, 50%) var(--ay, 55%), rgba(0, 0, 0, .16), rgba(0, 0, 0, .06) 55%, transparent);
    opacity: 0; transition: opacity .32s var(--ease);
  }
  html.p8-aura .paliers:is([data-etat="retourne"], :focus-within) .carte:is(:hover, :focus-within)::before { opacity: 1; }
  html.p8-aura.p7-fond-sombre .carte::before { background: radial-gradient(closest-side at var(--ax, 50%) var(--ay, 55%), rgba(0, 0, 0, .28), rgba(0, 0, 0, .1) 55%, transparent); }
}
@media (hover: hover) and (min-width: 1000px) {
  html.js.p8-aura .face--texte { transition: opacity 0s linear .32s, transform .32s var(--ease); }
  html.js.p8-aura .paliers[data-etat="retourne"] .carte:hover .face--texte { transform: rotateY(180deg) scale(1.04); }
}
/* Cartes à plat (mouvement réduit, ou sans script) : l'aura seule, au survol. */
@media (hover: hover) and (min-width: 1000px) {
  html.p8-aura:not(.js) .carte:is(:hover, :focus-within)::before { opacity: 1; }
}
/* Le bouton des démos (&lien-demos=1) : secondaire, sous la rangée de cartes,
   au bureau seulement (au téléphone, la section des démos suit aussitôt). */
.d-demos { display: none; }
@media (min-width: 1000px) {
  html.p7-cartes-d .d-demos { display: block; text-align: center; margin-top: 8px; }
  html.p7-cartes-d .d-demos a {
    display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 10px 20px; border-radius: 999px;
    border: 1px solid var(--gris); color: var(--noir); background: var(--blanc); font-size: 15px; font-weight: 500; text-decoration: none;
    transition: border-color .2s var(--ease), background-color .2s var(--ease);
  }
  html.p7-cartes-d .d-demos a:hover { border-color: var(--noir); background: var(--papier); }
  html.p7-cartes-d .d-demos a span { transition: transform .3s var(--ease); }
  html.p7-cartes-d .d-demos a:hover span { transform: translateX(3px); }
  /* Épinglé (bureau, script, mouvement permis) : il arrive avec le titre. */
  html.js.p7-cartes-d .paliers .d-demos { opacity: var(--ta, 1); }
}
@media (min-width: 1000px) {
  html.js.p7-cartes-d .paliers .d-demos { position: relative; z-index: 2; }
}

/* ---- 6 bis. Bandeau de promesses (passe 2) -------------------------------- */
/* Un ruban qui défile en boucle (transform seulement : le compositeur), deux
   copies de la liste ; la vignette vidéo est posée au centre, PAR-DESSUS le
   texte, qui passe derrière elle. Gris léger #858585 : 3,3:1 sur #F5F5F5,
   au-dessus du seuil des grands textes (3:1). */
.promesses {
  /* Passe 4 : la section tient le rectangle à sa taille finale (493 px de
     haut à 1440, 740 de large depuis le 07/10 : +140 px à la demande de Théo) avec la même marge qu'avant au-dessus et en dessous. */
  --rect-l: clamp(240px, 51.4vw, 740px);
  position: relative; overflow: clip; background: var(--papier);
  padding: clamp(96px, 14vh, 160px) 0;
  min-height: calc(var(--rect-l) * 2 / 3 + 2 * clamp(96px, 14vh, 160px));
  display: grid; place-items: center;
}
.promesses-ruban { width: 100%; }
.promesses-liste { display: flex; list-style: none; padding: 0; margin: 0; }
.promesse {
  display: flex; align-items: center; white-space: nowrap;
  font-size: clamp(64px, 10.4vw, 168px); line-height: 1; letter-spacing: -.035em;
}
.promesse b { font-weight: 800; color: var(--noir); font-stretch: 100%; }
.promesse span { font-weight: 300; color: #858585; margin-left: .22em; }
.promesse-sep { width: .26em; height: .37em; margin: 0 .5em; color: var(--noir); flex: none; }
.promesses-video {
  position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; z-index: 2;
}
/* LE RECTANGLE QUI SE REDRESSE (passe 4), d'après la référence MESURÉE
   (Conicorn, 1440×900, 07/10) : un rectangle 600×400 au rayon de 104 px qui
   part incliné en arrière et plus petit — perspective 2 000 px, rotateX 60°,
   échelle 0,8, origine au centre — et arrive à plat, à l'échelle 1, quand
   son haut atteint 53 % de la hauteur d'écran (≈ 520 px de scroll à 900 px).
   Ici --v va de 0 (incliné) à 1 (à plat) ; sa valeur initiale est 1 : sans
   timeline, en mouvement réduit ou sans script, le rectangle est à plat. */
.vignette {
  width: var(--rect-l, 400px); border-radius: calc(var(--rect-l, 400px) * .1733); background: var(--noir);
  transform: perspective(2000px) rotateX(calc(60deg * (1 - var(--v)))) scale(calc(.8 + .2 * var(--v)));
}
@media all {
  @supports (animation-timeline: view()) {
    .vignette { animation: v2-v linear both; animation-timeline: view(); animation-range: cover 0% cover 47vh; }
  }
  html.js-driver .vignette { animation: none; }
}
@keyframes v2-v { from { --v: 0; } to { --v: 1; } }
.vignette video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vignette.slot--vide { place-items: end start; }
.vignette.slot--vide .slot-note { color: var(--sur-noir); padding: 0 0 calc(var(--rect-l, 400px) * .08) calc(var(--rect-l, 400px) * .1); }
/* Mouvement réduit (le reste du ruban est dans « Rubans », plus bas) : la
   liste passe à la ligne, en plus petit, sous la vignette. */

/* PASSE 6 — LE BANDEAU AU TÉLÉPHONE (html.p6-promesses ; ?promesses=actuel
   rend l'ancien). Sous 720 px, le ruban de 64 px passait derrière la vidéo :
   on ne lisait que des bouts de mots (Théo, 07/10). Ici, UNE promesse par
   largeur d'écran, centrée : le mot en grand, sa suite dessous (qui passe à
   la ligne, jamais au milieu d'un mot), le symbole au-dessus. Le ruban
   avance PAS À PAS : chaque promesse tient 2,9 s, puis glisse en 0,6 s
   (transform seulement, en vw : WebKit ne calcule pas la largeur de la
   piste comme Chromium, un pas en % y tombait à 293 px). Mesuré : un ruban continu ne montrait une promesse
   entière que 0 à 1 fois sur 24 instants, il ne peut pas faire mieux à
   390 px. La vidéo descend SOUS le ruban, dans le flux : rien ne passe
   par-dessus le texte. Même HTML que le bureau, qui ne change pas ; la case
   Pause, le survol, le focus et le hors-écran arrêtent le pas comme avant. */
@media (max-width: 720px) {
  html.p6-promesses .promesses {
    --rect-l: calc(100vw - 2 * var(--pad));
    display: flex; flex-direction: column; align-items: center; gap: 40px;
    min-height: 0; padding: 84px 0 72px;
  }
  html.p6-promesses .promesses .ruban-pause-l { top: 20px; }
  html.p6-promesses .promesses-ruban { --ruban-duree: 28s; }
  html.p6-promesses .promesse {
    flex: 0 0 100vw; width: 100vw; display: grid; justify-items: center; align-content: start; text-align: center;
    padding: 0 var(--pad); white-space: normal; font-size: 56px; line-height: 1; letter-spacing: -.03em;
  }
  html.p6-promesses .promesse b { white-space: nowrap; }
  html.p6-promesses .promesse span {
    max-width: 13em; margin: 12px 0 0; font-size: 26px; line-height: 1.15; letter-spacing: -.01em;
    color: #5E5E5E; font-weight: 400; text-wrap: balance;
  }
  html.p6-promesses .promesse-sep { grid-row: 1; width: 14px; height: 20px; margin: 0 0 16px; }
  html.p6-promesses .promesses-video { position: static; inset: auto; display: block; }
}
@media (max-width: 720px) {
  html.p6-promesses .promesses .ruban-piste { animation-name: p6-pas; animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
}
@keyframes p6-pas {
  0.000% { transform: translateX(0); }
  10.375% { transform: translateX(0); }
  12.500% { transform: translateX(-100vw); }
  22.875% { transform: translateX(-100vw); }
  25.000% { transform: translateX(-200vw); }
  35.375% { transform: translateX(-200vw); }
  37.500% { transform: translateX(-300vw); }
  47.875% { transform: translateX(-300vw); }
  50.000% { transform: translateX(-400vw); }
  60.375% { transform: translateX(-400vw); }
  62.500% { transform: translateX(-500vw); }
  72.875% { transform: translateX(-500vw); }
  75.000% { transform: translateX(-600vw); }
  85.375% { transform: translateX(-600vw); }
  87.500% { transform: translateX(-700vw); }
  97.875% { transform: translateX(-700vw); }
  100.000% { transform: translateX(-800vw); }
}

/* ---- Rubans : la mécanique PARTAGÉE (promesses, bande des démos) ----------
   Une piste de deux moitiés identiques qui glisse de −50 % en boucle
   (transform seulement : le compositeur). Elle s'arrête : au survol, quand
   un élément du ruban a le focus clavier, quand la case Pause est cochée
   (sans script), et hors écran (data-hors, posé par v2.js). Mouvement
   réduit : immobile, les copies cachées, la liste passe à la ligne.
   --ruban-duree règle la vitesse de chaque ruban. */
.ruban-fenetre { overflow: hidden; }
.ruban-piste { display: flex; width: max-content; }
.ruban-pause { position: absolute; opacity: 0; width: 1px; height: 1px; }
.ruban-pause-l {
  position: absolute; top: 24px; right: var(--pad); z-index: 3;
  font-size: 12px; letter-spacing: .08em; color: var(--gris-f); cursor: pointer;
  padding: 10px 14px; border: 1px solid var(--filet); border-radius: 999px; background: var(--blanc);
}
/* Revue du 11/10 : 44 px de haut, la cible tactile minimale (41 avant). */
.ruban-pause-l { display: inline-flex; align-items: center; min-height: 44px; padding-block: 0; }
.ruban-pause:checked + .ruban-pause-l { background: var(--noir); color: var(--blanc); border-color: var(--noir); }
.ruban-pause:focus-visible + .ruban-pause-l { outline: 2px solid var(--noir); outline-offset: 3px; }
@media all {
  .ruban-piste { animation: v2-ruban var(--ruban-duree, 48s) linear infinite; will-change: transform; }
  .ruban[data-hors] .ruban-piste,
  .ruban:has(.ruban-pause:checked) .ruban-piste,
  .ruban:has(:focus-visible) .ruban-piste,
  .ruban-fenetre:hover .ruban-piste { animation-play-state: paused; }
}
@keyframes v2-ruban { to { transform: translateX(-50%); } }

/* ---- 1 bis. Bande des démos (passe 4) -------------------------------------
   Un filet noir de 1 px, le label (même style que les numéros des cartes et
   des étapes : 12 px, capitales, +0,14 em, gris #767676 = 4,54:1), puis les
   noms des boutiques en défilement lent. Chaque nom a son traitement, avec
   les seules polices de la page (Archivo variable, le serif des titres) :
   aucune icône, aucun faux logo. Hauteur : 104 px à 1440 (deux marges de
   32 px et une ligne de 40 px) — assez pour séparer, assez peu pour ne pas
   devenir une section. */
.marques {
  --ruban-duree: 60s; --marque-h: 40px;
  position: relative; display: flex; align-items: center; gap: 32px;
  border-top: 1px solid var(--noir); padding: 32px 0 32px var(--pad); background: var(--blanc);
}
.marques-label {
  flex: none; font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gris); white-space: nowrap;
}
.marques .ruban-fenetre { flex: 1; min-width: 0; }
.marques .ruban-pause-l { position: static; flex: none; margin-right: var(--pad); order: 3; }
.marques .ruban-fenetre { order: 2; }
.marques-liste { display: flex; align-items: center; list-style: none; margin: 0; padding: 0; }
.marque {
  display: flex; align-items: center; height: var(--marque-h); margin-right: clamp(48px, 6vw, 96px);
  white-space: nowrap; color: var(--encre); line-height: 1; font-size: 30px;
}
.marque-logo { height: var(--marque-h); width: auto; display: block; }
.marque--raster  { font-weight: 900; font-stretch: 125%; text-transform: uppercase; letter-spacing: .02em; font-size: 28px; }
.marque--circa   { font-family: var(--f-titre); font-style: italic; font-size: 34px; letter-spacing: -.01em; }
.marque--colonne { font-family: var(--f-titre); text-transform: uppercase; letter-spacing: .24em; font-size: 22px; }
.marque--eclipse { font-weight: 300; font-stretch: 125%; text-transform: uppercase; letter-spacing: .32em; font-size: 20px; }
.marque--signal  { font-weight: 600; letter-spacing: -.045em; font-size: 32px; }
/* OFFSET (passe 4B) : la seule en italique sans empattement : Archivo 800
   penché (oblique synthétique, Archivo n'a pas d'italique ici), chasse
   étroite, capitales serrées. Distinct de RASTER (900 large droit). */
.marque--offset  { font-weight: 800; font-stretch: 100%; font-style: oblique 10deg; text-transform: uppercase; letter-spacing: -.02em; font-size: 30px; }
.marque--palier  { font-weight: 600; font-size: 24px; }
@media (max-width: 720px) {
  .marques { flex-wrap: wrap; gap: 14px 0; padding: 22px 0; --marque-h: 32px; }
  .marques-label { padding-left: var(--pad); flex: 1; }
  .marques .ruban-fenetre { flex-basis: 100%; order: 4; }
  .marques .ruban-pause-l { order: 2; }
  .marque { font-size: 24px; }
}

/* ---- 7. Zoom + démos ------------------------------------------------------ */
.demos { background: var(--papier); padding-bottom: clamp(96px, 14vh, 160px); }
.zoom-scene { position: relative; display: grid; place-items: center; padding: clamp(96px, 14vh, 160px) var(--pad) 160px; }
.zoom-decor { display: none; }
.zoom-texte { position: relative; z-index: 2; text-align: center; max-width: 760px; }
.demos-sub { margin-top: 18px; color: var(--gris-f); }
/* La barre d'état des démos (11/10) : une pilule de verre, trois segments
   séparés par des filets, un point qui bat pour dire « en ligne ». Elle entre
   avec le titre (même --r dans la scène du zoom). */
.demos-etat {
  list-style: none; margin: 32px auto 0; padding: 6px; display: inline-flex; flex-wrap: wrap; justify-content: center;
  border: 1px solid rgba(0,0,0,.08); border-radius: 999px; background: var(--glass);
  -webkit-backdrop-filter: blur(20px) saturate(1.4); backdrop-filter: blur(20px) saturate(1.4);
  font: 500 14px/1 var(--font-body); color: var(--noir); font-variant-numeric: tabular-nums;
}
.demos-etat li { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 16px; }
.demos-etat li + li { border-left: 1px solid rgba(0,0,0,.1); }
.demos-etat-live { border-radius: 999px; background: var(--noir); color: var(--blanc); }
.demos-etat li.demos-etat-live + li { border-left-color: transparent; }
.pouls { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--etat-ok); }
.pouls::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: inherit; }
@media all {
  .pouls::after { animation: v2-pouls 2s cubic-bezier(.16, 1, .3, 1) infinite; }
}
@keyframes v2-pouls { from { transform: scale(1); opacity: .7; } to { transform: scale(3.2); opacity: 0; } }
@media (max-width: 720px) {
  .demos-etat { flex-wrap: nowrap; font-size: 13px; }
  .demos-etat li { padding: 0 12px; white-space: nowrap; }
}
/* Au téléphone, la version cède la place : la pilule tient sur une ligne. */
@media (max-width: 480px) { .demos-etat-version { display: none !important; } .demos-etat-version + li { border-left-color: transparent; } }
@media all {
  /* Le décor : un cadre qui grandit jusqu'au plein écran (0,42 → 1 sur 55 %
     de la course), puis se dissout pendant que le titre arrive. Valeur
     initiale de --z = 1 : décor invisible, titre seul. */
  .zoom { height: calc(100svh + 1400px); --pre: 0; }
  /* 11/10 : avec les trois phrases, un prélude (--pre, en part de la course)
     précède le zoom ; la course s'allonge d'autant (700 px). --zz est la
     course du zoom d'avant, intacte. */
  .zoom:has(.zoom-ligne--phrases) { height: calc(100svh + 2100px); --pre: .3333; }
  .zoom-scene {
    position: sticky; top: 0; height: 100svh; overflow: hidden; padding-block: 0;
    /* Déclarées sur la SCÈNE : le décor et le titre (frères) les lisent. */
    --zz: clamp(0, calc((var(--z) - var(--pre)) / (1 - var(--pre))), 1);
    --g: clamp(0, calc(var(--zz) / .55), 1);
    --r: clamp(0, calc((var(--zz) - .62) / .26), 1);
    --s: calc(.42 + .58 * var(--g));
  }
  .zoom-decor {
    display: grid; place-items: center; position: absolute; inset: 0; z-index: 0; pointer-events: none;
    opacity: calc(1 - var(--r));
  }
  /* Tant que l'image plein cadre n'existe pas : un aplat noir, pas un gris
     sur gris qu'on ne voit pas grandir. L'étiquette se range dans un coin. */
  .zoom-decor .slot--vide { background: var(--noir); place-items: end start; }
  .zoom-decor .slot--vide .slot-note { color: var(--sur-noir); padding: 0 0 28px 32px; }
  .zoom-decor .slot {
    width: 100vw; height: 100svh; aspect-ratio: auto;
    transform: scale(var(--s)); border-radius: calc(var(--rayon) / var(--s));
    will-change: transform;
  }
  /* PASSE 2 — LE VIDE DES DÉMOS. Centré dans la scène épinglée, le titre
     laissait toute la moitié basse de l'écran vide avant les cartes (385 px
     mesurés à 1440×900). Il se pose donc en bas de la scène, à 20svh du
     bord, et les cartes remontent de ces 20svh moins 160 px : 160 px entre
     le sous-titre et les cartes, quelle que soit la hauteur d'écran. */
  .zoom-texte { align-self: end; margin-bottom: 20svh; opacity: var(--r); translate: 0 calc((1 - var(--r)) * 28px); }
  .demos-corps { position: relative; z-index: 3; margin-top: calc(160px - 20svh); }
  @supports (animation-timeline: view()) {
    .zoom { animation: v2-z linear both; animation-timeline: view(); animation-range: contain 0% contain 100%; }
  }
  html.js-driver .zoom { animation: none; }
}
@keyframes v2-z { from { --z: 0; } to { --z: 1; } }
/* Revue du 11/10 : sans script ET sans animation-timeline (Safari d'avant
   26, Firefox), rien ne pilote --z : la scène restait un sas épinglé de
   1 400 px, presque vide. Elle reprend alors sa hauteur naturelle : la
   phrase, le titre et les cartes à la suite, le décor caché. */
@supports not (animation-timeline: view()) {
  html:not(.js) .zoom { height: auto; }
  html:not(.js) .zoom-scene { position: relative; height: auto; overflow: visible; padding-block: clamp(96px, 14vh, 160px) 160px; }
  html:not(.js) .zoom-decor { display: none; }
  html:not(.js) .zoom-texte { align-self: auto; margin-bottom: 0; opacity: 1; translate: none; }
  html:not(.js) .zoom-ligne { position: relative; top: auto; padding-bottom: 48px; opacity: 1; translate: none; }
  html:not(.js) .demos-corps { margin-top: 0; }
}
/* 11/10 (Théo) : « One theme. Three tiers. One payment. » devient le titre du
   vide au-dessus de l'image qui grandit. Sans mouvement : un bloc posé au-dessus
   de la scène. Avec : il s'allume lettre par lettre sur le premier quart de la
   course (--t piloté par --z, pas par sa propre position, la scène est
   épinglée), puis s'efface et monte quand l'image passe la moitié. */
.zoom-ligne { position: relative; z-index: 1; padding: 0 var(--pad) 48px; }
.zoom-ligne .manif-label { --gris0: 118; margin: 0 auto 20px; line-height: 16px; height: 16px; text-align: center;
  font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; }
.zoom-ligne .manif-p { max-width: 1200px; margin: 0 auto; text-align: center; color: #1A1A1A;
  font-size: var(--manif); line-height: var(--manif-lh); letter-spacing: var(--d2-ls); text-wrap: balance; }
.br-m { display: none; }
@media (max-width: 720px) {
  .br-m { display: inline; }
  .zoom-ligne .manif-p { font-size: clamp(30px, 9vw, 38px); line-height: 1.08; }
}
@media all {
  .zoom-ligne {
    position: absolute; left: 0; right: 0; top: clamp(96px, 13svh, 150px); padding-bottom: 0;
    /* Le cadre qui grandit pousse le titre : il monte (120 px) et s'efface
       avant que le cadre ne l'atteigne (calculé : au plus près, 135 px d'écart). */
    opacity: calc(1 - clamp(0, calc((var(--g) - .15) / .25), 1));
    translate: 0 calc(clamp(0, calc((var(--g) - .1) / .3), 1) * -120px);
  }
  .zoom-ligne .manif-bloc { --t: clamp(0, calc(var(--z) / .1), 1); animation: none; }
  /* Le cadre part plus bas pour laisser la place au titre, et regagne le
     centre en grandissant. */
  .zoom-scene:has(.zoom-ligne) .zoom-decor { translate: 0 calc((1 - var(--g)) * 22svh); }
}
/* 11/10 (Théo : « les faire apparaître un par un, les uns en dessous des
   autres, pour combler ce padding, que ce soit moins brutal ») : une phrase
   par ligne, plus grandes, qui entrent chacune à son tour pendant le
   prélude (--p, 0 → 1) : elles montent, se précisent (flou → net) et
   s'allument. Le cadre attend en bas, plus bas qu'avant, et ne grandit
   qu'une fois la troisième phrase posée. */
.zoom-ligne--phrases .zl-phrase { display: block; }
.zoom-ligne--phrases .manif-p { font-size: clamp(36px, 4.6vw, 72px); line-height: 1.06; text-wrap: nowrap; }
.zoom-ligne--phrases .zl-phrase + .zl-phrase { margin-top: .12em; }
@media (max-width: 720px) { .zoom-ligne--phrases .manif-p { font-size: clamp(32px, 10.4vw, 44px); } }
@media all {
  /* Théo, 11/10 : « toujours un padding assez important » entre la dernière
     phrase et le cadre, surtout au téléphone. Le texte ne se cale plus sur
     le haut de l'écran mais sur le cadre : son bas est à --ecart du haut du
     cadre, quelle que soit la hauteur d'écran. Le cadre (100svh à l'échelle
     ,42, décalé de --decal) a son haut à 29svh + --decal. */
  .zoom-scene:has(.zoom-ligne--phrases) { --decal: 30svh; --ecart: clamp(48px, 7svh, 72px); }
  .zoom-ligne--phrases {
    --p: clamp(0, calc(var(--z) / var(--pre)), 1);
    top: auto; bottom: calc(71svh - var(--decal) + var(--ecart));
    /* Collé au cadre, le texte doit partir dès que le cadre grandit : il
       s'efface sur le premier cinquième de la croissance et monte plus vite. */
    opacity: calc(1 - clamp(0, calc(var(--g) / .18), 1));
    translate: 0 calc(clamp(0, calc(var(--g) / .25), 1) * -160px);
  }
  .zoom-ligne--phrases .manif-bloc { --t: clamp(0, calc(var(--p) / .92), 1); }
  .zoom-ligne--phrases .zl-phrase {
    --v: clamp(0, calc((var(--p) - var(--k) * .3) / .28), 1);
    opacity: var(--v);
    translate: 0 calc((1 - var(--v)) * 36px);
    filter: blur(calc((1 - var(--v)) * 10px));
  }
  .zoom-ligne--phrases .manif-label { opacity: clamp(0, calc(var(--p) / .12), 1); }
  .zoom-scene:has(.zoom-ligne--phrases) .zoom-decor { translate: 0 calc((1 - var(--g)) * var(--decal)); }
}
@media (max-width: 720px) {
  .zoom-scene:has(.zoom-ligne--phrases) { --decal: 20svh; --ecart: 44px; }
}
/* PASSE 6 — LE DÉCOR DU ZOOM AU TÉLÉPHONE : un second emplacement, vertical
   ('zoom-mobile', images.php), montré sous 720 px à la place du 16/9. Au
   bureau il n'existe pas à l'écran (une image paresseuse non affichée n'est
   pas chargée). Tant que les deux sont vides, le rendu est le même aplat. */
.zoom-decor .zoom-image--mobile { display: none; }
@media (max-width: 720px) {
  .zoom-decor .zoom-image:not(.zoom-image--mobile) { display: none; }
  .zoom-decor .zoom-image--mobile { display: grid; }
  .zoom-decor .zoom-image--mobile:not(.slot--vide) { display: block; }
}

/* Les cartes (passe 2) : 3 + 2 centrées, environ 344 px de large à 1440
   (203 px avant), au lieu d'une rangée de cinq vignettes ; au téléphone, un
   rail qu'on fait défiler au doigt, chaque carte calée par scroll-snap. */
.demos-liste { list-style: none; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 40px 24px; }
.demo { flex: 0 0 calc((100% - 2 * 24px) / 3); min-width: 0; }
@media (max-width: 999px) { .demo { flex-basis: calc((100% - 24px) / 2); } }
@media (max-width: 699px) {
  .demos-liste {
    flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto; gap: 14px;
    margin-inline: calc(-1 * var(--pad)); padding: 0 var(--pad) 12px; scroll-padding-inline: var(--pad);
    scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  }
  .demo { flex-basis: 74vw; scroll-snap-align: start; }
}
/* PASSE 6 — LES DÉMOS EN GRILLE AU TÉLÉPHONE (html.p6-demos ; ?demos=rail
   rend l'ancien rail). Théo : « une démo par une démo avec un slide
   horizontal », alors que la grille du bureau « est vraiment pas mal ».
   Sous 700 px : deux colonnes (défaut, html.p6-demos-grille), ou une
   vedette pleine largeur puis deux colonnes (?demos=vedette : la première
   et, si le compte l'impose, la dernière en pleine largeur). Mêmes
   vignettes 4/5, même carte ; entre 700 et 999 px rien ne change. */
@media (max-width: 699px) {
  html.p6-demos .demos-liste {
    display: grid; grid-template-columns: 1fr 1fr; gap: 34px 14px;
    overflow: visible; margin-inline: 0; padding: 0; scroll-snap-type: none; scroll-padding-inline: 0;
  }
  html.p6-demos .demo { min-width: 0; }
  html.p6-demos .demo-lien { gap: 4px; }
  html.p6-demos .demo-image { margin-bottom: 10px; }
  html.p6-demos .demo-nom { font-size: 26px; line-height: 1.05; }
  html.p6-demos :is(.demo-mdp, .demo-ouvre) { font-size: 13px; }
  html.p6-demos-vedette .demo:first-child,
  html.p6-demos-vedette .demo:last-child:nth-child(even) { grid-column: 1 / -1; }
  html.p6-demos-vedette .demo:first-child .demo-nom,
  html.p6-demos-vedette .demo:last-child:nth-child(even) .demo-nom { font-size: 34px; }
  html.p6-demos-vedette .demo:first-child .slot,
  html.p6-demos-vedette .demo:last-child:nth-child(even) .slot { aspect-ratio: 4 / 3; }
  html.p6-demos .demos-note { margin-top: 44px; }
}
.demo-lien { position: relative; display: grid; gap: 6px; text-decoration: none; color: var(--noir); border-radius: var(--rayon); }
.demo-image { margin-bottom: 12px; }
/* Revue du 11/10 : les cartes de démo prennent le rayon des surfaces (24 px,
   comme les tuiles et les vitrines) au lieu des 12 px des petites images. */
.demo-lien, .demo-image.slot { border-radius: var(--r-surface); }
.demo-image img { transition: scale .8s var(--ease); }
.demo-lien:hover .demo-image img { scale: 1.03; }
.demo-nom { font-family: var(--f-titre); font-size: var(--d3); line-height: 1.1; letter-spacing: var(--d3-ls); }
.demo-mdp { font-size: 14px; color: var(--gris-f); }
.demo-mdp b { font-weight: 600; color: var(--noir); }
.demo-ouvre { font-size: 14px; font-weight: 500; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--filet); }
.demo-lien:hover .demo-ouvre { text-decoration-color: currentColor; }
.demos-note { max-width: 720px; margin-top: 40px; font-size: 13px; line-height: 1.55; color: var(--gris-f); }

/* ---- 8. Comment ça marche ------------------------------------------------- */
.etapes { padding: clamp(112px, 16vh, 180px) 0; }
.etapes-grille { display: grid; gap: 48px; }
@media (min-width: 900px) {
  .etapes-grille { grid-template-columns: 5fr 7fr; gap: 64px; align-items: start; }
  .etapes-tete { position: sticky; top: 120px; }
}
.etapes-tete .bt { margin-top: 32px; }
.etapes-liste { list-style: none; padding: 0; }
.etape { display: grid; grid-template-columns: 56px 1fr; column-gap: 16px; row-gap: 8px; padding: 28px 0 30px; border-top: 1px solid var(--filet); }
.etape:last-child { border-bottom: 1px solid var(--filet); }
.etape-n { grid-row: 1 / 3; font-size: 12px; letter-spacing: .14em; font-weight: 500; color: var(--gris); padding-top: .7em; }
.etape-t { font-size: var(--d3); line-height: 1.12; letter-spacing: var(--d3-ls); }
.etape-p { color: var(--gris-f); max-width: 34em; }

/* PASSE 6 — LES ÉTAPES AU TÉLÉPHONE (html.p6-etapes ; ?etapes=actuel rend
   les quatre blocs d'avant). Théo : « 4 parties bof ». Sous 900 px : un très
   grand chiffre en Caslon, en contour, qui se remplit quand le trait arrive
   à lui ; un trait vertical à gauche qui se remplit avec le scroll ; une
   image par étape. Toujours une <ol> de quatre <li>. Le script (v2.js,
   « étapes ») écrit --et (le trait, 0 → 1) sur la liste et --on (le
   chiffre plein) sur chaque étape ; SANS script, en mouvement réduit, ou
   s'il n'a pas encore tourné : les valeurs de repli valent 1, le trait est
   plein et les chiffres aussi. Transform et opacité seulement. */
.etape-image { display: none; }
@media (max-width: 899px) {
  html.p6-etapes .etapes-grille { gap: 56px; }
  html.p6-etapes .etapes-liste { position: relative; padding-left: 30px; max-width: 560px; }
  html.p6-etapes .etapes-liste::before,
  html.p6-etapes .etapes-liste::after { content: ""; position: absolute; left: 0; top: 18px; bottom: 0; width: 1px; background: var(--filet); }
  html.p6-etapes .etapes-liste::after {
    left: -.5px; width: 2px; background: var(--noir);
    transform-origin: 50% 0; transform: scaleY(var(--et, 1)); will-change: transform;
  }
  html.p6-etapes .etape { display: block; position: relative; padding: 0 0 64px; border: 0; }
  html.p6-etapes .etape:last-child { border: 0; padding-bottom: 8px; }
  /* Le repère sur le trait, à hauteur du chiffre : un petit carré. */
  html.p6-etapes .etape::before {
    content: ""; position: absolute; left: -34.5px; top: 14px; width: 9px; height: 9px;
    background: var(--blanc); border: 1px solid var(--noir);
  }
  html.p6-etapes .etape::after {
    content: ""; position: absolute; left: -34.5px; top: 14px; width: 9px; height: 9px;
    background: var(--noir); opacity: var(--on, 1);
  }
  html.p6-etapes .etape > .etape-n {
    position: relative; display: block; margin: 0 0 18px; padding: 0;
    font-family: var(--f-titre); font-weight: 400; font-size: clamp(96px, 31vw, 136px); line-height: .82; letter-spacing: -.03em;
    color: transparent; -webkit-text-stroke: 1px var(--noir); font-variant-numeric: lining-nums;
  }
  html.p6-etapes .etape > .etape-n::after {
    content: attr(data-n); position: absolute; left: 0; top: 0;
    color: var(--noir); -webkit-text-stroke: 0; opacity: var(--on, 1);
  }
  html.p6-etapes .etape-t { margin-bottom: 10px; }
  html.p6-etapes .etape-image { display: grid; margin-top: 24px; }
  html.p6-etapes .etape-image:not(.slot--vide) { display: block; border: 1px solid var(--filet); }
}
@media (max-width: 899px) and (prefers-contrast: more) {
  html.p6-etapes .etapes-liste::before { background: var(--gris); }
}

/* PASSE 8, CHANTIER 6 — « FOUR STEPS » EN COURBE (?etapes=courbe, sous 900 px).
   Théo : un trait qui se dessine au défilement et fait apparaître texte et
   images. La courbe (SVG étiré sur la liste, trait d'épaisseur constante) se
   trace par stroke-dashoffset ; chaque étape est un bloc posé dans un creux de
   la courbe (68 % de la largeur, côté opposé au trait), qui apparaît quand le
   trait arrive à son niveau. Deux moteurs, à comparer (&tracer=) :
     css  animation-timeline natif (view-timeline sur la liste) ;
     js   v2.js écrit --et (le trait) et --on (chaque étape), comme en passe 6 ;
     auto le natif si le navigateur sait, sinon le script (défaut).
   Sans script, en mouvement réduit, ou avant le premier calcul : tout est
   tracé, tout est visible (les valeurs de repli valent 1). */
.courbe { display: none; }
@media (max-width: 899px) {
  html.p8-courbe .courbe-cadre { position: relative; max-width: 560px; }
  html.p8-courbe .courbe { display: block; position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
  html.p8-courbe .courbe path { fill: none; vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; }
  html.p8-courbe .courbe-fond { stroke: var(--filet); stroke-width: 1.5; }
  html.p8-courbe .courbe-trait { stroke: var(--noir); stroke-width: 2; stroke-dasharray: none; }
  /* PASSE 9 (le bug des captures de Théo) : le SVG était étiré sans
     proportion (viewBox 100 × 400 sur ~366 × 2 734 px) avec un trait à
     épaisseur constante (vector-effect) ; les tirets « 1 1 » de pathLength=1
     se calculaient alors sur une longueur fausse, WebKit ET Chromium, et le
     trait se répétait (noir, gris, noir, et un point isolé). Le tiret n'est
     posé que quand v2.js a redessiné le chemin en pixels réels
     (.courbe-px : viewBox = taille de la boîte, aucune déformation) ; avant,
     sans script ou en mouvement réduit, le trait est plein. */
  html.p8-courbe .courbe-px .courbe-trait { stroke-dasharray: 1 1; stroke-dashoffset: calc(1 - var(--et, 1)); }
  html.p8-courbe .courbe-pointe { display: none; }
  html.p8-pointe .courbe:not(.courbe-px) .courbe-pointe { display: none; }
  html.p8-pointe .courbe-pointe {
    display: block; stroke: var(--noir); stroke-width: 7; stroke-dasharray: .004 1.2;
    stroke-dashoffset: calc(.004 - var(--et, 1)); filter: drop-shadow(0 0 4px rgba(0, 0, 0, .35));
  }
  /* La liste : quatre rangées de même hauteur (la courbe est dessinée pour
     des rangées égales), le trait vertical de la passe 6 s'efface. */
  html.p8-courbe .etapes-liste { display: grid; grid-auto-rows: 1fr; gap: 0; padding: 0; max-width: none; }
  html.p8-courbe .etapes-liste::before, html.p8-courbe .etapes-liste::after,
  html.p8-courbe .etape::before, html.p8-courbe .etape::after { content: none; }
  html.p8-courbe .etape { width: 68%; padding: 56px 0 90px; opacity: var(--on, 1); transform: translateY(calc((1 - var(--on, 1)) * 14px)); }
  html.p8-courbe .etape:nth-child(even) { margin-left: auto; }
  html.p8-courbe .etape > .etape-n { display: inline-block; font-size: clamp(56px, 17vw, 72px); margin-bottom: 10px; }
  html.p8-courbe .etape-p { font-size: 15px; line-height: 1.5; }
  html.p8-courbe .etape-image { margin-top: 16px; }
}
/* Le moteur natif : la liste porte la ligne de temps ; le trait va de 0
   (haut de la liste à 60 % de l'écran) à 1 (bas de la liste à 60 %). */
@keyframes p8-trace { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes p8-pointe { from { stroke-dashoffset: .004; } to { stroke-dashoffset: -.996; } }
@keyframes p8-etape { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (max-width: 899px) {
  @supports (animation-timeline: view()) {
    html.js:is(.p8-tracer-css, .p8-tracer-auto) .courbe-cadre { view-timeline: --courbe block; }
    html.js:is(.p8-tracer-css, .p8-tracer-auto) .courbe-trait { animation: p8-trace linear both; animation-timeline: --courbe; animation-range: cover 40vh cover calc(100% - 40vh); }
    html.js:is(.p8-tracer-css, .p8-tracer-auto).p8-pointe .courbe-pointe { animation: p8-pointe linear both; animation-timeline: --courbe; animation-range: cover 40vh cover calc(100% - 40vh); }
    html.js:is(.p8-tracer-css, .p8-tracer-auto) .etape { animation: p8-etape linear both; animation-timeline: view(); animation-range: cover 40vh cover calc(40vh + 90px); }
  }
}

/* ---- 9. FAQ, au-dessus du contact ---------------------------------------- */
.faq { padding: 0 0 clamp(72px, 10vh, 112px); }
.faq-col { max-width: calc(var(--col-texte) + 2 * var(--pad)); text-align: center; }   /* 840 avant la revue du 11/10 */
.faq-sub { margin: 16px 0 40px; color: var(--gris-f); }
.faq-liste { display: grid; gap: 10px; text-align: left; }
.faq-item { background: var(--papier); border-radius: var(--rayon); }
.faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  min-height: 64px; padding: 18px 22px; cursor: pointer; list-style: none;
  font-size: 17px; font-weight: 500; color: var(--noir); border-radius: var(--rayon);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:focus-visible { outline-offset: -2px; }
/* Le signe : deux traits ; ouvert, le vertical s'efface (+ devient −). */
.faq-signe { position: relative; flex: none; width: 14px; height: 14px; }
.faq-signe::before, .faq-signe::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 2px; margin-top: -1px; border-radius: 2px; background: currentColor; transition: transform .3s var(--ease), opacity .3s var(--ease); }
.faq-signe::after { transform: rotate(90deg); }
.faq-item[open] .faq-signe::after { transform: rotate(90deg) scaleX(0); opacity: 0; }
.faq-item p { padding: 0 22px 22px; max-width: 44em; font-size: 15px; line-height: 1.6; color: var(--gris-f); }
@media all {
  @supports (interpolate-size: allow-keywords) {
    .faq-liste { interpolate-size: allow-keywords; }
    .faq-item::details-content { height: 0; overflow: clip; transition: height .3s var(--ease), content-visibility .3s allow-discrete; }
    .faq-item[open]::details-content { height: auto; }
  }
}

/* ---- 10. Contact : une question par écran (passe 2, piste B) ------------- */
/* Le bloc noir arrondi est gardé. Sans script : les quatre étapes empilées,
   un vrai formulaire. Avec script (.est-pas-a-pas posé par v2.js) : une
   étape visible, la question en grand Libre Caslon, la réponse en grand
   Archivo, Suivant / Entrée / Retour, l'avancement « 2 / 4 ». */
.contact { padding-bottom: clamp(72px, 10vh, 112px); }
.contact-bloc {
  position: relative; display: grid; gap: clamp(28px, 4vw, 48px);
  background: var(--noir); color: var(--blanc);
  border-radius: var(--rayon); padding: clamp(28px, 5.5vw, 80px) clamp(22px, 5vw, 72px);
}
.contact-h { font: 500 14px/1.4 var(--font-body); letter-spacing: .02em; color: var(--sur-noir); max-width: 40em; }
.contact-q {
  font-family: var(--f-titre); font-weight: var(--titre-w); color: var(--blanc);
  font-size: clamp(32px, 4.6vw, 64px); line-height: 1.06; letter-spacing: var(--d2-ls);
  padding: 0; text-wrap: balance;
}
.etape-n { display: block; margin-bottom: 18px; font: 500 13px/1 var(--font-body); letter-spacing: .14em; color: var(--sur-noir); font-variant-numeric: tabular-nums; }
/* Revue du 11/10 : la règle ci-dessus (faite pour le contact noir) débordait
   sur les quatre étapes, sur fond blanc : #A3A3A3, 2,52:1. Hors du contact
   noir, le numéro passe à --gris (4,54:1). */
.etape .etape-n { color: var(--gris); }
.contact-form { display: grid; gap: clamp(40px, 6vw, 72px); }
/* Un <fieldset> en bloc (une grille ignore le float de la légende et la
   posait à côté des réponses) ; l'espacement vient des marges. */
.pas { border: 0; margin: 0; padding: 0; min-width: 0; display: block; }
.pas > legend { display: block; width: 100%; margin: 0 0 32px; }
.pas > * + * { margin-top: 24px; }
.contact-pied [hidden] { display: none; }
/* Les choix : de grandes pilules Archivo, le bouton radio caché mais réel. */
.choix-liste { display: flex; flex-wrap: wrap; gap: 12px; }
.choix { position: relative; cursor: pointer; }
.choix input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.choix span {
  display: inline-flex; align-items: center; min-height: 56px; padding: 0 26px; border-radius: 999px;
  border: 1px solid #6A6A6A; color: var(--blanc);
  font: 400 clamp(18px, 1.6vw, 22px)/1.2 var(--font-body);
  transition: background-color .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.choix:hover span { border-color: var(--blanc); }
.choix input:checked + span { background: var(--blanc); color: var(--noir); border-color: var(--blanc); }
.choix input:focus-visible + span { outline: 2px solid var(--blanc); outline-offset: 3px; }
.champ { display: grid; gap: 10px; max-width: 640px; }
.champ span { font-size: 13px; letter-spacing: .06em; color: var(--sur-noir); }
.champ input, .champ textarea {
  width: 100%; padding: 14px 0 12px; border: 0; border-bottom: 1px solid #6A6A6A; border-radius: 0;
  background: transparent; color: var(--blanc);
  font: 400 clamp(22px, 2.2vw, 30px)/1.3 var(--font-body);
}
.champ textarea { resize: vertical; min-height: 140px; border: 1px solid #6A6A6A; border-radius: var(--rayon); padding: 14px 16px; font-size: clamp(18px, 1.6vw, 22px); }
.champ input:focus-visible { outline: none; border-bottom: 2px solid var(--blanc); padding-bottom: 11px; }
.champ textarea:focus-visible { outline: 2px solid var(--blanc); outline-offset: 2px; }
.champ input[aria-invalid="true"] { border-bottom-color: var(--blanc); }
.etape-err:empty { display: none; }
.etape-err, .contact-erreur { font-size: 15px; color: var(--blanc); padding-left: 14px; border-left: 2px solid var(--blanc); }
.contact-pied { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 14px; }
.contact-delai { flex-basis: 100%; margin-top: 18px; font-size: 14px; max-width: 40em; }
.contact-sub { color: var(--sur-noir); }
.bt--contour { background: transparent; color: var(--blanc); border-color: #6A6A6A; }
.bt--contour:hover { border-color: var(--blanc); }
.contact .bt:focus-visible { outline: 2px solid var(--blanc); outline-offset: 3px; }
.contact-merci { display: grid; gap: 18px; padding-block: clamp(24px, 6vw, 80px); }
.contact-merci:focus { outline: none; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Le pas à pas (script) : une étape, une hauteur stable (aucun saut du
   bloc d'une question à l'autre), une entrée douce. */
.contact-form.est-pas-a-pas { gap: 40px; min-height: clamp(420px, 52svh, 560px); align-content: space-between; }
.est-pas-a-pas .pas:not(.est-courante) { display: none; }
.est-pas-a-pas .contact-delai { margin-top: 8px; }
@media all {
  .est-pas-a-pas .pas.est-courante { animation: v2-etape .45s var(--ease) both; }
}
@keyframes v2-etape { from { opacity: 0; translate: 0 14px; } }
@media (max-width: 620px) {
  .choix-liste { flex-direction: column; align-items: stretch; }
  .choix span { width: 100%; }
  .contact-pied .bt { flex: 1 1 auto; }
  .contact-form.est-pas-a-pas { min-height: 0; }
}

/* ---- 10 bis. Contact en VERRE (passe 5, ?contact=a | ?contact=b) ----------
   Théo : plus de carré noir, une carte claire « liquid glass », le pied de
   page reste blanc et on y arrive sans coupure. Le verre ne se voit que s'il
   y a quelque chose à flouter derrière : un fond doux de deux grandes formes
   grises très pâles, floues, qui se fondent dans le blanc avant le pied.
   Tout ici est préfixé .contact--v : l'actuel (défaut) n'est pas touché. */
.contact--v { position: relative; overflow: clip; padding: clamp(40px, 6vh, 72px) 0 clamp(72px, 10vh, 112px); background: var(--blanc); }
.contact-fond { position: absolute; inset: 0; pointer-events: none; }
/* Revue du 11/10 : les taches floues et l'ombre douce de la carte sont
   retirées (hors charte : pas d'ombre douce). La carte devient une surface
   du système : filet, papier, --r-surface. */
.fond-forme { display: none; }
.fond-forme--1 { width: 46vw; height: 30vw; max-width: 720px; max-height: 470px; left: 12%; top: 14%; background: #E4E4E4; }
.fond-forme--2 { width: 38vw; height: 26vw; max-width: 600px; max-height: 400px; right: 10%; top: 38%; background: #EDEDED; }
.verre {
  position: relative; max-width: var(--col-texte); margin: 0 auto;
  padding: clamp(24px, 4vw, 48px);
  border-radius: var(--r-surface);
  background: var(--papier);
  border: 1px solid var(--hair);
  box-shadow: none;
}
/* Sans backdrop-filter : un fond presque opaque, lisible. */
@media (prefers-contrast: more) {
  .verre { background: var(--blanc); border-color: var(--noir); box-shadow: none; }
  .contact--v .rep-c, .contact--v .champ input, .contact--v .champ textarea { border-color: var(--noir); }
}
.verre-tete { display: flex; align-items: center; gap: 14px; margin-bottom: clamp(24px, 3vw, 36px); }
.verre-avatar { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--filet); flex: none; }
.verre-studio { font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--gris-f); }
.verre-h { font-size: 15px; font-weight: 400; color: var(--encre); margin-top: 2px; }
.contact--v .contact-q { color: var(--noir); font-size: clamp(30px, 3.8vw, 52px); }
.contact--v .contact-form { gap: clamp(28px, 4vw, 40px); }
.contact--v .contact-form.est-pas-a-pas { min-height: 0; gap: 28px; }
.contact--v .pas > legend { margin-bottom: 24px; }
.verre-texte { font-size: 14px; line-height: 1.55; color: var(--gris-f); max-width: 40em; }
.verre-signature { display: flex; align-items: center; gap: 6px; margin-top: 22px; color: var(--gris-f); font-size: 14px; }
.verre-signature img { height: 24px; width: auto; display: block; }
.verre-signature > span[aria-hidden] { display: none; }   /* le tiret cadratin devant le logo (règle de voix) */
.contact--v .contact-merci { padding-block: 8px 0; gap: 12px; }
/* Champs : sur le clair. */
.contact--v .champ span { color: var(--gris-f); }
.contact--v .champ input { color: var(--noir); border-bottom-color: #9A9A9A; }
.contact--v .champ input:focus-visible { border-bottom-color: var(--noir); }
.contact--v .champ textarea { color: var(--noir); border-color: #9A9A9A; background: rgba(255,255,255,.6); min-height: 96px; font-size: 17px; }
.contact--v .champ textarea:focus-visible { outline-color: var(--noir); }
.contact--v .champ--msg { margin-top: 24px; max-width: none; }
.contact--v .etape-err, .contact--v .contact-erreur { color: var(--noir); border-left-color: var(--noir); }
/* Boutons : noir sur verre clair, plus petits que l'actuel. */
.bt--noir { background: var(--noir); color: var(--blanc); min-height: 44px; padding: 0 22px; font-size: 14px; }
.bt--noir:hover { background: #2B2B2B; }
.bt--fin { background: transparent; color: var(--noir); border-color: #9A9A9A; min-height: 44px; padding: 0 20px; font-size: 14px; }
.bt--fin:hover { border-color: var(--noir); }
.contact--v .bt:focus-visible { outline: 2px solid var(--noir); outline-offset: 3px; }
.contact--v .contact-delai { flex-basis: auto; margin-top: 0; }
/* Le suivi : caché sans script (les étapes sont empilées). */
.verre-suivi { display: none; list-style: none; margin: 0; padding: 0; gap: 6px; }
.est-pas-a-pas .verre-suivi { display: flex; }
/* Réponses : un vrai bouton radio sous chaque ligne / pastille. */
.rep { position: relative; display: block; cursor: pointer; }
.rep input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.rep-ok { display: none; }

/* -- A : réponses en lignes, suivi en segments -- */
.contact--a .verre-suivi li { flex: 1; height: 3px; border-radius: 3px; background: var(--filet); position: relative; overflow: hidden; }
.contact--a .verre-suivi li::after { content: ""; position: absolute; inset: 0; background: var(--noir); transform: scaleX(0); transform-origin: left; transition: transform .3s var(--ease); }
.contact--a .contact-form[data-etape-courante="1"] .verre-suivi li:nth-child(-n+1)::after,
.contact--a .contact-form[data-etape-courante="2"] .verre-suivi li:nth-child(-n+2)::after,
.contact--a .contact-form[data-etape-courante="3"] .verre-suivi li:nth-child(-n+3)::after { transform: scaleX(1); }
.contact--a .reps { border-top: 1px solid #C8C8C8; }
.contact--a .rep { border-bottom: 1px solid #C8C8C8; }
.contact--a .rep-c {
  display: grid; grid-template-columns: 48px 1fr 28px; align-items: center; min-height: 64px;
  font: 400 clamp(18px, 1.6vw, 22px)/1.25 var(--font-body); color: var(--encre);
  transition: box-shadow .2s var(--ease);
}
.contact--a .rep-n { font-size: 12px; font-weight: 500; letter-spacing: .14em; color: var(--gris-f); }
.contact--a .rep-f, .contact--a .rep-ok { justify-self: end; font-size: 18px; }
.contact--a .rep-f { opacity: 0; transform: translateX(-6px); transition: opacity .2s var(--ease), transform .2s var(--ease); }
.contact--a .rep:hover .rep-f, .contact--a .rep input:focus-visible + .rep-c .rep-f { opacity: 1; transform: none; }
.contact--a .rep input:focus-visible + .rep-c { outline: 2px solid var(--noir); outline-offset: 2px; }
/* Sélectionné : texte plein, filet épais, coche. Pas seulement la couleur. */
.contact--a .rep input:checked + .rep-c { font-weight: 600; color: var(--noir); box-shadow: inset 0 -2px 0 var(--noir); }
.contact--a .rep input:checked + .rep-c .rep-f { display: none; }
.contact--a .rep input:checked + .rep-c .rep-ok { display: block; }

/* -- B : réponses en pastilles, suivi en points -- */
.contact--b .verre-suivi { gap: 8px; align-items: center; }
.contact--b .verre-suivi li { width: 8px; height: 8px; border-radius: 4px; background: #C8C8C8; transition: width .3s var(--ease), background-color .3s var(--ease); }
/* Faits : noirs ; le courant s'allonge en pilule. */
.contact--b .contact-form[data-etape-courante="2"] .verre-suivi li:nth-child(1),
.contact--b .contact-form[data-etape-courante="3"] .verre-suivi li:nth-child(-n+2) { background: var(--noir); }
.contact--b .contact-form[data-etape-courante="1"] .verre-suivi li:nth-child(1),
.contact--b .contact-form[data-etape-courante="2"] .verre-suivi li:nth-child(2),
.contact--b .contact-form[data-etape-courante="3"] .verre-suivi li:nth-child(3) { width: 28px; background: var(--noir); }
.contact--b .reps { display: flex; flex-wrap: wrap; gap: 10px; }
.contact--b .rep { display: inline-block; }
.contact--b .rep-c {
  display: flex; align-items: center; gap: 8px; min-height: 52px; padding: 0 24px;
  border: 1px solid #8A8A8A; border-radius: 999px; background: rgba(255,255,255,.5);
  font: 400 clamp(16px, 1.4vw, 19px)/1.2 var(--font-body); color: var(--encre);
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.contact--b .rep-n, .contact--b .rep-f { display: none; }
.contact--b .rep:hover .rep-c { border-color: var(--noir); }
.contact--b .rep input:focus-visible + .rep-c { outline: 2px solid var(--noir); outline-offset: 3px; }
/* Sélectionnée : noir plein, texte blanc, et une coche (pas seulement la couleur). */
.contact--b .rep input:checked + .rep-c { background: var(--noir); border-color: var(--noir); color: var(--blanc); font-weight: 500; }
.contact--b .rep input:checked + .rep-c .rep-ok { display: inline; font-size: 15px; }

@media (prefers-contrast: more) {
  .contact--b .verre-suivi li { background: #767676; }
  .contact--b .rep-c { border-color: var(--noir); }
}
@media (max-width: 620px) {
  .verre { padding: 22px 18px; }
  .contact--a .rep-c { grid-template-columns: 36px 1fr 24px; min-height: 56px; }
  .contact--b .rep-c { min-height: 48px; padding: 0 18px; }
  .contact--b .reps { gap: 8px; }
  .fond-forme--1 { width: 80vw; height: 60vw; left: -10%; }
  .fond-forme--2 { width: 70vw; height: 50vw; right: -12%; }
}

/* ---- 11. Nav et pied : seulement des jetons ------------------------------ */
/* Au-dessus d'une surface noire (manifeste, bloc contact), la nav passe en
   tenue sombre : le script pose html.nav-sombre. Mêmes règles, autres jetons. */
html.nav-sombre .nav {
  --bg-rgb: 0,0,0;
  --white: #FFFFFF; --dim: #C9C9C9; --faint: var(--sur-noir);
  --hair: rgba(255,255,255,.16); --hair-2: rgba(255,255,255,.08);
  --glass: rgba(0,0,0,.55); --glass-hover: rgba(255,255,255,.09);
  --nav-hover: rgba(255,255,255,.09); --nav-current: rgba(255,255,255,.13);
  --surface: #0E0E0E; --surface-2: #1A1A1A; --surface-overlay: rgba(10,10,10,.97);
  color: var(--blanc);
}
.wordmark .glyph { width: 16px; height: 23px; }
/* La bulle des réseaux reste une carte sombre : ses jetons sont ceux du noir. */
.foot-card {
  --white: #FFFFFF; --dim: #C9C9C9; --faint: var(--sur-noir);
  --hair: rgba(255,255,255,.12); --hair-2: rgba(255,255,255,.07);
  background: #0E0E0E;
}
/* Les couleurs des plateformes (coche bleue, anneau d'Instagram, bouton rose
   de TikTok, bannière violette) passent au noir et blanc. */
.foot-card-pane--x .foot-card-coche, .foot-card-pane--instagram .foot-card-coche { color: #FFFFFF; }
.foot-card-coche path { stroke: #000; }
.foot-card-pane--x .foot-card-act, .foot-card-pane--instagram .foot-card-act,
.foot-card-pane--youtube .foot-card-act, .foot-card-pane--tiktok .foot-card-act { background: #FFFFFF; color: #000000; }
.foot-card-pane--instagram .foot-card-ring { background: conic-gradient(from 200deg, #FFFFFF, #6B6B6B, #FFFFFF); }
.foot-card-ring .foot-card-avatar, .foot-card-pane--youtube .foot-card-avatar { border-color: #0E0E0E; }
.foot-card-banner { background: linear-gradient(135deg, #2E2E2E 0%, #0E0E0E 60%); }
.foot-card-pane--tiktok::before { background: linear-gradient(90deg, #FFFFFF, #0E0E0E 50%, #FFFFFF); }
/* font-stretch plutôt que font-variation-settings (revue du 11/10) : même
   rendu en Archivo, et sans effet trompeur sur une famille sans axe wdth. */
.foot-brand .mark { font-weight: 900; font-stretch: 125%; }
@media (max-width: 620px) {
  .foot-legal { flex-direction: column; align-items: flex-start; gap: 14px; }
  .foot-top { align-self: stretch; justify-content: center; padding-block: 12px; margin-top: 4px; }
}

/* ---- Panier dans le menu burger (07/10, Théo) : sous 900 px la barre ne garde
   que le logo, la recherche et le burger ; le panier passe en pied du menu.
   Au-dessus, le lien de la feuille n'existe pas à l'écran et le bouton rond
   reste dans la barre comme avant. */
.menu-panier { display: none; }
@media (max-width: 900px) {
  .nav .iconbtn-panier { display: none; }
  .menu-panier {
    display: flex; align-items: center; gap: 10px; min-height: 44px;
    margin: 8px 0 0; padding: 12px 16px; border-top: 1px solid var(--hair-2);
    border-radius: 0 0 14px 14px; color: var(--white); font-size: 14px; text-decoration: none;
  }
  .menu-panier .count { margin-left: auto; position: static; }
  .menu-panier:hover { background: var(--glass-hover); }
}

/* ---- Menu mobile à deux niveaux (07/10, piste A choisie par Théo) ---------
   Sous 900 px le menu ouvert prend tout l'écran. Premier écran : les quatre
   entrées en grand, un trait fin entre chacune, un chevron à droite pour dire
   qu'elles ouvrent quelque chose, le panier en bas. Toucher une entrée ouvre
   le second écran : un retour, l'entrée elle-même, puis ses groupes AVEC leurs
   titres et la description de chaque lien. Sans script, la feuille reste la
   liste à plat d'avant : rien ne disparaît (le script pose data-niv). */
@media (max-width: 900px) {
  .menu[open] > .menu-sheet {
    position: fixed; inset: 0; z-index: 1; left: 0; right: 0; top: 0;
    max-height: none; height: 100dvh; border: 0; border-radius: 0; box-shadow: none;
    padding: calc(clamp(14px, 2.2vw, 26px) + 64px) var(--pad) max(24px, env(safe-area-inset-bottom));
    background: #fff; backdrop-filter: none; -webkit-backdrop-filter: none;
    display: flex; flex-direction: column; overflow-y: auto;
  }
  .nav .wordmark, .nav .find-toggle, .nav .menu > summary { position: relative; z-index: 3; }
  html:has(.menu[open]) { overflow: hidden; }

  /* Premier écran */
  .menu-sheet[data-niv] .pill-entry > a {
    display: flex; align-items: center; justify-content: space-between;
    min-height: 68px; padding: 14px 2px; border-radius: 0;
    border-bottom: 1px solid var(--hair-2, rgba(0,0,0,.06));
    font-family: var(--f-titre); font-weight: var(--titre-w); font-size: 32px; line-height: 1.1;
    letter-spacing: -.01em; color: var(--noir);
  }
  .menu-sheet[data-niv] .pill-entry[data-menu] > a::after {
    content: ""; flex: none; width: 10px; height: 10px; margin-right: 4px;
    border-top: 1.6px solid currentColor; border-right: 1.6px solid currentColor;
    transform: rotate(45deg); opacity: .5;
  }
  .menu-sheet[data-niv] .pill-entry > a[aria-current="page"] { color: var(--noir); }
  .menu-sheet[data-niv="1"] .nav-panel { display: none; }

  /* Second écran */
  .menu-sheet[data-niv="2"] .pill, .menu-sheet[data-niv="2"] .menu-panier { display: none; }
  .menu-sheet[data-niv="2"] .nav-panel {
    display: block; margin: 0; padding: 0; border: 0;
  }
  .menu-sheet[data-niv="2"] .nav-menu { display: none; position: static; inset: auto; transform: none; width: auto; opacity: 1; visibility: visible; pointer-events: auto; }
  .menu-sheet[data-niv="2"][data-vue="themes"] .nav-menu[data-menu="themes"],
  .menu-sheet[data-niv="2"][data-vue="services"] .nav-menu[data-menu="services"],
  .menu-sheet[data-niv="2"][data-vue="support"] .nav-menu[data-menu="support"] { display: block; }
  .menu-sheet[data-niv="2"] .nav-group { display: block; margin-top: 22px; }
  .menu-sheet[data-niv="2"] .nav-group-t {
    display: block; margin: 0 0 6px; font-size: 12px; font-weight: 500;
    letter-spacing: .14em; text-transform: uppercase; color: #6B6B6B;
  }
  .menu-sheet[data-niv="2"] .nav-item {
    display: block; min-height: 64px; padding: 14px 2px; border-radius: 0;
    border-bottom: 1px solid var(--hair-2, rgba(0,0,0,.06)); color: var(--noir);
  }
  .menu-sheet[data-niv="2"] .nav-item-t { display: block; font-size: 20px; font-weight: 600; letter-spacing: -.01em; }
  .menu-sheet[data-niv="2"] .nav-item-d { display: block; margin-top: 3px; font-size: 14px; line-height: 1.35; color: #6B6B6B; }
  .menu-retour { display: none; }
  .menu-sheet[data-niv="2"] .menu-retour {
    display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin: 0 0 6px -4px; padding: 0 4px;
    border: 0; background: none; cursor: pointer; font: inherit; font-size: 15px; font-weight: 500; color: #6B6B6B;
  }
  .menu-retour::before {
    content: ""; width: 9px; height: 9px; border-left: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
    transform: rotate(45deg); margin-right: 2px;
  }
  .menu-titre-vue {
    display: block; margin: 8px 2px 0; font-family: var(--f-titre); font-weight: var(--titre-w);
    font-size: 40px; line-height: 1.05; letter-spacing: -.015em; color: var(--noir);
  }
  .menu-tout { display: block; margin: 10px 2px 0; font-size: 15px; color: #6B6B6B; text-decoration: underline; text-underline-offset: 3px; }
  .menu-panier { margin-top: auto; }
}
@media (min-width: 901px) { .menu-retour, .menu-titre-vue, .menu-tout { display: none; } }

/* PASSE 6 — LE MENU MOBILE, PLUS DE PRÉSENCE (html.p6-menu ; ?menu=actuel
   rend celui du 07/10). Même structure à deux niveaux. Théo : la police
   « trop neutre », et le second écran « perd en impact ». Ici :
   1. premier écran : les quatre entrées à 46 px, un numéro d'ordre
      discret (01 → 04, compteur CSS, rien dans le HTML), un filet plus net ;
   2. second écran : les liens en Caslon (24 px), la description en Archivo
      dessous ; les titres de groupe restent des étiquettes ;
   3. une image en tête du second écran (tpl/v2/images.php, menu-*), sous
      le titre : la seule chose qui attire l'œil avant les liens. Absente
      ailleurs (bureau, menu sans script, ?menu=actuel : pas dans le HTML). */
.nav-menu > .menu-image { display: none; }
@media (max-width: 900px) {
  html.p6-menu .menu-sheet[data-niv] .pill { counter-reset: entree; }
  html.p6-menu .menu-sheet[data-niv] .pill-entry > a {
    justify-content: flex-start; gap: 16px; min-height: 84px; padding: 16px 2px;
    font-size: clamp(40px, 12vw, 48px); line-height: 1; letter-spacing: -.02em;
    border-bottom-color: rgba(0,0,0,.18);
  }
  html.p6-menu .menu-sheet[data-niv] .pill-hover + .pill-entry > a { border-top: 1px solid rgba(0,0,0,.18); }
  /* Passe 7 : les numéros seulement sur demande (?menu-numeros=1). */
  html.p6-menu.p7-menu-numeros .menu-sheet[data-niv] .pill-entry > a::before {
    counter-increment: entree; content: counter(entree, decimal-leading-zero);
    align-self: flex-start; width: 24px; flex: none; padding-top: 6px;
    font: 500 12px/1 var(--font-body); letter-spacing: .14em; color: #6B6B6B;
  }
  html.p6-menu .menu-sheet[data-niv] .pill-entry[data-menu] > a::after { margin-left: auto; width: 12px; height: 12px; opacity: .7; }
  html.p6-menu .menu-titre-vue { font-size: clamp(42px, 12vw, 50px); line-height: 1; letter-spacing: -.02em; }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-menu > .menu-image {
    display: grid; margin: 18px 0 2px; border-radius: var(--rayon);
    /* 16/7 de la largeur, mais jamais plus de 16 % de la hauteur d'écran :
       à 360 × 640, les liens du premier groupe restent sans défiler. */
    aspect-ratio: auto; height: min(calc((100vw - 2 * var(--pad)) * 7 / 16), 16svh, 240px);
  }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-menu > .menu-image:not(.slot--vide) { display: block; }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-group { margin-top: 18px; }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-item { min-height: 60px; padding: 12px 2px; border-bottom-color: rgba(0,0,0,.12); }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-item-t {
    font-family: var(--f-titre); font-weight: var(--titre-w); font-size: 24px; line-height: 1.1; letter-spacing: -.01em;
  }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-item-d { margin-top: 4px; }
}
/* PASSE 7 — LA SECTION THEMES EN DÉPLIANTS (?menu-themes=a|b, sous 900 px).
   v2.js remplace l'étiquette du groupe par un bouton (aria-expanded,
   aria-controls) et range ses liens dans une zone qui s'ouvre par
   grid-template-rows (0fr → 1fr, 220 ms, sans saut : le texte ne bouge pas,
   seule la hauteur de la zone change). Zone fermée : liens invisibles et
   hors tabulation (visibility), jamais lus. Mouvement réduit : immédiat. */
@media (max-width: 900px) {
  html.p7-menu-themes .nav-menu[data-menu="themes"] .nav-group + .nav-group { padding-left: 0; border-left: 0; }
  html.p7-menu-themes .p7-groupe {
    appearance: none; -webkit-appearance: none; display: flex; align-items: center; justify-content: space-between;
    width: 100%; min-height: 48px; margin: 0; padding: 0 2px; border: 0; border-bottom: 1px solid rgba(0, 0, 0, .12);
    background: none; color: inherit; cursor: pointer; text-align: left;
    font: 500 12px/1 var(--font-body); letter-spacing: .14em; text-transform: uppercase;
  }
  html.p7-menu-themes .p7-groupe::after {
    content: ""; width: 9px; height: 9px; margin-right: 4px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
    transform: translateY(-2px) rotate(45deg); transition: transform .22s var(--ease);
  }
  html.p7-menu-themes .p7-groupe[aria-expanded="true"]::after { transform: translateY(2px) rotate(225deg); }
  html.p7-menu-themes .p7-groupe:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
  html.p7-menu-themes .p7-zone { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .22s var(--ease); }
  html.p7-menu-themes .p7-zone[data-p7-replie="1"] { grid-template-rows: 0fr; }
  html.p7-menu-themes .p7-zone-in { min-height: 0; overflow: hidden; visibility: visible; }
  html.p7-menu-themes .p7-zone[data-p7-replie="1"] .p7-zone-in { visibility: hidden; transition: visibility 0s linear .22s; }
}
/* Écrans courts (360 × 640 et moins de 700 px de haut) : l'image se range en
   vignette à droite du titre, sans prendre de hauteur ; les deux groupes de
   Themes restent alors visibles sans défiler (mesuré). */
@media (max-width: 900px) and (max-height: 700px) {
  /* Placée par rapport à la feuille (fixe, elle porte le défilement) : sous
     la nav (64 px + la marge haute de la feuille), à hauteur du titre. */
  html.p6-menu .menu-sheet[data-niv="2"] .nav-menu > .menu-image {
    position: absolute; top: calc(clamp(14px, 2.2vw, 26px) + 64px + 56px); right: var(--pad);
    width: 38%; height: 58px; margin: 0;
  }
  html.p6-menu :is(.menu-titre-vue, .menu-tout) { max-width: calc(62% - 16px); }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-item { min-height: 54px; padding-block: 9px; }
  html.p6-menu .menu-sheet[data-niv="2"] .nav-group { margin-top: 14px; }
}

/* PASSE 9, CHANTIER 1 — LA PAGE COMPARER (/en/themes/compare).
   Mécanique de la page Comparer d'Apple, mesurée le 08/10 : titre centré
   (Apple 40/44 au téléphone, 64/68 au bureau), barre collante des modèles
   (59 / 69 px chez Apple, puis le prix et le bouton), colonnes alignées (deux
   de 165 px et 22 px d'écart à 402, trois dans 980 px au bureau), texte des
   cases à 17 px, intitulés de groupe en tête. Ici : la barre porte d'un coup
   le palier, le prix et le bouton (une seule bande, moins haute qu'Apple),
   et chaque ligne garde son intitulé visible au-dessus des cases, parce que
   nos cases ne se lisent pas seules comme « Puce A20 Pro ». */
.cmp { --cmp-cols: 3; --cmp-gap: clamp(14px, 2.2vw, 29px); --cmp-nav: 76px; padding-bottom: 96px; }
.cmp .wrap-v2 { --col: 980px; }
.cmp-tete { padding-top: calc(var(--cmp-nav) + clamp(40px, 7vw, 88px)); padding-bottom: clamp(28px, 4vw, 48px); text-align: center; }
.cmp-h1 { font-size: clamp(40px, 5.2vw, 64px); line-height: 1.07; letter-spacing: -.01em; }
.cmp-sous { max-width: 34em; margin: 16px auto 0; font-size: 17px; line-height: 1.47; color: var(--gris-f); text-wrap: pretty; }

.cmp-barre { position: sticky; top: var(--cmp-nav); z-index: 5; background: var(--blanc); border-bottom: 1px solid var(--filet); }
.cmp-barre::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: calc(var(--cmp-nav) + 2px); background: var(--blanc); opacity: 0; pointer-events: none; transition: opacity .2s var(--ease); }
/* Collée (v2.js pose .cmp-colle) : un fond blanc remonte jusqu'en haut, sous
   la nav flottante, pour que les lignes ne passent pas entre les deux. */
.cmp.cmp-colle .cmp-barre::before { opacity: 1; }
.cmp-barre-in { display: grid; grid-template-columns: repeat(var(--cmp-cols), 1fr); column-gap: var(--cmp-gap); padding-block: 14px 16px; }
.cmp-choix { display: none; }
.cmp-col { display: grid; gap: 4px; align-content: start; }
.cmp-col-nom { font: 600 19px/1.2 var(--font-body); letter-spacing: -.01em; color: var(--noir); }
.cmp-col-prix { font-size: 17px; line-height: 1.3; color: var(--noir); }
.cmp-col-prix s, .cmp-groupe s { margin-left: 4px; font-size: 13px; color: var(--gris); }
.cmp-col-voir { justify-self: start; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin-top: 6px; padding: 0 18px; border-radius: 999px; background: var(--noir); color: var(--blanc); font: 600 15px/1 var(--font-body); text-decoration: none; transition: background-color .2s var(--ease); }
.cmp-col-voir:hover { background: var(--encre); }

.cmp-groupe, .cmp-groupe :is(caption, thead, tbody, tr, th, td) { display: block; }
.cmp-groupe { width: 100%; margin-top: clamp(56px, 8vw, 96px); border-collapse: collapse; }
.cmp-groupe caption { text-align: left; padding-bottom: 8px; }
.cmp-h2 { font-family: var(--f-titre); font-weight: var(--titre-w); font-size: clamp(32px, 3.6vw, 48px); line-height: 1.08; color: var(--noir); }
.cmp-chapeau { margin-top: 8px; font-size: 17px; line-height: 1.47; color: var(--gris-f); }
.cmp-groupe .cmp-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.cmp-groupe tbody tr { display: grid; grid-template-columns: repeat(var(--cmp-cols), 1fr); column-gap: var(--cmp-gap); row-gap: 12px; padding-block: 24px; border-top: 1px solid var(--filet); }
.cmp-groupe tbody th { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; text-align: left; font-weight: 400; }
.cmp-t { font: 600 19px/1.3 var(--font-body); letter-spacing: -.01em; color: var(--noir); }
.cmp-chip { display: inline-flex; align-items: center; min-height: 26px; padding: 0 11px; border-radius: 999px; font: 600 14px/1 var(--font-body); letter-spacing: .03em; border: 1px solid var(--gris); color: var(--noir); }
.cmp-chip-1 { background: var(--papier); }
.cmp-chip-2 { background: var(--noir); border-color: var(--noir); color: var(--blanc); }
.cmp-groupe th .cmp-d { flex-basis: 100%; }
.cmp-groupe td { font-size: 17px; line-height: 1.47; color: var(--noir); }
.cmp-d { display: block; font-size: 15px; line-height: 1.47; color: var(--gris-f); }
.cmp-d-fort { font-size: 17px; color: var(--noir); }
.cmp-v { font-weight: 600; }
.cmp-n { display: block; margin-top: 4px; font-size: 15px; color: var(--gris-f); }
.cmp-oui { display: block; width: 20px; height: 20px; margin-bottom: 6px; background: var(--noir); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.4 4.8 9 10 3.2' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.4 4.8 9 10 3.2' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
.cmp-non { color: var(--gris); }
.cmp-vide .cmp-non::before { content: "–"; display: block; margin-bottom: 4px; font-size: 20px; line-height: 20px; }
/* Le palier venu d'une carte (?a=…) : une case légèrement teintée, au bureau. */
.cmp .cmp-choisi { position: relative; }
@media (min-width: 900px) {
  .cmp td.cmp-choisi::before, .cmp-col.cmp-choisi::before { content: ""; position: absolute; inset: -10px calc(var(--cmp-gap) / -2); z-index: -1; background: var(--papier); border-radius: 12px; }
  .cmp-groupe tbody tr { isolation: isolate; }
  .cmp-barre-in { isolation: isolate; }
}
.cmp-pied { margin-top: 56px; max-width: 46em; font-size: 15px; line-height: 1.5; color: var(--gris-f); }
.cmp-retour { margin-top: 20px; }
.cmp-retour a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-weight: 600; text-decoration: none; }
.cmp-retour a:hover { text-decoration: underline; }

/* Au téléphone, avec script : deux colonnes, choisies dans deux listes
   (comme Apple). Sans script : les trois colonnes restent, plus serrées. */
@media (max-width: 899px) {
  .cmp { --cmp-nav: 68px; }
  .cmp-col-nom { font-size: 16px; }
  .cmp-col-voir { padding: 0 14px; }
  .cmp-groupe td { font-size: 15px; }
  .cmp-d-fort { font-size: 15px; }
  .cmp-chip { min-height: 28px; font-size: 15px; }
  .cmp-col-prix s, .cmp-groupe s { font-size: 15px; }
  .cmp-col-voir { font-size: 15px; }
  html.js .cmp { --cmp-cols: 2; --cmp-gap: 22px; }
  html.js .cmp-choix { display: block; position: relative; grid-row: 1; }
  html.js .cmp-choix-a { grid-column: 1; }
  html.js .cmp-choix-b { grid-column: 2; }
  html.js .cmp-choix select {
    appearance: none; -webkit-appearance: none; width: 100%; min-height: 44px; padding: 0 24px 0 0; border: 0; border-bottom: 1px solid var(--filet); border-radius: 0;
    background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23000' stroke-width='1.5'/%3E%3C/svg%3E") right 2px center / 12px 8px no-repeat;
    font: 600 16px/1.2 var(--font-body); letter-spacing: -.02em; color: var(--noir);
  }
  html.js .cmp-choix select:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
  html.js .cmp-col .cmp-col-nom { display: none; }
  html.js .cmp-barre-in { row-gap: 10px; padding-block: 8px 12px; }
  /* Les colonnes non choisies s'effacent ; les choisies prennent leur place. */
  html.js .cmp [data-p] { display: none; }
  html.js .cmp-barre-in > [data-p] { grid-row: 2; }
  html.js .cmp[data-a="grid"] [data-p="grid"] { display: block; grid-column: 1; order: 1; }
  html.js .cmp[data-b="grid"] [data-p="grid"] { display: block; grid-column: 2; order: 2; }
  html.js .cmp[data-a="grid-core"] [data-p="grid-core"] { display: block; grid-column: 1; order: 1; }
  html.js .cmp[data-b="grid-core"] [data-p="grid-core"] { display: block; grid-column: 2; order: 2; }
  html.js .cmp[data-a="grid-studio"] [data-p="grid-studio"] { display: block; grid-column: 1; order: 1; }
  html.js .cmp[data-b="grid-studio"] [data-p="grid-studio"] { display: block; grid-column: 2; order: 2; }
  html.js .cmp-col > * + * { margin-top: 4px; }
}

/* PASSE 9, CHANTIER 1 — le lien « Compare the tiers » (?comparer=1). Un lien
   texte, plus discret que la pilule : il pousse la pilule vers le bas de la
   même hauteur sur les trois cartes, qui restent égales. */
html.p9-comparer .d-comparer {
  margin-top: auto; align-self: center; display: inline-flex; align-items: center; min-height: 44px; padding: 0 8px;
  font-size: 15px; font-weight: 500; color: var(--d-texte); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px;
}
html.p9-comparer .d-comparer:hover { text-decoration-thickness: 2px; }
html.p9-comparer .d-comparer + .d-bouton { margin-top: 2px; }
html.p9-comparer .m-comparer { display: none; }
@media (max-width: 999px) {
  html.p9-comparer .m-comparer { display: block; margin-top: 10px; text-align: center; }
  html.p9-comparer .m-comparer a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px; font-size: 15px; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
}

/* PASSE 9 — DEUX AMÉLIORATIONS DE LA GALERIE mobile=d (&d=2, &d=3).
   2 : les pastilles portent le nom et le prix (on sait ce qu'il y a à côté
       avant de glisser, et la cible n'est plus un point anonyme) ;
   3 : deux flèches autour des pastilles (le geste de glisser n'est ni
       visible ni possible au clavier ou à VoiceOver ; Apple en met). */
.m-nav9, .m-fleche { display: none; }
@media (max-width: 999px) {
  html.p9-d .m-nav9 { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 16px; }
  html.p9-d .m-nav9 .m-points { margin: 0; }
  html.p9-d-2 .m-points { padding: 4px; gap: 2px; }
  html.p9-d-2 .m-points a { width: auto; min-width: 96px; height: auto; min-height: 48px; padding: 6px 14px; border-radius: 999px; display: grid; gap: 2px; text-decoration: none; color: var(--gris-f); transition: background-color .25s var(--ease), color .25s var(--ease); }
  html.p9-d-2 .m-points a::before { content: none; }
  html.p9-d-2 .m-points a[aria-current="true"] { background: var(--noir); color: var(--blanc); }
  html.p9-d-2 .m-pt-nom { font: 600 15px/1.1 var(--font-body); letter-spacing: .02em; }
  html.p9-d-2 .m-pt-prix { font: 400 15px/1.1 var(--font-body); }
  html.js.p9-d-3 .m-fleche { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 1px solid var(--gris); border-radius: 999px; background: var(--blanc); color: var(--noir); cursor: pointer; transition: opacity .2s var(--ease); }
  html.p9-d-3 .m-fleche svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
  html.p9-d-3 .m-fleche:disabled { opacity: .35; cursor: default; }
}
/* La face du bureau a une hauteur fixe (450 px à 1440) : le lien y prend
   22 px, la liste et la pilule rendent les 14 px qui manquaient. */
@container (max-height: 470px) {
  html.p9-comparer .d-comparer { min-height: 22px; padding: 0 4px; font-size: 12px; }
  html.p9-comparer .d-liste { margin-bottom: 2px; }
  html.p9-comparer .d-comparer + .d-bouton { margin-top: 4px; min-height: 40px; padding-block: 8px; }
}
@container (max-height: 380px) { html.p9-comparer .d-acc summary { min-height: 27px; } }
@container (max-height: 300px) { html.p9-comparer .d-acc summary { min-height: 20px; } }
/* Avec la galerie mobile=d, un seul lien suffit, sous le sélecteur : le même
   lien dans chaque carte le répétait trois fois au même endroit. */
@media (max-width: 999px) {
  html.p9-comparer.p8-mobile-d .d-comparer { display: none; }
  html.p9-comparer.p8-mobile-d .d-comparer + .d-bouton { margin-top: auto; }
  html.p9-comparer .m-comparer a span { display: inline-block; }
}

/* PASSE 9, CHANTIER 4 — L'AURA QUI SUIT LA SOURIS (?aura=b), REFAITE.
   Théo : « l'aura se décale de la carte, et la zone d'aura est trop faible ».
   Cause mesurée : un seul dégradé radial « closest-side » centré sur la
   souris. Son rayon est la distance au bord le plus proche : souris au
   centre, il finit au bord du cadre (34 px de halo à peine visibles) ;
   souris près d'un bord, il tombe à quelques pixels, et l'aura devient une
   ellipse plate décalée hors de la carte (sa capture). De plus, la carte de
   droite, peinte après, recouvrait la moitié du halo de celle du milieu.
   Désormais deux couches, toutes deux attachées à la carte, jamais déplacées :
     ::before  un halo de la forme de la carte, centré, qui déborde de 60 à
               100 px de chaque côté (ombre portée sans décalage) ;
     ::after   le point le plus sombre, de rayon FIXE (160 px), qui suit la
               souris mais dont le centre reste à 60 px dans le contour de la
               carte (v2.js borne --hx/--hy) : il ne dépasse jamais de plus de
               100 px, n'est jamais coupé par son cadre, et seule l'intensité
               se déplace.
   La carte survolée passe devant ses voisines : son halo n'est plus coupé.
   Mouvement réduit : le halo et le point au centre, sans zoom ni transition.
   La charte proscrit les ombres douces : Théo l'a voulue, c'est acté. */
@media (hover: hover) and (min-width: 1000px) {
  html.p8-aura-b .carte::before {
    inset: 0; border-radius: 22px; background: none;
    box-shadow: 0 0 90px 26px rgba(0, 0, 0, .17), 0 0 34px 6px rgba(0, 0, 0, .08);
  }
  html.p8-aura-b .carte::after {
    content: ""; position: absolute; inset: -100px; z-index: -1; pointer-events: none;
    background: radial-gradient(circle 160px at var(--hx, 50%) var(--hy, 50%), rgba(0, 0, 0, .26), rgba(0, 0, 0, .1) 50%, transparent);
    opacity: 0; transition: opacity .32s var(--ease);
  }
  html.p8-aura-b .paliers:is([data-etat="retourne"], :focus-within) .carte:is(:hover, :focus-within)::after { opacity: 1; }
  html.p8-aura-b .paliers:is([data-etat="retourne"], :focus-within) .carte:is(:hover, :focus-within) { z-index: 4; }
  html.p8-aura-b.p7-fond-sombre .carte::before { background: none; box-shadow: 0 0 90px 26px rgba(0, 0, 0, .32), 0 0 34px 6px rgba(0, 0, 0, .14); }
}
@media (hover: hover) and (min-width: 1000px) {
  html.p8-aura-b:not(.js) .carte:is(:hover, :focus-within)::after { opacity: 1; }
}

/* PASSE 9, CHANTIER 5 — LE MENU BURGER À LA APPLE (?menu=apple, sous 900 px).
   Relevé sur apple.com/fr à 402 px (08/10) et repris de près, avec l'accord
   de Théo, sans logo, texte ni image d'Apple :
     · panneau plein écran, fond qui se pose en 0,44 s (cubic-bezier(.4,0,.6,1)) ;
     · entrées à 28 px, graisse 600, interligne 28 px, marge gauche 48 px,
       pas de 46 px d'une entrée à l'autre, aucun séparateur ;
     · apparition échelonnée : chaque entrée glisse de 12 px vers le bas en
       fondu (0,24 s), 20 ms après la précédente ;
     · sous-menu : l'écran glisse, chevron de retour en haut à gauche, les
       groupes secondaires en 17 px graisse 600 sous un intitulé gris 17 px ;
     · croix en haut à droite, à la place du burger ; le fond ne défile plus.
   Police : la pile système d'Apple (-apple-system, BlinkMacSystemFont,
   system-ui), qui EST la police d'Apple sur iPhone et Mac ; ailleurs Inter
   auto-hébergée (assets/v2/fonts, OFL). SF Pro n'est pas embarquée (licence).
   Interlettrage d'Apple, repris tel quel : +0,007 em à 28 px (0,196 px),
   -0,022 em à 17 px ; graisses 600 et 400, comme SF. Inter, un peu plus
   large que SF, garde ces valeurs : l'écart mesuré reste sous 4 % de la
   largeur d'une entrée (RAPPORT-PASSE-9). Le reste du site garde Archivo. */
.am, .am-ouvrir { display: none; }
@media (max-width: 899px) {
  html.js.p9-menu-apple .nav .menu { display: none; }
  html.js.p9-menu-apple .am-ouvrir {
    display: inline-flex; order: 4; position: relative; z-index: 3; align-items: center; justify-content: center; flex-direction: column; gap: 5px;
    width: 34px; height: 34px; padding: 0; border: 1px solid var(--hair); border-radius: 999px;
    background: var(--glass); -webkit-backdrop-filter: blur(18px) saturate(1.4); backdrop-filter: blur(18px) saturate(1.4); color: var(--noir); cursor: pointer;
  }
  html.js.p9-menu-apple .am-ouvrir::before { content: ""; position: absolute; inset: -6px; }   /* cible de 46 px (34 + 2 × 6) */
  html.js.p9-menu-apple .am-ouvrir span { display: block; width: 14px; height: 1.5px; border-radius: 1px; background: currentColor; }
  html.js.p9-menu-apple .am-ouvrir:focus-visible { outline: 2px solid var(--noir); outline-offset: 3px; }

  html.js.p9-menu-apple .am:not([hidden]) { display: block; }
  html.js.p9-menu-apple .am {
    --am-ff: -apple-system, BlinkMacSystemFont, "Inter WOTG", system-ui, "Helvetica Neue", Arial, sans-serif;
    --am-courbe: cubic-bezier(.4, 0, .6, 1);
    position: fixed; inset: 0; z-index: 80; overflow-y: auto; overscroll-behavior: contain;
    background: rgba(255, 255, 255, 0); color: var(--noir); font-family: var(--am-ff);
    -webkit-font-smoothing: antialiased; transition: background-color .44s var(--am-courbe);
  }
  html.js.p9-menu-apple .am.am-ouvert { background: rgba(255, 255, 255, 1); }
  html.p9-am-fige, html.p9-am-fige body { overflow: hidden; }

  html.js.p9-menu-apple .am-tete { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; height: 62px; padding: 14px 18px 0; }
  html.js.p9-menu-apple .am-logo, html.js.p9-menu-apple .am-retour, html.js.p9-menu-apple .am-fermer {
    display: grid; place-items: center; width: 44px; height: 44px; margin: -5px; padding: 0; border: 0; background: none; color: var(--noir); cursor: pointer;
    opacity: 0; transition: opacity .24s var(--am-courbe);
  }
  html.js.p9-menu-apple .am-ouvert :is(.am-logo, .am-retour, .am-fermer) { opacity: 1; }
  html.js.p9-menu-apple :is(.am-retour, .am-logo)[hidden] { display: none; }
  html.js.p9-menu-apple .am-fermer { margin-left: auto; }
  html.js.p9-menu-apple .am svg path { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  html.js.p9-menu-apple .am-logo svg { fill: currentColor; }
  html.js.p9-menu-apple .am :is(a, button):focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; border-radius: 6px; }

  html.js.p9-menu-apple .am-vues { position: relative; }
  html.js.p9-menu-apple .am-vue { padding: 40px 48px 64px; }
  html.js.p9-menu-apple .am-vue[hidden] { display: none; }
  html.js.p9-menu-apple .am-liste, html.js.p9-menu-apple .am-petite { list-style: none; margin: 0; padding: 0; }
  html.js.p9-menu-apple .am-entree {
    display: flex; align-items: center; gap: 10px; width: 100%; min-height: 46px; padding: 3px 0 4px; border: 0; background: none; text-align: left; cursor: pointer;
    font: 600 28px/28px var(--am-ff); letter-spacing: .007em; color: #1D1D1F; text-decoration: none;
    transition: color .32s var(--am-courbe);
  }
  html.js.p9-menu-apple .am-entree:hover { color: var(--noir); }
  html.js.p9-menu-apple .am-entree svg { width: 14px; height: 14px; margin-left: auto; color: var(--gris); }
  html.js.p9-menu-apple .am-compte { font-size: 17px; font-weight: 400; color: var(--gris-f); }
  html.js.p9-menu-apple .am-groupe { margin: 44px 0 10px; font: 400 17px/21px var(--am-ff); letter-spacing: -.022em; color: #6E6E73; }
  html.js.p9-menu-apple .am-petite a { display: flex; align-items: center; min-height: 44px; font: 600 17px/25px var(--am-ff); letter-spacing: -.022em; color: #1D1D1F; text-decoration: none; }
  /* L'apparition échelonnée : 20 ms d'une entrée à l'autre. */
  html.js.p9-menu-apple .am-vue :is(li, .am-groupe) { opacity: 0; transform: translateY(-12px); transition: opacity .24s var(--am-courbe) calc(var(--k, 0) * 20ms + 80ms), transform .24s var(--am-courbe) calc(var(--k, 0) * 20ms + 80ms); }
  html.js.p9-menu-apple .am-ouvert .am-vue.am-montre :is(li, .am-groupe) { opacity: 1; transform: none; }
  /* Le sous-menu arrive de la droite, la racine s'efface vers la gauche. */
  html.js.p9-menu-apple .am-vue { transition: transform .32s var(--am-courbe), opacity .32s var(--am-courbe); }
  html.js.p9-menu-apple .am-vue.am-sort { transform: translateX(-24px); opacity: 0; }
  html.js.p9-menu-apple .am-sous.am-arrive { transform: translateX(24px); opacity: 0; }
}

/* PASSE 9, CHANTIER 6 — &creux=1 : « la courbe autour du texte, dans les
   creux, avec les images à côté » (Théo). Le S de la passe 8 longe une bande
   de 32 % pendant que texte ET image s'empilent dans les 68 % restants : il
   ne passe pas entre eux. Ici chaque étape décale son texte d'un côté et son
   image de l'autre, plus bas ; v2.js calcule le chemin depuis la mise en
   page : il descend le long du texte, traverse dans le creux entre le texte
   et l'image, puis longe l'image ; l'étape suivante a son texte de ce côté.
   Sans script, la courbe est retirée (son tracé dépend de la mise en page). */
@media (max-width: 899px) {
  html.p9-creux .etapes-liste { grid-auto-rows: auto; }
  html.p9-creux .etape { width: 100%; padding: 40px 0 24px; margin-left: 0; }
  html.p9-creux .etape:nth-child(even) { margin-left: 0; }
  html.p9-creux .etape > :not(.etape-image) { width: 66%; }
  html.p9-creux .etape:nth-child(odd) > :not(.etape-image) { margin-right: auto; }
  html.p9-creux .etape:nth-child(even) > :not(.etape-image) { margin-left: auto; }
  html.p9-creux .etape > .etape-n { display: block; width: max-content; }
  html.p9-creux .etape:nth-child(even) > .etape-n { margin-left: auto; }
  html.p9-creux .etape-image { width: 60%; margin-top: 64px; }
  html.p9-creux .etape:nth-child(odd) > .etape-image { margin-left: auto; }
  html.p9-creux .etape:nth-child(even) > .etape-image { margin-right: auto; margin-left: 0; }
  html.p9-creux:not(.js) .courbe { display: none; }
}
/* Au téléphone, « See GRID STUDIO » passait sur deux lignes dans sa colonne :
   le bouton dit « See STUDIO » (le palier est écrit juste au-dessus). */
.cmp-col-voir { white-space: nowrap; }
@media (max-width: 899px) { html.js .cmp-col .cmp-grid { display: none; } }

/* PASSE 10 — LA PAGE COMPARER À DEUX COLONNES (/en/themes/compare).
   Théo : « illisible, on ne comprend rien » ; il a choisi une autre
   référence (references/passe-10/), version deux colonnes, en-tête collant,
   et sa version BUREAU adaptée au téléphone. Repris de la référence, mesurée
   le 08/10 (tools/mesurer-p10-reference-comparer.js) : une colonne
   d'intitulés de 1,6 part et deux colonnes de valeurs d'une part chacune
   (597 / 373 / 373 px à 1440), les valeurs CENTRÉES sous le nom du thème,
   un titre de section en capitales espacées, un « i » qui explique la
   ligne, des filets fins entre les lignes, un fond à peine teinté au survol.
   Pas repris : sa palette, son badge, ses cartes empilées sous 800 px.
   Volontairement plus grand qu'elle (13,5 px) : corps à 17 px au bureau,
   16 au téléphone, détails à 15, titres de section à 13.
   Police du contenu : Helvetica Neue (iPhone et Mac), Inter auto-hébergée
   ailleurs ; le titre de la page garde la police du site.
   Règle d'alignement, tenue partout : une valeur est centrée dans sa
   colonne, et la colonne est la même boîte dans l'en-tête et dans chaque
   ligne (même grille, même conteneur) : tools/sonde-alignement-comparer.js.
   Filets à #949494 (3,03:1 sur blanc, la mission demande 3:1). */
@font-face { font-family: 'Inter WOTG'; font-style: normal; font-weight: 400; font-display: swap; src: url(fonts/inter-400.woff2) format('woff2'); }
@font-face { font-family: 'Inter WOTG'; font-style: normal; font-weight: 600; font-display: swap; src: url(fonts/inter-600.woff2) format('woff2'); }
.cmp2 {
  --c2-ff: "Helvetica Neue", "Inter WOTG", system-ui, sans-serif;
  --c2-filet: #949494;
  /* Le bas de la nav flottante (top clamp(14px, 2.2vw, 26px) + sa hauteur,
     34 px sous 1000 px, 50,6 à 52,9 au-dessus), arrondi vers le haut : ni
     trou ni chevauchement sans script. Avec script, v2.js pose --c2-colle
     au pixel près, mesuré sur la nav. */
  --c2-nav: calc(clamp(14px, 2.2vw, 26px) + 53px);
  --c2-grille: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr);
  --ca: 2; --cb: 3;
  padding-bottom: 96px; font-family: var(--c2-ff); color: var(--noir);
  -webkit-font-smoothing: antialiased; font-variant-numeric: tabular-nums;
}
.cmp2 .wrap-v2 { --col: 1344px; }
.cmp2-haut { padding-top: calc(var(--c2-nav) + clamp(40px, 7vw, 88px)); padding-bottom: clamp(28px, 4vw, 48px); }
.cmp2-h1 { font-size: clamp(40px, 5.2vw, 64px); line-height: 1.07; letter-spacing: -.01em; }
.cmp2-sous { max-width: 34em; margin-top: 16px; font-size: 17px; line-height: 1.47; color: var(--gris-f); text-wrap: pretty; }

/* Les deux thèmes montrés : le reste s'efface (la grille place a puis b). */
.cmp2 :is(td, th, .cmp3-n)[data-p], .cmp2-offre { display: none; }
.cmp2[data-a="grid"] :is(td, th, .cmp3-n)[data-p="grid"], .cmp2[data-a="grid-core"] :is(td, th, .cmp3-n)[data-p="grid-core"], .cmp2[data-a="grid-studio"] :is(td, th, .cmp3-n)[data-p="grid-studio"] { display: flex; grid-column: var(--ca); }
.cmp2[data-b="grid"] :is(td, th, .cmp3-n)[data-p="grid"], .cmp2[data-b="grid-core"] :is(td, th, .cmp3-n)[data-p="grid-core"], .cmp2[data-b="grid-studio"] :is(td, th, .cmp3-n)[data-p="grid-studio"] { display: flex; grid-column: var(--cb); }
.cmp2[data-a="grid"] [data-col="a"] .cmp2-offre[data-p="grid"], .cmp2[data-a="grid-core"] [data-col="a"] .cmp2-offre[data-p="grid-core"], .cmp2[data-a="grid-studio"] [data-col="a"] .cmp2-offre[data-p="grid-studio"],
.cmp2[data-b="grid"] [data-col="b"] .cmp2-offre[data-p="grid"], .cmp2[data-b="grid-core"] [data-col="b"] .cmp2-offre[data-p="grid-core"], .cmp2[data-b="grid-studio"] [data-col="b"] .cmp2-offre[data-p="grid-studio"],
.cmp2[data-c="grid"] [data-col="c"] .cmp2-offre[data-p="grid"], .cmp2[data-c="grid-core"] [data-col="c"] .cmp2-offre[data-p="grid-core"], .cmp2[data-c="grid-studio"] [data-col="c"] .cmp2-offre[data-p="grid-studio"] { display: grid; }
/* Le nombre ne s'écrit que s'il diffère entre les deux thèmes montrés. */
.cmp2-nb { display: none; }
.cmp2[data-a="grid"][data-b="grid-core"] tr[data-nb~="grid|grid-core"] .cmp2-nb, .cmp2[data-a="grid-core"][data-b="grid"] tr[data-nb~="grid-core|grid"] .cmp2-nb,
.cmp2[data-a="grid"][data-b="grid-studio"] tr[data-nb~="grid|grid-studio"] .cmp2-nb, .cmp2[data-a="grid-studio"][data-b="grid"] tr[data-nb~="grid-studio|grid"] .cmp2-nb,
.cmp2[data-a="grid-core"][data-b="grid-studio"] tr[data-nb~="grid-core|grid-studio"] .cmp2-nb, .cmp2[data-a="grid-studio"][data-b="grid-core"] tr[data-nb~="grid-studio|grid-core"] .cmp2-nb { display: block; }
.cmp2[data-a="grid"][data-b="grid-core"] tr[data-nb~="grid|grid-core"] .cmp2-oui, .cmp2[data-a="grid-core"][data-b="grid"] tr[data-nb~="grid-core|grid"] .cmp2-oui,
.cmp2[data-a="grid"][data-b="grid-studio"] tr[data-nb~="grid|grid-studio"] .cmp2-oui, .cmp2[data-a="grid-studio"][data-b="grid"] tr[data-nb~="grid-studio|grid"] .cmp2-oui,
.cmp2[data-a="grid-core"][data-b="grid-studio"] tr[data-nb~="grid-core|grid-studio"] .cmp2-oui, .cmp2[data-a="grid-studio"][data-b="grid-core"] tr[data-nb~="grid-studio|grid-core"] .cmp2-oui { display: none; }

/* L'en-tête collant, à la grille des lignes. */
.cmp2-tete { position: sticky; top: var(--c2-colle, var(--c2-nav)); z-index: 5; background: var(--blanc); border-bottom: 1px solid var(--c2-filet); }
.cmp2-tete::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: calc(var(--c2-colle, var(--c2-nav)) + 2px); background: var(--blanc); opacity: 0; pointer-events: none; transition: opacity .2s var(--ease); }
.cmp2.cmp2-colle .cmp2-tete::before { opacity: 1; }
/* Collé, le fond blanc remplace le voile de la nav (108 px de haut), qui
   descendait sur les noms de l'en-tête et les délavait. */
html:has(.cmp2.cmp2-colle) .nav::before { opacity: 0; }
.cmp2-grille { display: grid; grid-template-columns: var(--c2-grille); }
.cmp2-coin { grid-column: 1; grid-row: 1; align-self: center; padding: 16px 24px 16px 0; }
.cmp2-coin-t { font-size: 17px; font-weight: 600; line-height: 1.4; }
.cmp2-coin-p { margin-top: 2px; font-size: 15px; line-height: 1.45; color: var(--gris-f); }
.cmp2-envoyer { display: none; }
.cmp2-col, .cmp2-changer { grid-row: 1; display: grid; justify-items: center; align-content: start; padding: 14px 12px 16px; text-align: center; }
.cmp2 :is(.cmp2-col, .cmp2-changer)[data-col="a"] { grid-column: var(--ca); }
.cmp2 :is(.cmp2-col, .cmp2-changer)[data-col="b"] { grid-column: var(--cb); }
.cmp2 :is(.cmp2-col, .cmp2-changer)[data-col="c"] { display: none; }
/* Le nom : un bouton qui met le thème en avant (aria-pressed). */
.cmp2-nom { display: block; min-height: 44px; padding: 0 12px; border: 0; border-radius: 10px; background: none; color: var(--noir); font: 400 20px/44px var(--c2-ff); letter-spacing: -.005em; white-space: nowrap; cursor: pointer; text-decoration: underline 2px transparent; text-underline-offset: 8px; transition: text-decoration-color .2s var(--ease); }
.cmp2-nom:hover { background: rgba(0, 0, 0, .05); }
.cmp2-nom:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
.cmp2-nom[aria-pressed="true"] { font-weight: 700; text-decoration-color: var(--c2-acc); }
/* La rangée de choix, au-dessus de l'en-tête collant. */
.cmp2-choisir .cmp2-changer { align-content: end; padding-bottom: 6px; }
.cmp2-choisir .cmp2-coin { padding-bottom: 12px; }
.cmp2-astuce { display: none; }
.cmp2-tete .cmp2-coin { align-self: center; }
.cmp2-choix { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 30px 0 16px; border: 1px solid var(--c2-filet); border-radius: 999px; font: 400 15px/1.2 var(--c2-ff); color: var(--gris-f); cursor: pointer; }
.cmp2-choix:hover { background: rgba(0, 0, 0, .05); }
.cmp2-choix select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; font-size: 16px; }
.cmp2-choix:has(select:focus-visible) { outline: 2px solid var(--noir); outline-offset: 2px; }
.cmp2-chevron { position: absolute; right: 12px; top: 50%; margin-top: -4px; pointer-events: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.cmp2-offre { justify-items: center; gap: 4px; }
.cmp2-offre .cmp2-voir { margin-top: 6px; }
.cmp2-prix { font-size: 17px; line-height: 1.35; }
.cmp2-prix s { margin-left: 4px; font-size: 15px; color: var(--gris); }
.cmp2-voir { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 44px; padding: 0 20px; border: 1px solid var(--noir); border-radius: 999px; color: var(--noir); font: 600 15px/1 var(--c2-ff); text-decoration: none; white-space: nowrap; transition: background-color .2s var(--ease), color .2s var(--ease); }
.cmp2-voir:hover { background: var(--noir); color: var(--blanc); }
.cmp2-voir:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }

/* Les sections et leurs lignes. */
.cmp2-groupe, .cmp2-groupe :is(caption, thead, tbody, tr, th, td) { display: block; }
.cmp2-groupe { width: 100%; margin-top: 56px; border-collapse: collapse; }
.cmp2-groupe:first-child { margin-top: 40px; }
.cmp2-groupe caption { text-align: left; padding-bottom: 14px; }
.cmp2-h2 { font: 600 13px/1.3 var(--c2-ff); letter-spacing: .14em; text-transform: uppercase; color: var(--noir); }
.cmp2-chapeau { margin-top: 6px; font-size: 15px; line-height: 1.45; color: var(--gris-f); }
.cmp2-groupe .cmp2-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.cmp2-groupe tbody tr { display: grid; grid-template-columns: var(--c2-grille); align-items: center; border-bottom: 1px solid var(--c2-filet); }
.cmp2-groupe tbody tr:first-child { border-top: 1px solid var(--c2-filet); }
.cmp2-groupe tbody th { grid-column: 1; grid-row: 1; padding: 14px 24px 14px 0; text-align: left; font-weight: 400; }
.cmp2-t { font-size: 17px; line-height: 1.45; }
.cmp2-groupe td { grid-row: 1; align-self: stretch; flex-direction: column; align-items: center; justify-content: center; padding: 12px; text-align: center; font-size: 16px; line-height: 1.45; }
.cmp2-oui { display: block; }
.cmp2-m { display: block; width: 20px; height: 20px; background: var(--noir); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.4 4.8 9 10 3.2' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.4 4.8 9 10 3.2' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
.cmp2-non { display: block; font-size: 20px; line-height: 20px; color: var(--gris); }
.cmp2-nb { font-weight: 600; white-space: nowrap; }
@media (hover: hover) { .cmp2-groupe tbody tr:hover { background: rgba(0, 0, 0, .035); } }

/* Le détail d'une ligne. Sans script et au téléphone : visible, sous
   l'intitulé. Au bureau avec script : une infobulle sous le « i », ouverte
   au survol, au focus clavier, ou par un appui (aria-expanded) ; Échap la
   ferme ; on peut passer la souris dessus sans qu'elle disparaisse. */
.cmp2-aide { display: contents; }
.cmp2-i { display: none; }
.cmp2-d { display: block; margin-top: 4px; font-size: 15px; line-height: 1.45; color: var(--gris-f); text-wrap: pretty; }
@media (min-width: 720px) {
  html.js .cmp2-aide { display: inline-block; position: relative; margin-left: 8px; vertical-align: -1px; }
  html.js .cmp2-i { position: relative; display: grid; place-items: center; width: 20px; height: 20px; padding: 0; border: 1px solid var(--gris); border-radius: 50%; background: none; color: var(--gris-f); font: 600 13px/1 var(--c2-ff); cursor: help; }
  html.js .cmp2-i::before { content: ""; position: absolute; inset: -12px; }   /* cible de 44 px */
  html.js .cmp2-i:hover, html.js .cmp2-i[aria-expanded="true"] { border-color: var(--noir); color: var(--noir); }
  html.js .cmp2-i:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
  html.js .cmp2-d { display: none; position: absolute; z-index: 6; left: -12px; top: 100%; width: max-content; max-width: min(320px, 70vw); margin-top: 10px; padding: 10px 14px; border-radius: 10px; background: var(--noir); color: var(--blanc); font-size: 15px; line-height: 1.45; }
  html.js .cmp2-d::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 12px; }   /* le pont : la souris passe du « i » à la bulle */
  html.js .cmp2-aide:not(.cmp2-tu):hover .cmp2-d, html.js .cmp2-aide:not(.cmp2-tu) .cmp2-i:focus-visible + .cmp2-d, html.js .cmp2-i[aria-expanded="true"] + .cmp2-d { display: block; }
}

.cmp2-pied { margin-top: 56px; max-width: 46em; font-size: 15px; line-height: 1.5; color: var(--gris-f); }
.cmp2-retour { margin-top: 20px; }
.cmp2-retour a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-size: 17px; font-weight: 600; color: var(--noir); text-decoration: none; }
.cmp2-retour a:hover { text-decoration: underline; }

/* Sans script : la liste native et le bouton Compare (rechargement ?a=&b=). */
html:not(.js) .cmp2-choix-t, html:not(.js) .cmp2-chevron, html:not(.js) .cmp2-ajout { display: none !important; }
html:not(.js) .cmp2-choix { padding: 0; border: 0; }
html:not(.js) .cmp2-choix select { position: static; opacity: 1; width: auto; height: 44px; font: 600 16px var(--c2-ff); }
html.js .cmp2-ajout-lien { display: none; }
.cmp2-ajout, .cmp2-ajout-lien { display: none; }
html:not(.js) .cmp2-envoyer { display: inline-flex; align-items: center; min-height: 44px; margin-top: 10px; padding: 0 20px; border: 1px solid var(--noir); border-radius: 999px; background: var(--noir); color: var(--blanc); font: 600 15px/1 var(--c2-ff); cursor: pointer; }

@media (max-width: 999px) { .cmp2 { --c2-nav: calc(clamp(14px, 2.2vw, 26px) + 34px); } }
/* Pointeur tactile : les boutons de la nav passent à 45 px (mesuré à 402 : la nav finit à 59 px). */
@media (max-width: 999px) and (pointer: coarse) { .cmp2 { --c2-nav: calc(clamp(14px, 2.2vw, 26px) + 45px); } }
/* Entre 720 et 1023 px, la colonne d'un thème fait 175 à 250 px : le nom
   à 20 px et sa flèche n'y tenaient plus à 768 (GRID STUDIO décentré de 9 px). */
@media (min-width: 720px) and (max-width: 1023px) {
  .cmp2-nom { font-size: 17px; }
  .cmp2-voir { padding: 0 16px; }
}

/* Téléphone : la version bureau, adaptée. L'intitulé passe au-dessus, en
   pleine largeur, son détail visible dessous ; les deux valeurs côte à côte,
   chacune exactement sous le nom de son thème dans l'en-tête collant. */
@media (max-width: 719px) {
  .cmp2 { --c2-grille: minmax(0, 1fr) minmax(0, 1fr); --ca: 1; --cb: 2; }
  .cmp2-grille, .cmp2-groupe tbody tr { column-gap: 12px; }
  .cmp2-coin { display: none; }
  html:not(.js) .cmp2-choisir .cmp2-coin { display: block; grid-column: 1 / -1; grid-row: 3; padding: 0 0 12px; }
  html:not(.js) .cmp2-choisir :is(.cmp2-coin-t, .cmp2-coin-p) { display: none; }   /* « or add the third » : impossible sous 900 px */
  .cmp2-col { padding: 6px 0 12px; }
  .cmp2-nom { font-size: 17px; padding: 0 8px; }
  .cmp2-offre { gap: 2px; width: 100%; }
  .cmp2-offre .cmp2-voir { margin-top: 4px; }
  .cmp2-changer { padding: 0 0 8px; }
  .cmp2-choix { width: 100%; }
  .cmp2-astuce { display: block; grid-column: 1 / -1; grid-row: 2; padding-bottom: 12px; font-size: 15px; line-height: 1.45; color: var(--gris-f); }
  .cmp2-tete .cmp2-coin { display: none; }
  .cmp2-prix { font-size: 15px; }
  .cmp2-voir { width: 100%; padding: 0 8px; }
  .cmp2-groupe { margin-top: 44px; }
  .cmp2-groupe tbody th { grid-column: 1 / -1; padding: 14px 0 6px; }
  .cmp2-t { font-size: 16px; font-weight: 600; }
  .cmp2-groupe td { grid-row: 2; padding: 4px 0 14px; font-size: 15px; }
  .cmp2-retour a { font-size: 16px; }
}

/* AVENANT 1 — §1 : deux ou trois colonnes au bureau (≥ 900 px), deux
   verrouillées dessous. Entre 720 et 899 px (768, la tablette), la mise en
   page du bureau à deux colonnes : la colonne d'un thème y fait 175 à
   210 px, trois n'y tiendraient qu'en coupant les noms. */
@media (min-width: 900px) {
  html.js .cmp2-ajout { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin-top: 10px; padding: 0 18px 0 14px; border: 1px solid var(--noir); border-radius: 999px; background: none; color: var(--noir); font: 600 15px/1 var(--c2-ff); cursor: pointer; }
  html.js .cmp2-ajout:hover { background: var(--noir); color: var(--blanc); }
  html.js .cmp2-ajout:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
  .cmp2-ajout-signe { position: relative; width: 12px; height: 12px; }
  .cmp2-ajout-signe::before, .cmp2-ajout-signe::after { content: ""; position: absolute; left: 0; top: 5.25px; width: 12px; height: 1.5px; background: currentColor; }
  .cmp2-ajout-signe::after { transform: rotate(90deg); }
  .cmp2[data-c] .cmp2-ajout-signe::after { display: none; }
  html:not(.js) .cmp2-ajout-lien { display: inline-flex; align-items: center; min-height: 44px; margin-top: 6px; font-size: 15px; font-weight: 600; color: var(--noir); }
  .cmp2[data-c] { --c2-grille: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr)); --cc: 4; }
  .cmp2[data-c] :is(.cmp2-col, .cmp2-changer)[data-col="c"] { display: grid; grid-column: var(--cc); }
  .cmp2[data-c="grid"] :is(td, th, .cmp3-n)[data-p="grid"], .cmp2[data-c="grid-core"] :is(td, th, .cmp3-n)[data-p="grid-core"], .cmp2[data-c="grid-studio"] :is(td, th, .cmp3-n)[data-p="grid-studio"] { display: flex; grid-column: var(--cc); }
  /* À trois, une seule règle : le nombre se lit si les comptes diffèrent. */
  .cmp2.cmp2[data-c] tr:not([data-nb3]) .cmp2-nb { display: none; }
  .cmp2.cmp2[data-c] tr:not([data-nb3]) .cmp2-oui { display: block; }
  .cmp2.cmp2[data-c] tr[data-nb3] .cmp2-nb { display: block; }
  .cmp2.cmp2[data-c] tr[data-nb3] .cmp2-oui { display: none; }
}
@media (min-width: 900px) and (max-width: 1199px) {
  .cmp2[data-c] .cmp2-nom { font-size: 17px; }
  .cmp2[data-c] .cmp2-voir { padding: 0 14px; }
  .cmp2[data-c] .cmp2-choix { padding: 0 26px 0 12px; }
}

/* AVENANT 1 — §2 : le thème mis en avant. Sa colonne est teintée (fond
   léger), son nom en gras et souligné, et ce qu'il apporte au palier d'en
   dessous est marqué : « New » ou « +N settings » sous sa valeur, et un
   trait à gauche des lignes nouvelles. Le spectre vit dans les traits,
   jamais en nappe : la teinte de fond reste à 8 % au plus. Sans accent
   choisi, le gris de la V2 (rendu actuel). */
.cmp2 { --c2-acc: var(--noir); --c2-teinte: var(--papier); --c2-trait: var(--noir); --c2-acc-teinte: var(--papier); }
.cmp2-accent-1 { --c2-acc: #992CFF; --c2-teinte: #F9F2FF; --c2-trait: #B05CFF; --c2-acc-teinte: #F9F2FF; }   /* le violet du prisme V2, assombri : 5,05:1 sur blanc, 4,61 sur sa teinte */
.cmp2-accent-2 { --c2-acc: #0063FB; --c2-teinte: #F0F6FF; --c2-trait: #3E8AFF; --c2-acc-teinte: #F0F6FF; }   /* le bleu du prisme : 5,03 et 4,61 */
.cmp2-accent-3 { --c2-acc: #008458; --c2-teinte: #F3FFFB; --c2-trait: #008458; --c2-acc-teinte: #F3FFFB; }   /* la menthe, en vert profond : 4,73 et 4,62 (la menthe pure, 1,25:1, ne fait pas un trait) */
.cmp2-plus { display: none; margin-top: 2px; font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--c2-acc); white-space: nowrap; }
.cmp2[data-h="grid"] td[data-p="grid"], .cmp2[data-h="grid-core"] td[data-p="grid-core"], .cmp2[data-h="grid-studio"] td[data-p="grid-studio"],
.cmp2[data-a="grid"][data-h="grid"] .cmp2-col[data-col="a"], .cmp2[data-a="grid-core"][data-h="grid-core"] .cmp2-col[data-col="a"], .cmp2[data-a="grid-studio"][data-h="grid-studio"] .cmp2-col[data-col="a"], .cmp2[data-b="grid"][data-h="grid"] .cmp2-col[data-col="b"], .cmp2[data-b="grid-core"][data-h="grid-core"] .cmp2-col[data-col="b"], .cmp2[data-b="grid-studio"][data-h="grid-studio"] .cmp2-col[data-col="b"], .cmp2[data-c="grid"][data-h="grid"] .cmp2-col[data-col="c"], .cmp2[data-c="grid-core"][data-h="grid-core"] .cmp2-col[data-col="c"], .cmp2[data-c="grid-studio"][data-h="grid-studio"] .cmp2-col[data-col="c"] { background: var(--c2-teinte); }
.cmp2[data-h="grid"] td[data-p="grid"] .cmp2-plus, .cmp2[data-h="grid-core"] td[data-p="grid-core"] .cmp2-plus, .cmp2[data-h="grid-studio"] td[data-p="grid-studio"] .cmp2-plus { display: block; }
.cmp2[data-h="grid"] td[data-p="grid"] .cmp2-m, .cmp2[data-h="grid-core"] td[data-p="grid-core"] .cmp2-m, .cmp2[data-h="grid-studio"] td[data-p="grid-studio"] .cmp2-m { background: var(--c2-acc); }
.cmp2[data-h="grid"] td[data-p="grid"] .cmp2-nb, .cmp2[data-h="grid-core"] td[data-p="grid-core"] .cmp2-nb, .cmp2[data-h="grid-studio"] td[data-p="grid-studio"] .cmp2-nb { color: var(--c2-acc); }
.cmp2[data-h="grid"] .cmp2-offre[data-p="grid"] .cmp2-voir, .cmp2[data-h="grid-core"] .cmp2-offre[data-p="grid-core"] .cmp2-voir, .cmp2[data-h="grid-studio"] .cmp2-offre[data-p="grid-studio"] .cmp2-voir { border-color: var(--c2-acc); background: var(--c2-acc); color: var(--blanc); }
.cmp2-groupe tbody th { position: relative; }
.cmp2[data-h="grid-core"] tr[data-neuf~="grid-core"] th::before, .cmp2[data-h="grid-studio"] tr[data-neuf~="grid-studio"] th::before { content: ""; position: absolute; left: -14px; top: 12px; bottom: 12px; width: 3px; border-radius: 2px; background: var(--c2-trait); }
@media (max-width: 719px) {
  .cmp2[data-h="grid-core"] tr[data-neuf~="grid-core"] th::before, .cmp2[data-h="grid-studio"] tr[data-neuf~="grid-studio"] th::before { left: -10px; top: 14px; bottom: 6px; }
}

/* PASSE 10, AVENANT 2 — LE CONTENU REPREND L'ACCORDÉON DE LA V1.
   Théo : « pour le contenu je préfère la disposition qu'on a sur le site en
   V1, il faut simplement qu'on l'adapte ». Comme la V1 (wotg.css, .cmp-groupe) :
   une ligne repliée par groupe — repère « + », nom, chapeau, puis un nombre
   par palier (le compte de ses coches dans le groupe) — et, ouverte, ses
   lignes avec coches et tirets, le détail visible sous l'intitulé. Adapté :
   les colonnes sont les thèmes montrés (2, ou 3 au bureau), à la grille de
   l'en-tête collant, nombres et coches centrés sous leur nom ; nos couleurs
   et nos polices, pas celles de la V1. */
.cmp3-outils { display: flex; justify-content: flex-end; margin: 28px 0 12px; }
.cmp3-tout { display: none; }
html.js .cmp3-tout { display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px; border: 1px solid var(--c2-filet); border-radius: 999px; background: none; color: var(--noir); font: 600 15px/1 var(--c2-ff); cursor: pointer; }
html.js .cmp3-tout:hover { border-color: var(--noir); }
html.js .cmp3-tout:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
.cmp3-g { border-bottom: 1px solid var(--c2-filet); scroll-margin-top: calc(var(--c2-colle, var(--c2-nav)) + 172px); }
.cmp3-g:first-of-type { border-top: 1px solid var(--c2-filet); }
.cmp3-s { display: block; list-style: none; cursor: pointer; }
.cmp3-s::-webkit-details-marker { display: none; }
.cmp3-s:focus-visible { outline: 2px solid var(--noir); outline-offset: -2px; }
.cmp3-ligne { display: grid; grid-template-columns: var(--c2-grille); align-items: stretch; }
.cmp3-crit { grid-column: 1; grid-row: 1; display: grid; grid-template-columns: 12px minmax(0, 1fr); align-items: baseline; gap: 2px 14px; padding: 22px 24px 22px 0; }
.cmp3-mark { position: relative; width: 12px; height: 12px; align-self: center; }
.cmp3-mark::before, .cmp3-mark::after { content: ""; position: absolute; left: 0; top: 5.25px; width: 12px; height: 1.5px; background: currentColor; }
.cmp3-mark::after { transform: rotate(90deg); transition: transform .2s var(--ease); }
.cmp3-g[open] .cmp3-mark::after { transform: rotate(0deg); }
.cmp3-nom { font: 600 20px/1.3 var(--c2-ff); }
.cmp3-s:hover .cmp3-nom { text-decoration: underline; text-underline-offset: 4px; }
.cmp3-chapeau { grid-column: 2; font-size: 15px; line-height: 1.45; color: var(--gris-f); max-width: 52ch; hyphens: manual; overflow-wrap: normal; }
.cmp3-n { grid-row: 1; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding: 12px; text-align: center; }
.cmp3-nb { font: 600 24px/1.1 var(--c2-ff); font-variant-numeric: tabular-nums; }
.cmp3-g[open] .cmp3-nb { color: var(--gris-f); }
.cmp3-neuf { display: none; font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--c2-acc); white-space: nowrap; }
.cmp3-table { margin: 0 0 6px; }
.cmp3-table tbody tr:first-child { border-top: 1px solid var(--c2-filet); }
.cmp3-table tbody tr:last-child { border-bottom: 0; }
.cmp3-d { display: block; margin-top: 2px; font-size: 15px; line-height: 1.45; color: var(--gris-f); text-wrap: pretty; }
.cmp3-v { font-weight: 600; white-space: nowrap; }
/* « Complete », le repère de GRID STUDIO dans la V1, en accent ; une ligne
   vide sous les autres prix, pour que les boutons restent à la même hauteur. */
.cmp3-complet { min-height: 18px; font: 600 13px/18px var(--c2-ff); letter-spacing: .12em; text-transform: uppercase; color: var(--c2-acc); }
/* La mise en avant, dans les groupes : la colonne teintée jusque sur la
   ligne repliée, et « +N new » sous le nombre quand le groupe a du nouveau
   pour ce thème : on sait où ouvrir sans tout ouvrir. */
.cmp2[data-h="grid"] .cmp3-n[data-p="grid"], .cmp2[data-h="grid-core"] .cmp3-n[data-p="grid-core"], .cmp2[data-h="grid-studio"] .cmp3-n[data-p="grid-studio"] { background: var(--c2-teinte); }
.cmp2[data-h="grid-core"] .cmp3-n[data-p="grid-core"] .cmp3-neuf, .cmp2[data-h="grid-studio"] .cmp3-n[data-p="grid-studio"] .cmp3-neuf { display: block; }
.cmp2[data-h="grid"] .cmp3-n[data-p="grid"] .cmp3-nb, .cmp2[data-h="grid-core"] .cmp3-n[data-p="grid-core"] .cmp3-nb, .cmp2[data-h="grid-studio"] .cmp3-n[data-p="grid-studio"] .cmp3-nb { color: var(--c2-acc); }
/* La colonne mise en avant porte un filet d'accent sous son en-tête (2 px). */
.cmp2[data-h] .cmp2-col { box-shadow: none; }
.cmp2[data-a="grid"][data-h="grid"] .cmp2-col[data-col="a"], .cmp2[data-a="grid-core"][data-h="grid-core"] .cmp2-col[data-col="a"], .cmp2[data-a="grid-studio"][data-h="grid-studio"] .cmp2-col[data-col="a"], .cmp2[data-b="grid"][data-h="grid"] .cmp2-col[data-col="b"], .cmp2[data-b="grid-core"][data-h="grid-core"] .cmp2-col[data-col="b"], .cmp2[data-b="grid-studio"][data-h="grid-studio"] .cmp2-col[data-col="b"], .cmp2[data-c="grid"][data-h="grid"] .cmp2-col[data-col="c"], .cmp2[data-c="grid-core"][data-h="grid-core"] .cmp2-col[data-col="c"], .cmp2[data-c="grid-studio"][data-h="grid-studio"] .cmp2-col[data-col="c"] { box-shadow: inset 0 -2px 0 var(--c2-acc); }
@media (max-width: 719px) {
  .cmp3-outils { margin-top: 20px; }
  .cmp3-ligne { column-gap: 12px; }   /* le même écart que l'en-tête collant : les nombres tombent sous les noms */
  .cmp3-crit { grid-column: 1 / -1; display: block; padding: 18px 0 4px 26px; position: relative; }
  .cmp3-mark { position: absolute; left: 0; top: 25px; }
  .cmp3-nom { font-size: 18px; }
  .cmp3-chapeau { display: inline; margin-left: 4px; }
  .cmp3-n { grid-row: 2; padding: 6px 0 16px; }
  .cmp3-nb { font-size: 22px; }
  .cmp3-g { scroll-margin-top: calc(var(--c2-colle, var(--c2-nav)) + 162px); }
}

/* AVENANT 2, PRÉCISION 1 — au téléphone, la mécanique de la V1 (mesurée sur
   /en/themes à 402 px : grille 216 / 50 / 50 / 50, libellé et nombres sur la
   même ligne, chapeau sous le nom, coches sous les thèmes). Ici deux colonnes
   de valeurs de 64 px : le libellé gagne (226 px à 402). Seule différence
   voulue : l'en-tête reste collant. Plus lisible que la V1 : chapeau à 14 px
   (V1 11,5), détail à 15 px, ligne de groupe de 60 px et plus. */
@media (max-width: 719px) {
  .cmp2.cmp2-groupes { --c2-grille: minmax(0, 1fr) 64px 64px; --ca: 2; --cb: 3; }
  .cmp2.cmp2-groupes :is(.cmp2-grille, .cmp3-ligne, .cmp2-groupe tbody tr) { column-gap: 6px; }
  .cmp2.cmp2-groupes .cmp2-tete .cmp2-coin { display: block; grid-column: 1; grid-row: 1; align-self: center; padding: 10px 8px 10px 0; }
  .cmp2.cmp2-groupes .cmp2-tete .cmp2-coin-t { font-size: 16px; }
  .cmp2.cmp2-groupes .cmp2-tete .cmp2-coin-p { font-size: 14px; }
  .cmp2.cmp2-groupes .cmp2-col { padding: 6px 0 10px; }
  .cmp2.cmp2-groupes .cmp2-nom { width: 100%; min-height: 44px; padding: 4px 0; font-size: 15px; line-height: 18px; white-space: normal; text-underline-offset: 4px; }
  .cmp2.cmp2-groupes .cmp2-prix { font-size: 15px; }
  .cmp2.cmp2-groupes .cmp2-prix s { display: block; margin: 0; font-size: 13px; }
  .cmp2.cmp2-groupes .cmp3-complet { letter-spacing: 0; text-transform: none; }
  .cmp2.cmp2-groupes .cmp2-offre .cmp2-voir { width: 44px; height: 44px; min-height: 44px; margin-top: 2px; padding: 0; border-radius: 50%; }
  .cmp2.cmp2-groupes .cmp2-voir-t { display: none; }
  /* La rangée de choix : deux listes côte à côte (les colonnes de 64 px sont trop étroites pour elles). */
  .cmp2.cmp2-groupes .cmp2-choisir .cmp2-grille { grid-template-columns: 1fr 1fr; column-gap: 12px; }
  .cmp2.cmp2-groupes .cmp2-choisir [data-col="a"] { grid-column: 1; }
  .cmp2.cmp2-groupes .cmp2-choisir [data-col="b"] { grid-column: 2; }
  /* Les lignes : intitulé et détail à gauche, coches à droite, sur la même ligne. */
  .cmp2.cmp2-groupes .cmp2-groupe tbody th { grid-column: 1; grid-row: 1; padding: 14px 8px 14px 0; }
  .cmp2.cmp2-groupes .cmp2-groupe td { grid-row: 1; padding: 12px 0; }
  .cmp2.cmp2-groupes .cmp2-plus, .cmp2.cmp2-groupes .cmp3-neuf { font-size: 13px; white-space: normal; }
  .cmp2.cmp2-groupes .cmp3-v { white-space: normal; }
  /* La ligne repliée : nom, chapeau dessous, un nombre par thème. */
  .cmp2.cmp2-groupes .cmp3-crit { grid-column: 1; display: grid; grid-template-columns: 12px minmax(0, 1fr); padding: 16px 8px 16px 0; position: static; }
  .cmp2.cmp2-groupes .cmp3-mark { position: relative; left: auto; top: auto; }
  .cmp2.cmp2-groupes .cmp3-chapeau { display: block; grid-column: 2; margin: 0; font-size: 14px; }
  .cmp2.cmp2-groupes .cmp3-n { grid-row: 1; padding: 8px 0; }
}

/* PASSE 10, AVENANT 3 — CRÉNEAUX LIBRES, ACCENT SUR LES SEULES DIFFÉRENCES,
   TÉLÉPHONE À LA MANIÈRE D'APPLE (comparer-av3.php, la page par défaut).
   L'avenant 2 reste à ?mise=av2 : tout ce qui suit est sous .cmp2-av3.

   L'accent ne colore que (a) la valeur la plus haute d'une ligne ou d'un
   groupe quand les thèmes affichés diffèrent (data-acc × data-s, calculés
   du manifeste), et (b) les nouveautés du thème mis en avant (« New »,
   « +N new », « +N settings »). Le reste est neutre : la teinte de la
   colonne mise en avant passe au gris de la V2, « Complete », See, le
   soulignement du nom et le repère des lignes nouvelles au noir ou au gris. */
.cmp2-av3 { --c2-teinte: #FAFAFA; }   /* gris neutre ; #F5F5F5 faisait tomber l'accent 3 à 4,3:1 sous « New » */
.cmp2.cmp2-av3[data-h] td .cmp2-m { background: var(--noir); }
.cmp2.cmp2-av3[data-h] .cmp3-n[data-p] .cmp3-nb { color: inherit; }
.cmp2.cmp2-av3 .cmp3-complet { color: var(--gris-f); }
.cmp2.cmp2-av3 .cmp2-offre[data-p] .cmp2-voir.cmp2-voir { border-color: var(--noir); background: none; color: var(--noir); }
.cmp2.cmp2-av3 .cmp2-offre[data-p] .cmp2-voir.cmp2-voir:hover { background: var(--noir); color: var(--blanc); }
.cmp2.cmp2-av3 .cmp2-nom[aria-pressed="true"] { text-decoration-color: var(--noir); }
.cmp2.cmp2-av3[data-h][data-s] .cmp2-col.cmp4-creneau[data-col] { box-shadow: none; }
.cmp2.cmp2-av3 tr[data-neuf] th::before { background: var(--noir); }
.cmp2.cmp2-av3[data-s="grid+grid-core"] [data-acc~="grid@grid+grid-core"] > [data-p="grid"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid+grid-core"] [data-acc~="grid-core@grid+grid-core"] > [data-p="grid-core"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid+grid-studio"] [data-acc~="grid@grid+grid-studio"] > [data-p="grid"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid+grid-studio"] [data-acc~="grid-studio@grid+grid-studio"] > [data-p="grid-studio"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid-core+grid-studio"] [data-acc~="grid-core@grid-core+grid-studio"] > [data-p="grid-core"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid-core+grid-studio"] [data-acc~="grid-studio@grid-core+grid-studio"] > [data-p="grid-studio"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid+grid-core+grid-studio"] [data-acc~="grid@grid+grid-core+grid-studio"] > [data-p="grid"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid+grid-core+grid-studio"] [data-acc~="grid-core@grid+grid-core+grid-studio"] > [data-p="grid-core"] .cmp2-m,
.cmp2.cmp2-av3[data-s="grid+grid-core+grid-studio"] [data-acc~="grid-studio@grid+grid-core+grid-studio"] > [data-p="grid-studio"] .cmp2-m { background: var(--c2-acc); }
.cmp2.cmp2-av3[data-s="grid+grid-core"] [data-acc~="grid@grid+grid-core"] > [data-p="grid"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid+grid-core"] [data-acc~="grid-core@grid+grid-core"] > [data-p="grid-core"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid+grid-studio"] [data-acc~="grid@grid+grid-studio"] > [data-p="grid"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid+grid-studio"] [data-acc~="grid-studio@grid+grid-studio"] > [data-p="grid-studio"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid-core+grid-studio"] [data-acc~="grid-core@grid-core+grid-studio"] > [data-p="grid-core"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid-core+grid-studio"] [data-acc~="grid-studio@grid-core+grid-studio"] > [data-p="grid-studio"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid+grid-core+grid-studio"] [data-acc~="grid@grid+grid-core+grid-studio"] > [data-p="grid"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid+grid-core+grid-studio"] [data-acc~="grid-core@grid+grid-core+grid-studio"] > [data-p="grid-core"] :is(.cmp3-nb, .cmp3-v),
.cmp2.cmp2-av3[data-s="grid+grid-core+grid-studio"] [data-acc~="grid-studio@grid+grid-core+grid-studio"] > [data-p="grid-studio"] :is(.cmp3-nb, .cmp3-v) { color: var(--c2-acc); }
/* Les créneaux, au bureau : la grille porte un rail de 48 px à droite, ouvert
   ou fermé ; deux ou trois colonnes de thèmes, remplies ou vides. */
.cmp4-vide, .cmp4-rail, .cmp4-appliquer, .cmp4-mini { display: none; }
.cmp2-av3[data-a=""] .cmp4-creneau[data-col="a"] .cmp4-vide, .cmp2-av3[data-b=""] .cmp4-creneau[data-col="b"] .cmp4-vide, .cmp2-av3[data-c=""] .cmp4-creneau[data-col="c"] .cmp4-vide { display: grid; }
.cmp4-vide { place-items: center; width: 100%; min-height: 118px; padding: 12px; border: 1px dashed var(--c2-filet); border-radius: 12px; color: var(--gris-f); font-size: 15px; line-height: 1.4; text-align: center; }
.cmp4-outils { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; margin-top: 10px; }
.cmp4-choix { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 30px 0 16px; border: 1px solid var(--c2-filet); border-radius: 999px; font: 400 15px/1.2 var(--c2-ff); color: var(--gris-f); cursor: pointer; }
.cmp4-choix:hover { border-color: var(--noir); }
.cmp4-choix select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; font-size: 16px; }
.cmp4-choix:has(select:focus-visible) { outline: 2px solid var(--noir); outline-offset: 2px; }
.cmp4-retirer { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 1px solid var(--c2-filet); border-radius: 50%; background: none; color: var(--gris-f); cursor: pointer; }
.cmp4-retirer[hidden] { display: none; }
.cmp4-retirer:hover { border-color: var(--noir); color: var(--noir); }
.cmp4-retirer:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
.cmp4-retirer svg, .cmp4-rail-signe { pointer-events: none; }
.cmp4-retirer path { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.cmp2-av3 .cmp2-col { align-content: start; }
@media (min-width: 900px) {
  .cmp2.cmp2-av3 { --c2-grille: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr)) 48px; }
  .cmp2.cmp2-av3[data-c] { --c2-grille: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr)) 48px; }
  .cmp4-rail { display: flex; grid-column: -2 / -1; grid-row: 1; align-items: center; justify-content: center; border-left: 1px dashed var(--c2-filet); }
  .cmp4-rail-b { display: grid; place-items: center; width: 44px; height: 44px; border: 1px solid var(--c2-filet); border-radius: 50%; color: var(--noir); }
  .cmp4-rail-b:hover { border-color: var(--noir); }
  .cmp4-rail-b:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
  .cmp4-rail-signe { position: relative; width: 14px; height: 14px; }
  .cmp4-rail-signe::before, .cmp4-rail-signe::after { content: ""; position: absolute; left: 0; top: 6.25px; width: 14px; height: 1.5px; background: currentColor; }
  .cmp4-rail-signe::after { transform: rotate(90deg); }
  .cmp4-rail-signe.cmp4-moins::after { display: none; }
}
@media (min-width: 900px) and (max-width: 1199px) {
  .cmp2.cmp2-av3 .cmp4-choix { padding: 0 26px 0 12px; }
  .cmp2.cmp2-av3[data-c] .cmp2-voir { padding: 0 12px; }
}
/* Open all / Close all : au-dessus des quatre groupes, à la marge gauche de la colonne de libellés, en bouton texte. */
.cmp2-av3 .cmp3-outils { justify-content: flex-start; margin: 32px 0 0; padding-bottom: 8px; }
html.js .cmp2-av3 .cmp3-tout { min-height: 44px; padding: 0; border: 0; border-radius: 0; background: none; font-weight: 600; text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
html.js .cmp2-av3 .cmp3-tout:hover { text-decoration-thickness: 2px; }
/* Sans script : la liste native et « Apply » sous chaque créneau ; le rail est un lien. */
html:not(.js) .cmp2-av3 .cmp4-choix-t, html:not(.js) .cmp2-av3 .cmp4-choix .cmp2-chevron { display: none; }
html:not(.js) .cmp2-av3 .cmp4-choix { padding: 0; border: 0; }
html:not(.js) .cmp2-av3 .cmp4-choix select { position: static; opacity: 1; width: auto; max-width: 150px; height: 44px; font: 600 15px var(--c2-ff); }
html:not(.js) .cmp2-av3 .cmp4-appliquer { display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; border: 1px solid var(--noir); border-radius: 999px; background: none; font: 600 14px/1 var(--c2-ff); cursor: pointer; }
html:not(.js) .cmp2-av3 .cmp4-outils { flex-wrap: wrap; }

/* Téléphone, à la manière d'Apple : plus de colonne de libellés ; deux
   colonnes de 50 %, un trait vertical fin entre elles ; l'intitulé et son
   détail sur toute la largeur au-dessus des deux valeurs. L'en-tête porte
   les deux thèmes avec leur liste ; avec script il défile, et une barre
   réduite (nom, prix, la liste d'un appui) se colle sous la nav. */
@media (max-width: 719px) {
  .cmp2-av3 .cmp2-sous { max-width: 31ch; }
  .cmp2-av3 .cmp3-chapeau { display: block; max-width: 31ch; margin: 2px 0 0; }
  .cmp2-av3 .cmp3-crit { padding-left: 26px; }
  html.js .cmp2-av3 .cmp2-tete { position: relative; top: auto; }
  .cmp2-av3 .cmp4-outils { flex-wrap: nowrap; }
  .cmp2-av3 .cmp4-choix { flex: 1; min-width: 0; padding: 0 26px 0 12px; }
  .cmp2-av3 .cmp4-vide { min-height: 110px; }
  /* Sans script : la liste native sur toute la largeur de la colonne, × et Apply dessous (sinon elle couvrait les deux). */
  html:not(.js) .cmp2-av3 .cmp4-outils { flex-wrap: wrap; }
  html:not(.js) .cmp2-av3 .cmp4-choix { flex: 1 1 100%; }
  html:not(.js) .cmp2-av3 .cmp4-choix select { width: 100%; max-width: none; }
  /* le trait vertical : un dégradé de 1 px au milieu de la grille ; les zones pleine largeur (intitulés, groupes, bas de page) le recouvrent de blanc */
  .cmp2-av3 :is(.cmp2-corps, .cmp2-tete .cmp2-grille, .cmp4-mini-in) { background: linear-gradient(var(--c2-filet), var(--c2-filet)) 50% 0 / 1px 100% no-repeat content-box; }
  .cmp2-av3 :is(.cmp2-groupe tbody th, .cmp3-crit, .cmp3-outils, .cmp2-pied, .cmp2-retour) { background: var(--blanc); }
  .cmp2-av3 .cmp2-pied { margin-top: 0; padding-top: 56px; }   /* la marge laissait voir le trait vertical */
  .cmp2-av3 .cmp2-retour { margin-top: 0; padding-top: 20px; }
  html.js .cmp2-av3.cmp4-mini-on .cmp4-mini { display: block; position: fixed; left: 0; right: 0; top: var(--c2-colle, 59px); z-index: 6; background: var(--blanc); border-bottom: 1px solid var(--c2-filet); }
  html.js .cmp2-av3.cmp4-mini-on .cmp4-mini::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--c2-colle, 59px); background: var(--blanc); }
  html:has(.cmp4-mini-on) .nav::before { opacity: 0; }
  .cmp4-mini-in { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 12px; }
  .cmp4-mini-col { position: relative; display: flex; align-items: center; justify-content: center; min-height: 56px; padding: 6px 18px 6px 4px; text-align: center; font-size: 15px; line-height: 1.25; cursor: pointer; }
  .cmp4-mini-col select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; font-size: 16px; }
  .cmp4-mini-col:has(select:focus-visible) { outline: 2px solid var(--noir); outline-offset: -2px; }
  .cmp4-mini-col .cmp2-chevron { right: 4px; }
  .cmp4-mini-nom, .cmp4-mini-vide { display: none; }
  .cmp4-mini-nom b { display: block; font-weight: 600; }
  .cmp2-av3[data-a="grid"] .cmp4-mini-col[data-col="a"] .cmp4-mini-nom[data-p="grid"], .cmp2-av3[data-a="grid-core"] .cmp4-mini-col[data-col="a"] .cmp4-mini-nom[data-p="grid-core"], .cmp2-av3[data-a="grid-studio"] .cmp4-mini-col[data-col="a"] .cmp4-mini-nom[data-p="grid-studio"], .cmp2-av3[data-b="grid"] .cmp4-mini-col[data-col="b"] .cmp4-mini-nom[data-p="grid"], .cmp2-av3[data-b="grid-core"] .cmp4-mini-col[data-col="b"] .cmp4-mini-nom[data-p="grid-core"], .cmp2-av3[data-b="grid-studio"] .cmp4-mini-col[data-col="b"] .cmp4-mini-nom[data-p="grid-studio"] { display: block; }
  .cmp2-av3[data-a=""] .cmp4-mini-col[data-col="a"] .cmp4-mini-vide, .cmp2-av3[data-b=""] .cmp4-mini-col[data-col="b"] .cmp4-mini-vide { display: block; color: var(--gris-f); }
}

/* PASSE 10, AVENANT 4 — le bureau seulement (≥ 900 px). Sous 900 px, rien de
   ce qui suit n'agit : les nouveautés sont cachées et l'avenant 3 rend seul.
   La page tient data-ka/kb/kc (t : thème, sel : « Select a theme », plus : « + »).
   Pistes : la colonne des libellés, puis un créneau par piste, 1fr pour un
   thème ou un « Select a theme », 56 px pour un « + » (bouton de 44 px). */
.cmp5-plus, .cmp5-fermer, .cmp5-echange, .cmp5-trait, .cmp5-traits { display: none; }
@media (min-width: 900px) {
  .cmp2.cmp2-av4[data-ka] { --ta: minmax(0, 1fr); --tb: minmax(0, 1fr); --tc: minmax(0, 1fr); --ca: 2; --cb: 3; --cc: 4; --c2-grille: minmax(0, 1.6fr) var(--ta) var(--tb) var(--tc); }
  .cmp2.cmp2-av4[data-ka="plus"] { --ta: 56px; }
  .cmp2.cmp2-av4[data-kb="plus"] { --tb: 56px; }
  .cmp2.cmp2-av4[data-kc="plus"] { --tc: 56px; }
  .cmp2.cmp2-av4[data-ka] .cmp4-creneau[data-col="c"] { display: grid; grid-column: var(--cc); }
  .cmp2.cmp2-av4[data-c="grid"] :is(td, th, .cmp3-n)[data-p="grid"], .cmp2.cmp2-av4[data-c="grid-core"] :is(td, th, .cmp3-n)[data-p="grid-core"], .cmp2.cmp2-av4[data-c="grid-studio"] :is(td, th, .cmp3-n)[data-p="grid-studio"] { display: flex; grid-column: var(--cc); }

  /* 1. La colonne vide : seul reste « Select a theme », à la place du nom.
     La phrase reste pour les lecteurs d'écran, cachée à l'œil ; plus de cadre. */
  .cmp2.cmp2-av4 .cmp4-creneau .cmp4-vide { position: absolute; width: 1px; height: 1px; min-height: 0; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
  .cmp2.cmp2-av4[data-ka="sel"] .cmp4-creneau[data-col="a"] .cmp4-outils, .cmp2.cmp2-av4[data-kb="sel"] .cmp4-creneau[data-col="b"] .cmp4-outils, .cmp2.cmp2-av4[data-kc="sel"] .cmp4-creneau[data-col="c"] .cmp4-outils { margin-top: 0; }
  .cmp5-fermer { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 1px solid var(--c2-filet); border-radius: 50%; background: none; color: var(--gris-f); cursor: pointer; }
  .cmp5-fermer[hidden] { display: none; }
  .cmp5-fermer:hover { border-color: var(--noir); color: var(--noir); }
  .cmp5-fermer:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
  .cmp5-fermer svg { pointer-events: none; }
  .cmp5-fermer path { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }

  /* 2. Les traits : 1 px plein, couleur des filets des groupes, entre deux
     colonnes larges (thème ou « Select a theme »), de l'en-tête à la
     dernière ligne. Dans l'en-tête : un élément de la grille ; dans le corps :
     une grille calque aux mêmes pistes. Aucun ne prend de place ni ne décale
     le centrage des cases. Les valeurs : même marge à gauche et à droite. */
  .cmp5-trait, .cmp5-traits i { grid-row: 1; justify-self: start; width: 0; border-left: 1px solid var(--c2-filet); pointer-events: none; }
  .cmp5-trait { position: relative; z-index: 1; }
  :is(.cmp5-trait, .cmp5-traits i)[data-col="b"] { grid-column: var(--cb); }
  :is(.cmp5-trait, .cmp5-traits i)[data-col="c"] { grid-column: var(--cc); }
  .cmp2.cmp2-av4:not([data-ka="plus"]):not([data-kb="plus"]) :is(.cmp5-trait, .cmp5-traits i)[data-col="b"],
  .cmp2.cmp2-av4:not([data-kb="plus"]):not([data-kc="plus"]) :is(.cmp5-trait, .cmp5-traits i)[data-col="c"] { display: block; }
  .cmp2.cmp2-av4 .cmp2-corps { position: relative; display: flow-root; }   /* flow-root : la marge de « Open all » reste dedans, le calque part du bas de l'en-tête */
  .cmp2.cmp2-av4 .cmp5-traits i { display: none; }
  .cmp2.cmp2-av4 .cmp5-traits { display: grid; position: absolute; inset: 0; z-index: 1; padding-inline: inherit; grid-template-columns: var(--c2-grille); pointer-events: none; }
  /* Le pied arrête les traits à la dernière ligne (fond blanc au-dessus du calque, marge changée en retrait). */
  .cmp2.cmp2-av4 :is(.cmp2-pied, .cmp2-retour) { position: relative; z-index: 2; background: var(--blanc); }
  .cmp2.cmp2-av4 .cmp2-pied { max-width: none; margin-top: 0; padding: 56px calc(100% - 46em) 0 0; }
  .cmp2.cmp2-av4 .cmp2-retour { margin-top: 0; padding-top: 20px; }
  .cmp2.cmp2-av4 :is(.cmp2-groupe td, .cmp3-n) { padding-inline: 16px; }

  /* 3. Le « + » : un bouton de 44 × 44 dans sa propre piste étroite, sur
     l'axe des noms (haut du créneau 14 px, comme le nom de 44 px de haut et
     « Select a theme »). Trait fin plein, celui de « Select a theme ». */
  .cmp2.cmp2-av4[data-ka="plus"] .cmp4-creneau[data-col="a"], .cmp2.cmp2-av4[data-kb="plus"] .cmp4-creneau[data-col="b"], .cmp2.cmp2-av4[data-kc="plus"] .cmp4-creneau[data-col="c"] { padding-inline: 6px; }
  .cmp2.cmp2-av4[data-ka="plus"] .cmp4-creneau[data-col="a"] > :not(.cmp5-plus), .cmp2.cmp2-av4[data-kb="plus"] .cmp4-creneau[data-col="b"] > :not(.cmp5-plus), .cmp2.cmp2-av4[data-kc="plus"] .cmp4-creneau[data-col="c"] > :not(.cmp5-plus) { display: none; }
  .cmp2.cmp2-av4[data-ka="plus"] .cmp4-creneau[data-col="a"] .cmp5-plus, .cmp2.cmp2-av4[data-kb="plus"] .cmp4-creneau[data-col="b"] .cmp5-plus, .cmp2.cmp2-av4[data-kc="plus"] .cmp4-creneau[data-col="c"] .cmp5-plus { display: grid; }
  .cmp5-plus { place-items: center; width: 44px; height: 44px; padding: 0; border: 1px solid var(--c2-filet); border-radius: 50%; background: none; color: var(--noir); cursor: pointer; }
  .cmp2.cmp5-plus-carre .cmp5-plus { border-radius: 10px; }   /* ?plus=carre */
  .cmp5-plus:hover { border-color: var(--noir); }
  .cmp5-plus:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }

  /* 4. L'échange : 44 × 44 centré sur le trait (le trait est le premier pixel
     de la piste : -21,5 px), sur l'axe des noms ; un disque de la couleur de
     la page coupe le trait derrière l'icône de 20 px. */
  .cmp5-echange { display: grid; place-items: center; position: relative; z-index: 2; grid-row: 1; align-self: start; justify-self: start; width: 44px; height: 44px; margin: 14px 0 0 -21.5px; border-radius: 50%; color: var(--noir); }
  .cmp5-echange[data-entre="ab"] { grid-column: var(--cb); }
  .cmp5-echange[data-entre="bc"] { grid-column: var(--cc); }
  .cmp5-echange[hidden] { display: none; }
  .cmp5-echange::before { content: ""; position: absolute; inset: 6px; z-index: -1; border-radius: 50%; background: var(--blanc); transition: background-color .2s var(--ease); }
  .cmp5-echange:hover::before { background: #EDEDED; }
  .cmp5-echange:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
  .cmp5-icone { pointer-events: none; }
  .cmp5-icone path { stroke: currentColor; stroke-width: 1.5; stroke-miterlimit: 10; stroke-linecap: round; stroke-linejoin: round; }
}

/* PASSE 10, AVENANT 5 — le téléphone seulement (< 720 px, le point de rupture
   du téléphone des avenants 3 et 4 : max-width 719px). Au-dessus, .cmp6 est
   caché et rien de ce qui suit n'agit : la page rend l'avenant 4.
   Valeurs reprises de la maquette validée par Théo (references/passe-10/
   avenant5/maquette-telephone.html) : une colonne de fonctions, deux colonnes
   de thème de 90 px, marges de 16 px, Archivo. Écarts voulus : les filets à
   la couleur des groupes (--c2-filet, 3:1 sur blanc) au lieu de #E2E2E2 ;
   « Differences only » enfoncé reste noir (l'accent ne marque que les
   différences de données) ; les deux boutons ont 44 px de haut (42 sur la
   maquette). */
.cmp6 { display: none; }
@media (max-width: 719px) {
  .cmp2-av5 .cmp2-tete, .cmp2-av5 .cmp4-mini, html.js .cmp2-av5.cmp2-av5.cmp4-mini-on .cmp4-mini { display: none; }
  .cmp2-av5 .cmp2-corps > :not(.cmp2-pied, .cmp2-retour) { display: none; }
  .cmp2-av5 .cmp2-corps { background: none; padding-inline: 16px; }
  .cmp2-av5 .cmp2-haut { padding-inline: 16px; }
  /* Pas d'ancrage du défilement : l'en-tête qui se réduit ferait remonter la page de 52 px et le
     réduirait puis l'agrandirait en boucle (Chromium) ; sans ancrage, comme la maquette. */
  .cmp2-av5 { overflow-anchor: none; }

  .cmp6 { --w: 90px; --m: 16px; display: block; font: 400 15px/1.3 var(--font-body); color: var(--encre); font-variant-numeric: normal; }
  .cmp6 :where(p, b, em, small) { margin: 0; }
  .cmp6 :where(button, select) { font: inherit; color: inherit; }
  .cmp6-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

  /* L'en-tête collant, à la grille des tableaux, sous la nav (--c2-colle, posé par v2.js). */
  .cmp6-tete { position: sticky; top: var(--c2-colle, var(--c2-nav)); z-index: 5; background: rgba(255, 255, 255, .97); -webkit-backdrop-filter: saturate(1.4) blur(10px); backdrop-filter: saturate(1.4) blur(10px); border-top: 1px solid var(--c2-filet); border-bottom: 1px solid var(--c2-filet); }
  .cmp6-tete::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: calc(var(--c2-colle, var(--c2-nav)) + 2px); background: var(--blanc); opacity: 0; pointer-events: none; }
  .cmp2.cmp2-colle .cmp6-tete::before { opacity: 1; }
  html:not(.js) .cmp6-tete { position: relative; top: auto; }   /* sans script : pas de réduction, l'en-tête (et Apply) défile */
  .cmp6-grille { display: grid; grid-template-columns: minmax(0, 1fr) var(--w) var(--w); padding: 0 var(--m); }
  .cmp6-zone { position: relative; }
  .cmp6-coin { grid-column: 1; grid-row: 1; display: flex; flex-direction: column; justify-content: flex-end; padding: 10px 12px 12px 0; }
  .cmp6-coin p { max-width: 12ch; font: 600 16px/1.2 var(--font-body); letter-spacing: -.005em; color: var(--encre); }
  .cmp6-col { grid-row: 1; position: relative; min-width: 0; padding: 8px 6px 10px; border-left: 1px solid var(--c2-filet); text-align: center; }
  .cmp6-col[data-col="a"] { grid-column: 2; }
  .cmp6-col[data-col="b"] { grid-column: 3; }
  .cmp6-nom { min-height: 2.2em; font: 800 14px/1.1 var(--font-body); letter-spacing: .03em; }
  .cmp6-nom span { display: block; }
  .cmp6-prix { margin: 2px 0 6px; font: 600 20px/1.1 var(--font-body); letter-spacing: -.01em; }
  .cmp6-prix s { display: block; font-size: 13px; font-weight: 400; color: var(--gris-f); }
  .cmp6-choix { position: relative; display: block; height: 44px; overflow: hidden; font-size: 13px; font-weight: 500; line-height: 34px; color: var(--encre); cursor: pointer; }
  .cmp6-pastille { display: block; height: 34px; margin: 5px 0; border-radius: 99px; background: var(--papier); box-shadow: inset 0 0 0 1px var(--c2-filet); }
  .cmp6-pastille .cmp6-chev { margin-left: 3px; vertical-align: -2px; color: var(--gris-f); }
  /* Créneau vide : « Select a theme » sur deux lignes dans la pastille ; le prix vide garde sa hauteur. */
  .cmp6[data-a=""] .cmp6-col[data-col="a"] .cmp6-pastille, .cmp6[data-b=""] .cmp6-col[data-col="b"] .cmp6-pastille { display: flex; align-items: center; justify-content: center; padding: 0 8px; line-height: 14px; }
  .cmp6[data-a=""] .cmp6-col[data-col="a"] .cmp6-chev, .cmp6[data-b=""] .cmp6-col[data-col="b"] .cmp6-chev { display: none; }
  .cmp6-prix:empty { min-height: 22px; }
  .cmp6-choix select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; font-size: 16px; cursor: pointer; }
  .cmp6-choix:has(select:focus-visible) .cmp6-pastille { outline: 2px solid var(--noir); outline-offset: 0; }
  .cmp6-appliquer { display: none; }
  html:not(.js) .cmp6-appliquer { display: block; width: 100%; min-height: 44px; margin-top: 4px; border: 1px solid var(--noir); border-radius: 99px; background: none; font: 600 14px/1 var(--font-body); cursor: pointer; }
  html:not(.js) .cmp6-choix select { opacity: 1; position: static; display: block; height: 44px; margin-top: 0; }   /* sans script : la liste se voit, Apply envoie */
  html:not(.js) .cmp6-choix { height: auto; overflow: visible; }
  html:not(.js) .cmp6-pastille { display: none; }
  .cmp6-tete.cmp6-mini .cmp6-choix { display: none; }
  .cmp6-tete.cmp6-mini .cmp6-col { padding-bottom: 8px; }
  .cmp6-tete.cmp6-mini .cmp6-prix { margin-bottom: 0; }
  /* L'échange : posé sur le trait entre les deux thèmes (le bord gauche de la colonne b), à la hauteur du nom. */
  .cmp6-echange { grid-column: 3 / 4; grid-row: 1 / 2; position: absolute; z-index: 6; top: 8px; left: -22px; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; background: none; color: var(--encre); cursor: pointer; }
  .cmp6-echange[hidden] { display: none; }
  .cmp6-echange > span { display: grid; place-items: center; width: 28px; height: 28px; border: 1px solid var(--c2-filet); border-radius: 50%; background: var(--blanc); }
  .cmp6-icone { width: 16px; height: 16px; }
  .cmp6-icone path { stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  .cmp6-echange:focus-visible { outline: none; }
  .cmp6-echange:focus-visible > span { outline: 2px solid var(--noir); outline-offset: 2px; }

  /* Open all, Differences only (réglages ajoutés, sans effet tant qu'on n'appuie pas). */
  .cmp6-outils { display: flex; justify-content: space-between; align-items: center; min-height: 48px; padding: 5px var(--m); border-bottom: 1px solid var(--c2-filet); }
  html:not(.js) .cmp6-outils { display: none; }
  .cmp6-outils button { display: inline-flex; align-items: center; min-height: 44px; padding: 0; border: 0; background: none; font: 500 14px/1.3 var(--font-body); color: var(--encre); text-decoration: underline; text-decoration-color: var(--c2-filet); text-underline-offset: 3px; cursor: pointer; }
  .cmp6-outils .cmp6-diffb[aria-pressed="true"] { text-decoration-color: currentColor; text-decoration-thickness: 2px; }
  .cmp6-outils button:disabled { color: var(--gris); cursor: default; }
  .cmp6-outils button:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }

  /* Les groupes : la ligne de résumé reprend la grille (nom et chapeau, puis le compte de chaque thème). */
  .cmp6-g { border-bottom: 1px solid var(--c2-filet); scroll-margin-top: calc(var(--c2-colle, var(--c2-nav)) + 76px); }
  .cmp6-s { display: block; padding: 0; list-style: none; cursor: pointer; }
  .cmp6-s::-webkit-details-marker { display: none; }
  .cmp6-s:focus-visible { outline: 2px solid var(--noir); outline-offset: -2px; }
  .cmp6-sg { align-items: stretch; min-height: 64px; }
  .cmp6-gn { display: flex; flex-direction: column; justify-content: center; padding: 14px 12px 14px 0; }
  .cmp6-gt { display: flex; align-items: center; gap: 8px; font: 500 20px/1.15 var(--font-body); letter-spacing: -.01em; }
  .cmp6-gt .cmp6-chev { flex: none; color: var(--gris-f); transition: transform .25s ease; }
  .cmp6-g[open] > .cmp6-s .cmp6-chev { transform: rotate(180deg); }
  .cmp6-chap { margin-top: 2px; font-size: 13px; line-height: 1.3; color: var(--gris-f); }
  .cmp6-n { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; border-left: 1px solid var(--c2-filet); text-align: center; }
  .cmp6-nb { font: 600 20px/1 var(--font-body); }
  .cmp6-nouv { font: 600 12px/1.1 var(--font-body); font-style: normal; color: var(--c2-acc); }
  .cmp6-rien { visibility: hidden; }

  /* Une ligne par fonction : le libellé court s'ouvre sur le titre long et la description. */
  .cmp6-tw { padding: 0 var(--m); }
  .cmp6-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
  .cmp6-colt { width: var(--w); }
  .cmp6-table tr { border-top: 1px solid var(--c2-filet); }
  .cmp6-table :is(th, td) { min-width: 0; padding: 0; vertical-align: top; text-align: start; font-weight: 400; }
  .cmp6-table th.cmp6-f { padding-inline-end: 8px; }
  .cmp6-f summary { position: relative; display: block; min-height: 56px; padding: 14px 22px 14px 0; font: 500 15px/1.3 var(--font-body); list-style: none; cursor: pointer; }
  .cmp6-f summary::-webkit-details-marker { display: none; }
  .cmp6-f summary::after { content: ""; position: absolute; right: 2px; top: 20px; width: 8px; height: 8px; border-right: 1.5px solid var(--gris); border-bottom: 1.5px solid var(--gris); transform: rotate(45deg); transition: transform .2s ease; }
  .cmp6-f details[open] > summary::after { top: 24px; transform: rotate(-135deg); }
  .cmp6-f summary:focus-visible { outline: 2px solid var(--noir); outline-offset: -2px; }
  .cmp6-long { padding: 0 0 14px; font-size: 14px; line-height: 1.4; color: var(--gris-f); }
  .cmp6-long b { display: block; margin-bottom: 2px; font-weight: 600; color: var(--encre); }
  .cmp6-table td.cmp6-c { width: var(--w); padding: 14px 4px; border-left: 1px solid var(--c2-filet); text-align: center; }
  .cmp6-ok { display: block; width: 20px; height: 20px; margin: 2px auto 0; color: var(--encre); }
  .cmp6-non { display: block; font-size: 16px; line-height: 24px; color: var(--gris); }
  .cmp6-v { display: block; font: 500 15px/24px var(--font-body); }
  .cmp6-plus { display: block; margin-top: 6px; font: 600 14px/1.15 var(--font-body); }
  .cmp6-plus small { display: block; font: 400 14px/1.15 var(--font-body); }
  .cmp6-dif { background: var(--c2-acc-teinte); }
  .cmp6-dif :is(.cmp6-ok, .cmp6-v, .cmp6-plus) { color: var(--c2-acc); }
  .cmp6-neuf { display: inline-block; margin-top: 6px; padding: 3px 8px; border: 1px solid var(--c2-acc); border-radius: 99px; background: var(--blanc); font: 700 11px/1.2 var(--font-body); letter-spacing: .06em; text-transform: uppercase; color: var(--c2-acc); }
  .cmp6.cmp6-diff tr[data-diff="0"] { display: none; }
}
/* Sous 340 px (petit écran, zoom) : le libellé passe sur toute la largeur, au-dessus de deux cases de 50 %. */
@media (max-width: 339px) {
  .cmp6-grille { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .cmp6-coin, .cmp6-gn { grid-column: 1 / -1; }
  .cmp6-coin { padding: 10px 0 8px; }
  .cmp6-coin p { max-width: none; }
  .cmp6 .cmp6-col { grid-row: 2; }
  .cmp6-col[data-col="a"] { grid-column: 1; }
  .cmp6-col[data-col="b"] { grid-column: 2; }
  .cmp6-echange { grid-column: 1 / 2; grid-row: 2 / 3; left: auto; right: -22px; }
  .cmp6-col[data-col="a"], .cmp6-n[data-col="a"] { border-left: 0; }
  .cmp6-table, .cmp6-table tbody { display: block; }
  .cmp6-table tr { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .cmp6-table th.cmp6-f { grid-column: 1 / -1; padding-inline-end: 0; }
  .cmp6-table td.cmp6-c { width: auto; }
  .cmp6-table tr > td.cmp6-c:nth-child(2) { border-left: 0; }
}

/* ========================================================================
   PASSE 11 (09/10) — l'accueil avec ce que Théo a validé. Les défauts
   changent dans layout.php (cartes D, galerie d=2, entrée c, aura b, menu
   Apple, courbe b + creux) ; ici, seulement les ajouts, tous derrière une
   classe p11-* posée par un paramètre, sauf B2 (défaut provisoire).
   ======================================================================== */

/* B2 — « Compare the tiers » sorti des cartes : un seul élément, centré, sous
   la rangée des trois cartes (sous la galerie au téléphone). &comparer=bouton
   (défaut provisoire) : bouton secondaire, même famille que « View the demos » ;
   &comparer=lien : lien souligné. Cible de 44 px partout. */
.p11-comparer { margin: 12px 0 0; text-align: center; }
.p11-comparer a { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--noir); font-size: 15px; font-weight: 500; }
.p11-comparer a span { transition: transform .3s var(--ease); }
.p11-comparer a:hover span { transform: translateX(3px); }
.p11-comparer a:focus-visible { outline: 2px solid var(--noir); outline-offset: 2px; }
.p11-comparer-bouton a { padding: 10px 20px; border: 1px solid var(--gris); border-radius: 999px; background: var(--blanc); text-decoration: none; transition: border-color .2s var(--ease), background-color .2s var(--ease); }
.p11-comparer-bouton a:hover { border-color: var(--noir); background: var(--papier); }
.p11-comparer-lien a { padding: 0 8px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.p11-comparer-lien a:hover { text-decoration-thickness: 2px; }
@media (min-width: 1000px) {
  /* Épinglé (bureau, script) : il arrive avec le titre, comme « View the demos ». */
  html.js.p7-cartes-d .paliers .p11-comparer { position: relative; z-index: 2; opacity: var(--ta, 1); }
}

/* B1 — le panier dans le menu Apple (&panier=a|b, sous 900 px, avec script).
   Repris d'Apple dans l'esprit (mesuré sur apple.com/fr à 402 px : un sac au
   trait fin dans une zone de 48 px ; au toucher, le contenu apparaît en fondu,
   0,24 s après 0,08 s, sous un grand titre) : ici l'icône est la nôtre (trait
   de 1,5 px, comme la croix et le chevron du panneau), avec un compteur ; le
   volet (b) recouvre les entrées sous la tête du panneau. */
@media (max-width: 899px) {
  html.js.p11-panier .am-sac {
    position: relative; display: grid; place-items: center; width: 44px; height: 44px; margin: -5px 6px -5px auto; padding: 0;
    border: 0; background: none; color: var(--noir); cursor: pointer; text-decoration: none;
    opacity: 0; transition: opacity .24s var(--am-courbe);
  }
  html.js.p11-panier .am-ouvert .am-sac { opacity: 1; }
  html.js.p11-panier .am-sac + .am-fermer { margin-left: 0; }
  html.js.p11-panier .am-sac-i { width: 22px; height: 22px; }
  html.js.p11-panier .am-sac-n {
    position: absolute; top: 5px; right: 3px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
    background: var(--noir); color: var(--blanc); font: 600 12px/18px var(--am-ff); text-align: center; font-variant-numeric: tabular-nums;
  }
  html.js.p11-panier .am-sac-n[hidden] { display: none; }
  html.js.p11-panier .am-sac[aria-expanded="true"] .am-sac-i path { stroke-width: 2; }
  /* b : le volet, plein largeur sous la tête ; il cache les entrées tant qu'il est ouvert. */
  html.js.p11-panier-b .am-volet { padding: 32px 48px 48px; opacity: 0; transform: translateY(-8px); transition: opacity .24s var(--am-courbe) .08s, transform .24s var(--am-courbe) .08s; }
  html.js.p11-panier-b .am-volet[hidden] { display: none; }
  html.js.p11-panier-b .am-volet.am-volet-montre { opacity: 1; transform: none; }
  html.js.p11-panier-b .am.am-volet-ouvert .am-vues { display: none; }
  html.js.p11-panier-b .am-volet-t { margin: 0 0 16px; font: 600 28px/1.1 var(--am-ff); letter-spacing: .007em; color: #1D1D1F; outline: none; }
  html.js.p11-panier-b .am-volet-p { margin: 0 0 20px; font: 400 17px/1.4 var(--am-ff); color: #6E6E73; }
  html.js.p11-panier-b .am-volet-lien { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font: 600 17px/1 var(--am-ff); color: var(--noir); text-decoration: underline; text-underline-offset: 3px; }
  html.js.p11-panier-b .am-volet-lignes { list-style: none; margin: 0 0 8px; padding: 0; }
  html.js.p11-panier-b .am-volet-lignes li { display: grid; grid-template-columns: 1fr auto; column-gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--filet); }
  html.js.p11-panier-b .am-volet-nom { font: 600 17px/1.3 var(--am-ff); color: #1D1D1F; }
  html.js.p11-panier-b .am-volet-fam { grid-row: 2; font: 400 14px/1.4 var(--am-ff); color: #6E6E73; }
  html.js.p11-panier-b .am-volet-prix { grid-row: 1 / 3; grid-column: 2; align-self: center; font: 600 17px/1 var(--am-ff); font-variant-numeric: tabular-nums; }
  html.js.p11-panier-b .am-volet-total { display: flex; justify-content: space-between; margin: 12px 0 24px; font: 600 19px/1.2 var(--am-ff); font-variant-numeric: tabular-nums; }
  html.js.p11-panier-b .am-volet-cta { display: flex; align-items: center; justify-content: center; min-height: 48px; border-radius: 999px; background: var(--noir); color: var(--blanc); font: 600 17px/1 var(--am-ff); text-decoration: none; }
  html.js.p11-panier-b .am-volet-cta:focus-visible { outline-offset: 3px; }
}

/* B6 — le badge d'une pastille de la galerie (d=2), lu dans tpl/v2/badges.php,
   vide par défaut. Posé en surplomb sur le bord haut de la pastille (position
   absolue) : la pastille garde sa taille et sa ligne, rien ne bouge autour. */
@media (max-width: 999px) {
  html.p9-d-2 .m-points a { position: relative; }
  html.p9-d-2 .m-pt-badge {
    position: absolute; left: 50%; top: -14px; transform: translateX(-50%); white-space: nowrap; pointer-events: none;
    padding: 2px 7px; border: 1px solid var(--noir); border-radius: 999px; background: var(--blanc); color: var(--noir);
    font: 600 11px/14px var(--font-body); letter-spacing: .04em; text-transform: uppercase;
  }
}

/* B5 — la galerie au téléphone (&glisse=1) : la carte qui arrive fait glisser
   son contenu dans le sens du geste. 300 ms, 28 px, courbe qui freine
   (cubic-bezier(.2, .8, .2, 1)), 25 ms d'une ligne à l'autre : 400 ms au plus.
   Mouvement réduit : un fondu de 150 ms, sans déplacement. */
@media (max-width: 999px) {
  html.js.p11-glisse .carte.p11-arrive .c7d > * { animation: p11-glisse .3s cubic-bezier(.2, .8, .2, 1) both; }
  html.js.p11-glisse .carte.p11-arrive .c7d > :nth-child(2) { animation-delay: 25ms; }
  html.js.p11-glisse .carte.p11-arrive .c7d > :nth-child(3) { animation-delay: 50ms; }
  html.js.p11-glisse .carte.p11-arrive .c7d > :nth-child(4) { animation-delay: 75ms; }
  html.js.p11-glisse .carte.p11-arrive .c7d > :nth-child(n + 5) { animation-delay: 100ms; }
}
@keyframes p11-glisse { from { opacity: 0; transform: translateX(calc(var(--sens, 1) * 28px)); } to { opacity: 1; transform: none; } }
@keyframes p11-fondu { from { opacity: 0; } to { opacity: 1; } }

/* B3 — l'inclinaison (&incline=1|2, bureau, souris, mouvement permis). La face
   texte de la carte retournée reçoit, après son rotateY(180deg) et le zoom de
   l'aura, deux petites rotations lues dans --ix / --iy (3° au plus, v2.js) ; la
   perspective est celle de .carte (1 400 px). transform seul : aucun recalcul de
   mise en page. 180 ms pour suivre, 450 ms pour revenir au repos. */
@media (hover: hover) and (min-width: 1000px) {
  html.js.p11-incline .paliers[data-etat="retourne"] .carte .face--texte { transition: opacity 0s linear .32s, transform .45s cubic-bezier(.2, .8, .2, 1); }
  html.js.p11-incline .paliers[data-etat="retourne"] .carte:hover .face--texte { transform: rotateY(180deg) rotateX(var(--ix, 0deg)) rotateY(var(--iy, 0deg)); transition: opacity 0s linear .32s, transform .18s ease-out; }
  html.js.p11-incline.p8-aura .paliers[data-etat="retourne"] .carte:hover .face--texte { transform: rotateY(180deg) scale(1.04) rotateX(var(--ix, 0deg)) rotateY(var(--iy, 0deg)); }
}

/* Décisions de Théo du 09/10 (point 6) : cinq promesses au lieu de huit. Le
   même rythme qu'avant : au téléphone, 3,5 s par promesse (28 s pour 8 →
   17,5 s pour 5, pas à pas à cinq temps, même part de pause : 83 %) ; au
   bureau, la même vitesse en pixels (8 promesses : 15 358 px en 48 s, 320 px/s ;
   5 promesses : 11 222 px, mesurés à 1440, « NO PAID APP » étant plus long → 35 s). Le pas à huit temps
   (p6-pas) reste, pour huit promesses. */
.promesses[data-n="5"] .promesses-ruban { --ruban-duree: 35s; }
@media (max-width: 720px) {
  html.p6-promesses .promesses[data-n="5"] .promesses-ruban { --ruban-duree: 17.5s; }
}
@media (max-width: 720px) {
  html.p6-promesses .promesses[data-n="5"] .ruban-piste { animation-name: d0910-pas5; }
}
@keyframes d0910-pas5 {
  0.000% { transform: translateX(0); }
  16.600% { transform: translateX(0); }
  20.000% { transform: translateX(-100vw); }
  36.600% { transform: translateX(-100vw); }
  40.000% { transform: translateX(-200vw); }
  56.600% { transform: translateX(-200vw); }
  60.000% { transform: translateX(-300vw); }
  76.600% { transform: translateX(-300vw); }
  80.000% { transform: translateX(-400vw); }
  96.600% { transform: translateX(-400vw); }
  100.000% { transform: translateX(-500vw); }
}
/* « NO PAID APP » (11 signes) passe à 351 px en 56 px : plus large que la promesse à 360 px (324 px utiles).
   Le mot long seul descend à 14vw sous 400 px : 316 px à 360, 281 px à 320 (284 utiles) ; une ligne. */
@media (max-width: 720px) {
  html.p6-promesses .promesse.promesse-longue b { font-size: min(1em, 14vw); }
}

/* =====================================================================
   PASSE 12 (09/10) — le texte de l'accueil tranché par Théo. Seulement des
   éléments neufs (classes p12-*, demo-boutique, demo-affil) et le rythme du
   bandeau à trois et deux promesses : avec ?texte=p11, aucune de ces règles
   ne trouve d'élément, la page est celle d'avant.
   ===================================================================== */
/* Sections neuves : pourquoi payer, après le paiement, garantie. */
.p12-pourquoi, .p12-apres, .p12-garantie { padding: clamp(88px, 13vh, 150px) 0; }
.p12-apres { background: var(--papier); }
.p12-garantie { padding-top: 0; }
.p12-sub { max-width: 38em; margin-top: 18px; font-size: 18px; line-height: 1.5; color: var(--gris-f); }
.p12-pourquoi-liste { list-style: none; padding: 0; margin-top: 48px; display: grid; gap: 0; }
.p12-pourquoi-liste li { display: grid; align-content: start; grid-template-columns: 56px 1fr; column-gap: 16px; row-gap: 6px; padding: 24px 0 26px; border-top: 1px solid var(--filet); }
.p12-pourquoi-liste li:last-child { border-bottom: 1px solid var(--filet); }
.p12-n { grid-row: 1 / 3; font-size: 12px; letter-spacing: .14em; font-weight: 500; color: var(--gris); padding-top: .55em; }
.p12-h { font-size: var(--d3); line-height: 1.15; letter-spacing: var(--d3-ls); font-weight: 600; }
.p12-p { max-width: 36em; font-size: 17px; line-height: 1.55; color: var(--gris-f); }
@media (min-width: 900px) {
  .p12-pourquoi-liste { grid-template-columns: 1fr 1fr; column-gap: 64px; }
  .p12-pourquoi-liste li:nth-last-child(2) { border-bottom: 1px solid var(--filet); }
}
.p12-apres-col, .p12-garantie-col { max-width: calc(var(--col-texte) + 2 * var(--pad)); }
.p12-apres .d2 { margin-bottom: 28px; }
.p12-apres .p12-p + .p12-p { margin-top: 14px; }
.p12-garantie-col { text-align: center; }
.p12-garantie-t { font-family: var(--font-body); font-size: clamp(24px, 2.6vw, 34px); line-height: 1.2; font-weight: 600; letter-spacing: -.01em; text-wrap: balance; }
.p12-garantie .p12-p { margin: 14px auto 28px; font-size: 15px; }

/* Les cartes D : l'étiquette « Opening price », la règle sous le prix, la
   phrase « Choose X if… ». Petites : la face du bureau a une hauteur fixe. */
html.p7-cartes-d .p12-ouv-t { margin: 0 0 2px; font-size: 12px; line-height: 1.3; letter-spacing: .04em; text-transform: uppercase; color: var(--d-doux); }
html.p7-cartes-d .p12-ouv-r { margin-top: 6px; font-size: 13px; line-height: 1.35; color: var(--d-doux); }
html.p7-cartes-d .p12-phrase { margin-top: 12px; font-size: 14px; line-height: 1.4; color: var(--d-texte); }
/* Le barré de ?prix=a, le montant et la pastille ne tiennent pas sur une ligne à 320 px (l'ancien rendu
   coupait déjà la pastille) : au téléphone, sur les cartes de la passe 12, la pastille passe à la ligne. */
@media (max-width: 899px) { html.p7-cartes-d .d-prix:has(.p12-ouv-r) .d-ligne-prix { flex-wrap: wrap; row-gap: 6px; } }
@container (max-height: 470px) {
  html.p7-cartes-d .p12-ouv-t { font-size: 10px; }
  html.p7-cartes-d .p12-ouv-r { margin-top: 4px; font-size: 11px; line-height: 1.3; }
  html.p7-cartes-d .p12-phrase { margin-top: 9px; font-size: 12px; line-height: 1.35; }
}
/* La face du bureau (hauteur fixe) : avec la phrase « Choose X if… », les
   lignes restent des libellés, sans dépliant (comme sous 380 px avant) ; le
   détail reste sur la page Comparer et au téléphone. Seulement les cartes de
   la passe 12 (:has(.p12-phrase)) : ?cartes-texte=actuel garde l'accordéon. */
@container (max-height: 470px) {
  html.p7-cartes-d .c7d:has(.p12-phrase) :is(.d-acc-d, .d-signe) { display: none; }
  html.p7-cartes-d .c7d:has(.p12-phrase) .d-acc summary { pointer-events: none; min-height: 30px; padding-block: 3px; }
  html.p7-cartes-d .c7d:has(.p12-phrase) .d-acc[open] { background: none; border-color: transparent; }
  html.p7-cartes-d .c7d:has(.p12-phrase) .d-acc[open] summary { color: var(--d-doux); }
  html.p7-cartes-d .c7d:has(.p12-phrase) .d-label { display: none; }
  html.p7-cartes-d .c7d:has(.p12-phrase) .d-liste { margin-top: 8px; }
  /* ?cartes-texte=actuel : l'ancien texte sous le prix d'ouverture ne tient
     plus ; l'étiquette au-dessus des lignes cède, comme sur les cartes de la
     passe 12. L'accordéon reste. */
  html.p7-cartes-d .c7d:not(:has(.p12-phrase)):has(.p12-ouv-r) .d-label { display: none; }
}
@container (max-height: 380px) {
  html.p7-cartes-d .p12-phrase { display: none; }
}
@container (max-height: 300px) {
  html.p7-cartes-d .p12-ouv-t, html.p7-cartes-d .p12-ouv-r { display: none; }
}

/* Les démos : la boutique en légende sous le palier, la non-affiliation sous la carte. */
.demo-boutique { font-size: 14px; color: var(--gris-f); }
.demo-affil { margin-top: 10px; font-size: 12px; line-height: 1.45; color: var(--gris-f); }

/* Le bandeau à trois (B) et deux (A) promesses : au téléphone, 3,5 s par
   promesse comme avant (10,5 s et 7 s, même part de pause) ; au bureau, la
   même vitesse en pixels (environ 320 px/s ; une liste couvre déjà 1920 px :
   deux copies suffisent, comme avant). */
.promesses[data-n="3"] .promesses-ruban { --ruban-duree: 15s; }   /* 4 890 px à 1440 */
.promesses[data-n="2"] .promesses-ruban { --ruban-duree: 7.5s; }  /* 2 388 px à 1440 */
@media (max-width: 720px) {
  html.p6-promesses .promesses[data-n="3"] .promesses-ruban { --ruban-duree: 10.5s; }
  html.p6-promesses .promesses[data-n="2"] .promesses-ruban { --ruban-duree: 7s; }
}
@media (max-width: 720px) {
  html.p6-promesses .promesses[data-n="3"] .ruban-piste { animation-name: p12-pas3; }
  html.p6-promesses .promesses[data-n="2"] .ruban-piste { animation-name: p12-pas2; }
}
@keyframes p12-pas3 {
  0.000% { transform: translateX(0); }
  27.667% { transform: translateX(0); }
  33.333% { transform: translateX(-100vw); }
  61.000% { transform: translateX(-100vw); }
  66.667% { transform: translateX(-200vw); }
  94.333% { transform: translateX(-200vw); }
  100.000% { transform: translateX(-300vw); }
}
@keyframes p12-pas2 {
  0.000% { transform: translateX(0); }
  41.500% { transform: translateX(0); }
  50.000% { transform: translateX(-100vw); }
  91.500% { transform: translateX(-100vw); }
  100.000% { transform: translateX(-200vw); }
}
/* « ONE PAYMENT » (7,3 fois la taille de police) : 407 px en 56 px, plus large
   que la promesse jusqu'à 430 px (394 utiles). Bandeaux A et B : 12vw au plus,
   279 px à 320 (284 utiles), 375 px à 430 (394). Une ligne. */
@media (max-width: 720px) {
  html.p6-promesses .promesses:is([data-n="2"], [data-n="3"]) .promesse.promesse-longue b { font-size: min(1em, 12vw); }
}

/* 11/10 (Théo : « la justification gêne la lecture ») : le long manifeste
   quitte le centrage. Aligné à gauche, il garde un bord fixe où l'œil revient
   à chaque ligne ; text-wrap: pretty évite les veuves sans équilibrer les
   lignes en escalier. Le label suit le même bord. */
.manif--b .manif-bloc { max-width: var(--col); margin-inline: auto; }   /* 1120 avant la revue du 11/10 : même bord que les sections */
.manif--b .manif-label, .manif--b .manif-p { text-align: left; margin-left: 0; }
.manif--b .manif-p { text-wrap: pretty; max-width: 26em; }

/* 11/10, après test (Théo : « absorbé par le texte », « qu'il s'illumine
   doucement avec le scroll », « assez lent pour que les gens lisent »,
   centré comme avant). La section est haute ; sa scène, collée en haut de
   l'écran, reste immobile pendant que le texte s'allume. --t court sur la
   partie figée seulement (de --e-debut à --e-fin de la course), la fin
   laisse un temps pour lire la dernière ligne avant que la page reparte.
   LA LENTEUR SE RÈGLE ICI : --manif-course (la hauteur de défilement pendant
   laquelle la scène reste figée). 240svh = 2 160 px à 1440×900, soit environ
   7 px de défilement par lettre. */
.manif--epingle {
  --manif-course: 240svh;
  --e-debut: .04; --e-fin: .86;
  height: calc(100svh + var(--manif-course));
  padding: 0;
}
@media (max-width: 720px) { .manif--epingle { --manif-course: 210svh; } }
.manif--epingle .manif-scene {
  position: sticky; top: 0; height: 100svh;
  display: grid; place-items: center;
  padding: calc(var(--nav-h, 72px) + 8px) var(--pad) 40px;
  overflow: hidden;
}
.manif--epingle .manif-bloc { max-width: 1080px; width: 100%; margin-inline: auto; animation: none; }
.manif--epingle :is(.manif-label, .manif-p) { text-align: center; margin-inline: auto; }
.manif--epingle .manif-p {
  max-width: 24em; text-wrap: balance;
  /* La scène tient dans l'écran : sur un écran bas, la taille suit la hauteur. */
  font-size: min(clamp(30px, 3.9vw, 60px), 6svh);
}
/* L'allumage : un gris très clair au départ, pour que le texte lu se
   détache nettement de celui qui reste à lire ; un front large (12
   lettres) qui se lit comme une lumière qui avance, pas comme un curseur. */
.manif--epingle .manif-p .l { --gris0: 206; --doux: 12; }
.manif--epingle .manif-label .l { --doux: 3; }
/* Les mots forts (Théo, 11/10 : « que ça surprenne ») : ils s'allument dans
   la couleur d'accent, et au passage de la lumière un halo de la même
   couleur gonfle puis retombe (--bosse, maximale à mi-allumage). */
.manif--epingle .mot--fort .l {
  --bosse: calc(4 * var(--w) * (1 - var(--w)));
  color: color-mix(in srgb, var(--accent) calc(var(--w) * 100%), rgb(var(--gris0) var(--gris0) var(--gris0)));
  text-shadow: 0 0 calc(var(--bosse) * 22px) color-mix(in srgb, var(--accent) calc(var(--bosse) * 70%), transparent);
}
/* Le fil : la progression de la lecture, discrète, sous le texte. */
.manif-fil {
  display: block; width: 120px; height: 1px; margin: clamp(28px, 5svh, 48px) auto 0;
  background: linear-gradient(currentColor, currentColor) left / calc(var(--t) * 100%) 100% no-repeat, rgba(0,0,0,.12);
  color: #1A1A1A;
}
@media all {
  @supports (animation-timeline: view()) {
    .manif--epingle {
      animation: v2-t linear both; animation-timeline: view();
      animation-range: contain calc(var(--e-debut) * 100%) contain calc(var(--e-fin) * 100%);
    }
    .manif--epingle .l { transition: none; }
  }
}
@media (max-width: 720px) {
  .manif--epingle .manif-p { font-size: min(26px, 7vw); line-height: 1.26; }
}

/* ?manif-fond=noir : la lumière baisse. Le fond passe au noir quand la scène
   se fige (--f, 0 → 1 sur les premiers 6 % de la course) et revient au blanc
   à la fin ; le texte s'allume du gris sombre au blanc. */
@property --f { syntax: "<number>"; inherits: true; initial-value: 0; }
.manif--noir {
  --fond: color-mix(in srgb, #0A0A0A calc(var(--f) * 100%), #FFFFFF);
  background: var(--fond);
}
.manif--noir .manif-p .l {
  --eteint: color-mix(in srgb, #3A3A3A calc(var(--f) * 100%), #CECECE);
  --allume: color-mix(in srgb, #F2F2F2 calc(var(--f) * 100%), #1A1A1A);
  color: color-mix(in srgb, var(--allume) calc(var(--w) * 100%), var(--eteint));
}
.manif--noir .manif-label .l { color: color-mix(in srgb, #9A9A9A calc(var(--f) * 100%), #767676); }
.manif--noir .manif-fil { color: color-mix(in srgb, #F2F2F2 calc(var(--f) * 100%), #1A1A1A);
  background-color: color-mix(in srgb, rgba(255,255,255,.18) calc(var(--f) * 100%), rgba(0,0,0,.12)); }
@keyframes v2-f { 0% { --f: 0; } 6% { --f: 1; } 94% { --f: 1; } 100% { --f: 0; } }
@media all {
  @supports (animation-timeline: view()) {
    .manif--noir {
      animation: v2-t linear both, v2-f linear both; animation-timeline: view(), view();
      animation-range: contain calc(var(--e-debut) * 100%) contain calc(var(--e-fin) * 100%), contain 0% contain 100%;
    }
  }
}
html.js-driver .manif--epingle { animation: none; }

/* Revue du 11/10 : les cibles tactiles de la barre. Le dessin ne bouge pas
   (pilules de 34 px, logo de 16 px) ; une zone de clic invisible, centrée,
   de 44 px au moins, est posée par-dessus. Le logo n'en reçoit une que sous
   900 px : au-delà il est calé en absolu et déjà large de 80 px. */
.nav .iconbtn { position: relative; }
.nav .iconbtn::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, 44px); height: max(100%, 44px); translate: -50% -50%; }
@media (max-width: 900px) {
  .nav .wordmark { position: relative; min-width: 44px; min-height: 44px; justify-content: flex-start; }
}
