/*
 * LA LANDING DU TUNNEL.
 *
 * Sortie telle quelle de la maquette : on ne retouche pas le style ici,
 * on le deplace. Toute correction visuelle se fait dans ce fichier, pas
 * dans le gabarit, pour que la page reste cachable.
 */

/* Tout ce qui suit est releve dans public/css/{jetons,portal,vitrine}.css.
       Les blocs existants sont repris a l'identique ; les blocs nouveaux
       empruntent leur vocabulaire au lieu d'en inventer un. */
    :root {
      --lv-large: 1240px; --lv-marge: 36px; --lv-rythme: 80px; --lv-ecart: 52px;
      --lv-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
      --white-rgb: 255, 255, 255; --black-rgb: 0, 0, 0;
      --surface-sombre: #0a0f1a; --surface-sombre-rgb: 10, 15, 26;
      --texte-sur-sombre: rgba(255, 255, 255, 0.94);
      --texte-discret-sur-sombre: rgba(255, 255, 255, 0.68);
      /* L'ENCRE SOURDE, MESUREE ET NON CHOISIE A L'OEIL. Sur `--surface-sombre`,
         0,42 rendait 4,09 pour un seuil de 4,5, sur du texte de 10 et 12,5 px.
         0,45 passerait d'un centieme et retomberait au premier ajustement de
         fond ; 0,47 rend 4,84. Elle ne sert QUE d'encre : les voiles de fond a
         0,42 gardent la leur, ils ne font pas le meme travail. */
      --lv-mention: rgba(var(--white-rgb), 0.47);
      --slate-mid: #1e293b;
      --portal-accent-rgb: 0, 207, 234;
      --portal-gold-rgb: 242, 190, 99; --portal-gold-clair-rgb: 255, 232, 159;
      --portal-blue-rgb: 95, 168, 255; --portal-purple-rgb: 169, 139, 255;
      --portal-green-rgb: 110, 214, 148; --portal-orange-rgb: 247, 152, 94;
      --portal-red-rgb: 248, 113, 113; --portal-rose-rgb: 240, 132, 196;
      --portal-anis-rgb: 188, 214, 106;
      /* jetons.css : les six canaux de la demonstration les emploient. */
      --red-mid: #991b1b; --couleur-danger: #ef4444; --amber-bright: #facc15;
      --couleur-succes: #22c55e; --portal-accent: #00cfea; --blue-rgb: 59, 130, 246;
    }
    * { box-sizing: border-box; }
    html, body { margin: 0; background: var(--surface-sombre); }
    body { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
           color: var(--texte-discret-sur-sombre); -webkit-font-smoothing: antialiased; overflow-x: hidden; }
    a { color: rgb(var(--portal-accent-rgb)); text-decoration: none; }
    a:hover { color: var(--texte-sur-sombre); }

    /* --- Le fond vivant --------------------------------------------------- */
    .lv-fond { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
    /* LA GRILLE EST FIXE, donc a la taille de l ECRAN. En absolu sur une
       enveloppe de douze mille pixels, son masque circulaire ne la laissait
       vivre que dans une ellipse au milieu du document : on ne la croisait
       jamais. Alpha 0,055 pour 0,041 d effectif, un filet qu on voit sans le
       regarder. */
    .lv-grille { position: fixed; inset: 0; pointer-events: none; z-index: 0; opacity: 0.55;
      background-image: linear-gradient(rgba(var(--white-rgb),0.036) 1px, transparent 1px),
                        linear-gradient(90deg, rgba(var(--white-rgb),0.036) 1px, transparent 1px);
      background-size: 54px 54px;
      mask-image: radial-gradient(circle at 50% 40%, rgba(0,0,0,1) 20%, transparent 96%);
      -webkit-mask-image: radial-gradient(circle at 50% 40%, rgba(0,0,0,1) 20%, transparent 96%); }
    /* LE DECALAGE EST PORTE PAR LE PLAN, PAS PAR CHAQUE HALO. Quatorze halos
       flous de 658 px promus en calques, c est une vingtaine de mega-octets et
       quatorze flous re-rasterises a chaque image : la page se figeait. Trois
       plans suffisent, et les halos ne portent plus aucune transformation. */
    .lv-plan { position: absolute; inset: 0; translate: 0 var(--lv-parallaxe, 0px); }
    .lv-orbe { position: absolute; width: 68vw; height: 68vw; min-width: 520px; min-height: 520px;
      border-radius: 50%; opacity: 0.46; animation: lvFlotte 18s ease-in-out infinite alternate; }
    /* Les halos du corps de page : plus petits, immobiles, juste assez pour
       qu aucun ecran ne soit du noir plat. Seuls ceux de l ouverture bougent. */
    .lv-orbe--calme { width: 52vw; height: 52vw; min-width: 420px; min-height: 420px;
      opacity: 0.34; animation: none; }
    /* Le grain. Sans lui le noir est une surface morte : c est ce qui donnait
       a la page son air de vide. Fixe, derriere le contenu, jamais sur le texte. */
    .lv-grain { position: fixed; inset: 0; pointer-events: none; z-index: 0; opacity: 0.035;
      background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='170' height='170' filter='url(%23g)'/%3E%3C/svg%3E"); }
    /* Une vignette tres douce : les bords de l ecran se ferment, le regard
       reste au centre de la colonne de lecture. */
    .lv-vignette { position: fixed; inset: 0; pointer-events: none; z-index: 0;
      background: radial-gradient(132% 96% at 50% 28%, transparent 66%, rgba(0,0,0,0.13) 100%); }
    @keyframes lvFlotte { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(5vw,-4vh,0) scale(1.12); } }
    @media (prefers-reduced-motion: reduce) {
      .lv-orbe { animation: none; }
      .lv-plan { translate: none; }
    }
    .lv { position: relative; z-index: 1; }

    /* PAS DE RESERVE POUR UN EN-TETE QUI N'EST PAS FIXE.

       `vitrine.css` pose 88 px de padding sur `.lv` : la landing en place a un
       en-tete fixe, et sans cette reserve le contenu passerait dessous. Ici
       l'en-tete est dans le flux, donc la reserve ne reserve rien -- elle
       ouvrait un vide de 88 px entre le bord de la fenetre et le bandeau. */
    .lv { padding-top: 0; }
    @media (max-width: 700px) { .lv { padding-top: 0; } }

    /* --- LES TRAITS QUI COURENT SUR LA GRILLE ------------------------------
       La tete est un arret de degrade, pas une ombre portee : un `box-shadow`
       sur un element anime en permanence se re-rasterise a chaque image, et
       c est exactement ce qu on vient de retirer des halos.
       Les lignes sont des multiples de 54 px, le pas de `.lv-fond::after`. */
    .lv-traits { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
    /* La trainee est ecrite UNE fois, ici et pas sur `:root` : un `var()`
       imbrique se resout la ou la variable est DECLAREE, et `--lv-teinte`
       n existe pas sur la racine. Pose la-haut, le degrade devenait
       invalide et les traits rendaient `none`, sans erreur visible. */
    .lv-trait { position: absolute; left: 0; height: 1px; width: var(--lv-long, 220px);
      --lv-trainee: rgba(var(--lv-teinte), 0) 0%, rgba(var(--lv-teinte), 0.02) 34%,
        rgba(var(--lv-teinte), 0.11) 74%, rgba(var(--lv-teinte), 0.18) 92%,
        rgba(var(--white-rgb), 0.17) 99%, rgba(var(--white-rgb), 0) 100%;
      transform: translateX(-320px); opacity: 0;
      animation: lvTrait var(--lv-tempo, 19s) linear infinite var(--lv-attente, 0s);
      background: linear-gradient(90deg, var(--lv-trainee)); }
    /* Le trajet occupe le premier tiers du cycle ; le reste est une attente,
       sinon les traits se suivent sans respiration. */
    @keyframes lvTrait {
      0%   { transform: translateX(-320px); opacity: 0; }
      3%   { opacity: 1; }
      28%  { opacity: 1; }
      33%  { transform: translateX(calc(100vw + 320px)); opacity: 0; }
      100% { transform: translateX(calc(100vw + 320px)); opacity: 0; }
    }
    /* La variante descendante. `width` et `height` s echangent, le degrade
       tourne d un quart de tour, et la course se fait sur la hauteur. */
    .lv-trait--bas { width: 1px; height: var(--lv-long, 220px);
      transform: translateY(-320px); animation-name: lvTraitBas;
      background: linear-gradient(180deg, var(--lv-trainee)); }
    @keyframes lvTraitBas {
      0%   { transform: translateY(-320px); opacity: 0; }
      3%   { opacity: 1; }
      28%  { opacity: 1; }
      33%  { transform: translateY(calc(100vh + 320px)); opacity: 0; }
      100% { transform: translateY(calc(100vh + 320px)); opacity: 0; }
    }
    @media (prefers-reduced-motion: reduce) { .lv-trait { animation: none; opacity: 0; } }

    /* --- Le gabarit -------------------------------------------------------- */
    .lv-conteneur { max-width: var(--lv-large); margin: 0 auto; padding-left: var(--lv-marge); padding-right: var(--lv-marge); }
    .lv-section { padding-top: var(--lv-rythme); padding-bottom: var(--lv-rythme); }
    /* LE SPECTRE DE L APPAREIL, de 4,0e14 a 7,5e14 Hz : du rouge au violet.
       C est la matiere de la therapie, pas un degrade decoratif. Il ouvre
       chaque bande et ferme le bandeau : la page porte sa propre signature. */
    .lv-bande { border-top: 0; background: rgba(var(--white-rgb), 0.035); position: relative; }
    /* Le spectre, ecrit une fois : le rail des bandes et celui du bandeau y
       puisent tous les deux. */
    :root {
      --lv-spectre: linear-gradient(90deg,
        rgba(var(--portal-red-rgb), 0) 0%, rgba(var(--portal-red-rgb), 0.55) 9%,
        rgba(var(--portal-orange-rgb), 0.55) 24%, rgba(var(--portal-anis-rgb), 0.55) 39%,
        rgba(var(--portal-green-rgb), 0.55) 54%, rgba(var(--portal-accent-rgb), 0.55) 68%,
        rgba(var(--portal-blue-rgb), 0.55) 80%, rgba(var(--portal-purple-rgb), 0.55) 92%,
        rgba(var(--portal-purple-rgb), 0) 100%);
      --lv-lueur: linear-gradient(90deg, rgba(var(--portal-red-rgb),0.05) 0%,
        rgba(var(--portal-orange-rgb),0.05) 25%, rgba(var(--portal-green-rgb),0.05) 52%,
        rgba(var(--portal-accent-rgb),0.05) 72%, rgba(var(--portal-purple-rgb),0.05) 100%);
    }
    /* LES DEUX TRAITS D UNE BANDE, portes par un seul pseudo-element : deux
       couches de fond, l une calee en haut, l autre en bas. */
    .lv-bande::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.9;
      background-image: var(--lv-spectre), var(--lv-spectre);
      background-size: 100% 2px, 100% 2px;
      background-position: left top, left bottom;
      background-repeat: no-repeat; }
    /* LES DEUX LUEURS, et elles pointent VERS L INTERIEUR : le masque est
       opaque aux deux extremites et transparent au milieu, donc celle du haut
       descend et celle du bas remonte. La bande se lit comme une zone tenue
       entre deux bords, pas comme deux lignes posees la. */
    .lv-bande::after { content: ""; position: absolute; inset: 0; pointer-events: none;
      background-image: var(--lv-lueur), var(--lv-lueur);
      background-size: 100% 90px, 100% 90px;
      background-position: left top, left bottom;
      background-repeat: no-repeat;
      mask-image: linear-gradient(180deg, rgba(0,0,0,1) 0, transparent 90px,
        transparent calc(100% - 90px), rgba(0,0,0,1) 100%);
      -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,1) 0, transparent 90px,
        transparent calc(100% - 90px), rgba(0,0,0,1) 100%); }
    .lv-entete::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
      background: var(--lv-spectre); opacity: 0.75; }

    /* --- La typographie ---------------------------------------------------- */
    .lv-etiquette { display: block; margin: 0 0 14px; font-family: var(--lv-mono); font-size: 10px;
      font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(var(--portal-gold-rgb), 0.9); }
    .lv-etiquette--sourde { color: var(--lv-mention); }
    .lv-titre { margin: 0 0 16px; font-size: clamp(26px, 2.4vw, 30px); line-height: 1.14; font-weight: 900;
      letter-spacing: -0.01em; color: var(--texte-sur-sombre); text-wrap: balance; }
    .lv-chapo { margin: 0 0 26px; max-width: 62ch; font-size: 14.5px; line-height: 1.6; color: var(--texte-discret-sur-sombre); }
    .lv-chapo:last-child { margin-bottom: 0; }
    .lv-chapo--lignes { white-space: pre-line; }

    /* --- Les colonnes ------------------------------------------------------ */
    .lv-duo { display: grid; gap: var(--lv-ecart); align-items: start; }
    @media (min-width: 900px) {
      .lv-duo { grid-template-columns: 1fr 1fr; }
      .lv-duo--hero { grid-template-columns: 1.35fr 1fr; align-items: center; }
      .lv-duo--lecture { grid-template-columns: 1.15fr 0.85fr; }
      .lv-duo--origine { grid-template-columns: 1.08fr 1fr; }
      .lv-duo--demande { grid-template-columns: 0.9fr 1.1fr; }
      .lv-duo--regulation { grid-template-columns: 1.25fr 0.75fr; align-items: center; }
      .lv-duo--serre { gap: 20px; }
    }
    .lv-quatre { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    @media (max-width: 520px) { .lv-quatre { grid-template-columns: minmax(0, 1fr); } }
    @media (min-width: 1000px) { .lv-quatre { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
    .lv-trois { display: grid; gap: 20px; grid-template-columns: minmax(0, 1fr); }
    @media (min-width: 860px) { .lv-trois { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
    @media (min-width: 860px) {
      .lv-trois--tarifs { column-gap: 20px; row-gap: 0; grid-template-rows: repeat(6, auto); }
      .lv-trois--tarifs > .lv-carte { display: grid; grid-template-rows: subgrid; grid-row: span 6;
        row-gap: 0; align-content: start; }
    }
    /* Les trois actions prennent la meme largeur : les bas de carte s alignent
       aussi, et la hierarchie reste portee par la couleur, pas par la taille. */
    .lv-trois--tarifs .lv-actions { display: block; }
    .lv-trois--tarifs .lv-actions > * { display: flex; width: 100%; justify-content: center; }

    /* --- L'ouverture -------------------------------------------------------- */
    .lv-hero { padding-top: 70px; padding-bottom: 60px; }
    .lv-hero__titre { margin: 0 0 20px; font-size: clamp(34px, 4.4vw, 56px); line-height: 1.06; font-weight: 900;
      letter-spacing: -0.015em; color: var(--texte-sur-sombre); text-wrap: balance; }
    /* L EMPHASE DU TITRE D OUVERTURE, reprise de vitrine.css:1070.
       L or plat manquait de corps a 56 px. Un degrade dans le sens de la
       lecture lui donne le comportement d un metal : plus clair la ou la
       lumiere arrive, plus cuivre a la fin du mot. Trois arrets et pas deux,
       sinon le milieu s affaisse. */
    .lv-or { font-style: normal;
      /* Le repli, et il doit rester lisible seul : un navigateur sans
         `background-clip: text` affiche cette couleur et rien d autre. */
      color: rgb(var(--portal-gold-rgb));
      background-image: linear-gradient(100deg, #FBE0A6 0%, #F2BE63 42%, #C08A3C 100%);
      -webkit-background-clip: text; background-clip: text;
      -webkit-text-fill-color: transparent;
      /* Chaque fragment reprend le degrade complet : sans cela, un syntagme
         coupe en fin de ligne recevrait une moitie de degrade sur chaque bout. */
      -webkit-box-decoration-break: clone; box-decoration-break: clone;
      /* Un halo tres bas, juste de quoi decoller les lettres du bleu nuit. */
      filter: drop-shadow(0 0 18px rgba(var(--portal-gold-rgb), 0.28)); }
    /* Le second accent, vitrine.css:1171. Le logo va du cyan a l or ; le titre
       refait ce trajet. Ce n est pas une couleur de plus, c est la meme paire,
       dans le meme ordre. Modificateur de `.lv-or` : il ne change que la rampe
       et le halo. */
    .lv-cyan { color: rgb(var(--portal-accent-rgb));
      background-image: linear-gradient(100deg, #8BE9FF 0%, var(--portal-accent) 42%, #0F8FA6 100%);
      filter: drop-shadow(0 0 18px rgba(var(--portal-accent-rgb), 0.26)); }
    .lv-hero__lead { margin: 0 0 14px; max-width: 56ch; font-size: 16px; line-height: 1.58; color: rgba(var(--white-rgb), 0.82); }
    .lv-hero__precision { margin: 0 0 28px; max-width: 56ch; font-size: 14.5px; line-height: 1.6; color: var(--texte-discret-sur-sombre); }
    .lv-actions { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
    /* La ligne de reassurance sous un appel a l action. A 12,5 px c est du
       petit texte : le seuil est 4,5:1, et 0,46 tient 4,66:1 sur notre sol.
       0,44 tombe a 4,39, donc c est le plancher, pas un choix d oeil. */
    .lv-note { margin: 18px 0 0; max-width: 48ch; font-size: 12.5px; line-height: 1.5; color: var(--lv-mention); }

    /* --- Les boutons -------------------------------------------------------- */
    .portal-cta, .portal-btn { display: inline-flex; align-items: center; justify-content: center;
      border: 1px solid rgba(var(--portal-gold-rgb), 0.36);
      background: linear-gradient(135deg, rgba(var(--portal-gold-rgb), 0.96), rgba(var(--portal-gold-clair-rgb), 0.82));
      color: var(--slate-mid); border-radius: 12px; padding: 15px 34px; font-weight: 600; font-size: 16px;
      line-height: 1; text-decoration: none;
      box-shadow: 0 14px 32px rgba(var(--black-rgb),0.22), inset 0 1px 0 rgba(var(--white-rgb), 0.26);
      transition: transform .18s ease, box-shadow .18s ease, filter .18s ease; }
    .portal-cta:hover { transform: translateY(-1px); filter: brightness(1.04); color: var(--slate-mid); }
    .portal-cta--petit { padding: 10px 18px; font-size: 14px; border-radius: 10px; box-shadow: none; }
    /* portal.css : `.portal-btn` partage le fond dore, avec sa propre mesure. */
    .portal-btn { appearance: none; padding: 13px 26px; font-size: 15px; cursor: pointer; font-family: inherit; }
    .portal-btn:hover { transform: translateY(-2px); filter: brightness(1.04);
      box-shadow: 0 18px 40px rgba(var(--black-rgb), 0.30), 0 0 0 4px rgba(var(--portal-gold-rgb), 0.10),
                  inset 0 1px 0 rgba(var(--white-rgb), 0.34); }
    .portal-btn:focus-visible { outline: 3px solid rgba(var(--portal-accent-rgb), 0.44); outline-offset: 3px; }
    /* Un libelle de bouton ne se coupe pas. Sous 420 px le retrait lateral
       tombe a 12 px, sans quoi les libelles longs deborderaient de leur
       carte au lieu de passer a la ligne. */
    .portal-cta, .lv-lien-second { white-space: nowrap; }
    .lv-lien-second { display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px; border-radius: 10px;
      border: 1px solid rgba(var(--white-rgb), 0.14); background: rgba(var(--white-rgb), 0.04);
      color: var(--texte-sur-sombre); font-size: 14.5px; text-decoration: none;
      transition: transform .18s ease, background .18s ease, border-color .18s ease; }
    .lv-lien-second:hover { transform: translateY(-1px); background: rgba(var(--white-rgb), 0.08);
      border-color: rgba(var(--white-rgb), 0.28); color: var(--texte-sur-sombre); }
    /* Ces deux paliers viennent APRES le raccourci `padding: 0 18px` :
       a specificite egale, c est la derniere regle de la feuille qui
       gagne. Poses plus haut, ils ne faisaient rien. */
    @media (max-width: 420px) {
      .portal-cta, .lv-lien-second { padding-left: 12px; padding-right: 12px; }
    }
    @media (max-width: 359px) {
      .portal-cta, .lv-lien-second { padding-left: 8px; padding-right: 8px; }
    }

    /* --- Les cartes, et la lueur de bordure ---------------------------------- */
    .lv-carte { padding: 22px 20px 24px; border: 1px solid rgba(var(--white-rgb), 0.10); border-radius: 16px;
      background: rgba(var(--white-rgb), 0.04); }
    .lv-carte__titre { margin: 0 0 8px; font-size: 14.5px; font-weight: 700; line-height: 1.3; color: var(--texte-sur-sombre); }

    .lv-carte__texte { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--texte-discret-sur-sombre); }
    .lv-carte__point { display: block; width: 8px; height: 8px; border-radius: 50%; margin: 0 0 14px;
      background: rgb(var(--lv-teinte, var(--portal-blue-rgb)));
      box-shadow: 0 0 0 4px rgba(var(--lv-teinte, var(--portal-blue-rgb)), 0.14); }
    .lv-carte--domaine { display: block; width: 100%; text-align: left; font: inherit; cursor: pointer;
      transition: transform .18s ease, border-color .18s ease, background .18s ease; }
    .lv-carte--domaine .lv-carte__titre, .lv-carte--domaine .lv-carte__texte { display: block; }
    .lv-carte--domaine:hover { transform: translateY(-2px); border-color: rgba(var(--lv-teinte), 0.45); }
    .lv-carte--domaine.is-choisi { border-color: rgba(var(--lv-teinte), 0.62);
      background: linear-gradient(rgba(var(--lv-teinte), 0.10), rgba(var(--white-rgb), 0.02)); }
    .lv-carte--invite { display: flex; flex-direction: column; justify-content: flex-end;
      background: linear-gradient(rgba(var(--portal-gold-rgb), 0.14), rgba(var(--portal-gold-rgb), 0.05));
      border-color: rgba(var(--portal-gold-rgb), 0.3); }
    .lv-carte--invite p { margin: 0 0 12px; font-size: 14.5px; line-height: 1.5; color: rgba(var(--white-rgb), 0.86); }
    .lv-carte--invite a:not(.portal-cta) { font-size: 14.5px; font-weight: 700; color: rgb(var(--portal-gold-rgb)); }
    /* Plus de `min-height` : il ne couvrait pas les textes longs en colonne
       etroite (110 px de saut a 375 px) et en reservait trop sur grand ecran.
       Ce sont les sept textes empiles qui reservent la hauteur, exactement. */
    .lv-domaine__pile { display: grid; }
    .lv-domaine__pile > * { grid-area: 1 / 1; }
    /* `visibility: hidden` et non `display: none` : le fantome doit occuper sa
       place, c est tout son role. */
    .lv-domaine__texte--fantome { visibility: hidden; pointer-events: none; }
    .lv-domaine__texte { margin: 26px 0 0; max-width: 92ch; font-size: 13.5px; line-height: 1.6;
      color: rgba(var(--white-rgb), 0.5); }
    .lv-domaine__texte strong { color: var(--texte-sur-sombre); font-weight: 700; }
    /* Les demandes du domaine choisi, sur leur propre ligne. Plus petites que
       le texte du domaine : elles le precisent, elles ne le remplacent pas. */
    .lv-demandes { display: inline-block; margin-top: 8px; font-size: .86em; opacity: .78; }

    /* Un bouton qui se lit comme un lien. « Voir un exemple en pleine taille »
       ouvre une fenetre, donc c'est un bouton, et il doit garder l'allure du
       lien qu'il etait. Le raccourci `font` remettrait aussi la TAILLE, celle
       du parent : seule la famille se reprend. */
    button.lv-lien-second { background: none; border: 0; cursor: pointer;
      font-family: inherit; font-style: inherit; }

    /* Les chiffres du hero menent a la section qui les etablit, sans changer
       d'allure : c'est la ou le doute nait qu'on l'emmene. */
    .lv-chiffres--lien { text-decoration: none; color: inherit; }
    .lv-chiffres--lien:hover .lv-chiffre__quoi { color: rgba(var(--white-rgb), 0.82); }
    .lv-carte[data-lueur] { position: relative; --lueur-x: 50%; --lueur-y: 50%; }
    .lv-carte[data-lueur]::after { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
      opacity: 0; transition: opacity .26s ease; pointer-events: none;
      background: radial-gradient(240px circle at var(--lueur-x) var(--lueur-y),
        rgba(var(--lv-teinte, var(--portal-accent-rgb)), 1),
        rgba(var(--lv-teinte, var(--portal-accent-rgb)), 0.38) 44%, transparent 74%);
      filter: saturate(1.25);
      -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
      mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
      -webkit-mask-composite: xor; mask-composite: exclude; }
    .lv-carte[data-lueur]:hover::after { opacity: 1; }
    .lv-carte--invite[data-lueur] { --lv-teinte: var(--portal-gold-rgb); }
    @media (prefers-reduced-motion: reduce) { .lv-carte--domaine, .lv-carte[data-lueur]::after { transition: none; } }

    /* --- Les rangees a marqueur ---------------------------------------------- */
    .lv-rang { display: grid; grid-template-columns: 12px 1fr; gap: 11px; align-items: start; font-size: 13.5px;
      line-height: 1.55; color: var(--texte-discret-sur-sombre); }
    .lv-rang + .lv-rang { margin-top: 12px; }
    .lv-rang__point { width: 8px; height: 8px; margin-top: 6px; border-radius: 50%; background: rgb(var(--lv-teinte, var(--portal-blue-rgb))); }
    .lv-rang__quoi { color: var(--texte-sur-sombre); font-weight: 700; }
    .lv-cadre { display: grid; grid-template-columns: 14px 1fr; gap: 13px; align-items: start; }
    .lv-cadre + .lv-cadre { margin-top: 12px; }
    .lv-cadre__signe { font-size: 13px; line-height: 1.5; margin-top: 1px; }
    .lv-cadre__texte { font-size: 13.5px; line-height: 1.55; color: var(--texte-discret-sur-sombre); }
    .lv-etape { display: grid; grid-template-columns: 38px 1fr; gap: 18px; align-items: start; }

    /* --- LES ETAPES EN RAIL -------------------------------------------------
       Elles tenaient dans le tiers haut de leur colonne et laissaient le reste
       vide a cote d une demonstration deux fois plus haute. Elles se
       repartissent sur toute la hauteur, accrochees a un rail, et le numero
       devient un noeud sur ce rail au lieu d un chiffre pose a cote.
       La classe est sur le CONTENEUR : `.lv-etape` sert ailleurs. */
    .lv-etapes { display: flex; flex-direction: column; justify-content: space-between;
      height: 100%; position: relative; gap: 8px; }
    .lv-etapes::before { content: ""; position: absolute; left: 15px; top: 22px; bottom: 22px; width: 1px;
      background: linear-gradient(180deg,
        rgba(var(--portal-accent-rgb), 0) 0%, rgba(var(--portal-accent-rgb), 0.34) 14%,
        rgba(var(--portal-accent-rgb), 0.34) 86%, rgba(var(--portal-accent-rgb), 0) 100%); }
    .lv-etapes .lv-etape { display: block; margin: 0; padding: 14px 18px 14px 46px; position: relative;
      border-radius: 14px; border: 1px solid transparent;
      transition: background-color .24s ease, border-color .24s ease; }
    .lv-etapes .lv-etape + .lv-etape { margin-top: 0; }
    .lv-etapes .lv-etape:hover { background: rgba(var(--white-rgb), 0.04);
      border-color: rgba(var(--white-rgb), 0.09); }
    /* Le noeud porte le fond de la page pour DECOUPER le rail : sans ce fond,
       le trait passerait derriere le chiffre et le traverserait. */
    .lv-etapes .lv-etape__rang { position: absolute; left: 6px; top: 15px;
      width: 20px; height: 20px; border-radius: 50%; display: inline-flex;
      align-items: center; justify-content: center; font-size: 9.5px; letter-spacing: 0;
      background: var(--surface-sombre); border: 1px solid rgba(var(--portal-accent-rgb), 0.42);
      color: rgb(var(--portal-accent-rgb)); transition: border-color .24s ease, box-shadow .24s ease; }
    .lv-etapes .lv-etape:hover .lv-etape__rang { border-color: rgba(var(--portal-accent-rgb), 0.85);
      box-shadow: 0 0 14px rgba(var(--portal-accent-rgb), 0.28); }
    @media (prefers-reduced-motion: reduce) {
      .lv-etapes .lv-etape, .lv-etapes .lv-etape__rang { transition: none; }
    }
    .lv-etape + .lv-etape { margin-top: 20px; }
    .lv-etape__rang { font-family: var(--lv-mono); font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
      color: rgba(var(--portal-accent-rgb), 0.9); padding-top: 2px; }
    .lv-etape__titre { margin: 0 0 4px; font-size: 14.5px; font-weight: 700; color: var(--texte-sur-sombre); }
    .lv-etape__texte { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--texte-discret-sur-sombre); }

    /* --- Le panneau ------------------------------------------------------------ */
    .lv-panneau { padding: 22px 20px 24px; border: 1px solid rgba(var(--white-rgb), 0.14); border-radius: 16px;
      background: rgba(var(--surface-sombre-rgb), 0.55); }
    .lv-panneau__ligne { display: grid; grid-template-columns: 112px 1fr; gap: 13px; align-items: start;
      font-size: 13.5px; line-height: 1.5; }
    .lv-panneau__ligne + .lv-panneau__ligne { margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(var(--white-rgb), 0.08); }
    .lv-panneau__quoi { font-family: var(--lv-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
      color: var(--lv-mention); padding-top: 3px; }
    .lv-panneau__valeur { color: var(--texte-discret-sur-sombre); }

    /* --- Les chiffres ----------------------------------------------------------- */
    .lv-chiffres { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-top: 26px;
      padding-top: 26px; }
    .lv-chiffre__valeur { display: block; font-size: 26px; font-weight: 900; line-height: 1; color: rgb(var(--portal-accent-rgb)); }
    .lv-chiffre__quoi { display: block; margin-top: 6px; font-family: var(--lv-mono); font-size: 9.5px;
      letter-spacing: 0.08em; text-transform: uppercase; color: rgba(var(--white-rgb), 0.55); }
    @media (max-width: 520px) { .lv-chiffres { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 10px; } }

    /* --- Entetes de colonne, observations, these ---------------------------------- */
    /* 0,50 et non 0,42 : sur le sol ardoise de l application, un blanc a 0,42
       tombe a 3,84 contre le fond de carte. Mesure : 0,50 rend 4,81. */
    .lv-colonne__entete { display: block; margin: 0 0 18px; font-family: var(--lv-mono); font-size: 10px;
      letter-spacing: 0.16em; text-transform: uppercase; color: rgba(var(--white-rgb), 0.50); }
    .lv-colonne__entete--accent { color: rgba(var(--portal-accent-rgb), 0.9); }
    .lv-observation__note { margin: 18px 0 0; font-size: 13px; line-height: 1.55; color: rgba(var(--white-rgb), 0.5); }
    /* Une phrase est une BOITE : elle passe a la ligne entiere quand elle ne
       tient pas dans la place restante, au lieu de laisser un mot seul
       accroche a la ligne d avant. Elle se coupe quand meme si elle ne tient
       pas sur une ligne pleine, donc rien ne peut deborder. */
    .lv-phrase { display: inline-block;
      /* Et la matiere se repartit entre les lignes de la boite, pour ne jamais
         laisser un mot seul en bas. Mesure : de 6 a 23 phrases finissaient sur
         un mot unique selon la largeur, zero desormais, sans qu une seule
         phrase change de hauteur. */
      text-wrap: balance; }
    .lv-these { margin: 32px 0 0; max-width: 72ch; font-size: 14.5px; line-height: 1.6; color: rgba(var(--white-rgb), 0.82); }

    /* --- Les six ecrans du decodage ------------------------------------------------ */
    .lv-pages { display: flex; flex-direction: column; gap: 12px; }
    /* Le rayon vit ICI, pas dans le dessin : la boite porte la bordure, l anneau
       et le decoupage des six pastilles, et son rayon est celui de `.lv-demo`.
       Le rectangle de fond des six ecrans, lui, a perdu son `rx` : deux chassis
       arrondis l un dans l autre, a deux rayons differents, se voyaient. */
    .lv-pages__boite { border-radius: 16px; overflow: hidden; border: 1px solid rgba(var(--white-rgb), 0.14);
      background: rgba(var(--surface-sombre-rgb), 0.55);
      box-shadow: 0 0 0 4px rgba(var(--portal-accent-rgb), 0.10); }
    .lv-pages__cadre { position: relative; aspect-ratio: 480 / 300; }
    .lv-pages__vue { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0; transition: opacity .7s ease; }
    .lv-pages__vue.est-vue { opacity: 1; }
    .lv-pages__nom { font-size: 13px; font-weight: 600; color: rgba(var(--white-rgb), 0.86); }
    .lv-pages__palette { display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; padding: 8px;
      background: rgba(var(--black-rgb), 0.42); border-top: 1px solid rgba(var(--white-rgb), 0.10); }
    .lv-pages__canal { height: 10px; padding: 0; border-radius: 8px; border: 1px solid rgba(var(--white-rgb), 0.16);
      background: linear-gradient(135deg, #0f766e, rgb(var(--portal-accent-rgb)));
      box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.14); opacity: .34; cursor: pointer;
      transition: opacity .4s ease, transform .4s ease, box-shadow .4s ease; }
    .lv-pages__canal:hover { opacity: .68; }
    .lv-pages__canal.est-vue { opacity: 1; transform: scale(1.06);
      box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.22), 0 0 14px rgba(var(--portal-accent-rgb), 0.5); }
    /* Plus de `min-height` : il plafonnait a deux lignes alors que le nombre
       de lignes depend de la largeur de la colonne. Ce sont les six legendes
       empilees qui reservent la hauteur, exactement. */
    .lv-pages__note { margin: 0; font-size: 12.5px; line-height: 1.55; color: rgba(var(--white-rgb), 0.52); }
    .lv-pages__legende { display: grid; }
    .lv-pages__legende > * { grid-area: 1 / 1; }
    .lv-pages__ligne { display: grid; gap: 12px; align-content: start; }
    /* `visibility: hidden` et non `display: none` : le fantome doit occuper
       sa place, c est tout son role. Il sort quand meme de l arbre
       d accessibilite et du parcours au clavier. */
    .lv-pages__ligne--fantome { visibility: hidden; pointer-events: none; }
    @media (prefers-reduced-motion: reduce) { .lv-pages__vue, .lv-pages__canal { transition: none; } }

    /* --- Le jeu des six pages empilees --------------------------------------------- */
    .lv-apercu { display: flex; flex-direction: column; gap: 14px; }
    .lv-deck { position: relative; width: 100%; max-width: 420px; margin: 0 auto; aspect-ratio: 1 / 0.94; }
    .lv-deck__page { position: absolute; top: 50%; left: 50%; width: 47%; height: auto; transform-origin: 50% 50%;
      transition: transform .28s ease, opacity .28s ease; }
    /* SIX CARTES, TROIS DE CHAQUE COTE. Les rangs impairs partent a gauche,
       les pairs a droite, et chaque paire se rapproche du centre : la derniere
       est posee a plat devant, c'est l'etat de ressource. Les ecarts sont en
       pourcentage de la CARTE et non du jeu, donc l'eventail garde sa forme a
       toutes les largeurs. A 420 px de large, la carte fait 197 px : l'ecart le
       plus grand, 52 %, laisse 9 px entre son bord et celui du jeu. */
    .lv-deck__page--1 { transform: translate(-50%, -50%) translate(-52%, 5%) rotate(-16deg); opacity: .64; z-index: 1; }
    .lv-deck__page--2 { transform: translate(-50%, -50%) translate( 52%, 5%) rotate( 15deg); opacity: .70; z-index: 1; }
    .lv-deck__page--3 { transform: translate(-50%, -50%) translate(-33%, 3%) rotate(-10deg); opacity: .80; z-index: 2; }
    .lv-deck__page--4 { transform: translate(-50%, -50%) translate( 33%, 3%) rotate(  9deg); opacity: .86; z-index: 3; }
    .lv-deck__page--5 { transform: translate(-50%, -50%) translate(-15%, 1%) rotate( -5deg); opacity: .94; z-index: 4; }
    .lv-deck__page--6 { transform: translate(-50%, -50%) translate(  3%, 0%) rotate(  2deg); opacity: 1;   z-index: 5; }

    /* LA CARTE EST UN BOUTON, ET ELLE MONTRE LE HAUT DE SA PAGE.
       Les cinq pages reelles vont de 1,24 a 0,27 de proportion : posees telles
       quelles, la plus courte ferait un carre et la plus longue un ruban. La
       carte impose donc SA proportion et cadre le haut ; la page entiere se lit
       dans la loupe, ou c'est la hauteur qui defile. */
    .lv-deck__page { padding: 0; border: 1px solid rgba(var(--white-rgb), 0.14);
      border-radius: 10px; overflow: hidden; background: rgba(var(--black-rgb), 0.5);
      cursor: pointer; box-shadow: 0 18px 44px rgba(var(--black-rgb), 0.5); }
    .lv-deck__page > img { display: block; width: 100%; aspect-ratio: 222 / 300;
      object-fit: cover; object-position: top; }
    .lv-deck__page:hover { filter: brightness(1.12); }
    .lv-deck__page:focus-visible { outline: 2px solid var(--lv-accent, #2dd4e8); outline-offset: 3px; }

    /* --- La loupe : la page entiere, en 16:9, qu on fait defiler ------------------- */
    /* LA FENETRE EST EN 16:9 ET LA HAUTEUR DEFILE. Une planche de resultat fait
       jusqu'a 5 400 px de haut : aucun cadre ne la contient, et la reduire pour
       qu'elle tienne la rendrait illisible. On lui donne donc la largeur et on
       laisse la hauteur courir. */
    .lv-loupe { width: min(1180px, 94vw); max-width: none; padding: 0; border: 0;
      border-radius: 14px; background: var(--lv-carte, #0d141d);
      color: rgba(var(--white-rgb), 0.92); box-shadow: 0 40px 110px rgba(var(--black-rgb), 0.7); }
    .lv-loupe::backdrop { background: rgba(var(--black-rgb), 0.72); backdrop-filter: blur(3px); }
    .lv-loupe__tete { display: flex; align-items: center; justify-content: space-between;
      gap: 16px; padding: 12px 18px; border-bottom: 1px solid rgba(var(--white-rgb), 0.10); }
    .lv-loupe__nom { margin: 0; font-size: 15px; font-weight: 600; }
    .lv-loupe__fermer { border: 0; background: none; cursor: pointer; font-size: 26px;
      line-height: 1; padding: 0 6px; color: rgba(var(--white-rgb), 0.6); }
    .lv-loupe__fermer:hover { color: rgba(var(--white-rgb), 0.95); }
    .lv-loupe__fermer:focus-visible { outline: 2px solid var(--lv-accent, #2dd4e8); outline-offset: 2px; }
    /* LE 16:9 EST UNE FORME, PAS UNE FATALITE. Sur un ecran large il donne la
       fenetre voulue ; sur un telephone il la reduit a 206 px de haut -- 26 %
       de l'ecran -- pour une planche qui en fait sept. On lirait par une fente,
       avec 271 px inutilisES en dessous. `min-height` releve le cadre quand la
       proportion le rend trop court, `max-height` l'empeche de sortir de la
       fenetre. Aucun seuil de largeur : c'est la place disponible qui decide.
       Mesure a 1440 : 664 px, le 16:9 inchange. A 390 : 560 au lieu de 206. */
    /* LA PROPORTION SE CALCULE, ELLE NE SE DECLARE PAS ICI.
       `aspect-ratio` avec un `min-height` ne raccourcit pas la boite : il
       l'ELARGIT pour tenir la proportion. Mesure : cadre de 996 px de large
       dans une fenetre de 390. Le remede du premier defaut en fabriquait un
       second, plus visible que lui.
       La hauteur est donc calculee depuis la largeur de la loupe -- la meme
       expression que sa `width`, divisee par 16/9 -- et bornee : jamais moins
       de 70 % de la fenetre, jamais plus de 82 %. La largeur, elle, n'est plus
       touchee. A 1440 : 656 px, le 16:9. A 390 : 560, soit 70 %. */
    .lv-loupe__cadre { height: clamp(70svh, calc(min(1180px, 94vw) * 0.5625), 82svh);
      overflow-y: auto; overscroll-behavior: contain; }
    .lv-loupe__cadre img { display: block; width: 100%; height: auto; }

    @media (prefers-reduced-motion: reduce) { .lv-deck__page { transition: none; } }
    .lv-apercu__ligne { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
      font-family: var(--lv-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
      color: var(--lv-mention); }
    .lv-apercu__texte { margin: 0; font-size: 13px; line-height: 1.55; color: rgba(var(--white-rgb), 0.5); }

    /* --- Les vignettes de capture ------------------------------------------------------ */
    .lv-vignette__image { display: block; width: 100%; height: auto; border-radius: 10px;
      border: 1px solid rgba(var(--white-rgb), 0.10); background: rgba(var(--surface-sombre-rgb), 0.55); }
    .lv-vignette__rang { display: block; margin-top: 10px; font-family: var(--lv-mono); font-size: 10px;
      letter-spacing: 0.1em; text-transform: uppercase; color: rgba(var(--white-rgb), 0.55); }

    /* --- La FAQ, en `details` natif ------------------------------------------------------ */
    .lv-faq { margin-top: 30px; padding-top: 26px; }
    .lv-faq__item { border-bottom: 1px solid rgba(var(--white-rgb), 0.08); }
    .lv-faq__item > summary { display: flex; align-items: baseline; gap: 10px; padding: 13px 0; font-size: 14.5px;
      font-weight: 700; line-height: 1.4; color: var(--texte-sur-sombre); cursor: pointer; list-style: none;
      transition: color .18s ease; }
    .lv-faq__item > summary::-webkit-details-marker { display: none; }
    .lv-faq__item > summary::before { content: ""; flex: 0 0 auto; width: 7px; height: 7px; margin-top: 4px;
      border-right: 1.6px solid rgba(var(--portal-accent-rgb), 0.85);
      border-bottom: 1.6px solid rgba(var(--portal-accent-rgb), 0.85);
      transform: rotate(-45deg); transition: transform .18s ease; }
    .lv-faq__item[open] > summary::before { transform: rotate(45deg); }
    .lv-faq__item > summary:hover { color: rgb(var(--portal-accent-rgb)); }
    .lv-faq__item > p { margin: 0 0 15px 17px; font-size: 13.5px; line-height: 1.6; color: var(--texte-discret-sur-sombre); }

    /* --- Le formulaire : les regles de portal.css, telles quelles ------------
       Un champ doit se voir AVANT d etre rempli : bordure a 0,24 et fond
       creuse a 0,34 de noir, mesures pour passer les 3,0 de la norme sur la
       limite d un controle. Le cadre du parrainage porte le cyan du produit. */
    .lv-formulaire .portal-access__inner { padding: 28px 26px 30px; border: 1px solid rgba(var(--white-rgb), 0.10);
      border-radius: 18px; background: rgba(var(--white-rgb), 0.04); }
    .portal-access__form { display: grid; gap: 14px; }
    .portal-field { display: grid; gap: 7px; }
    .portal-field label, .portal-checkbox { color: rgba(var(--white-rgb), 0.78); font-size: 14px; line-height: 1.35; }
    .portal-field input, .portal-field select { width: 100%; min-height: 42px; border-radius: 12px;
      border: 1px solid rgba(var(--white-rgb), 0.24); background: rgba(var(--black-rgb), 0.34);
      color: #ffffff; padding: 9px 12px; outline: none; font: inherit;
      transition: border-color .18s ease, box-shadow .18s ease, background .18s ease; }
    .portal-field select { color-scheme: dark; }
    .portal-field input:focus, .portal-field select:focus { border-color: rgba(var(--portal-accent-rgb), 0.44);
      background: rgba(var(--white-rgb), 0.08); box-shadow: 0 0 0 4px rgba(var(--portal-accent-rgb), 0.10); }
    .portal-access__form textarea { width: 100%; min-height: 96px; border-radius: 12px;
      border: 1px solid rgba(var(--white-rgb), 0.24); background: rgba(var(--black-rgb), 0.34);
      color: #ffffff; padding: 10px 12px; font: inherit; outline: none; resize: vertical;
      transition: border-color .18s ease, box-shadow .18s ease, background .18s ease; }
    .portal-access__form textarea:focus { border-color: rgba(var(--portal-accent-rgb), 0.55);
      background: rgba(var(--white-rgb), 0.09); box-shadow: 0 0 0 3px rgba(var(--portal-accent-rgb), 0.14); }
    .portal-access__referral { display: grid; gap: 12px; margin: 0; padding: 16px; border-radius: 16px;
      border: 1px solid rgba(var(--portal-accent-rgb), 0.26); background: rgba(var(--portal-accent-rgb), 0.06); }
    .portal-access__referral legend { padding: 0 6px; font-size: 13px; letter-spacing: .04em;
      color: rgba(var(--portal-accent-rgb), 0.92); }
    .portal-access__referral small { color: rgba(var(--white-rgb), 0.52); font-size: 12.5px; line-height: 1.4; }
    .portal-checkbox { display: flex; align-items: flex-start; gap: 9px; cursor: pointer; }
    .portal-checkbox input { flex: none; width: 16px; height: 16px; margin-top: 2px;
      accent-color: rgb(var(--portal-gold-rgb)); min-height: 0; }
    .portal-btn--full { width: 100%; }
    /* L indicatif et le numero sur une ligne : 112 px au selecteur, le reste
       au numero, qui est ce qu on saisit. */
    .champ-telephone { display: grid; grid-template-columns: minmax(0, 112px) minmax(0, 1fr); gap: 8px; align-items: stretch; }
    .champ-telephone select, .champ-telephone input { width: 100%; min-height: 42px; margin-bottom: 0; }
    .champ-telephone__pays { position: relative; min-width: 0; }
    .champ-telephone__apercu { position: absolute; inset: 0; display: flex; align-items: center; gap: 8px;
      padding: 0 30px 0 12px; color: #ffffff; font-size: 16px; pointer-events: none; }
    .champ-telephone__apercu img, .champ-telephone__drapeau { flex: none; width: 20px; height: 15px;
      border-radius: 3px; box-shadow: 0 0 0 1px rgba(var(--white-rgb), 0.28); }
    /* Deux classes, pas une : une classe seule se fait battre par la regle de
       champ de `.portal-access__form select`, et le texte du selecteur
       reapparait sous l apercu. */
    .champ-telephone .champ-telephone__pays select { appearance: none; -webkit-appearance: none;
      color: transparent; padding-right: 30px;
      /* La taille a zero en plus de la couleur : en contraste eleve le
         navigateur REIMPOSE la couleur, une taille nulle ne se reimpose pas. */
      font-size: 0; }
    /* Le menu deroulant, lui, se lit : il garde sa couleur. */
    .champ-telephone .champ-telephone__pays select option { font-size: 15px; color: var(--texte-sur-sombre);
      background: var(--slate-mid); }
    /* La fleche du systeme se dessine avec la couleur du texte : la rendre
       transparente l effacerait aussi. L apercu porte donc la sienne. */
    .champ-telephone__apercu::after { content: ""; position: absolute; right: 12px; width: 8px; height: 8px;
      border-right: 2px solid rgba(var(--white-rgb), 0.6); border-bottom: 2px solid rgba(var(--white-rgb), 0.6);
      transform: translateY(-2px) rotate(45deg); }
    /* Sous cette largeur l indicatif et le numero ne tiennent plus cote a cote :
       le pays passe au-dessus plutot que d ecraser le champ qu on remplit. */
    @media (max-width: 520px) { .champ-telephone { grid-template-columns: 1fr; } }

    /* --- L'offre ------------------------------------------------------------------------------ */
    .lv-prix { display: block; font-size: 34px; font-weight: 900; line-height: 1; letter-spacing: -0.015em;
      color: var(--texte-sur-sombre); white-space: nowrap; }
    .lv-prix__quoi { display: block; margin-top: 8px; font-family: var(--lv-mono); font-size: 9.5px;
      letter-spacing: 0.08em; text-transform: uppercase; color: rgba(var(--white-rgb), 0.55); }
    .lv-liste { margin: 16px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 9px; }
    .lv-liste li { font-size: 13.5px; line-height: 1.5; color: var(--texte-discret-sur-sombre);
      display: grid; grid-template-columns: 12px 1fr; gap: 11px; }
    .lv-liste li::before { content: "·"; color: var(--lv-mention); }

    /* --- L'objection en vue ----------------------------------------------------------------------
       Meme carte que partout, mais la question porte le poids d'un titre : c'est
       elle qu'on vient chercher, la reponse se lit apres. */
    .lv-objection__q { margin: 0 0 10px; font-size: 16px; font-weight: 700; line-height: 1.32; color: var(--texte-sur-sombre); }
    .lv-objection__r { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--texte-discret-sur-sombre); }

    /* --- L'entete et le pied ------------------------------------------------------------------------ */
    /* Pas de filet gris ici : le rail spectral ferme deja le bandeau. */
    .lv-entete { position: relative; padding-top: 15px; padding-bottom: 15px;
      background: rgba(var(--surface-sombre-rgb), 0.72); backdrop-filter: blur(10px) saturate(1); -webkit-backdrop-filter: blur(10px) saturate(1); }
    /* `1fr auto 1fr` et non `space-between` : la piste du milieu est centree
       sur l ECRAN, quelles que soient les largeurs de la marque et des actions.
       En flex, la nav se decale des que les deux cotes different. */
    .lv-entete__dedans { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
      gap: 22px; min-height: 56px; max-width: none; padding-left: 30px; padding-right: 30px; }
    /* Chaque enfant a SA colonne, en dur. Le placement automatique ne suffit
       pas : entre 721 et 1240 px la nav est masquee, donc elle sort de la
       grille, les actions remontent en colonne 2 et se calaient a la fin du
       MILIEU. Mesure a 1100 px : 344 px de vide a droite. */
    .lv-entete__dedans > .lv-marque { grid-column: 1; justify-self: start; }
    .lv-entete__dedans > .lv-nav { grid-column: 2; justify-self: center; }
    .lv-entete__dedans > .lv-entete__actions { grid-column: 3; justify-self: end; }
    .lv-marque { display: inline-flex; align-items: center; gap: 12px; color: inherit; text-decoration: none; min-width: 0; flex: 0 0 auto; }
    .lv-marque__signe { width: 56px; height: 56px; flex: 0 0 56px; display: inline-flex; align-items: center; justify-content: center; }
    .lv-marque img { width: 48px; height: 48px; display: block; object-fit: contain; }
    .lv-marque__texte { display: grid; gap: 2px; min-width: 0; }
    .lv-marque__nom { font-size: 20px; font-weight: 900; text-transform: uppercase; letter-spacing: 0.08em; line-height: 1.15; color: var(--texte-sur-sombre); }
    .lv-marque__sous { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; font-size: 11.5px; letter-spacing: 0.06em; line-height: 1.25; color: rgba(var(--white-rgb), 0.55); white-space: nowrap; }
    /* Une seule ligne : la nav ne se replie pas, elle disparait sous 1000 px,
       au meme endroit que `portal.css` sur la landing en place.

       LE CHIFFRE EST MESURE, ET IL A CHANGE. La maquette coupait a 1180 px, un
       nombre releve du temps des anciens libelles, plus longs. Mesure refaite
       dans le navigateur, en forcant l affichage de la nav pour lire sa
       largeur reelle : l en-tete tient a partir de 980 px. Le menu etait donc
       cache entre 1000 et 1179 px alors qu il tenait, c est-a-dire sur la
       plupart des portables.

       En dessous de 1000 px, la page se parcourt au defilement : il n y a pas
       de menu de remplacement, ici comme sur la landing en place. */
    .lv-nav { display: flex; align-items: center; gap: 18px; font-size: 13.5px; flex-wrap: nowrap; flex: 0 0 auto; }
    /* 0,78 comme `portal-page .lv-nav a` sur la landing en place, et non le
       0,68 du jeton discret : les deux barres doivent se lire pareil. */
    .lv-nav a { color: rgba(var(--white-rgb), 0.78); white-space: nowrap; }
    .lv-nav a:hover { color: var(--texte-sur-sombre); }
    @media (max-width: 1000px) { .lv-nav { display: none; } }
    .lv-entete__actions { display: flex; align-items: center; gap: 16px; flex: 0 0 auto; }
    /* L'ONGLET DES LANGUES, DANS LE BANDEAU.

       Le vrai selecteur (partials/locale-switcher) porte `position: fixed` :
       il est fait pour flotter dans le coin des pages sans bandeau. Ici il vit
       ENTRE la navigation et le bouton de connexion ; sorti du flux, il se
       posait par-dessus ce bouton.

       Meme correctif que `portal.css` pour son propre bandeau. Les regles de
       la maquette ont ete retirees : elles habillaient ses boutons inertes,
       qui n'existent plus, et sa regle de conteneur imposait une rangee de
       pastilles a un objet qui n'en est plus une. */
    .lv-entete__actions .locale-switcher {
      /* RELATIVE, ET SURTOUT PAS STATIC.

         Le panneau des langues est en position absolue avec right:0 : il
         s ancre sur le premier ancetre POSITIONNE. En passant le conteneur en
         static, on lui retire ce repere, et le panneau va chercher la page :
         il s etale alors sur toute la largeur. Relative le sort du flux fixe
         tout en lui rendant son role d ancre. */
      position: relative;
      top: auto;
      right: auto;
      z-index: 60;
      flex: 0 0 auto;
    }
    /* Sous 760 px le bandeau passe en colonne, comme portal.css le fait sur le
       site : la marque centree au-dessus, l action en dessous. Les trois
       paliers de la marque sont ceux du produit, repris a l identique. */
    @media (max-width: 760px) {
      .lv-entete__dedans { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 12px; }
      /* Une seule colonne : les affectations en dur seraient des lignes vides. */
      .lv-entete__dedans > .lv-marque,
      .lv-entete__dedans > .lv-nav,
      .lv-entete__dedans > .lv-entete__actions { grid-column: 1; justify-self: center; }
      /* Comme `portal-header__actions` : pleine largeur, centrees, et elles se
         replient. A 360 px, selecteur plus bouton faisaient 355 px sur une
         ligne, soit onze pixels de marge. */
      .lv-entete__actions { width: 100%; justify-content: center; flex-wrap: wrap;
        gap: 12px; }
      .lv-marque__sous { font-size: 12px; }
    }
    @media (max-width: 640px) {
      .lv-marque__signe { width: 44px; height: 44px; flex: 0 0 44px; }
      .lv-marque img { width: 40px; height: 40px; }
      .lv-marque__nom { font-size: 17px; }
    }
    @media (max-width: 420px) { .lv-marque__nom { font-size: 15px; } }
    .lv-pied { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 44px; padding-top: 36px; }
    @media (max-width: 900px) { .lv-pied { grid-template-columns: 1fr; gap: 30px; } }
    .lv-pied__marque { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
    .lv-pied__marque img { width: 32px; height: 32px; }
    .lv-pied__marque span { font-size: 14px; font-weight: 700; color: var(--texte-sur-sombre); }
    .lv-pied__mention { margin: 0; font-size: 13px; line-height: 1.55; color: rgba(var(--white-rgb), 0.5); }
    /* Le credit de realisation n est pas un appel a l action : il prend
       l encre du pied, pas le cyan des liens. Valeurs de vitrine.css. */
    .lv-pied__mention a { color: rgba(var(--white-rgb), 0.62); text-decoration: none; transition: color .18s ease; }
    .lv-pied__mention a:hover, .lv-pied__mention a:focus-visible { color: rgba(var(--white-rgb), 0.95);
      text-decoration: underline; text-underline-offset: 3px; }
    .lv-pied__liens { display: flex; flex-direction: column; gap: 9px; }
    /* Les quatre liens legaux en deux paires : la colonne LEGAL faisait
       quatre lignes quand CONTACT en faisait deux, et le pied descendait
       plus bas a droite qu au milieu. Deux rangees et un remplissage en
       colonne : les deux premiers restent en place, les deux suivants se
       posent a leur droite. */
    .lv-pied__liens--paire { display: grid; grid-auto-flow: column;
      grid-template-rows: repeat(2, auto); justify-content: start;
      column-gap: 28px; row-gap: 9px; }
    .lv-pied__liens a { font-size: 13.5px; color: var(--texte-discret-sur-sombre); }
    .lv-pied__copyright { margin: 16px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--lv-mention); }

    /* --- LA DEMONSTRATION DU TEST, reprise de vitrine.css ------------------- */
    .lv-demo { position: relative; border-radius: 16px; overflow: hidden;
      border: 1px solid rgba(var(--white-rgb), 0.14); background: rgba(var(--surface-sombre-rgb), 0.55);
      /* Plus d ombre portee : un flou de soixante pixels effacait la grille
         autour du cadre. Il ne reste que l anneau, qui n a pas de flou. */
      box-shadow: 0 0 0 4px rgba(var(--portal-accent-rgb), 0.10); }
    /* Le format de la SOURCE : les images du test sont en 16/9. */
    .lv-demo__cadre { position: relative; aspect-ratio: 16 / 9; overflow: hidden; }
    .lv-demo__image { position: absolute; inset: 0; background-size: cover; background-position: center; }
    .lv-demo__voile { position: absolute; inset: 0; mix-blend-mode: multiply; opacity: 0; pointer-events: none; }
    /* La seconde couche porte l image a venir et monte par-dessus la premiere :
       le fondu se fait d une image a l autre, jamais par le noir. */
    .lv-demo__image--suivante { opacity: 0; transition: opacity .7s ease; }
    .lv-demo__palette { display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; padding: 8px;
      background: rgba(var(--black-rgb), 0.42); border-top: 1px solid rgba(var(--white-rgb), 0.10); }
    .lv-demo__canal { height: 20px; border-radius: 8px; border: 1px solid rgba(var(--white-rgb), 0.16);
      box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.14); opacity: .42;
      transition: opacity .5s ease, transform .5s ease, box-shadow .5s ease; }
    .lv-demo__canal.is-active { opacity: 1; transform: scale(1.08);
      box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.22), 0 0 0 2px rgba(var(--white-rgb), 0.72),
                  0 0 16px rgba(var(--white-rgb), 0.32); }
    .lv-demo__canal--r { background: linear-gradient(135deg, var(--red-mid), var(--couleur-danger)); }
    .lv-demo__canal--j { background: linear-gradient(135deg, #a16207, var(--amber-bright)); }
    .lv-demo__canal--v { background: linear-gradient(135deg, #166534, var(--couleur-succes)); }
    .lv-demo__canal--c { background: linear-gradient(135deg, #0f766e, var(--portal-accent)); }
    .lv-demo__canal--b { background: linear-gradient(135deg, #1d4ed8, rgb(var(--blue-rgb))); }
    .lv-demo__canal--m { background: linear-gradient(135deg, #a21caf, #e879f9); }
    /* La legende passe DEVANT l ombre du cadre : l ombre de 60 px de flou
       retombait sur cette ligne et la ternissait. */
    .lv-demo__legende { position: relative; z-index: 1; max-width: 52ch; margin: 14px 0 0;
      font-size: 13.5px; line-height: 1.55; color: rgba(var(--white-rgb), 0.5); }
    @media (prefers-reduced-motion: reduce) {
      .lv-demo__image--suivante, .lv-demo__canal { transition: none; }
    }

    /* --- LA NEURO-REGULATION MONTREE, reprise de vitrine.css -------------- */
    /* ===== La neuro-regulation, montree =====

       LE RYTHME EST CELUI DU PRODUIT, pas un effet. L'alternance noir/couleur
       entre 1 et 4 Hz EST le geste de regulation ; ici elle est posee a 0,5 Hz,
       soit un battement toutes les deux secondes. C'est la borne basse, adoucie
       par rapport a la seance : sur une page publique, personne n'a depose la
       declaration de contre-indications que le produit exige avant un programme,
       et l'epilepsie en fait partie. On montre le geste, on ne le pratique pas.

       DEUX ANIMATIONS SUR LE MEME ELEMENT, et c'est ce qui rend la chose lisible
       a la lecture. `battement` tient le rythme, `teinte` tient la couleur, et
       elles ne se melangent jamais : la teinte change toutes les six secondes,
       soit exactement trois battements, donc TOUJOURS pendant un noir. Le
       changement de couleur ne se voit pas, on ne voit que la couleur suivante
       arriver au battement d'apres.

       Ecrites en une seule animation de vingt-quatre etapes, il aurait fallu
       recompter tout le tableau a chaque reglage du rythme. */
    .lv-neuro {
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* 480 et non 340 : la boite du dessin a grandi pour laisser vivre le halo,
       mais le portable, lui, n'a pas change de taille. Sans cette compensation il
       aurait retreci d'un tiers a la premiere correction du flou.

       Les marges negatives reprennent la place que le halo occupe autour de
       l'objet : elle est transparente, et sans elles la section se serait ouverte
       de soixante-dix pixels de vide de chaque cote. */
    .lv-neuro svg {
        width: 100%;
        max-width: 480px;
        height: auto;
        margin: -46px -44px;
    }

    /* Le halo et la dalle partagent leurs deux animations : c'est la meme
       lumiere, l'une dans l'ecran et l'autre autour. */
    .lv-neuro__dalle,
    .lv-neuro__halo {
        animation:
            lv-neuro-battement 2s ease-in-out infinite,
            lv-neuro-teinte 18s linear infinite;
    }

    .lv-neuro__halo { opacity: 0; }

    /* LE CHASSIS EST NEUTRE. Il etait dore, par report de l'icone dont ce trace
       est parti. L'or est la couleur du bouton d'action sur cette page : un objet
       qui la porte en entier en prend le poids sans le meriter. Et un cadre dore
       se bat avec le vert et le rouge qu'il encadre, alors que sa fonction est de
       les laisser parler.

       Legerement chaud plutot que gris pur : c'est ce qui le fait lire comme de
       l'aluminium et non comme un fil de fer. */
    .lv-neuro__coque,
    .lv-neuro__socle {
        stroke: rgba(214, 224, 238, 0.40);
        stroke-width: 2.2;
        stroke-linejoin: round;
    }

    .lv-neuro__coque { fill: #070C15; }
    .lv-neuro__socle { fill: #0B1626; }

    .lv-neuro__camera { fill: rgba(214, 224, 238, 0.34); }

    .lv-neuro__pave {
        fill: none;
        stroke: rgba(214, 224, 238, 0.22);
        stroke-width: 1.4;
        stroke-linejoin: round;
    }

    /* Les touches ne s'allument pas : elles sont dans l'ombre de l'ecran, et un
       clavier qui battrait avec la dalle ferait un objet clignotant au lieu d'un
       ecran allume dans une piece sombre. */
    .lv-neuro__touches rect {
        fill: rgba(214, 224, 238, 0.07);
        stroke: rgba(214, 224, 238, 0.18);
        stroke-width: 0.8;
    }

    @keyframes lv-neuro-battement {
        /* Une montee et une descente adoucies, pas un creneau. Le geste garde sa
           frequence mais perd son arete : c'est la seule liberte prise ici. */
        0%   { opacity: 0; }
        22%  { opacity: 1; }
        50%  { opacity: 1; }
        72%  { opacity: 0; }
        100% { opacity: 0; }
    }

    /* Le halo suit le meme rythme, plus faible : une lumiere d'ecran n'eclaire
       pas la piece autant qu'elle eclaire le visage. */
    .lv-neuro__halo { animation-name: lv-neuro-halo, lv-neuro-teinte; }

    @keyframes lv-neuro-halo {
        0%   { opacity: 0; }
        22%  { opacity: 0.34; }
        50%  { opacity: 0.34; }
        72%  { opacity: 0; }
        100% { opacity: 0; }
    }

    /* Trois battements de bleu, trois de vert, trois de rouge, puis on
       recommence. Les bornes sont doublees a un centieme de pour cent l'une de
       l'autre : c'est ce qui fait un changement net sans passer par un degrade
       qui melangerait les trois. */
    @keyframes lv-neuro-teinte {
        0%, 33.32%      { fill: #2D7DF6; }
        33.33%, 66.65%  { fill: #34C77B; }
        66.66%, 100%    { fill: #E2453D; }
    }

    /* Un battement lumineux ne se force a personne. Sans mouvement, la dalle
       reste allumee sur sa premiere couleur : l'objet se lit toujours comme un
       ecran, il ne bat simplement plus. */
    @media (prefers-reduced-motion: reduce) {
        .lv-neuro__dalle {
            animation: none;
            fill: #2D7DF6;
            opacity: 0.9;
        }

        .lv-neuro__halo {
            animation: none;
            fill: #2D7DF6;
            opacity: 0.28;
        }
    }
    .lv-duo--regulation { align-items: center; }
    @media (min-width: 900px) { .lv-duo--regulation { grid-template-columns: 1.25fr 0.75fr; } }

    /* --- Les deux schemas --------------------------------------------------- */
    .lv-schema { margin: 30px 0 0; }
    .lv-schema svg { display: block; width: 100%; height: auto; }
    .lv-schema figcaption { margin: 14px 0 0; font-size: 13.5px; line-height: 1.55;
      color: rgba(var(--white-rgb), 0.6); max-width: 78ch; }
    .lv-schema__texte { font-size: 12px; fill: rgba(255, 255, 255, 0.62); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .06em; }
    .lv-schema__fort { font-size: 13px; font-weight: 700; fill: rgba(255, 255, 255, 0.92); font-family: inherit; letter-spacing: 0; }
    .lv-schema__annee { font-size: 12.5px; font-weight: 700; fill: rgb(var(--portal-gold-rgb)); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

    /* Ce qui reste a fournir : signale, jamais invente. */
    .lv-attente { color: rgba(var(--portal-gold-rgb), 0.92); border-bottom: 1px dashed rgba(var(--portal-gold-rgb), 0.5); }