/* Mouvement des pages publiques (plan du 2026-11-09, decisions D3 a D19).
   Chargee en DERNIER dans le <head> des 18 pages publiques, avec
   js/mouvement-amorce.js (synchrone) et js/mouvement.js (defer). Toutes les
   regles sont prefixees par une classe que l'amorce pose sur <html> : sans
   elle, cette feuille ne fait rien.
   Caractere « instrument, precis » : une seule courbe (--ease-soft), aucun
   rebond ; la prose des guides ne bouge jamais. Sous prefers-reduced-motion:
   reduce, tout est a l'etat final et la page change sans transition. */

:root {
  --mvt-ease: var(--ease-soft, cubic-bezier(0.2, 0.8, 0.2, 1));
  --mvt-survol: var(--dur-1, 180ms);
  --mvt-etat: var(--dur-3, 320ms);
  --mvt-entree: var(--dur-4, 550ms);
}

/* ─── 1. Entre deux pages publiques : la fenetre et le titre (2026-11-09) ───
   La declaration de la transition et le rideau des changements de monde
   vivent dans css/ds/rideau.css ; js/rideau.js decide pour chaque
   navigation. Ici, le cas courant, d'une page publique a l'autre : la
   nouvelle page s'ouvre en masque arrondi pendant que l'ancienne recule et
   s'eteint, et le titre de la page (main h1, nomme par js/rideau.js
   seulement s'il est a l'ecran au moment du clic) se transforme en celui de
   la suivante. Le logo de l'en-tete et la banniere cookies restent
   immobiles. */
html.mvt .nav-glass .logo-container { view-transition-name: mvt-logo; }
html.mvt .fly-cookie-banner { view-transition-name: mvt-cookies; }
::view-transition-old(root) { animation: mvt-fenetre-sortie 580ms var(--mvt-ease) both; }
::view-transition-new(root) { animation: mvt-fenetre-entree 580ms cubic-bezier(0.7, 0, 0.2, 1) both; }
::view-transition-group(mvt-titre) { animation-duration: 580ms; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); }
::view-transition-group(mvt-logo),
::view-transition-group(mvt-cookies) { animation-duration: 580ms; animation-timing-function: var(--mvt-ease); }
@keyframes mvt-fenetre-sortie { to { scale: 0.92; opacity: 0.2; filter: blur(4px); } }
@keyframes mvt-fenetre-entree { from { clip-path: inset(24% 20% round 32px); opacity: 0.5; scale: 1.05; } }

/* ─── 2. Ouverture (D3, D6) ───
   CSS pur, peint des la premiere image : le titre fait sa mise au point, puis
   ce qui le suit dans le meme bloc. Jamais sous 0,4 d'opacite. L'amorce retire
   mvt-ouverture quand on arrive par le fondu. */
@media (prefers-reduced-motion: no-preference) {
  html.mvt-ouverture :where(:has(> h1)) > h1 {
    animation: mvt-ouverture-titre var(--mvt-entree) var(--mvt-ease) both;
  }
  html.mvt-ouverture :where(:has(> h1)) > h1 + * {
    animation: mvt-ouverture-suite var(--mvt-entree) var(--mvt-ease) 80ms both;
  }
  html.mvt-ouverture :where(:has(> h1)) > h1 + * ~ * {
    animation: mvt-ouverture-suite var(--mvt-entree) var(--mvt-ease) 160ms both;
  }
}
@keyframes mvt-ouverture-titre { from { opacity: 0.4; filter: blur(6px); } }
@keyframes mvt-ouverture-suite { from { opacity: 0.4; translate: 0 8px; } }

/* ─── 3. Defilement (D4, D10 ; renforce le 2026-11-09, « on le ressent a peine ») ───
   a) Lie au defilement, CSS seul (animation-timeline: view()) : cartes, FAQ,
      offres et visuels montent en place a mesure qu'on descend, et suivent la
      molette dans les deux sens ; le haut de l'accueil et de fondateurs se
      floute en sortant. Chaque plage finit a `entry 100%` (le bas du bloc
      entre dans la fenetre) : position toujours atteignable, meme en bas de
      page, donc rien ne reste a mi-course ; aucun script, rien a armer.
      Navigateurs sans view() : les cartes passent par b).
   b) Une fois, mene par mouvement.js : titres de section mot par mot,
      chapeaux et paragraphes de tete. Arme ce qui est SOUS la ligne de
      flottaison, revele quand le haut passe 85 % de la fenetre.
   Animations @keyframes, jamais transition : .lp-card garde sa propre
   transition de survol (lp.css). `translate`, jamais `transform`, pour la
   meme raison. */
