/* ============================================================
   hero-scroll-expand.css
   Wrapper qui ouvre un trait fin en média plein écran au scroll.

   Phases pilotées par --expand-progress (0 → 1) défini par le JS :
   - 0.0 → 0.30 : un trait fin (3px) qui s'élargit horizontalement
                  de 0vw à 40vw (la "fente" se trace)
   - 0.30 → 0.55 : la fente s'ouvre verticalement pour révéler
                   un cadre 16:9 de 40vw
   - 0.55 → 1.0 : le cadre grandit en plein écran

   À utiliser avec hero-scroll-expand.js
   ============================================================ */

[data-scroll-expand] {
  position: relative;
  width: 100%;
  height: var(--scroll-expand-height, 300vh);
}

[data-scroll-expand] [data-scroll-expand-stage] {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Isole les recalculs CSS du hero du reste du document — sans cela,
     les changements width/height du media déclenchent un layout global à
     chaque frame de scroll (perceptible comme micro-saccades sur la home,
     vs scroll fluide sur les pages internes sans hero). */
  contain: layout paint style;
}

/* ---------------------------------------------------------------
   Le média central — animé en 3 phases via clip-path (zéro layout, pur GPU)
   ---------------------------------------------------------------
   Refactor du 2026-05-03 : passage de width/height calc() → clip-path inset().
   Raison : width/height déclenchent un layout à chaque frame de scroll
   (~16ms de coût), ce qui rendait le scroll de la home "mou" comparé aux
   pages internes sans hero. clip-path + filter sont composités GPU,
   coût frame négligeable.

   Effet visuel (phase 2) : on dévoile une fenêtre sur la vidéo (effet
   "lucarne qui s'élargit") plutôt qu'un zoom-out depuis la fente. Plus
   immersif, et techniquement obligatoire pour la perf.
   --------------------------------------------------------------- */
[data-scroll-expand] [data-scroll-expand-media] {
  position: absolute;
  inset: 0;
  /* Le media occupe toujours toute la stage (100vw × 100vh) — c'est le
     clip-path qui fait varier la zone visible. Pas de width/height animés. */
  width: 100%;
  height: 100%;
  overflow: hidden;

  /* Largeur finale en phase 3 : 40vw desktop, override mobile via @media */
  --w-base: 40vw;
  --h-base: calc(var(--w-base) * 9 / 16); /* 16:9 de la largeur de base */

  /* Progressions par phase (factorisées pour lisibilité) */
  --p1: clamp(0, var(--expand-progress, 0) / 0.30, 1);
  --p2: clamp(0, (var(--expand-progress, 0) - 0.30) / 0.25, 1);
  --p3: clamp(0, (var(--expand-progress, 0) - 0.55) / 0.45, 1);

  /* Inset horizontal : 50vw (rien de visible) → (100vw - 40vw)/2 = 30vw → 0 */
  --inset-x: calc(
    50vw
    - (50vw - (100vw - var(--w-base)) / 2) * var(--p1)
    - ((100vw - var(--w-base)) / 2) * var(--p3)
  );

  /* Inset vertical : (100vh - 3px)/2 (trait fin) → (100vh - h-base)/2 → 0 */
  --inset-y: calc(
    (100vh - 3px) / 2
    - ((100vh - 3px) / 2 - (100vh - var(--h-base)) / 2) * var(--p2)
    - ((100vh - var(--h-base)) / 2) * var(--p3)
  );

  /* Coins : 1px en mode trait, 12px en encart, 0 plein écran */
  --radius: calc(1px + 11px * var(--p2) - 12px * var(--p3));

  clip-path: inset(var(--inset-y) var(--inset-x) round var(--radius));

  /* GPU compositing : clip-path est composited, on isole le hero dans son
     propre layer pour ne pas polluer le main thread. */
  will-change: clip-path;
  transform: translateZ(0);
  backface-visibility: hidden;
  contain: layout paint style;
}

/* Le contenu interne (img, video) — toujours en pleine taille (100vw × 100vh).
   La portion visible est définie par le clip-path du parent. */
[data-scroll-expand] [data-scroll-expand-media] > * {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: clamp(0, (var(--expand-progress, 0) - 0.30) / 0.15, 1);
  transition: none;
  will-change: opacity;
}

/* En phase 1 (trait pur) on affiche un dégradé lumineux comme "trait" */
[data-scroll-expand] [data-scroll-expand-media]::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(var(--expand-glow-rgb, 124, 252, 159), 0.95) 50%,
    transparent 100%
  );
  /* Le trait disparaît dès que le média réel se révèle */
  opacity: clamp(0, 1 - var(--expand-progress, 0) / 0.30, 1);
  pointer-events: none;
  z-index: 1;
}

/* ---------------------------------------------------------------
   Texte overlay (titre + sous-titre) — fade out progressif
   --------------------------------------------------------------- */
[data-scroll-expand] [data-scroll-expand-overlay] {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  z-index: 2;
  padding: 1.5rem;
  pointer-events: none;
  /* Le texte reste visible pendant les phases 1 et 2, puis fade en phase 3 */
  opacity: clamp(0, 1 - (var(--expand-progress, 0) - 0.55) / 0.30, 1);
  transform: translateY(calc(var(--expand-progress, 0) * -30px));
}

/* Indicateur "scroll" en bas — fade dès la phase 1 */
[data-scroll-expand] [data-scroll-expand-hint] {
  position: absolute;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: calc(1 - var(--expand-progress, 0) * 2);
  z-index: 3;
  pointer-events: none;
  animation: scroll-expand-bounce 2s ease-in-out infinite;
}

@keyframes scroll-expand-bounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(-8px); }
}

/* ---------------------------------------------------------------
   Mobile : largeur de base élargie (75vw au lieu de 40vw)
   pour que le cadre reste lisible. Toute la mécanique clip-path
   suit automatiquement via la variable --w-base.
   --------------------------------------------------------------- */
@media (max-width: 768px) {
  [data-scroll-expand] [data-scroll-expand-media] {
    --w-base: 75vw;
  }
}

/* ---------------------------------------------------------------
   Reduced motion : on saute directement à l'état final
   --------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  [data-scroll-expand] [data-scroll-expand-media] {
    clip-path: none;
  }
  [data-scroll-expand] [data-scroll-expand-media] > * {
    opacity: 1;
  }
  [data-scroll-expand] [data-scroll-expand-media]::before {
    display: none;
  }
  [data-scroll-expand] [data-scroll-expand-overlay],
  [data-scroll-expand] [data-scroll-expand-hint] {
    opacity: 1;
    animation: none;
  }
}
