/* ==========================================================================
   Entropy — Mouvement
   Principe : lent, amorti, jamais de rebond. Le mouvement doit se remarquer
   après coup, pas pendant.
   ========================================================================== */

/* --- Apparition au défilement ------------------------------------------ */

[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition:
    opacity var(--dur-reveal) var(--ease),
    transform var(--dur-reveal) var(--ease),
    clip-path var(--dur-reveal) var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Variantes */
[data-reveal="fade"]   { transform: none; }
[data-reveal="left"]   { transform: translate3d(-28px, 0, 0); }
[data-reveal="right"]  { transform: translate3d(28px, 0, 0); }
[data-reveal="scale"]  { transform: scale(0.96); }
[data-reveal="scale"].is-in { transform: scale(1); }

/* Volet qui se lève sur les visuels.
   Le clip porte sur l'image, jamais sur l'élément observé : un clip-path sur
   la cible d'un IntersectionObserver ramène son ratio d'intersection à 0,
   et la révélation ne se déclencherait donc jamais. */
[data-reveal="curtain"] {
  opacity: 1;
  transform: none;
}

[data-reveal="curtain"] > img,
[data-reveal="curtain"] > picture > img {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--dur-reveal) var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal="curtain"].is-in > img,
[data-reveal="curtain"].is-in > picture > img { clip-path: inset(0 0 0 0); }

/* --- Titre découpé ligne par ligne ------------------------------------- */

.split-line {
  display: block;
  overflow: hidden;
}

.split-line > span {
  display: block;
  transform: translate3d(0, 110%, 0);
  transition: transform 1.25s var(--ease);
  transition-delay: calc(var(--line-i, 0) * 105ms);
  will-change: transform;
}

.is-in .split-line > span,
.split-line.is-in > span { transform: translate3d(0, 0, 0); }

/* --- Visuel du héros : zoom d'ouverture -------------------------------- */

.hero__media img {
  transform: scale(1.14) translateY(0);
  transition: transform 1.8s var(--ease);
}

.hero__media.is-in img { transform: scale(1) translateY(var(--parallax, 0px)); }

/* --- Effets de survol --------------------------------------------------- */

.magnetic { will-change: transform; }

.hover-lift { transition: transform var(--dur) var(--ease); }
.hover-lift:hover { transform: translateY(-4px); }

/* --- Compteurs ---------------------------------------------------------- */

.count { font-variant-numeric: tabular-nums; }

/* --- Keyframes ---------------------------------------------------------- */

@keyframes pulse-ring {
  0%   { transform: scale(0.7); opacity: 0.9; }
  70%  { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

@keyframes nudge-down {
  0%, 100% { transform: translateY(0); opacity: 0.55; }
  50%      { transform: translateY(4px); opacity: 1; }
}

@keyframes fade-up-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

.grain {
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: 0.028;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- Chargement des images --------------------------------------------- */

img[loading="lazy"] {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease);
}

img[loading="lazy"].is-loaded,
.no-js img[loading="lazy"] { opacity: 1; }

/* --- Respect des préférences système ----------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  [data-reveal],
  [data-reveal="curtain"] > img,
  [data-reveal="curtain"] > picture > img {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  .split-line > span { transform: none !important; }
  .hero__media img { transform: none !important; }
  img[loading="lazy"] { opacity: 1; }
}
