/* ─────────────────────────────────────────────────────────
 * Animations · home (index.html)
 * Polish invisible · CSS only · pas de dépendance
 * Activable / désactivable via prefers-reduced-motion
 * ───────────────────────────────────────────────────────── */

:root {
  --anim-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --anim-duration: 1100ms;
  --anim-stagger: 140ms;
}

/* ── Reveal au scroll ──────────────────────────────────── */
/* Élément invisible jusqu'à ce que IntersectionObserver
   ajoute .is-visible. */
.reveal,
.reveal-stagger {
  opacity: 0;
  transition: opacity var(--anim-duration) var(--anim-ease);
  will-change: opacity;
}

.reveal.is-visible,
.reveal-stagger.is-visible {
  opacity: 1;
  will-change: auto;
}

/* Stagger · index séquentiel posé inline via style="--reveal-i: 0" */
.reveal-stagger {
  transition-delay: calc(var(--reveal-i, 0) * var(--anim-stagger));
}

/* Gallery shoots · fade-only · pas de translation
   (les cellules sont collées, le slide vertical fait moche)
   ET sans stagger · toutes les images apparaissent ensemble. */
.shoots-gallery .reveal-stagger,
.mood-band .reveal-stagger {
  transform: none;
  transition-delay: 0ms;
}
.shoots-gallery .reveal-stagger.is-visible,
.mood-band .reveal-stagger.is-visible {
  transform: none;
}

/* Service blocks · fade plus long et translation plus discrète
   pour un effet doux. */
.services-row .reveal-stagger {
  transform: translateY(12px);
  transition-duration: 1600ms;
}
.services-row .reveal-stagger.is-visible {
  transform: translateY(0);
}

/* No-JS fallback · si reveal.js ne charge pas, le contenu
   reste visible. Surchargé par .reveal {opacity:0} si JS actif. */
.no-js .reveal,
.no-js .reveal-stagger {
  opacity: 1;
  transform: none;
}

/* ── Hero · entry au load ──────────────────────────────── */
/* On n'utilise pas l'observer pour le hero (above the fold).
   Animation déclenchée au chargement via animation-delay. */

.hero-editorial .hero-slot img {
  animation: hero-img-in 1600ms var(--anim-ease) both;
}

.hero-editorial .hero-overlay .overline {
  /* opacity only · l'élément a un transform inline qu'on
     ne doit surtout pas écraser. */
  animation: hero-fade-in 1000ms var(--anim-ease) 150ms both;
}

.hero-editorial .hero-overlay h1 {
  animation: hero-title-in 1100ms var(--anim-ease) 250ms both;
}

.hero-editorial .hero-corner {
  animation: hero-fade-in 800ms var(--anim-ease) 700ms both;
}

@keyframes hero-img-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes hero-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes hero-title-in {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Hero · ken burns continu ──────────────────────────── */
/* Très lent · imperceptible · donne du souffle à l'image. */
.hero-editorial .hero-slot img {
  animation:
    hero-img-in 1600ms var(--anim-ease) both,
    ken-burns 16s ease-in-out 1600ms infinite alternate;
  will-change: transform;
}

@keyframes ken-burns {
  from { transform: scale(1); }
  to   { transform: scale(1.04); }
}

/* ── Header · allégé au scroll ─────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg);
  transition:
    background-color 300ms var(--anim-ease),
    border-color 300ms var(--anim-ease),
    backdrop-filter 300ms var(--anim-ease);
}

.site-header.is-scrolled {
  background: rgba(249, 245, 239, 0.85);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

/* ── Hover · gallery slots ─────────────────────────────── */
.shoots-gallery .gallery-slot img {
  transition: transform 600ms var(--anim-ease);
}

.shoots-gallery .gallery-slot:hover img {
  transform: scale(1.03);
}

/* ── Override · slots de grille hairline ───────────────── */
/* .shoots-gallery et .mood-band ont un background gris (var(--rule))
   pour créer les filets de séparation 1px. Si on fade les slots eux-mêmes
   on découvre ce fond gris derrière. Donc on garde les wrappers
   opaques (cream) et on fade l'image à l'intérieur. */

.shoots-gallery .gallery-slot.reveal-stagger,
.mood-band .mood-slot.reveal-stagger,
.shoots-gallery .gallery-caption.reveal-stagger {
  opacity: 1;
  transform: none;
  transition: none;
}

.shoots-gallery .gallery-slot.reveal-stagger img,
.mood-band .mood-slot.reveal-stagger img {
  opacity: 0;
  transition:
    opacity var(--anim-duration) var(--anim-ease),
    transform 600ms var(--anim-ease);
  transition-delay: calc(var(--reveal-i, 0) * var(--anim-stagger));
}

.shoots-gallery .gallery-slot.reveal-stagger.is-visible img,
.mood-band .mood-slot.reveal-stagger.is-visible img {
  opacity: 1;
}

/* Caption · on fade son contenu, pas le wrapper. */
.shoots-gallery .gallery-caption.reveal-stagger > * {
  opacity: 0;
  transition: opacity var(--anim-duration) var(--anim-ease);
  transition-delay: calc(var(--reveal-i, 0) * var(--anim-stagger));
}

.shoots-gallery .gallery-caption.reveal-stagger.is-visible > * {
  opacity: 1;
}

/* ── Reduced motion · tout désactivé ───────────────────── */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal-stagger {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  .hero-editorial .hero-slot img,
  .hero-editorial .hero-overlay .overline,
  .hero-editorial .hero-overlay h1,
  .hero-editorial .hero-corner {
    animation: none !important;
  }

  .site-header {
    transition: none !important;
  }

  .shoots-gallery .gallery-slot img {
    transition: none !important;
  }

  .shoots-gallery .gallery-slot:hover img {
    transform: none !important;
  }
}
