/* ==========================================================================
   OPTIMIZ BTP — Motion

   Restitue la sensation relevée sur la version actuelle du site SANS
   importer sa pile d'animation (GSAP + ScrollTrigger, ~70 Ko gzip).
   Les révélations tiennent en quelques règles CSS + un IntersectionObserver.

   Contrat mesuré : 200ms micro-interaction · 300ms état · 500ms révélation
                    easing cubic-bezier(.4, 0, .2, 1)
                    translation 24px · cascade 80ms
   ========================================================================== */

/* ---- Révélation au défilement -------------------------------------------
   L'élément est posé par le HTML avec [data-reveal] ; le JS ajoute
   [data-reveal="visible"] quand il entre dans le viewport.

   ⚠️ Le contenu doit rester lisible si le JS échoue : c'est pourquoi
   l'état masqué n'est appliqué QUE lorsque la classe est posée par JS
   sur <html> (voir main.js). Sans JS, rien n'est jamais invisible.      */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  transition: opacity var(--motion-slow) var(--ease),
              transform var(--motion-slow) var(--ease);
  will-change: opacity, transform;
}

.js [data-reveal="visible"] {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Cascade entre éléments frères — le rang est posé en variable par le JS. */
.js [data-reveal][style*="--reveal-index"] {
  transition-delay: calc(var(--reveal-index, 0) * var(--reveal-stagger));
}

/* ---- Barre de progression ------------------------------------------------ */

.progress {
  height: 2px;
  background: var(--line);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  width: 0;
  background: var(--accent);
  border-radius: inherit;
  transition: width var(--motion-slow) var(--ease);
}

/* ---- Décor 3D -----------------------------------------------------------
   Le poster statique est le rendu PAR DÉFAUT, présent dans le HTML.
   Le canvas ne le remplace que si toutes les conditions sont réunies
   (desktop, mouvement autorisé, connexion correcte) — voir figure-3d.js.
   Aucune information ne doit exister uniquement dans la scène.          */

.figure-3d {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.figure-3d__poster {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--motion-slow) var(--ease);
}

.figure-3d__canvas {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--motion-slow) var(--ease);
}

.figure-3d[data-figure="ready"] .figure-3d__canvas { opacity: 1; }
.figure-3d[data-figure="ready"] .figure-3d__poster { opacity: 0; }

/* ==========================================================================
   Mouvement réduit — neutralisation totale
   Les durées passent déjà à 0ms via les tokens ; on désactive en plus
   toute transformation résiduelle et le poster reste affiché.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .figure-3d__canvas { display: none; }
  .figure-3d__poster { opacity: 1; }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;   /* !important requis : on écrase
                                               des animations inconnues */
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
