/* =========================================================================
   Apparitions au défilement
   -------------------------------------------------------------------------
   Trois traitements, pas un seul répété partout :

   1. « montée »  — le corps de texte et les cartes montent de 22 px en
                    perdant un flou léger ;
   2. « net »     — les titres arrivent franchement flous et se fixent, sans
                    presque bouger : c'est la mise au point ;
   3. « échelle » — les visuels se posent en revenant d'un très léger
                    agrandissement, sans flou (moins coûteux à composer).

   L'état masqué n'est appliqué QUE si le script inline du <head> a posé
   data-anim="oui" sur <html>. Sans JavaScript, sans IntersectionObserver ou
   en mouvement réduit, la page reste entièrement lisible d'emblée.

   Les listes sont enveloppées dans :where() et non :is() : :is() prend la
   spécificité de son argument le plus fort, ce qui ferait gagner le masquage
   sur la révélation. :where() vaut zéro, [data-vu] l'emporte toujours.

   ⚠ La liste de sélecteurs ci-dessous est reprise à l'identique dans
   js/apparitions.js. Les deux doivent rester synchronisées.
   ========================================================================= */

@media (prefers-reduced-motion: no-preference) {

  /* ---- 1. Montée : réglage par défaut --------------------------------- */
  [data-anim='oui'] :where(
    .section-entete > *,
    .section-suite,
    .confiance > *,
    .grille > *,
    .bento > *,
    .rail__element,
    .bandeau,
    .duo__texte > *,
    .temoin__carte > *,
    .equipe__membre,
    .appel__contenu > *,
    .prestations > .presta,
    .etape,
    .materiel__item,
    .filtres,
    .projet,
    .etude__fiche > *,
    .avant-apres__legende,
    .formulaire,
    .visite__etape,
    .recherche > *,
    .faq__element,
    .pratique__item,
    .legal,
    .pied__haut > *
  ) {
    opacity: 0;
    translate: 0 22px;
    filter: blur(6px);
    transition:
      opacity 800ms cubic-bezier(.16, .84, .28, 1),
      translate 800ms cubic-bezier(.16, .84, .28, 1),
      filter 800ms cubic-bezier(.16, .84, .28, 1);
    transition-delay: var(--retard, 0ms);
  }

  /* ---- 2. Net : la mise au point des titres ---------------------------- */
  [data-anim='oui'] :where(
    .hero-page__titre,
    .section-titre,
    .confiance__titre,
    .appel__titre,
    .recherche__titre,
    .presta__titre,
    .formulaire__titre,
    .pratique__titre,
    .temoin__intitule
  ) {
    opacity: 0;
    translate: 0 10px;
    filter: blur(14px);
    transition:
      opacity 1000ms cubic-bezier(.16, .84, .28, 1),
      translate 1000ms cubic-bezier(.16, .84, .28, 1),
      filter 1000ms cubic-bezier(.16, .84, .28, 1);
    transition-delay: var(--retard, 0ms);
  }

  /* ---- 3. Échelle : les visuels --------------------------------------- */
  [data-anim='oui'] :where(
    .duo__images .visuel,
    .temoin__visuel,
    .avant-apres,
    .hero-page__badge
  ) {
    opacity: 0;
    translate: none;
    scale: 1.035;
    filter: none;
    transition:
      opacity 900ms cubic-bezier(.16, .84, .28, 1),
      scale 900ms cubic-bezier(.16, .84, .28, 1);
    transition-delay: var(--retard, 0ms);
  }

  /* ---- État révélé, commun aux trois ---------------------------------- */
  [data-anim='oui'] [data-vu='true'] {
    opacity: 1;
    translate: none;
    scale: none;
    filter: none;
  }

  /* Une fois posé, on rend la main au navigateur : plus aucune trace de
     transition ne reste sur l'élément (utile pour les survols des cartes). */
  [data-anim='oui'] [data-vu='pose'] {
    opacity: 1;
    translate: none;
    scale: none;
    filter: none;
    transition: none;
  }
}