@media screen and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    html.mvt-complet :is(.lp-card, .lp-panel, .lp-tier, .lp-pilots, .contact-card, .lp-split__visual > *):not(:is(.lp-panel, .lp-tier, .lp-pilots) *),
    html.mvt:is(.mvt-complet, .mvt-guide) :is(.lp-faq__item, .faq-item) {
      /* backwards : une fois le bloc entre, plus aucun effet ne reste pose
         (ni contexte d'empilement, ni conteneur pour un descendant fixe). */
      animation: mvt-lie-monte var(--mvt-ease) backwards;
      animation-timeline: view();
      animation-range: entry calc(var(--mvt-col, 0) * 14%) entry 100%;
    }
    html.mvt :is(.lp-faq__item, .faq-item) { --mvt-dy: 28px; }
    html.mvt-complet .lp-split__visual > * { animation-name: mvt-lie-profondeur; }
    html.mvt-complet .ap-hero__copie {
      /* forwards : en haut de page, aucun filtre pose (le flou d'un parent
         changerait le verre des boutons qu'il contient). */
      animation: mvt-lie-sortie linear forwards;
      animation-timeline: view();
      /* Commence quand plus de la moitie est sortie : les boutons, en bas du
         bloc, ne sont jamais flous tant qu'ils sont a portee. */
      animation-range: exit 55% exit 100%;
    }
    /* Images : le film s'ouvre comme un masque pendant que la video recule
       dans son cadre. Le cadre a overflow: hidden, il deviendrait la
       reference de defilement de la video : elle suit donc la frise nommee
       du cadre (--mvt-film), jamais view(). */
    html.mvt-complet .ap-film__cadre {
      view-timeline: --mvt-film;
      animation: mvt-lie-masque linear backwards;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
    html.mvt-complet .ap-film__cadre video {
      animation: mvt-lie-recul linear backwards;
      animation-timeline: --mvt-film;
      animation-range: entry 0% entry 100%;
    }
  }
}
/* Cascade par colonne, sur les rangees de plusieurs blocs seulement. */
@media (min-width: 1081px) {
  html.mvt .lp-grid--4 > :nth-child(4n + 2),
  html.mvt :is(.lp-panels, .lp-offer) > :nth-child(2) { --mvt-col: 1; }
  html.mvt .lp-grid--4 > :nth-child(4n + 3) { --mvt-col: 2; }
  html.mvt .lp-grid--4 > :nth-child(4n + 4) { --mvt-col: 3; }
}
@keyframes mvt-lie-monte {
  from { opacity: 0; translate: 0 var(--mvt-dy, 72px); }
  45% { opacity: 1; }
}
@keyframes mvt-lie-profondeur {
  from { opacity: 0.2; scale: 0.88; translate: 0 96px; clip-path: inset(10% 8% round 28px); }
  50% { opacity: 1; }
}
@keyframes mvt-lie-masque { from { clip-path: inset(18% 20% round 32px); opacity: 0.35; } }
@keyframes mvt-lie-recul { from { scale: 1.25; } }
@keyframes mvt-lie-sortie { to { opacity: 0.15; filter: blur(8px); translate: 0 -56px; } }

@media (prefers-reduced-motion: no-preference) {
  html.mvt [data-mvt-mots] .mvt-mot { display: inline-block; }
  html.mvt .mvt-arme .mvt-mot { opacity: 0; filter: blur(10px); translate: 0 0.32em; }
  html.mvt .mvt-vu .mvt-mot {
    animation: mvt-mot 760ms var(--mvt-ease) backwards;
    animation-delay: calc(min(var(--i, 0), 10) * 45ms);
  }
  html.mvt .mvt-arme:not([data-mvt-mots]) { opacity: 0; translate: 0 var(--mvt-dy, 56px); }
  html.mvt .mvt-vu:not([data-mvt-mots]) {
    animation: mvt-monte 800ms var(--mvt-ease) backwards;
    animation-delay: calc(var(--rang, 0) * 90ms);
  }
}
@keyframes mvt-mot { from { opacity: 0; filter: blur(10px); translate: 0 0.32em; } }
@keyframes mvt-monte { from { opacity: 0; translate: 0 var(--mvt-dy, 56px); } }
/* Logo de l'appel final : se pose en tournant, sans rebond. Une fois, pas
   view() : .lp-final a overflow: hidden. */
