/* =====================================================================================================================
   La V2 du site (12 octobre 2026) : le premier site, cinq pages. Chargée après lab.css et illus.css, elle n'ajoute que ce
   qui est propre à la V2 : l'en-tête à quatre liens, les formes V01, la carte de verre du modèle et les blocs nouveaux.
   DA (DA-SANDFLOW.md v2) : noir et blanc ; le dégradé est toujours une image V01 de la charte, tenue par une forme
   construite (rond, losange), une par page ou presque, et il glisse lentement dans sa forme.
   ===================================================================================================================== */

/* ---------- L'en-tête (maquette Figma, 14 oct.) : Solutions et Company en panneau (menu.js de la V1), Model en lien direct ---------- */
.v2-entete nav.menu > ul { align-items: center; justify-content: flex-end; }   /* les menus à droite (landing du 28 oct.) */
/* la signature entière, plus petite qu'avant (138 × 20) et sans le point : SVG dans la page (gen.py, signature()) */
.v2-entete .v2-entete-signature { display: block; width: auto; height: 16px; color: var(--craie); }
.v2-entete .ncol { min-height: 0; }

/* L'écran de chargement de l'accueil (gen.py, chargeur() ; affiché par site-v2/chargeur.js, seulement quand la page tarde) :
   d'après elvalabs.ai, sur l'Encre : « loading » à gauche et le pourcentage à droite, chacun sur son double géant et flou ;
   au centre l'icône d'app du site, dont le symbole fait un demi-tour en boucle, ses deux formes s'écartant à mi-course, et
   dont le liseré de lumière tourne. */
