/*
 * Animations d'entrée — styles partagés pour tous les blocs qui les
 * proposent (Image AV, Texte avancé, Texte logo, Vidéo YouTube, Vidéo Cloud).
 * Voir assets/js/entrance-animations.js pour le mécanisme de déclenchement.
 *
 * Reprend exactement le mécanisme de la Galerie mosaïque (src/blocks/gallery/style.scss) :
 * classes additives (`av-anim-ready` posée par le script, puis `is-in` à la
 * révélation), jamais de valeur d'attribut échangée — ça évite tout conflit
 * de spécificité entre l'état caché et l'état affiché.
 *
 * `av-anim-ready` n'est ajoutée par le script qu'au moment opportun ; sans JS
 * ou avec `prefers-reduced-motion`, elle n'apparaît jamais et le contenu
 * reste visible normalement (amélioration progressive).
 */

.av-anim-ready {
	opacity: 0;
	transition:
		opacity var(--av-anim-duration, 600ms) ease,
		transform var(--av-anim-duration, 600ms) cubic-bezier(0.22, 0.61, 0.36, 1),
		filter var(--av-anim-duration, 600ms) ease;
	will-change: opacity, transform;
}

.av-anim-piece {
	display: inline-block;
}

/* Regroupe les lettres d'un même mot (effets chars-*) : empêche le
   navigateur de couper la ligne au milieu d'un mot, chaque lettre étant
   sinon une boîte indépendante comme n'importe quel point de coupure. */
.av-anim-word {
	display: inline-block;
	white-space: nowrap;
}

/* Effets appliqués à l'élément entier (image, vidéo, bloc de texte complet). */
[data-anim="slide-left"].av-anim-ready  { transform: translateX(-32px); }
[data-anim="slide-right"].av-anim-ready { transform: translateX(32px); }
[data-anim="slide-up"].av-anim-ready    { transform: translateY(32px); }
[data-anim="slide-down"].av-anim-ready  { transform: translateY(-32px); }
[data-anim="zoom-in"].av-anim-ready     { transform: scale(0.85); }
[data-anim="zoom-out"].av-anim-ready    { transform: scale(1.18); }
[data-anim="flip-x"].av-anim-ready      { transform: perspective(700px) rotateX(-80deg); }
[data-anim="flip-y"].av-anim-ready      { transform: perspective(700px) rotateY(-80deg); }
[data-anim="blur"].av-anim-ready        { filter: blur(10px); }
[data-anim="bounce"].av-anim-ready      { transform: scale(0.4); }

/* Effets texte : chaque fragment (lettre/mot) s'anime, pas le conteneur
   entier. La classe est posée directement sur le fragment par le script
   (pas de sélecteur descendant), pour rester à la même spécificité que la
   règle de révélation ci-dessous. */
.av-anim-rise.av-anim-ready    { transform: translateY(10px); }
.av-anim-rise-lg.av-anim-ready { transform: translateY(14px); }

/* Révélation. Doit être déclarée APRÈS les règles ci-dessus : même
   spécificité qu'elles (un sélecteur + une classe), l'ordre de déclaration
   tranche — exactement comme `.is-in` dans la Galerie mosaïque. */
.av-anim-ready.is-in {
	opacity: 1;
	transform: none;
	filter: none;
}
[data-anim="bounce"].av-anim-ready.is-in {
	transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}

@media (prefers-reduced-motion: reduce) {
	.av-anim-ready,
	.av-anim-piece {
		opacity: 1 !important;
		transform: none !important;
		filter: none !important;
		transition: none !important;
	}
}