@media (prefers-reduced-motion: no-preference) {
  html.mvt .lp-final__in > img.mvt-arme { scale: 0.5; rotate: -14deg; }
  html.mvt .lp-final__in > img.mvt-vu { animation-name: mvt-logo-final; animation-duration: 900ms; }
}
@keyframes mvt-logo-final { from { opacity: 0; scale: 0.5; rotate: -14deg; translate: 0 22px; } }

@media print {
  html.mvt .mvt-arme,
  html.mvt .mvt-arme .mvt-mot { opacity: 1 !important; filter: none !important; translate: none !important; scale: none !important; rotate: none !important; }
}

/* Defilement a inertie (Lenis, mouvement.js) : regles recommandees par
   lenis.css 1.3.27. Le cadre de demo ne happe pas la molette tant que la
   page glisse. */
html.lenis,
html.lenis body { height: auto; }
html.lenis.lenis-smooth iframe { pointer-events: none; }

/* ─── 4. En-tete et fil de progression (D5, D10, D11) ─── */
html.mvt { scroll-padding-top: 80px; }
@media (prefers-reduced-motion: no-preference) {
  html.mvt .nav-glass {
    transition: translate var(--mvt-etat) var(--mvt-ease), background-color var(--mvt-etat) var(--mvt-ease),
      box-shadow var(--mvt-etat) var(--mvt-ease);
  }
  html.mvt .lp-faq__head,
  html.mvt .lp-demo__panel { transition: top var(--mvt-etat) var(--mvt-ease); }
}
html.mvt-dense .nav-glass { background-color: rgba(3, 4, 7, 0.9); box-shadow: 0 12px 30px -20px rgba(0, 0, 0, 0.7); }
html.mvt-entete-cache .nav-glass { translate: 0 -100%; box-shadow: none; }
/* Les blocs colles sous l'en-tete remontent avec lui (lp.css : 96 et 90 px). */
html.mvt-entete-cache .lp-faq__head { top: 28px; }
html.mvt-entete-cache .lp-demo__panel { top: 22px; }

/* Fil fixe en haut de la fenetre, independant de l'en-tete, couleur d'accent
   de la page (orange sur /fondateurs/). CSS pur ; absent la ou l'animation
   liee au defilement n'existe pas. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    html.mvt:not(.mvt-fondu) body::after {
      content: '';
      position: fixed;
      inset: 0 0 auto 0;
      height: 2px;
      z-index: 1000;
      pointer-events: none;
      background: var(--lp-accent, var(--violet, #7b2d8e));
      transform-origin: 0 50%;
      animation: mvt-fil linear both;
      animation-timeline: scroll(root);
    }
  }
}
@keyframes mvt-fil { from { scale: 0 1; } to { scale: 1 1; } }

/* ─── 5. Survols, souris ou trackpad seulement (D10) ───
   Boutons aimantes : mouvement.js ecrit `translate` en style inline.
   Lumiere sur les cartes : blanc a 4 % au plus, jamais sur une carte de
   signal (.lp-signal), jamais d'ambre (« infere »). */
html.mvt .mvt-lampe { position: relative; }
html.mvt .mvt-lampe::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.04), transparent 70%);
  opacity: 0;
  transition: opacity var(--mvt-survol) var(--mvt-ease);
}
html.mvt .mvt-lampe:hover::after { opacity: 1; }

/* ─── 6. FAQ qui s'ouvrent en douceur (D5) ───
   CSS seul : la recherche dans la page ouvre toujours la reponse. Sans
   interpolate-size, l'ouverture reste instantanee. */
@media (prefers-reduced-motion: no-preference) {
  @supports selector(::details-content) {
    html.mvt :is(.lp-faq__item, .faq-item) { interpolate-size: allow-keywords; }
    html.mvt :is(.lp-faq__item, .faq-item)::details-content {
      block-size: 0;
      overflow-y: clip;
      transition: block-size var(--mvt-etat) var(--mvt-ease), content-visibility var(--mvt-etat) allow-discrete;
    }
    html.mvt :is(.lp-faq__item, .faq-item)[open]::details-content { block-size: auto; }
  }
}