@property --chargeur-a { syntax: '<angle>'; inherits: false; initial-value: 315deg; }
.chargeur { display: none; }
html.chargement .chargeur { position: fixed; inset: 0; z-index: 100; display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; padding: 0 2rem; background: #121117; color: #F7F6F3; animation: chargeur-entre .35s ease both; }
html.charge .chargeur { animation: chargeur-sort .55s ease forwards; pointer-events: none; }
@keyframes chargeur-entre { from { opacity: 0; } }
@keyframes chargeur-sort { to { opacity: 0; } }
.chargeur-mot, .chargeur-pct { position: relative; margin: 0; font-size: 0.8125rem; font-weight: 500; letter-spacing: .01em;
  color: rgba(247, 246, 243, .85); font-variant-numeric: tabular-nums; }
.chargeur-pct { justify-self: end; }
.chargeur-ombre { position: absolute; top: 50%; transform: translateY(-50%); font-size: clamp(4.5rem, 11vw, 10rem);
  font-weight: 500; letter-spacing: -.04em; line-height: 1; color: rgba(247, 246, 243, .06); filter: blur(10px); white-space: nowrap;
  pointer-events: none; }
.chargeur-mot .chargeur-ombre { left: -0.06em; }
.chargeur-pct .chargeur-ombre { right: -0.04em; }
.chargeur-mot > span:last-child, .chargeur-pct > span:last-child { position: relative; }
.chargeur-icone { position: relative; display: grid; place-items: center; width: 4.5rem; height: 4.5rem; border-radius: 1.125rem;
  background: linear-gradient(160deg, #222128, #141319 70%);
  box-shadow: inset 0 0 0 1px rgba(247, 246, 243, .09), 0 0.875rem 1.75rem rgba(0, 0, 0, .45); }
.chargeur-icone::after { content: ""; position: absolute; inset: 0; padding: 1px; border-radius: inherit; pointer-events: none;
  background: conic-gradient(from calc(var(--chargeur-a) - 70deg), transparent 0deg, rgba(255, 255, 255, .5) 70deg, transparent 140deg,
    transparent 180deg, rgba(255, 255, 255, .14) 250deg, transparent 320deg);
  -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); animation: chargeur-lisere 2.4s linear infinite; }
.chargeur-s { width: 2.25rem; height: auto; overflow: visible; animation: chargeur-tour 2.4s cubic-bezier(.65, 0, .35, 1) infinite; }
.chargeur-a { animation: chargeur-ecart-a 2.4s cubic-bezier(.65, 0, .35, 1) infinite; }
.chargeur-b { animation: chargeur-ecart-b 2.4s cubic-bezier(.65, 0, .35, 1) infinite; }
/* le symbole est symétrique par un demi-tour : la boucle repart de 0° sans saut visible */
@keyframes chargeur-tour { 0%, 30% { transform: rotate(0deg); } 75%, 100% { transform: rotate(180deg); } }
@keyframes chargeur-ecart-a { 0%, 30%, 75%, 100% { transform: none; } 52% { transform: translate(-34px, -34px); } }
@keyframes chargeur-ecart-b { 0%, 30%, 75%, 100% { transform: none; } 52% { transform: translate(34px, 34px); } }
@keyframes chargeur-lisere { to { --chargeur-a: 675deg; } }
@media (max-width: 767px) { html.chargement .chargeur { padding: 0 1rem; } }
@media (prefers-reduced-motion: reduce) {
  .chargeur-s, .chargeur-a, .chargeur-b, .chargeur-icone::after { animation: none; }
}
/* les boutons sombres en gris très discret, plein (Tanguy, 27 oct. : « grise un peu les boutons noirs », puis « je veux juste
   sans transparent ») : la teinte du voile blanc à 8 % sur l'Encre, posée opaque ; un cran plus clair au survol */
.v2 .btn.contour { background: #242329; }
.v2 .btn.contour:hover { background: #2E2D33; }
.btn .btn-fleche { flex: none; width: 0.618em; height: 0.618em; }   /* la flèche : la typo / nombre d'or, à 8 px du texte (l'écart du bouton) */   /* le panneau Use cases sans titre : ses liens en haut de la carte */
.v2-entete .lien { display: flex; align-items: center; min-height: 36px; padding: 0 10px; font-size: 13px; color: var(--craie);
  opacity: .86; border-radius: 4px; transition: opacity 200ms ease, background-color 200ms ease; }
.v2-entete .lien:hover, .v2-entete .lien.actif { opacity: 1; background: var(--carte2); }

/* ---------- Les formes V01 ---------- */
.f-rond, .f-losange, .f-carre { display: block; flex: none; background-repeat: no-repeat; background-size: 190%; background-position: 50% 50%; }
.f-rond { border-radius: 50%; }
.f-losange { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.f-s { width: 0.625rem; height: 0.625rem; background-size: 260%; }
.f-m { width: 3rem; height: 3rem; }
.f-l { width: 9rem; height: 9rem; background-size: 150%; }
.f-xl { width: min(40rem, 82vw); height: min(40rem, 82vw); background-size: 125%; }
.v01-halo { background-image: url(/rb/assets/v01/sandflow-01-halo-paysage.webp); }
.v01-nappe { background-image: url(/rb/assets/v01/sandflow-02-nappe-diagonale-paysage.webp); }
.v01-noyau { background-image: url(/rb/assets/v01/sandflow-03-noyau-carre.webp); }
.v01-confluence { background-image: url(/rb/assets/v01/sandflow-04-confluence-carre.webp); }
.v01-courant { background-image: url(/rb/assets/v01/sandflow-05-courant-vertical.webp); }
.v01-bain { background-image: url(/rb/assets/v01/sandflow-06-bain-chromatique-vertical.webp); }
/* Le dégradé glisse dans sa forme, lentement (règle du motion kit : nos images V01 dans un masque). */
@media (prefers-reduced-motion: no-preference) {
  .f-glisse { animation: v01-glisse 16s ease-in-out infinite alternate; }
}
@keyframes v01-glisse { from { background-position: 38% 42%; } to { background-position: 62% 58%; } }

/* ---------- Use cases : trois entrées qui mènent au modèle, puis l'objet ---------- */
.v2-flux { display: grid; grid-template-columns: minmax(0, 1.25fr) auto minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center;
  max-width: 68rem; margin: 0 auto; }
.v2-entrees { display: grid; gap: 1rem; margin: 0; padding: 0; list-style: none; }
.v2-entrees li { padding: 1.125rem 1.25rem; border-radius: 1rem; background: #fff; box-shadow: 0 1px 2px rgba(18, 17, 23, .04), 0 1rem 2rem -1.5rem rgba(18, 17, 23, .14); }
.v2-entrees .emplacement { min-height: 0; max-height: 9rem; }
.v2-k { margin: 0 0 0.625rem; font: 500 0.6875rem/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .16em;
  text-transform: uppercase; color: var(--gris); }
.v2-prompt { margin: 0; font-size: 1.125rem; font-weight: 300; letter-spacing: -.01em; }
.v2-noeud { display: flex; flex-direction: column; align-items: center; gap: 1rem; }
.v2-noeud p { margin: 0; font-size: 0.9375rem; font-weight: 500; }
.v2-sortie p:last-child { margin: 0; font-size: clamp(1.125rem, 1.8vw, 1.5rem); line-height: 1.35; font-weight: 300; letter-spacing: -.02em; }
.v2-cas-ui { align-items: stretch; }
.v2-cas-ui .emplacement { width: 100%; }

/* ---------- Research : le papier phare ---------- */
.v2-phare { max-width: 58rem; margin: 0 auto; padding: clamp(1.75rem, 3.4vw, 3rem); border: 1px solid var(--ligne); border-radius: 1.5rem; background: #17161c; }
.v2-pastille { display: inline-flex; align-items: center; gap: 0.5rem; margin: 0 0 1.5rem; padding: 0.375rem 0.75rem; border: 1px solid var(--ligne);
  border-radius: 999px; font-size: 0.75rem; letter-spacing: .04em; }
.v2-phare h3 { margin: 0 0 0.75rem; font-size: clamp(1.75rem, 3.2vw, 2.5rem); line-height: 1.1; letter-spacing: -.03em; font-weight: 300; }
.v2-phare > p:not(.v2-pastille) { margin: 0 0 1.75rem; color: var(--gris); }

/* ---------- About : deux paragraphes séparés par un losange ; la frise ---------- */
.v2-deux { display: flex; flex-direction: column; align-items: center; gap: 1.5rem; }
.v2-deux p { margin: 0; }
.v2-intro { max-width: 44rem; margin: 0 auto 2.5rem; text-align: center; font-size: clamp(1.25rem, 2.2vw, 1.75rem); line-height: 1.35;
  font-weight: 300; letter-spacing: -.02em; }
.v2-frise { max-width: 52rem; margin: 0 auto; padding: 0; list-style: none; }
.v2-frise li { display: grid; grid-template-columns: 12rem minmax(0, 1fr); gap: 0.25rem 1.5rem; padding: 1.125rem 0; border-top: 1px solid var(--ligne); }
.v2-frise li:last-child { border-bottom: 1px solid var(--ligne); }
.v2-date { font: 500 0.8125rem/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--gris); font-variant-numeric: tabular-nums; }

/* ---------- Contact : un rond entre le titre et la ligne ; les adresses ---------- */
.v2-hero-forme .f-rond { margin: 1.75rem auto 0; }
.v2-hero-forme .lead { margin-top: 1.5rem; }
.v2-adresses { max-width: 52rem; margin: 0 auto; padding: 0; list-style: none; }
.v2-adresses li { display: grid; grid-template-columns: 9rem minmax(0, 1fr); gap: 0.25rem 1.5rem; padding: 1.25rem 0; border-top: 1px solid var(--ligne); }
.v2-adresses li .v2-k { grid-row: span 2; margin: 0.4rem 0 0; }
.v2-adr { margin: 0; font-size: clamp(1.25rem, 2vw, 1.625rem); font-weight: 300; letter-spacing: -.02em; }
.v2-adresses li p:last-child { margin: 0; font-size: 0.9375rem; color: var(--gris); }
.v2-siege { max-width: 52rem; margin: 1.5rem auto 0; font: 0.75rem/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--gris); }

/* ---------- Tablette et téléphone ---------- */
@media (max-width: 900px) {
  .v2-flux { grid-template-columns: minmax(0, 1fr); }
  .v2-noeud { flex-direction: row; justify-content: center; }
  .v2-frise li, .v2-adresses li { grid-template-columns: minmax(0, 1fr); }
  .v2-adresses li .v2-k { grid-row: auto; }
}

/* =====================================================================================================================
   L'accueil (16 octobre, repris le 20) : la structure de la maquette Figma du 14 octobre et de la séance Tanguy-Félix, dans
   la grammaire de la V1. Tanguy, 20 oct. : « je préférais le style UI de notre ancienne mise en page […] là ça fait moins
   labo professionnel car les éléments sont trop de manière aléatoire, on doit reprendre le style propre à la LTX ».
   - Une seule largeur pour toutes les sections : celle de la V1 (.wrap, 75rem).
   - Les visuels dans les panneaux d'application de la V1 (.ui.v3 de /illus.css), avec de vraies images et de la vraie 3D,
     posés directement sur la bande.
   - Des cartes bento (.co) seulement pour les diagrammes : les deux graphiques du benchmark (Tanguy, 20 oct. : « beaucoup
     moins de card bento explicatif […] seulement sur les diagrammes explicatifs »).
   - Des rangées à filets à la LTX pour ce qui se lit en liste ; des contrôles fins (Tanguy, 20 oct. : « les boutons sont
     énormes, ça fait pas classe à la Apple »).
   - La mise en page et les animations de ltx.io (Tanguy, 20 oct. : « notre homepage a perdu trop du style LTX […] dans sa
     mise en page et dans ses animations ») : têtes à gauche avec « // », titre à gauche et ligne à droite ; carte phare ;
     phrase-manifeste colorée mot par mot ; entrées en fondu montant, titres qui sortent du flou, filets qui se tracent
     (v2-anim.js).
   - Aucune forme V01 posée pour décorer : la V01 ne marque plus que Sandflow dans les graphiques.
   - Aucun cadre vide, aucune note entre crochets à l'écran (Tanguy, 16 oct.).
   ===================================================================================================================== */

/* ---------- Le pied : le lieu sous la ligne de la marque ---------- */
.v2-lieu { display: block; margin-top: 0.75rem; color: var(--gris); }

/* ---------- Ouverture : la vidéo du lab en fond, quand elle existera (sinon Shape Waves) ---------- */
.v2-ouverture { position: relative; }
.v2-ouverture h1 .ouv-tel { display: none; }   /* le titre du téléphone (28 oct.), montré sous 768 px */

/* Le bouton du menu sur téléphone : trois traits qui se croisent en X à l'ouverture (Tanguy, 28 oct. : « un menu burger avec
   animation vers une croix à la place de Menu ») ; les traits se rejoignent au centre puis tournent, et l'inverse en
   refermant. Le mot « Menu » reste pour les lecteurs d'écran ; 44 px à toucher. */
.v2-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.v2-entete .burger summary { justify-content: center; width: 2.75rem; min-height: 2.75rem; margin-right: -0.75rem; padding: 0; border: 0; }
/* des pixels entiers (traits de 2 px à 0, 6 et 12 px) : en 1,5 px, le trait du milieu tombait sur un demi-pixel et ne
   paraissait pas de la même épaisseur que les autres (Tanguy, 28 oct.) */
.burger-ic { position: relative; display: block; width: 20px; height: 14px; }
.burger-ic i { position: absolute; left: 0; width: 100%; height: 2px; border-radius: 1px; background: currentColor;
  transition: transform .2s cubic-bezier(.65, 0, .35, 1), top .2s cubic-bezier(.65, 0, .35, 1) .2s, opacity 0s linear .2s; }
.burger-ic i:nth-child(1) { top: 0; }
.burger-ic i:nth-child(2) { top: 6px; }
.burger-ic i:nth-child(3) { top: 12px; }
.burger[open]:not(.ferme) .burger-ic i { transition: top .2s cubic-bezier(.65, 0, .35, 1), transform .2s cubic-bezier(.65, 0, .35, 1) .2s, opacity 0s linear .2s; }
.burger[open]:not(.ferme) .burger-ic i:nth-child(1), .burger[open]:not(.ferme) .burger-ic i:nth-child(3) { top: 6px; }
.burger[open]:not(.ferme) .burger-ic i:nth-child(1) { transform: rotate(45deg); }
.burger[open]:not(.ferme) .burger-ic i:nth-child(2) { opacity: 0; }
.burger[open]:not(.ferme) .burger-ic i:nth-child(3) { transform: rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .burger-ic i, .burger[open] .burger-ic i { transition: none; } }
/* Le tiroir, par-dessus la page (tiroir.js, 28 oct. : « qu'il arrive par-dessus, mais avec style ») : un verre sombre flouté
   sous l'en-tête, sur toute la hauteur ; les liens en grand et fins, sans filets, les titres de groupe en petites capitales.
   La page ne défile pas derrière (html.tiroir-ouvert). */
.v2-entete .burger[open] .tiroir { position: fixed; top: 60px; left: 0; right: 0; bottom: 0; max-height: none; overflow-y: auto;
  overscroll-behavior: contain; padding: 0.5rem 1.5rem calc(2rem + env(safe-area-inset-bottom, 0px)); border-bottom: 0;
  background: rgba(18, 17, 23, .8); -webkit-backdrop-filter: blur(24px) saturate(1.4); backdrop-filter: blur(24px) saturate(1.4); }
.v2-entete .tiroir-h { margin: 1.75rem 0 0.5rem; }
.v2-entete .tiroir a { padding: 0.5rem 0; border-bottom: 0; font-size: 1.625rem; font-weight: 300; letter-spacing: -.015em; line-height: 1.2; }
html.tiroir-ouvert { overflow: hidden; }
.v2-video-lab { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; object-fit: cover; opacity: .55; pointer-events: none; }
.v2-ouverture .wrap { position: relative; z-index: 1; }

/* ---------- Les panneaux de l'accueil : l'en-tête des panneaux de la V1, un corps qui remplit la hauteur ---------- */
.v3 .ui.v3.v2-p { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.v2-p-corps { position: relative; flex: 1 1 auto; min-height: 0; margin: 0; overflow: hidden; }
.v2-p-corps > img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Les étiquettes : seulement sur une image qui montre deux états (le balayage) ; petites et sombres, comme le « Cab » de la V1. */
.v2-etiquette { position: absolute; z-index: 2; left: 0.625rem; bottom: 0.625rem; padding: 0.25rem 0.625rem; border-radius: 999px;
  background: rgba(18, 17, 23, .58); -webkit-backdrop-filter: blur(0.75rem) saturate(1.2); backdrop-filter: blur(0.75rem) saturate(1.2);
  box-shadow: inset 0 0 0 1px rgba(247, 246, 243, .16); font-size: 0.6875rem; font-weight: 500; line-height: 1.2; color: #F7F6F3;
  white-space: nowrap; }
.v2-etiquette.droite { left: auto; right: 0.625rem; }

/* Le balayage : l'état final gagne le premier par la droite, puis se retire ; un trait blanc suit le bord. */
.v2-balayage { position: absolute; inset: 0; }
.v2-balayage > img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.v2-balayage-fin { clip-path: inset(0 0 0 50%); }
.v2-balayage-trait { position: absolute; z-index: 1; top: 0; bottom: 0; left: 50%; width: 2px; margin-left: -1px; background: #FFFFFF;
  box-shadow: 0 0 1rem rgba(0, 0, 0, .25); }
@media (prefers-reduced-motion: no-preference) {
  .v2-balayage-fin { animation: v2-balaie 10s cubic-bezier(.65, 0, .35, 1) infinite; }
  .v2-balayage-trait { animation: v2-trait 10s cubic-bezier(.65, 0, .35, 1) infinite; }
}
@keyframes v2-balaie { 0%, 10% { clip-path: inset(0 0 0 88%); } 45%, 60% { clip-path: inset(0 0 0 12%); } 95%, 100% { clip-path: inset(0 0 0 88%); } }
@keyframes v2-trait { 0%, 10% { left: 88%; } 45%, 60% { left: 12%; } 95%, 100% { left: 88%; } }

/* ---------- Section 2 : les usages, au format des « hover tabs » de LTX-2.5 (ltx.io, relevés le 26 oct.) ----------
   La liste à gauche (36 %), le média à droite (60 %, en 16:9, coins de 8 px) calé sur le bas de la liste ; l'usage choisi en
   plein, les autres à 40 % ; sa ligne s'ouvre sous son nom ; une carte glisse de sous le média. Cotes, durées et courbes de
   LTX (titres 28 px, ligne 18 px, filets, 0,4 s pour l'opacité, 0,6 s pour la ligne, 0,42 s et 0,3 s pour la carte). */
.v2-usages-sec { padding-bottom: clamp(6rem, 10vw, 8.5rem); }   /* la carte dépasse sous le média */
.v2-ht { --ht-ease: cubic-bezier(.16, 1, .3, 1); --ht-ouvre: cubic-bezier(.22, 1, .36, 1); display: grid;
  grid-template-columns: minmax(0, 36fr) minmax(0, 60fr); column-gap: 4%; align-items: end; }
.v2-ht-liste { display: flex; flex-direction: column; }
.v2-ht-item { padding: 1.2rem 0; border-bottom: 1px solid var(--ligne); opacity: .4; transition: opacity .4s var(--ht-ease); }
.v2-ht-item.is-active { opacity: 1; }
/* le survol éclaircit la ligne sans changer d'usage : le clic ou le défilement le font (Tanguy, 27 oct.) */
@media (hover: hover) { .v2-ht-item:not(.is-active):hover { opacity: .65; } }
/* Le blocage (v2-accueil.js) : la scène (tête et usages) collée à --bloc-haut pendant qu'on parcourt .v2-ht-piste ; sur un
   écran trop bas pour la tête (.v2-bloque-corps), elle est au-dessus du cadre et sa marge l'en fait sortir. */
.v2-usages-sec.v2-bloque .v2-ht-scene { position: sticky; top: var(--bloc-haut, 0px); }
.v2-usages-sec.v2-bloque-corps .v2-tete { margin-bottom: var(--bloc-ecart); }
.v2-ht-btn { display: flex; align-items: baseline; gap: 1.25rem;   /* 2 rem chez LTX : « les titres sont très éloignés de leurs chiffres » (28 oct.) */ width: 100%; margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; text-align: left; cursor: pointer; }
.v2-ht-btn:focus-visible { outline: 2px solid currentColor; outline-offset: 6px; border-radius: 2px; }
.v2-ht-num, .v2-ht-nom { font-size: 1.75rem; line-height: 1.1; font-weight: 400; letter-spacing: -.02em; }
.v2-ht-num { color: var(--gris); font-variant-numeric: tabular-nums; }
.v2-ht-fermer { display: none; }   /* la croix de l'accordéon, sur téléphone seulement */
.v2-ht-detail { display: grid; grid-template-rows: 0fr; opacity: 0; transform: translateY(-10px);
  transition: grid-template-rows .6s var(--ht-ouvre), opacity .6s var(--ht-ouvre), transform .6s var(--ht-ouvre); }
.v2-ht-detail > div { min-height: 0; overflow: hidden; }
/* La ligne de l'usage : petite, grise, en graisse fine (Tanguy, 26 oct.), plus discrète que les 18 px de LTX. */
.v2-ht-detail p { max-width: 22rem; margin: 0.875rem 0 0; font-size: 0.9375rem; font-weight: 300; line-height: 1.45;
  color: var(--gris); }   /* calée sous le numéro, plus sous le nom (Tanguy, 27 oct. : « ils vont trop à droite ») */
.is-active > .v2-ht-detail { grid-template-rows: 1fr; opacity: 1; transform: none; }
.v2-ht-slot { display: none; }

/* Les médias empilés ; le choisi se montre d'un coup (les autres sortent du rendu : la 3D s'arrête, les vidéos aussi). */
.v2-ht-medias { display: grid; }
.v2-ht-media { position: relative; grid-area: 1 / 1; }
.v2-ht-cadre { position: relative; z-index: 2; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 0.5rem; background: #ECECEF; }
.v2-ht-media:not(.is-active) .v2-ht-cadre { display: none; }
.v2-ht-video { display: block; width: 100%; height: 100%; object-fit: cover; }
/* L'anneau de chargement d'une vidéo (v2-accueil.js, .v-attente, 28 oct.) : au centre de la carte, montré seulement si
   l'attente dépasse 0,3 s. */
.v2-ht-cadre::after { content: ""; position: absolute; z-index: 5; top: 50%; left: 50%; width: 1.75rem; height: 1.75rem;
  margin: -0.875rem 0 0 -0.875rem; border: 2px solid rgba(247, 246, 243, .22); border-top-color: #F7F6F3; border-radius: 50%;
  opacity: 0; pointer-events: none; transition: opacity .2s ease; }
.v2-ht-cadre.v-attente::after { opacity: 1; transition-delay: .3s; animation: v2-tourne .9s linear infinite; }
@keyframes v2-tourne { to { transform: rotate(360deg); } }
/* La carte : rangée derrière le bas du média, elle en glisse à l'entrée et y remonte à la sortie ; en petit (Tanguy, 26 oct.). */
.v2-ht-carte { position: absolute; z-index: 1; top: calc(100% + 0.25rem); left: 0; right: 0; margin: 0.75rem 0 0; padding: 0.4375rem 0.875rem;
  border-radius: 0.5rem; background: var(--carte); font-size: 0.8125rem; line-height: 1.4; color: var(--texte);
  opacity: 0; visibility: hidden; pointer-events: none; transform: translate3d(0, calc(-100% - 1.25rem), 0);
  transition: transform .3s cubic-bezier(.4, 0, 1, 1), opacity .18s linear, visibility 0s linear .3s; }
.v2-ht-carte b { font-weight: 600; }
.v2-ht-media.is-active .v2-ht-carte { opacity: 1; visibility: visible; pointer-events: auto; transform: none;
  transition: transform .42s cubic-bezier(.22, 1, .36, 1), opacity .12s linear, visibility 0s; }

/* La chaise en vue partagée (objet-code, data-split), d'après nova3d.xyz : la vue à gauche, le programme à droite ; en clair, à
   la manière des pages produit d'Apple (Tanguy, 27 oct. : « le fond de la chaise est encore trop foncé, joue sur un fond plus
   clair à la apple ») : gris très clair, encre #1D1D1F, gris secondaires #6E6E73 et #86868B. */
.v2-chaise, .v2-chaise .rb-objet-code, .v2-chaise .oc-fenetre { height: 100%; }
.v2-chaise .rb-objet-code { position: relative; color: #1D1D1F; }
.v2-chaise .oc-fenetre { border: 0; border-radius: 0; box-shadow: none; background: #ECECEF; }
.v2-chaise .oc-barre { display: none; }
.v2-chaise .oc-corps { height: 100%; grid-template-columns: minmax(0, 66fr) minmax(0, 34fr); }
.v2-chaise .oc-vue { height: auto; background: #ECECEF; }
.v2-chaise .oc-aide { left: 0.875rem; right: auto; color: #86868B; }
.v2-chaise .oc-etat { color: #86868B; }
.v2-chaise .oc-code { height: auto; border: 0; border-left: 1px solid rgba(29, 29, 31, .06); background: #F7F7F9;
  scrollbar-color: rgba(29, 29, 31, .18) transparent; }
/* Le code en petit, et les lignes longues qui passent à la ligne sous leur début au lieu d'être coupées (Tanguy, 26 oct.) :
   le numéro reste dans la marge (retrait négatif). Couleurs du code : celles d'objet-code, faites pour le clair. */
.v2-chaise .rb-objet-code .oc-code pre { width: auto; min-width: 0; font-size: 0.5625rem; line-height: 1.6; white-space: pre-wrap;
  overflow-wrap: anywhere; color: #1D1D1F; }
.v2-chaise .oc-l { padding-left: calc(0.5rem + 4ch); padding-right: 0.5rem; text-indent: calc(-0.5rem - 4ch); }
.v2-chaise .oc-l::before { width: 3ch; margin: 0 1ch 0 0.5rem; text-indent: 0; color: #AEAEB2; }
.v2-chaise .oc-l.is-on { background: rgba(29, 29, 31, .045); box-shadow: inset 0.125rem 0 0 #1D1D1F; }
.v2-chaise .oc-l.is-on::before { color: #1D1D1F; }

/* Les mises en situation (Tanguy, 27 oct.) : une barre de pastilles en bas du cadre, la même dans toutes les vues (« le menu
   avec les boutons en dessous qui soit pareil sur tout ») : « Built in code » pour la chaise construite, puis les vidéos ; un
   clic remplace le cadre entier par la vidéo. Le programme garde toute la hauteur de sa colonne (ses dernières lignes défilent
   au-dessus de la barre) ; « Drag to turn » et les étiquettes Model / Code passent en haut de la vue. */
.v2-chaise { position: relative; }
.v2-chaise .oc-aide, .v2-chaise .oc-cote { top: 0.875rem; bottom: auto; }
.v2-chaise .rb-objet-code .oc-code pre { padding-bottom: 3.5rem; }
.v2-mises { position: absolute; z-index: 4; left: 50%; bottom: 0.75rem; display: flex; gap: 0.125rem; padding: 0.25rem;
  border-radius: 999px; background: rgba(255, 255, 255, .86); transform: translateX(-50%);
  -webkit-backdrop-filter: blur(0.75rem) saturate(1.2); backdrop-filter: blur(0.75rem) saturate(1.2);
  box-shadow: 0 0.25rem 1rem rgba(29, 29, 31, .12), inset 0 0 0 1px rgba(29, 29, 31, .06); }
.v2-mise { display: flex; align-items: center; gap: 0.5rem; min-width: 0; margin: 0; padding: 0.375rem 0.75rem 0.375rem 0.375rem;
  border: 0; border-radius: 999px; background: none; font: inherit; font-size: 0.6875rem; font-weight: 500; color: #1D1D1F;
  white-space: nowrap; cursor: pointer; transition: background-color .2s ease, color .2s ease; }
.v2-mise[aria-pressed="false"]:hover:not(:disabled) { background: rgba(29, 29, 31, .06); }
.v2-mise:focus-visible { outline: 2px solid #1D1D1F; outline-offset: 1px; }
.v2-mise:disabled { color: #86868B; cursor: default; }
.v2-mise[aria-pressed="true"] { background: #1D1D1F; color: #FFFFFF; }
.v2-mise-ic { display: grid; flex: none; place-items: center; width: 1.375rem; height: 1.375rem; border-radius: 999px; background: #ECECEF; }
.v2-mise[aria-pressed="true"] .v2-mise-ic { background: rgba(255, 255, 255, .14); }
.v2-mise-ic .ic { width: 0.8125rem; height: 0.8125rem; stroke-width: 1.5; }   /* le badge rond comme la pastille, le trait plus fin (Tanguy, 27 oct.) */
/* le noir qui glisse d'un bouton à l'autre (v2-accueil.js) : une copie des boutons, noire à libellés blancs, découpée en
   pastille ; ses deux bords (--fond-g, --fond-d) glissent chacun de son côté, celui de tête 90 ms avant l'autre, si bien
   qu'elle s'étire en chemin, et le texte passe au blanc exactement là où le noir passe */
@property --fond-g { syntax: '<length>'; inherits: true; initial-value: 0px; }
@property --fond-d { syntax: '<length>'; inherits: true; initial-value: 0px; }
.v2-mises.a-fond { transition: --fond-g .38s cubic-bezier(.65, 0, .25, 1), --fond-d .38s cubic-bezier(.65, 0, .25, 1); }
.v2-mises[data-sens="droite"] { transition-delay: .09s, 0s; }
.v2-mises[data-sens="gauche"] { transition-delay: 0s, .09s; }
.v2-mises.fixe { transition: none; }
.v2-mises-blanc { position: absolute; inset: 0; display: flex; gap: 0.125rem; padding: 0.25rem; pointer-events: none;
  background: #1D1D1F; clip-path: inset(0.25rem var(--fond-d) 0.25rem var(--fond-g) round 999px); }
.v2-mises-blanc .v2-mise { color: #FFFFFF; }
.v2-mises-blanc .v2-mise-ic { background: rgba(255, 255, 255, .14); }
.v2-mises.a-fond > .v2-mise { position: relative; }
.v2-mises.a-fond > .v2-mise[aria-pressed="true"] { background: none; color: #1D1D1F; }
.v2-mises.a-fond > .v2-mise[aria-pressed="true"] .v2-mise-ic { background: #ECECEF; }
.v2-mise-bientot { margin-left: 0.125rem; font-size: 0.625rem; font-weight: 400; color: #86868B; }
.v2-mise-ecran { position: absolute; inset: 0; z-index: 3; display: none; background: #ECECEF; }
.v2-mise-ecran video { display: block; width: 100%; height: 100%; object-fit: cover; }
.v2-chaise[data-vue="video"] .v2-mise-ecran { display: block; }
.v2-scenes { position: relative; width: 100%; height: 100%; }   /* Blocking to video : la vidéo et sa barre de scènes */

/* La visionneuse de la passerelle, usage 03 (passerelle/passerelle.js, 27 oct.) : sur l'Encre, le menu des pièces en haut à
   gauche, le retour à la scène entière en haut à droite (seulement quand une pièce est isolée), le curseur scan / 3D et le
   crédit du scan en bas. Mêmes couleurs que la visionneuse d'origine. */
.v2-ht-cadre-nuage { background: #121117; }
.pas[data-secours], .v2-ht-video.pas-secours[hidden] { display: none; }   /* la vidéo de secours à la place de la visionneuse */
.pas { position: absolute; inset: 0; color: #F7F6F3; font-size: 0.75rem; line-height: 1.4; }
.pas-scene { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.pas button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.pas .ic { flex: none; width: 0.875rem; height: 0.875rem; stroke-width: 1.5; }
.pas-menu { display: contents; }
.pas .pas-ouvrir, .pas .pas-retour, .pas-zoom { display: flex; align-items: center; gap: 0.5rem; padding: 0.4375rem 0.75rem;
  border: 1px solid rgba(247, 246, 243, .14); border-radius: 999px; background: rgba(24, 23, 29, .82);
  -webkit-backdrop-filter: blur(0.5rem); backdrop-filter: blur(0.5rem); transition: border-color .2s ease; }
.pas .pas-ouvrir { position: absolute; z-index: 2; top: 0.75rem; left: 0.75rem; max-width: calc(100% - 14rem); }
.pas-droite { position: absolute; z-index: 2; top: 0.75rem; right: 0.75rem; display: flex; gap: 0.5rem; }
.pas .pas-retour { padding-left: 0.5rem; }
.pas .pas-retour[hidden] { display: none; }
.pas-zoom { gap: 0; padding: 0.125rem; }
.pas .pas-zoom button { display: grid; place-items: center; width: 1.6875rem; height: 1.6875rem; border-radius: 50%;
  color: rgba(247, 246, 243, .82); transition: background-color .2s ease; }
.pas .pas-zoom button:hover, .pas .pas-zoom button:focus-visible { background: rgba(247, 246, 243, .1); color: #F7F6F3; outline: none; }
.pas .pas-ouvrir:hover, .pas .pas-ouvrir:focus-visible, .pas .pas-retour:hover, .pas .pas-retour:focus-visible {
  border-color: rgba(247, 246, 243, .4); outline: none; }
.pas .pas-ouvrir:disabled { opacity: .5; cursor: default; }
.pas-ouvrir .ic { transition: transform .2s ease; }
.pas-ouvrir[aria-expanded="true"] .ic { transform: rotate(180deg); }
.pas-titre { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pas-pastille, .pas-dot { flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; }
.pas-liste { position: absolute; z-index: 2; left: 0.75rem; top: 3.125rem; width: 15.5rem; max-height: calc(100% - 7.5rem);
  overflow-y: auto; margin: 0; padding: 0.375rem; list-style: none; border: 1px solid rgba(247, 246, 243, .14);
  border-radius: 0.875rem; background: rgba(24, 23, 29, .94); scrollbar-width: thin; }
.pas-liste button { display: flex; align-items: center; gap: 0.625rem; width: 100%; padding: 0.3125rem 0.625rem; border-radius: 0.5rem;
  text-align: left; color: rgba(247, 246, 243, .82); }
.pas-liste button:hover, .pas-liste button:focus-visible, .pas-liste button.hov { background: rgba(247, 246, 243, .07); color: #F7F6F3; outline: none; }
.pas-liste button[aria-pressed="true"] { background: rgba(247, 246, 243, .12); color: #F7F6F3; }
.pas-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pas-mm { color: #9C99A6; font-size: 0.6875rem; font-variant-numeric: tabular-nums; }
.pas-sep, .pas-bouts { font-size: 0.625rem; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: #9C99A6; }
.pas-sep { margin: 0.5rem 0.625rem 0.25rem; }
.pas-tip { position: absolute; z-index: 3; padding: 0.3125rem 0.625rem; border: 1px solid rgba(247, 246, 243, .14); border-radius: 0.5rem;
  background: rgba(24, 23, 29, .92); white-space: nowrap; pointer-events: none; transform: translate(0.875rem, 0.875rem); }
.pas-tip span { margin-left: 0.5rem; color: #9C99A6; }
.pas-compare { position: absolute; z-index: 1; left: 1rem; right: 1rem; bottom: 2rem; }
.pas-bouts { display: flex; justify-content: space-between; margin-bottom: 0.25rem; }
.pas-front { display: block; width: 100%; height: 1.5rem; margin: 0; background: transparent; cursor: ew-resize;
  -webkit-appearance: none; appearance: none; }
.pas-front::-webkit-slider-runnable-track { height: 1px; background: rgba(247, 246, 243, .3); }
.pas-front::-moz-range-track { height: 1px; background: rgba(247, 246, 243, .3); }
.pas-front::-webkit-slider-thumb { width: 1.25rem; height: 1.25rem; margin-top: -0.625rem; border-radius: 50%; background: #F7F6F3;
  box-shadow: 0 0 0 5px rgba(124, 92, 255, .35); -webkit-appearance: none; }
.pas-front::-moz-range-thumb { width: 1.25rem; height: 1.25rem; border: 0; border-radius: 50%; background: #F7F6F3;
  box-shadow: 0 0 0 5px rgba(124, 92, 255, .35); }
.pas-front:focus-visible { outline: none; }
.pas-front:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 5px #7C5CFF; }
.pas-front:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 5px #7C5CFF; }
.pas-front:disabled { opacity: .35; cursor: default; }
.pas-aide { position: absolute; left: 1rem; right: 1rem; bottom: 0.625rem; margin: 0; text-align: right; font-size: 0.6875rem;
  color: #9C99A6; pointer-events: none; }.pas-chargement { position: absolute; z-index: 4; inset: 0; display: grid; place-content: center; gap: 0.875rem; text-align: center;
  color: #9C99A6; background: #121117; transition: opacity .5s ease; }
.pas-chargement p { margin: 0; }
.pas-chargement.fini { opacity: 0; pointer-events: none; }
.pas-barre-fond { width: 13.75rem; height: 1px; background: rgba(247, 246, 243, .14); }
.pas-barre { display: block; width: 0; height: 100%; background: #F7F6F3; }
@media (prefers-reduced-motion: reduce) {
  .v2-ht-item, .v2-ht-detail, .v2-ht-carte, .v2-ht-media.is-active .v2-ht-carte,
  .v2-mises.a-fond { transition: none; }
}

/* Tablette, téléphone, écran tactile : l'accordéon de LTX. Le média de l'usage choisi s'ouvre sous sa ligne ; plus de carte. */
@media (max-width: 991px), (hover: none) and (pointer: coarse) {
  .v2-ht { display: block; }
  .v2-ht-medias { display: none; }
  /* Chaque usage s'ouvre quand on y arrive en défilant et reste ouvert (.is-ouvert, v2-accueil.js ; Tanguy, 28 oct. : « que
     les volets s'ouvrent au scroll ») ; la vidéo qui joue est celle de la carte la plus près du milieu de l'écran (.is-active). */
  .v2-ht-item.is-ouvert { opacity: 1; }
  /* le chevron « ^ » à droite du nom, discret (gris, sans fond), seulement quand l'usage est ouvert : il se retourne en
     s'ouvrant ; toucher la ligne referme l'usage (28 oct.) */
  .v2-ht-fermer { display: grid; place-items: center; flex: none; align-self: center; width: 1.5rem; height: 1.5rem; margin-left: auto;
    color: var(--gris); opacity: 0; transform: rotate(180deg);
    transition: opacity .3s var(--ht-ouvre), transform .45s var(--ht-ouvre); }
  .v2-ht-item.is-ouvert .v2-ht-fermer { opacity: 1; transform: none; }
  .v2-ht-item:not(.is-ouvert) > .v2-ht-detail { grid-template-rows: 0fr; opacity: 0; transform: translateY(-10px); }
  .v2-ht-item.is-ouvert > .v2-ht-detail { grid-template-rows: 1fr; opacity: 1; transform: none; }
  .v2-ht-slot { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .45s var(--ht-ouvre), opacity .45s linear; }
  .is-ouvert > .v2-ht-slot { grid-template-rows: 1fr; opacity: 1; }
  .v2-ht-slot > .v2-ht-media { min-height: 0; overflow: hidden; }
  .v2-ht-slot .v2-ht-media .v2-ht-cadre { display: block; margin: 1rem 0 0.5rem; border-radius: 10px; }
  .v2-ht-carte { display: none; }
  /* Toutes les cartes au 16:9 des vidéos (« que chaque card fasse la même taille »), la chaise comprise : son programme à côté
     d'elle, en petit, comme sur ordinateur (« le code de la chaise en petit à côté de la chaise, pas en dessous »). */
  .v2-chaise .rb-objet-code .oc-code pre { font-size: 0.375rem; padding-bottom: 2.75rem; }
  /* La barre de boutons (mises en situation, scènes) à cheval sur le bas de la carte, moitié sur le visuel, moitié dessous
     (Tanguy, 28 oct. : « elle couvre trop les visuels ») : l'arrondi passe du cadre au visuel, que la barre puisse dépasser ;
     la marge sous le cadre lui fait la place. La vue de la chaise se cadre au-dessus de sa moitié haute. */
  /* 2,75 rem sous la carte : la moitié basse de la barre et son ombre (20 px sous elle) tiennent dans le volet, qui rogne ce qui
     dépasse, et la barre s'écarte du trait de l'usage suivant (Tanguy, 28 oct. : « l'ombre des boutons se fait couper »,
     « les boutons sont trop collés au trait ») */
  .v2-ht-slot .v2-ht-media .v2-ht-cadre { overflow: visible; margin-bottom: 2.75rem; }
  .v2-ht-slot .v2-chaise .rb-objet-code, .v2-ht-slot .v2-mise-ecran, .v2-ht-slot .v2-ht-video { overflow: hidden; border-radius: 10px; }
  .v2-ht-slot .v2-mises { bottom: 0; transform: translate(-50%, 50%); }
  .v2-chaise .oc-vue { margin-bottom: 1.125rem; }
  /* plus petits sur cette carte : le zoom (boutons de 24 px, le minimum pour le doigt) et le rond de la poignée (sa bande de
     44 px reste à toucher) ; la chaise un peu plus près au départ (--oc-zoom, lu par objet-code.js) (Tanguy, 28 oct.) */
  .v2-chaise { --oc-zoom: 1.18; }
  .v2-chaise .oc-zoom { left: 0.5rem; padding: 0.125rem; }
  .v2-chaise .oc-zoom-b { width: 1.5rem; height: 1.5rem; }
  .v2-chaise .oc-zoom-b svg { width: 0.75rem; height: 0.75rem; }
  .v2-chaise .oc-poignee-bouton { width: 1.625rem; height: 1.625rem; }
  .v2-chaise .oc-poignee-bouton svg { width: 0.75rem; height: 0.75rem; }
  /* plus de petits textes posés sur la chaise (noms des pièces et leurs traits, « Model » et « Code ») ; « Drag to turn » en
     9 px (Tanguy, 28 oct.) */
  .v2-chaise .oc-noms, .v2-chaise .oc-fils, .v2-chaise .oc-cote { display: none; }
  .v2-chaise .oc-aide { top: 0.625rem; left: 0.625rem; font-size: 0.5625rem; }
  .v2-ht-cadre-3d .v2-mises { max-width: calc(100% - 1rem); overflow-x: auto; }
  .v2-ht-cadre-3d .oc-nom span { display: none; }   /* le nom du bloc seul : ses lignes déborderaient du cadre */
  .v2-ht-cadre-nuage { aspect-ratio: 4 / 3; }   /* la passerelle : assez de hauteur pour le menu et le curseur */
  .pas-aide { display: none; }
  .pas-compare { bottom: 0.75rem; }
}

/* ---------- Deux colonnes (le modèle phare de LTX) : le texte d'un côté, le panneau de l'autre ---------- */
.v2-split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.v2-split-inverse { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.v2-split .ui-scene.v3 { max-width: none; padding-bottom: 0; }

/* Des rangées à filets (« Trusted open foundation » de LTX) : le nom, la ligne grise, le bouton éventuel à droite. */
.v2-lignes { margin: 0; padding: 0; list-style: none; border-bottom: 1px solid var(--ligne); }
.v2-lignes li { display: grid; grid-template-columns: 9rem minmax(0, 1fr) auto; gap: 1rem; align-items: center; min-height: 4.25rem;
  padding: 0.875rem 0; border-top: 1px solid var(--ligne); }
.v2-lignes .t { font-size: 1rem; letter-spacing: -.01em; }
.v2-lignes .d { font-size: 0.8125rem; line-height: 1.45; color: var(--gris); }


/* ---------- Section 5 : la spécialisation, la lampe avant/après à gauche, les voies en rangées à droite ---------- */
.v2-lampe-scene .v2-p-corps { flex: none; aspect-ratio: 4 / 3; }
.v2-lampe > img { object-position: 50% 62%; }

/* ---------- Section 6 : le benchmark, deux cartes blanches égales ; un graphique par panneau, seule la marque porte la V01 ---------- */
.v2-graphe-scene.ui-scene.v3 { max-width: 32rem; }
.v2-graphe { display: grid; align-items: center; aspect-ratio: 4 / 3; padding: 1rem 1rem 0.5rem; }   /* deux panneaux de même hauteur */
.v2-svg { display: block; width: 100%; height: auto; }
.v2-svg .ax { stroke: rgba(18, 17, 23, .5); stroke-width: 1; }
.v2-svg .grille { stroke: rgba(18, 17, 23, .07); stroke-width: 1; }
.v2-svg text { font-size: 13px; fill: #5F5C68; }
.v2-svg .lab { font-size: 12px; fill: #8E8B96; }
.v2-svg .val { font-size: 13px; font-variant-numeric: tabular-nums; fill: #5F5C68; }
.v2-svg .fort { fill: #121117; font-weight: 500; }
.v2-svg .eux { fill: #FFFFFF; stroke: rgba(18, 17, 23, .22); stroke-width: 1.25; }
.v2-svg .base { fill: rgba(18, 17, 23, .08); stroke: rgba(18, 17, 23, .22); stroke-width: 1.25; }
.v2-svg .halo { fill: rgba(255, 140, 60, .1); }
.v2-note { margin: 1.25rem auto 0; font-size: 0.75rem; color: var(--gris); text-align: center; }

/* ---------- Section 7 : les industries, au format exact de « Build on LTX » (ltx.io/research ; Tanguy, 20 oct.) ----------
   La tête à gauche ; la liste à filets avec ses icônes, l'industrie choisie soulignée d'un trait plein ; à droite une carte
   (l'image, le nom à gauche et sa phrase à droite, des rangées à filets avec ↗) ; les cartes glissent de l'une à l'autre. */
.v2-ind { display: grid; grid-template-columns: minmax(0, 17.5rem) minmax(0, 1fr); gap: clamp(2rem, 6vw, 6rem); align-items: start; }
.v2-ind-onglets { display: flex; flex-direction: column; }
.v2-ind-onglet { display: flex; align-items: center; gap: 0.875rem; width: 100%; margin: 0; padding: 1.125rem 0; border: 0;
  border-bottom: 1px solid var(--ligne); border-radius: 0; background: none; font: inherit; font-size: clamp(1.125rem, 1.5vw, 1.3125rem);
  font-weight: 300; letter-spacing: -.02em; line-height: 1.2; text-align: left; white-space: nowrap; color: var(--gris); cursor: pointer;
  transition: color 250ms ease, border-color 250ms ease; }
.v2-ind-onglet:hover { color: var(--craie); }
.v2-ind-onglet[aria-selected="true"] { padding-bottom: calc(1.125rem - 1px); border-bottom: 2px solid var(--craie); color: var(--craie); }
.v2-ind-onglet:focus-visible { outline: 2px solid var(--craie); outline-offset: 3px; }
.v2-ind-ic { display: grid; flex: none; place-items: center; width: 1.25rem; height: 1.25rem; }
.v2-ind-ic .ic { display: block; width: 1.125rem; height: 1.125rem; }

/* La piste : les cartes côte à côte, un jour entre deux ; la fenêtre prend la hauteur de la carte choisie (v2-accueil.js). */
.v2-ind-fenetre { min-width: 0; overflow: hidden; transition: height 450ms cubic-bezier(.65, 0, .35, 1); }
.v2-ind-cartes { --glisse-jour: 2rem; display: flex; align-items: flex-start; gap: var(--glisse-jour);
  transition: transform 700ms cubic-bezier(.65, 0, .35, 1); }
@media (prefers-reduced-motion: reduce) {
  .v2-ind-fenetre, .v2-ind-cartes { transition: none; }
}
.v2-ind-carte { flex: 0 0 100%; min-width: 0; padding: clamp(1.125rem, 1.8vw, 1.625rem); border: 1px solid var(--ligne); border-radius: 1.5rem;
  background: #141318; }
.v2-ind-carte img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 7; object-fit: cover; border-radius: 0.75rem; }
.v2-ind-tete { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: 1.5rem; align-items: start; padding: 1.75rem 0.25rem; }
.v2-ind-tete h3 { margin: 0; font-size: clamp(1.625rem, 2.6vw, 2.25rem); line-height: 1.1; letter-spacing: -.03em; font-weight: 300; }
.v2-ind-tete p { max-width: 26rem; margin: 0.25rem 0 0; font-size: 0.9375rem; line-height: 1.45; color: rgba(247, 246, 243, .78); }
.v2-ind-lignes { margin: 0; padding: 0; list-style: none; }
/* Les rangées passent au blanc au survol, comme les rangées Flowing Menu que Tanguy aime (7 oct.). */
.v2-ind-ligne { display: grid; grid-template-columns: 11rem minmax(0, 1fr) auto; gap: 1rem; align-items: start;
  padding: 1.375rem 0.75rem; border-top: 1px solid var(--ligne); border-radius: 0.75rem; color: var(--craie); text-decoration: none;
  transition: background-color 250ms ease, color 250ms ease, border-color 250ms ease; }
.v2-ind-ligne .t { font-size: 1.0625rem; letter-spacing: -.015em; line-height: 1.3; }
.v2-ind-ligne .d { max-width: 26rem; font-size: 0.8125rem; line-height: 1.5; color: var(--gris); }
.v2-ind-ligne .f { color: var(--gris); transition: transform 250ms ease; }
.v2-ind-ligne:hover, .v2-ind-ligne:focus-visible { background: #F7F6F3; color: #121117; border-top-color: transparent; }
.v2-ind-ligne:hover .d, .v2-ind-ligne:hover .f, .v2-ind-ligne:focus-visible .d, .v2-ind-ligne:focus-visible .f { color: #4A4752; }
.v2-ind-ligne:hover .f { transform: translate(2px, -2px); }
.v2-ind-lignes li:hover + li .v2-ind-ligne { border-top-color: transparent; }

/* ---------- La tête de section de ltx.io : le sur-titre « // », le titre à gauche, la ligne (ou les contrôles) à droite ---------- */
.v2-sec .v2-tete { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 1.5rem clamp(2rem, 5vw, 5rem); align-items: end;
  margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.v2-tete-g { min-width: 0; }
/* le sur-titre en Inter, la seule famille de la charte, en capitales espacées comme ses propres sur-titres (Tanguy, 27 oct. :
   la chasse fixe du système faisait « la police classique » de tous les sites ; « une autre police qui garde l'identité bâton ») */
.v2-sur { margin: 0 0 1.25rem; font-size: 0.6875rem; font-weight: 500; line-height: 1; letter-spacing: .14em;
  text-transform: uppercase; color: var(--gris); }
/* 48 px au plus (avant 60) : nettement sous le titre d'ouverture (68 px), comme la hiérarchie d'Apple (Tanguy, 28 oct. :
   « prends les retours Apple en compte, sauf pour les espacements ») */
.v2-h2 { margin: 0; font-size: clamp(2.25rem, 3.4vw, 3rem); line-height: 1.04; letter-spacing: -.038em; font-weight: 300; }
.v2-h2 span { display: block; }
.v2-tete-d { display: flex; flex-direction: column; align-items: flex-start; gap: 1.25rem; min-width: 0; padding-bottom: 0.375rem; }
.v2-tete-l { max-width: 27rem; margin: 0; font-size: 0.9375rem; line-height: 1.5; color: var(--gris); }

/* ---------- La phrase-manifeste (« The next generation of world models… » de LTX) : en grand, centrée (Tanguy, 27 oct.) ---------- */
.v2-mission-sec { padding: clamp(5rem, 10vw, 9rem) 0 clamp(6rem, 11.5vw, 10.5rem); }
/* Après les usages (bande claire aussi), lab.css retire la marge du haut (.clair + .clair) : la phrase y reprend de l'air
   (Tanguy, 27 oct. : « ajoute de l'espace au dessus et un peu en dessous du long texte »). */
.v2-sec.clair + .v2-mission-sec { padding-top: clamp(4rem, 8vw, 7rem); }
/* 28 oct. : l'air au-dessus de la phrase ramené à celui du dessous, jusqu'à la carte du CTA (Tanguy : « réduire un peu l'espace
   en haut pour avoir le même qu'en bas ») ; mesuré à 1440 et 2000 px : 162 et 187 px en haut, 166 et 187 en bas. */
.v2-sec.clair + .v2-mission-sec { padding-top: calc(clamp(4rem, 8vw, 7rem) - 2.75rem); }
.v2-mission { max-width: 64rem; margin: 0 auto; text-align: center; font-size: clamp(1.625rem, 3.1vw, 2.75rem); line-height: 1.18; letter-spacing: -.028em;
  font-weight: 300; color: var(--craie); text-wrap: pretty; }   /* une graisse sous la normale (Tanguy, 27 oct.) */
.v2-mission b { font-weight: 500; }
/* La sphère de verre au-dessus de la phrase depuis le 28 oct. (avant : entre les deux phrases), petite et au centre (Tanguy, 27 oct. : « rapproche les deux paragraphes,
   la sphère doit encore être plus petite ») ; le canevas garde l'air du studio autour d'elle, la sphère en occupe un peu plus
   de la moitié. */
.v2-sphere-a { width: clamp(5rem, 7vw, 6.5rem); aspect-ratio: 1; margin: 0.25rem auto; }
/* Depuis le 28 oct. (après-midi), elle est dans la seconde ligne, sur l'axe de la page : « ready to drop » à sa gauche,
   « into production. » à sa droite. Les deux colonnes égales la gardent au centre ; ses marges négatives ramènent la hauteur
   de la ligne à celle du texte (le canevas a de l'air autour de la sphère). Elle y est à 70 % de sa taille d'avant (Tanguy :
   « réduis uniquement la bille sur le départ », pour ne pas toucher la ligne du dessus) : celle d'arrivée, dans le CTA, ne
   change pas. */
.v2-mission-grille { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.v2-mission-grille .debut { grid-column: 1 / -1; }
.v2-br-tel { display: none; }   /* le saut de la ligne du milieu, sur téléphone seulement */
.v2-mission-grille .gauche { text-align: right; }
.v2-mission-grille .droite { text-align: left; }
/* sur les côtés, l'air du canevas rogné : le texte reste à environ un espace de mot de la boule (Tanguy, 28 oct. : « trop
   d'espace à gauche et à droite de la boule ») */
.v2-mission-grille .v2-sphere-a { --d: clamp(3.5rem, 4.9vw, 4.5rem); width: var(--d); margin: calc((1.18em - var(--d)) / 2) calc(var(--d) * -.08); }

/* ---------- Section 4 : le modèle, en CTA (Tanguy, 27 oct.) ----------
   Le texte à gauche (« un alignement du texte à gauche, tu rajoutes des éléments pour rendre plus explicite l'usage du
   modèle ») ; la forme en très grand à droite, qui dépasse du haut et un peu de la droite de la carte. La sphère
   (.v2-sphere-vol, un canevas) part de .v2-sphere-a, suit le défilement en arc et grossit jusqu'à .v2-sphere-b ;
   v2-accueil.js la place à chaque image. Les textes passent devant elle. Version centrée : tools/archive/avant-cta-gauche-2026-10-27/. */
/* La section prolonge la bande claire de la phrase-manifeste (Tanguy, 27 oct. : « tu passes le CTA sur un gros fond blanc ») :
   le fond de .clair sans sa classe, qui changerait les couleurs de la carte ; l'air du haut est celui de la phrase. */
.v2-cta-modele { padding: 0 0 clamp(5rem, 10vw, 9rem); background: #F7F6F3; }
/* La carte, sur la largeur du site (Tanguy, 27 oct. : « cette section fait-la en card qui ne fait pas toute la largeur de
   l'écran », puis « plus arrondie ») ; son fond est celui de l'ouverture (main.js sur .waves), en plus sombre (data-couleur),
   sans éclat ni couleur sous la souris ; presque effacé au centre, entier sur les bords (Tanguy, 27 oct. : « on ne le voit
   qu'à l'extérieur ») : le masque radial touche les bords de la carte (un premier, plus large, les laissait à 58 %, « trop
   discret »), puis repoussé encore vers les bords (« encore plus au bord et moins au centre »). Depuis que la forme est à
   droite : visible à gauche, presque absent à droite (« le pattern doit être visible à gauche mais très peu à droite »). */
.v2-cta-carte { position: relative; overflow: hidden; border-radius: 2.5rem; background: #121117; }
.v2-cta-carte .waves { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.v2-cta-carte .waves canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; opacity: 0;
  transition: opacity 600ms cubic-bezier(.22, 1, .36, 1);
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 22%, rgba(0, 0, 0, .06) 62%, rgba(0, 0, 0, .06) 100%);
  mask-image: linear-gradient(90deg, #000 0%, #000 22%, rgba(0, 0, 0, .06) 62%, rgba(0, 0, 0, .06) 100%); }
.v2-cta-carte .waves[data-ready="true"] canvas { opacity: 1; }
/* Plus haute et plus épurée (Tanguy, 27 oct.) : le texte centré dans la hauteur, plus d'air autour. */
.v2-cta-carte { display: flex; align-items: center; min-height: clamp(26rem, 36vw, 32rem); }   /* puis moins haute (« trop haute ») */
/* La colonne de texte assez large pour le titre en deux lignes (« Next-gen is loading… / Our first model drops soon. »). */
.v2-cta-contenu { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: flex-start; max-width: 46rem;
  padding: clamp(3.5rem, 6vw, 5.5rem) clamp(1.5rem, 4.5vw, 4rem); text-align: left; }
.v2-cta-contenu .v2-sur { margin: 0 0 1.125rem; color: var(--gris); }
.v2-cta-t { margin: 0; font-size: clamp(1.875rem, 3.2vw, 2.75rem); line-height: 1.05; letter-spacing: -.035em; font-weight: 300; }
.v2-cta-t > span { display: block; }
/* Les points de « loading » se grisent l'un après l'autre puis reviennent au blanc, comme un chargement (Tanguy, 27 oct.). */
@media (prefers-reduced-motion: no-preference) {
  .v2-charge span { animation: v2-charge 1.4s ease-in-out infinite; }
  .v2-charge span:nth-child(2) { animation-delay: .2s; }
  .v2-charge span:nth-child(3) { animation-delay: .4s; }
}
.v2-cta-t .v2-charge, .v2-cta-t .v2-charge span { display: inline; }   /* « h2.stair span » (lab.css) les mettait en bloc */
@keyframes v2-charge { 0%, 60%, 100% { opacity: 1; } 30% { opacity: .22; } }
.v2-cta-p { max-width: 32rem; margin: 1.25rem 0 0; font-size: 1.0625rem; font-weight: 300; line-height: 1.5; color: var(--texte); }
.v2-cta-modele .btns { justify-content: flex-start; margin-top: 2.5rem; }
/* La forme, en très grand (S) : la boule occupe 62 % de son canevas, son centre 3,8 % sous celui du canevas (mesuré). Le
   canevas de la place d'arrivée est posé dans la carte, en haut à droite, pour qu'un tiers du diamètre de la boule dépasse
   au-dessus ; puis centrée (Tanguy, 27 oct. : « le modèle 3D doit être bien centré […] en hauteur ») : en largeur entre la fin
   de la colonne de texte (46 rem) et le bord droit, en hauteur avec son reflet (la boule 0,08 S au-dessus du milieu de la
   carte, le reflet dessous ; le haut du canevas à 50 % - 0,618 S). Le canevas qui voyage n'est pas dans la carte : son
   overflow ne le coupe pas ; il est 1,4 fois plus haut que large, la boule à la même taille (le labo la cadre sur le petit
   côté), pour que l'ombre et le reflet au sol tiennent dessous ; ses côtés s'effacent en fondu (un reflet large y était coupé
   net). Le reflet ne sort pas de la carte : le shader l'éteint hors de son coin haut droit arrondi (bord(), v2-accueil.js).
   Puis (Tanguy, 27 oct. : « la 3D doit déborder du dessus donc encore un peu plus grosse, et un peu plus à droite ») : S de
   40 à 46 vw, son bord droit (0,81 S) 1 rem au-delà de celui de la carte ; d'abord un tiers de la boule au-dessus de la
   carte, puis redescendue (« plus basse pour donner l'impression d'être centrée en hauteur dans la card ») : son centre
   0,04 S au-dessus du milieu de la carte (haut du canevas à 50 % - 0,578 S) : à cette taille, la boule et son reflet
   remplissent presque la hauteur. */
.v2-sphere-b, .v2-sphere-vol { width: clamp(26.25rem, 48.3vw, 43rem); aspect-ratio: 1; }   /* + 5 % (27 oct., plus bas) */
.v2-sphere-vol { aspect-ratio: 1 / 1.4;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 13%, #000 87%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 13%, #000 87%, transparent); }
/* Puis (Tanguy, 27 oct. : « déplace encore un peu la 3D sur la gauche et monte-la un peu ») : 3 rem plus à gauche, 0,05 S
   plus haut. Enfin (« la 3D je la veux encore 5 % plus grosse et un peu plus à gauche et un peu plus bas ») : S × 1,05,
   2 rem de plus à gauche, 0,03 S plus bas. */
.v2-sphere-b { position: absolute; top: calc(50% - clamp(26.25rem, 48.3vw, 43rem) * .598);
  left: calc(100% - clamp(26.25rem, 48.3vw, 43rem) * .81 - 4rem); }
.v2-sphere-vol { position: fixed; left: 0; top: 0; z-index: 1; transform-origin: 0 0; pointer-events: none; will-change: transform; }
.v2-mission { position: relative; z-index: 2; }
/* Sur téléphone, la forme reprend sa place au-dessus du texte, centrée, et dépasse du haut seulement. */
@media (max-width: 767px) {
  .v2-cta-carte { flex-direction: column; align-items: stretch; min-height: 0; }
  /* Plus grosse (336 px sur un écran de 393 ; la largeur de la carte au plus, qu'elle y reste centrée), et le texte de la carte
     remonte sur elle : le bas de la forme passe derrière le titre, le texte restant devant ; moins d'air au-dessus de
     « Coming soon » (Tanguy, 28 oct.). Avant : 17 rem, 28 px plus bas qu'au départ, le texte sous la forme. */
  :root { --sphere-tel: min(21rem, 100vw - 2rem); }
  .v2-sphere-b, .v2-sphere-vol { width: var(--sphere-tel); }
  .v2-sphere-b { position: relative; top: auto; left: auto; order: -1;
    margin: calc(var(--sphere-tel) * -.27) auto calc(var(--sphere-tel) * -.405); }
  .v2-cta-contenu { padding-top: 1rem; }
}


/* ---------- Le pied de page de l'accueil, d'après celui de ltx.io (relevé du 27 oct., ltx-pied2.mjs) ----------
   Leur disposition : la marque, une ligne, un bouton à contour et les carrés des réseaux à gauche ; les colonnes de liens à
   droite (grille 2 : 3) ; les mentions sous un filet. Puis à nos couleurs et à nos tailles (Tanguy, 27 oct. : « ajuste le bas
   de page à la couleur de notre site, et fais matcher la taille des typos et boutons avec nos normes ; ça doit être plus
   petit, trop d'espace ») : l'Encre, les titres de colonne de footer.site (.foot-h), le bouton .btn.contour, les liens et
   les mentions aux tailles du pied des autres pages.
   Le volet (« l'apparition en scroll volet ») : comme leur .page-wrapper (relatif, z-index 10, fond plein), la page passe
   au-dessus du pied, collé en bas de l'écran (sticky, bottom 0) : en défilant, elle glisse et le découvre. Trop bas ou trop
   étroit pour l'écran, il suit la page normalement. */
.home-lab main { position: relative; z-index: 10; background: #F7F6F3; }
.home-lab .v2-pied { position: sticky; bottom: 0; }   /* le volet : sur l'accueil seulement, où main passe au-dessus */
.v2-pied { position: relative; z-index: 0; padding: 7rem 0 calc(2.75rem + env(safe-area-inset-bottom, 0px));
  background: var(--encre); color: var(--craie); font-size: .8438rem; }
.v2-pied-in { display: flex; flex-direction: column; gap: 5.5rem; }   /* un peu plus haut (Tanguy, 27 oct.), deux fois */
/* à la largeur de l'en-tête et de la page (.wrap), plus de bord à bord à 3 rem (Tanguy, 27 oct. : « sur laptop je voudrais que
   le footer ait la même largeur que le header, là c'est pas aligné ») */
.v2-pied-in { width: min(var(--w), 100% - 2rem); margin: 0 auto; }
.v2-pied-grille { display: grid; grid-template-columns: 2fr 3fr; column-gap: 4rem; }
.v2-pied-marque { display: flex; flex-direction: column; align-items: flex-start; }
.v2-pied-logo { display: block; }
.v2-pied-logo { color: var(--craie); }
.v2-pied-signature { display: block; width: 8.25rem; height: auto; }
.v2-pied-ligne { max-width: 22rem; margin: 1rem 0 0; font-size: 1.25rem; line-height: 1.3; font-weight: 200;   /* plus fine (Tanguy, 27 oct.) */
  letter-spacing: -.01em; color: var(--craie); text-wrap: balance; }
.v2-pied .btn { margin-top: 1.5rem; }   /* le bouton blanc du site, comme dans l'ouverture (27 oct.) */
/* Les carrés des réseaux à droite, à la hauteur des titres de colonne (Tanguy, 27 oct.) ; sous les liens en une colonne. */
.v2-pied-liens .v2-pied-reseaux { display: flex; gap: .375rem; align-self: start; justify-self: end; margin: -.72rem 0 0; padding: 0; list-style: none; }
/* Le carré des réseaux à la couleur peinte dans les détails du logo de Hugging Face (#242329, media/SOURCES.md). */
.v2-pied-reseau { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: .625rem; background: #242329;
  transition: box-shadow .2s ease; }
/* Dans .v2-pied-liens, les carrés ne prennent ni le soulignement ni la couleur des liens ; au survol, un gris plus clair,
   sans trait (Tanguy, 27 oct.). */
.v2-pied-liens a.v2-pied-reseau { display: grid; padding: 0; background: #242329; transition: background-color .2s ease; }
.v2-pied-liens a.v2-pied-reseau:hover { background: #34333A; }
.v2-pied-reseau img { width: 1.125rem; height: 1.125rem; }
.v2-pied-liens { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3rem; align-content: start; }
.v2-pied-h { margin: 0 0 .625rem; font-size: .75rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--gris); }
.v2-pied-liens ul, .v2-pied-legal { margin: 0; padding: 0; list-style: none; }
.v2-pied-liens a { display: inline-block; padding: .3125rem 0; color: rgba(247, 246, 243, .86); }
/* Le soulignement qui se dessine au survol, comme leurs liens (« Draws animated underline for footer links »). */
.v2-pied-liens a, .v2-pied-legal a { background: linear-gradient(currentColor, currentColor) 0 calc(100% - .25rem) / 0 1px no-repeat;
  transition: background-size .3s cubic-bezier(.22, 1, .36, 1), color .2s ease; }
.v2-pied-liens a:hover, .v2-pied-legal a:hover { background-size: 100% 1px; color: var(--craie); }
.v2-pied a:focus-visible { outline: 2px solid var(--craie); outline-offset: 3px; border-radius: 2px; }
.v2-pied-bas { position: relative; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1.5rem; padding-top: 1.5rem; font-size: .7812rem; color: var(--gris); }
/* À la place du filet, une longue ligne de 3 px où glisse la nappe du labo des dégradés (02-nappe : sa diagonale, du
   jaune-orange au violet, relevée sur rb/assets/v01 et tournée à l'horizontale) (Tanguy, 27 oct.). Une période aller-retour
   de deux largeurs, décalée d'une période entière (200 %) : la boucle ne se voit pas. Immobile en mouvement réduit. */
.v2-pied-bas::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; border-radius: 3px;
  background: linear-gradient(90deg, #FC9101 0%, #FC8701 5%, #FD7602 10%, #FC6202 15%, #FC5D02 20%, #FC6321 25%, #F324C4 30%, #A22CFA 35%, #841CFB 40%, #750BFA 45%, #3804B4 50%, #750BFA 55%, #841CFB 60%, #A22CFA 65%, #F324C4 70%, #FC6321 75%, #FC5D02 80%, #FC6202 85%, #FD7602 90%, #FC8701 95%, #FC9101 100%) 0 0 / 200% 100% repeat-x; }
@media (prefers-reduced-motion: no-preference) {
  .v2-pied-bas::before { animation: v2-nappe 14s linear infinite; }
}
@keyframes v2-nappe { to { background-position: 200% 0; } }
.v2-pied-legal { display: flex; flex-wrap: wrap; gap: 0 1.25rem; }
.v2-pied-legal a { display: inline-block; padding: .3125rem 0; color: var(--gris); }
.v2-pied-copy { margin: 0; }
@media (max-width: 991px) {
  .v2-pied-grille { grid-template-columns: minmax(0, 1fr); row-gap: 2.5rem; }
  .v2-pied-liens { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; }
  .v2-pied-liens .v2-pied-reseaux { grid-column: 1 / -1; justify-self: start; margin-top: 0; }
}
@media (max-width: 767px), (max-height: 560px) {
  .home-lab .v2-pied { position: relative; }   /* le pied dépasserait l'écran : le volet en cacherait le haut */
}

/* ---------- Les animations (v2-anim.js pose .v2-anim sur <html>, puis .vu sur chaque bloc qui arrive à l'écran) ---------- */
.v2-anim .v2-entree { opacity: 0; transform: translateY(1.75rem); transition: opacity 1s cubic-bezier(.2, .7, .2, 1), transform 1s cubic-bezier(.2, .7, .2, 1); }
.v2-anim .v2-entree.vu { opacity: 1; transform: none; }
/* Les lignes du titre sortent du flou l'une après l'autre (« title-blur-reveal » de LTX). */
.v2-anim .v2-tete .v2-h2 span { opacity: 0; filter: blur(0.75rem); transform: translateY(0.35em);
  transition: opacity 1s cubic-bezier(.2, .7, .2, 1), filter 1s cubic-bezier(.2, .7, .2, 1), transform 1s cubic-bezier(.2, .7, .2, 1); }
.v2-anim .v2-tete.vu .v2-h2 span { opacity: 1; filter: none; transform: none; }
.v2-anim .v2-tete.vu .v2-h2 span:nth-child(2) { transition-delay: 120ms; }
.v2-anim .v2-tete.vu .v2-h2 span:nth-child(3) { transition-delay: 240ms; }
.v2-anim .v2-tete .v2-tete-d { opacity: 0; transition: opacity 1s 250ms ease; }
.v2-anim .v2-tete.vu .v2-tete-d { opacity: 1; }
/* Les filets d'une liste se tracent de gauche à droite (« line-divider » de LTX). */
.v2-anim .v2-lignes.v2-entree { border-bottom-color: transparent; }
.v2-anim .v2-lignes.v2-entree li { position: relative; border-top-color: transparent; }
.v2-anim .v2-lignes.v2-entree li::before, .v2-anim .v2-lignes.v2-entree li:last-child::after { content: ""; position: absolute; left: 0; right: 0;
  height: 1px; background: var(--ligne); transform: scaleX(0); transform-origin: left center; transition: transform 1.1s cubic-bezier(.2, .7, .2, 1); }
.v2-anim .v2-lignes.v2-entree li::before { top: -1px; }
.v2-anim .v2-lignes.v2-entree li:last-child::after { bottom: 0; }
.v2-anim .v2-lignes.vu li::before, .v2-anim .v2-lignes.vu li:last-child::after { transform: none; }
.v2-anim .v2-lignes.vu li:nth-child(2)::before { transition-delay: 90ms; }
.v2-anim .v2-lignes.vu li:nth-child(3)::before { transition-delay: 180ms; }
.v2-anim .v2-lignes.vu li:nth-child(4)::before { transition-delay: 270ms; }
.v2-anim .v2-lignes.vu li:last-child::after { transition-delay: 360ms; }
/* La phrase-manifeste : chaque mot passe du gris clair à l'encre au fil du défilement. */
.v2-anim .v2-mission .m { color: rgba(18, 17, 23, .16); transition: color 350ms ease; }
.v2-anim .v2-mission .m.on { color: var(--craie); }
/* L'ouverture : le titre sort du flou au chargement, puis la ligne et les boutons montent (CSS seule, sans attendre le script). */
@media (prefers-reduced-motion: no-preference) {
  .v2-ouverture h1 span { animation: v2-flou 1.2s cubic-bezier(.2, .7, .2, 1) both; }
  .v2-ouverture h1 span:nth-child(2), .v2-ouverture h1 span:nth-child(4) { animation-delay: 140ms; }
  .v2-ouverture h1 span:nth-child(5) { animation-delay: 280ms; }
  .v2-ouverture .lead, .v2-ouverture .btns { animation: v2-monte 1s 380ms cubic-bezier(.2, .7, .2, 1) both; }
  .v2-ouverture .btns { animation-delay: 500ms; }
}
@keyframes v2-flou { from { opacity: 0; filter: blur(0.875rem); transform: translateY(0.3em); } to { opacity: 1; filter: none; transform: none; } }
@keyframes v2-monte { from { opacity: 0; transform: translateY(1rem); } to { opacity: 1; transform: none; } }

/* ---------- Accueil sur tablette et téléphone ---------- */
@media (max-width: 900px) {
  .v2-sec .v2-tete { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .v2-split, .v2-split-inverse { grid-template-columns: minmax(0, 1fr); }
  .v2-split-inverse .v2-split-v { order: 0; }
  .v2-lignes li { grid-template-columns: minmax(0, 1fr); gap: 0.375rem; }
  .v2-lignes li .btn { justify-self: start; margin-top: 0.375rem; }
  .v2-ind { grid-template-columns: minmax(0, 1fr); }
  .v2-ind-onglets { flex-direction: row; gap: 1.5rem; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--ligne); }
  .v2-ind-onglet { flex: none; width: auto; padding: 0.875rem 0; border-bottom: 0; font-size: 1rem; }
  .v2-ind-onglet[aria-selected="true"] { padding-bottom: calc(0.875rem - 2px); border-bottom: 2px solid var(--craie); }
  .v2-ind-tete { grid-template-columns: minmax(0, 1fr); gap: 0.625rem; padding: 1.25rem 0.25rem; }
  .v2-ind-ligne { grid-template-columns: minmax(0, 1fr) auto; }
  .v2-ind-ligne .d { grid-column: 1; grid-row: 2; }
  .v2-ind-ligne .f { grid-row: 1 / span 2; grid-column: 2; }
  .v2-svg text { font-size: 17px; }
  .v2-svg .lab { font-size: 15px; }
}
/* Sur téléphone, la console passe au-dessus de la liste de ses pièces (comme la lampe de la V1). */
@media (max-width: 600px) {
  .v2-h2 { font-size: 8vw; }
  .v2-h2 span { white-space: nowrap; }
}

/* =====================================================================================================================
   Téléphone (Tanguy, 27 oct. : « optimise la page sur mobile, n'hésite pas à réduire la taille des textes pour garder une
   page épurée ») : des textes plus petits, d'un cran sous ceux de l'ordinateur ; la barre des mises en situation de la chaise
   sans ses pastilles d'icône (sinon elle débordait du cadre et coupait ses libellés).
   ===================================================================================================================== */
@media (max-width: 767px) {
  /* Le titre : la phrase de définition seule, plus grande, sur trois lignes ; la ligne dessous d'un seul tenant, trois lignes
     au plus (Tanguy, 28 oct. : « en évitant le retour à la ligne que tu as mis, tu peux réduire un peu la police »). */
  .v2-ouverture h1 { font-size: 10.5vw; }
  .v2-ouverture h1 .ouv-pc { display: none; }
  .v2-ouverture h1 .ouv-tel { display: block; }
  /* 15 px (le plancher d'Apple pour une phrase d'accroche) dès que la largeur le permet ; en dessous, la plus grande taille qui
     tient en trois lignes, mesurée de 320 à 393 px (28 oct.) */
  .v2-ouverture .lead { font-size: clamp(12px, 3.74vw, 15px); }
  .v2-ouverture .lead-accueil span { display: inline; }
  /* l'ouverture a la hauteur de l'écran visible, en-tête déduit, sur tout téléphone (sans le plancher de 34 rem de l'ordinateur,
     qui la faisait dépasser sur un petit écran) */
  .v2-ouverture.accueil { min-height: calc(100svh - 61px); }
  /* la phrase-manifeste : « parametric and editable, » sur la ligne du milieu, 2 px de plus, la bille plus petite ; la carte du
     modèle un peu plus loin d'elle, l'air repris au-dessus de la phrase (Tanguy, 28 oct.) */
  .v2-br-tel { display: inline; }
  .v2-mission-grille .v2-sphere-a { --d: 2.75rem; }
  .v2-usages-sec { padding-bottom: 4rem; }
  .v2-mission-sec { padding-bottom: 8rem; }
  .v2-h2 { font-size: 7vw; }
  .v2-ht-num, .v2-ht-nom { font-size: 1.375rem; }
  .v2-ht-btn { gap: 0.75rem; padding: 0.5rem 0; }   /* la ligne entière se touche au doigt ; le numéro près du nom (28 oct.) */
  .v2-ht-item { padding: 0.5rem 0; }
  .v2-ht-detail p { font-size: 0.875rem; }
  /* Un peu plus grande et plus aérée (Tanguy, 28 oct. : « grandis un peu Every object… et ajoute de l'espace entre les
     lignes ») : juste sous la plus grande taille où « into production. » et « Every object comes out » tiennent chacun sur une
     ligne, mesurée de 320 à 430 px (18,1 px à 320, 23,2 à 393) ; interligne 1,3 au lieu de 1,18. */
  .v2-mission { font-size: clamp(1.125rem, 7vw - 4.3px, 1.625rem); line-height: 1.3; }
  .v2-mission-grille .v2-sphere-a { margin: calc((1.3em - var(--d)) / 2) calc(var(--d) * -.08); }
  .v2-sec.clair + .v2-mission-sec { padding-top: 0; }   /* la liste des usages finit déjà sur son propre air */
  .v2-cta-t { font-size: 1.5rem; }
  .v2-cta-p { font-size: 0.9375rem; }
  .v2-cta-p br { display: none; }   /* les deux phrases à la suite : sinon « code. » restait seul sur sa ligne */
  .v2-pied-ligne { font-size: 1.0625rem; }
  .v2-mise-ic { display: none; }
  .v2-mise { padding: 0.5rem 0.625rem; font-size: 0.625rem; }
}
