/* ==========================================================================
   animations.css
   Apparitions au défilement. Fonctionne avec animations.js, qui pose la
   classe .est-visible sur chaque élément quand il entre dans l'écran.

   PRINCIPE DE SÉCURITÉ — l'état masqué n'est JAMAIS appliqué par cette
   feuille seule. Il est conditionné à la classe .anim-actif, que le
   JavaScript pose sur <html> à son démarrage. Si le fichier JS ne se
   charge pas, ne s'exécute pas, ou plante, .anim-actif n'existe pas :
   rien n'est masqué et le site s'affiche normalement. Sans cette
   précaution, un site client entier resterait invisible sur une erreur
   de script — le pire défaut possible sur une vitrine.

   À charger après style.css dans le gabarit.
   ========================================================================== */

/* --------------------------------------------------------- États de base --- */

.anim-actif [data-anim] {
  opacity: 0;
  will-change: opacity, transform;
  transition:
    opacity .7s cubic-bezier(.22, .61, .36, 1),
    transform .7s cubic-bezier(.22, .61, .36, 1);
}

.anim-actif [data-anim="monte"]          { transform: translateY(28px); }
.anim-actif [data-anim="glisse-droite"]  { transform: translateX(-32px); }
.anim-actif [data-anim="glisse-gauche"]  { transform: translateX(32px); }
.anim-actif [data-anim="zoom"]           { transform: scale(.94); }
.anim-actif [data-anim="fondu"]          { transform: none; }

/* Arrivée : une seule règle remet tout à zéro, quel que soit le type. */
.anim-actif [data-anim].est-visible {
  opacity: 1;
  transform: none;
}

/* Une fois l'animation jouée, on libère l'indice de compositing : le
   laisser en permanence sur des dizaines d'éléments consomme de la
   mémoire graphique pour rien, surtout sur un téléphone d'entrée de
   gamme. */
.anim-actif [data-anim].est-visible {
  will-change: auto;
}

/* ------------------------------------------------------------- Décalages --- */
/* Les éléments d'un même groupe n'arrivent pas ensemble mais en cascade.
   Le décalage est posé par une classe plutôt qu'en style inline, pour
   rester lisible dans le HTML généré. 90 ms : assez pour percevoir
   l'enchaînement, assez court pour ne pas faire attendre. */

.anim-actif [data-anim-delai="1"] { transition-delay: .09s; }
.anim-actif [data-anim-delai="2"] { transition-delay: .18s; }
.anim-actif [data-anim-delai="3"] { transition-delay: .27s; }
.anim-actif [data-anim-delai="4"] { transition-delay: .36s; }
.anim-actif [data-anim-delai="5"] { transition-delay: .45s; }
.anim-actif [data-anim-delai="6"] { transition-delay: .54s; }

/* ------------------------------------------------------- Cas particuliers --- */

/* La bannière est déjà visible au chargement : ses éléments ne doivent
   pas attendre un défilement qui n'aura pas lieu. Le script les révèle
   immédiatement, le décalage suffit à créer l'effet d'entrée. */
.anim-actif .bn-voile [data-anim] {
  transition-duration: .8s;
}

/* Bloc présentation : les deux colonnes arrivent ensemble (le script
   observe la section entière, voir data-anim-groupe), mais l'image est
   très légèrement décalée. Un départ strictement simultané donne un
   effet de rideau qui s'ouvre ; 120 ms d'écart suffisent à faire lire le
   titre en premier, ce qui est l'ordre de lecture voulu. */
.anim-actif .pr-colonne-image { transition-delay: .12s; }

/* Les cartes produits arrivent en cascade horizontale. Le nth-child
   évite d'avoir à poser un délai différent sur chaque carte depuis le
   générateur, dont le nombre varie d'un client à l'autre. */
.anim-actif .bv-produit:nth-child(1) { transition-delay: 0s; }
.anim-actif .bv-produit:nth-child(2) { transition-delay: .1s; }
.anim-actif .bv-produit:nth-child(3) { transition-delay: .2s; }
.anim-actif .bv-produit:nth-child(4) { transition-delay: .3s; }
.anim-actif .bv-produit:nth-child(5) { transition-delay: .4s; }
.anim-actif .bv-produit:nth-child(6) { transition-delay: .5s; }

/* Quand le carrousel mobile prend le relais, Swiper déplace les cartes
   lui-même. Une transition d'apparition en plus du glissement produit un
   effet brouillon, et une carte encore masquée dans un slide hors écran
   n'apparaîtrait jamais. On neutralise entièrement l'animation à
   l'intérieur du carrousel. */
.anim-actif .bv-carrousel [data-anim],
.anim-actif .swiper-slide[data-anim] {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* --------------------------------------------- Respect des préférences --- */
/* Un visiteur ayant demandé la réduction des animations dans son système
   ne doit rien voir bouger. On ne se contente pas d'accélérer : on
   supprime, et surtout on garantit que tout est visible. */

@media (prefers-reduced-motion: reduce) {
  .anim-actif [data-anim] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto;
  }
}

/* Impression : rien ne doit jamais manquer sur une feuille imprimée. */
@media print {
  .anim-actif [data-anim] {
    opacity: 1 !important;
    transform: none !important;
  }
}
