/* =========================================================================
   MOTION — animations pilotées par le CSS natif (scroll-driven en priorité)
   Dépend de tokens.css. motion.js n'est nécessaire que pour les effets
   marqués [JS] dans le catalogue.
   Règle : tout doit rester lisible et utilisable si les animations sont coupées.
   ========================================================================= */

/* --- 0. Garde-fou accessibilité — toujours en premier ------------------ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal], [data-reveal-stagger] > * { opacity: 1 !important; transform: none !important; }
}

/* =========================================================================
   1. RÉVÉLATION AU SCROLL — natif, zéro JS, zéro coût
   <div data-reveal>          apparition simple
   <div data-reveal="left">   depuis la gauche  (right | up | scale | blur)
   <ul data-reveal-stagger>   enfants en cascade
   ========================================================================= */
@supports (animation-timeline: view()) {
  [data-reveal] {
    animation: m-reveal-up linear both;
    animation-timeline: view();
    animation-range: entry 5% cover 30%;
  }
  [data-reveal="left"]  { animation-name: m-reveal-left; }
  [data-reveal="right"] { animation-name: m-reveal-right; }
  [data-reveal="scale"] { animation-name: m-reveal-scale; }
  [data-reveal="blur"]  { animation-name: m-reveal-blur; }

  [data-reveal-stagger] > * {
    animation: m-reveal-up linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 25%;
  }
}
/* Repli navigateurs sans scroll-driven animations : motion.js ajoute .is-visible */
@supports not (animation-timeline: view()) {
  [data-reveal], [data-reveal-stagger] > * {
    opacity: 0;
    translate: 0 24px;
    transition: opacity var(--dur-slow) var(--ease-out),
                translate var(--dur-slow) var(--ease-out);
    transition-delay: calc(var(--i, 0) * 80ms);
  }
  [data-reveal="left"]  { translate: -32px 0; }
  [data-reveal="right"] { translate: 32px 0; }
  [data-reveal="scale"] { translate: 0; scale: .94; }
  .is-visible, .is-visible > * { opacity: 1 !important; translate: 0 !important; scale: 1 !important; }
}

@keyframes m-reveal-up    { from { opacity: 0; translate: 0 28px; } to { opacity: 1; translate: 0 0; } }
@keyframes m-reveal-left  { from { opacity: 0; translate: -36px 0; } to { opacity: 1; translate: 0 0; } }
@keyframes m-reveal-right { from { opacity: 0; translate: 36px 0; }  to { opacity: 1; translate: 0 0; } }
@keyframes m-reveal-scale { from { opacity: 0; scale: .92; }         to { opacity: 1; scale: 1; } }
@keyframes m-reveal-blur  { from { opacity: 0; filter: blur(10px); } to { opacity: 1; filter: blur(0); } }

/* =========================================================================
   2. BARRE DE PROGRESSION DE LECTURE — natif
   <div class="m-progress"></div> en début de <body>
   ========================================================================= */
.m-progress {
  position: fixed; inset-block-start: 0; inset-inline: 0;
  height: 3px; background: var(--brand); transform-origin: 0 50%;
  z-index: var(--z-toast); scale: 0 1;
}
@supports (animation-timeline: scroll()) {
  .m-progress { animation: m-progress linear both; animation-timeline: scroll(root block); }
}
@keyframes m-progress { to { scale: 1 1; } }

/* =========================================================================
   3. PARALLAXE — natif, sur l'image d'un conteneur
   <div class="m-parallax"><img src="..."></div>
   ========================================================================= */
.m-parallax { overflow: hidden; }
.m-parallax > * { will-change: transform; }
@supports (animation-timeline: view()) {
  .m-parallax > * {
    animation: m-parallax linear both;
    animation-timeline: view();
    animation-range: cover;
  }
}
@keyframes m-parallax {
  from { translate: 0 calc(var(--m-parallax-depth, 12) * -1%); }
  to   { translate: 0 calc(var(--m-parallax-depth, 12) * 1%); }
}

/* =========================================================================
   4. SECTION ÉPINGLÉE / CARTES EMPILÉES
   <section class="m-stack"><article class="m-stack__card">…</article>…</section>
   ========================================================================= */
.m-stack__card {
  position: sticky;
  top: calc(var(--header-h) + var(--space-m));
  /* décalage progressif à écrire dans le HTML : style="--i:0" --i:1 … */
  margin-block-end: var(--space-xl);
  translate: 0 calc(var(--i, 0) * 12px);
}
@supports (animation-timeline: view()) {
  .m-stack__card {
    animation: m-stack-shrink linear both;
    animation-timeline: view();
    animation-range: exit-crossing 0% exit 100%;
  }
}
@keyframes m-stack-shrink { to { scale: .94; opacity: .55; filter: blur(2px); } }

/* =========================================================================
   5. TITRES — révélation par masque et par mot  [JS pour data-split]
   <h1 data-split>…</h1>  → motion.js découpe en mots
   ========================================================================= */
.m-mask { display: block; overflow: hidden; }
.m-mask > span {
  display: block;
  animation: m-mask-in var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 90ms);
}
@keyframes m-mask-in { from { translate: 0 110%; rotate: 2deg; } to { translate: 0 0; rotate: 0; } }

[data-split] .m-word {
  display: inline-block;
  animation: m-word-in var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes m-word-in { from { opacity: 0; translate: 0 .5em; filter: blur(4px); } to { opacity: 1; translate: 0 0; filter: blur(0); } }

/* Texte qui se colore au défilement (surlignage progressif) — natif */
.m-highlight {
  background-image: linear-gradient(to right, var(--brand), var(--brand));
  background-repeat: no-repeat; background-size: 0% 100%;
}
@supports (animation-timeline: view()) {
  .m-highlight { animation: m-highlight linear both; animation-timeline: view(); animation-range: entry 40% cover 60%; }
}
@keyframes m-highlight { to { background-size: 100% 100%; } }

/* =========================================================================
   6. SURVOL — micro-interactions
   ========================================================================= */
.m-underline { position: relative; text-decoration: none; }
.m-underline::after {
  content: ""; position: absolute; inset-inline: 0; inset-block-end: -2px; height: 1px;
  background: currentColor; scale: 0 1; transform-origin: right;
  transition: scale var(--dur-base) var(--ease-out);
}
.m-underline:hover::after { scale: 1 1; transform-origin: left; }

.m-lift { transition: translate var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }
.m-lift:hover { translate: 0 -6px; box-shadow: var(--shadow-l); }

/* [JS] halo qui suit le curseur — motion.js alimente --mx / --my */
.m-spotlight { position: relative; isolation: isolate; overflow: hidden; }
.m-spotlight::before {
  content: ""; position: absolute; inset: -1px; z-index: -1; opacity: 0;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%),
              oklch(from var(--brand) l c h / .18), transparent 65%);
  transition: opacity var(--dur-base) var(--ease-out);
}
.m-spotlight:hover::before { opacity: 1; }

/* [JS] aimantation du curseur — data-magnetic */
[data-magnetic] { transition: translate var(--dur-base) var(--ease-spring); will-change: transform; }
/* [JS] inclinaison 3D — data-tilt */
[data-tilt] { transform-style: preserve-3d; transition: transform var(--dur-base) var(--ease-out); }
[data-tilt] > * { transform: translateZ(20px); }

/* =========================================================================
   7. BOUCLES — bandeau défilant, respiration, curseur clignotant
   ========================================================================= */
.m-marquee { display: flex; overflow: hidden; gap: var(--space-l); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.m-marquee > * { display: flex; gap: var(--space-l); flex-shrink: 0; animation: m-marquee var(--m-marquee-dur, 30s) linear infinite; }
.m-marquee:hover > * { animation-play-state: paused; }
@keyframes m-marquee { to { translate: calc(-100% - var(--space-l)) 0; } }

.m-float { animation: m-float 6s var(--ease-in-out) infinite; }
@keyframes m-float { 50% { translate: 0 -12px; } }

.m-pulse-ring::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  border: 2px solid var(--brand); animation: m-pulse 2.4s var(--ease-out) infinite;
}
@keyframes m-pulse { to { scale: 1.35; opacity: 0; } }

/* =========================================================================
   8. TRANSITIONS DE PAGE — View Transitions (multi-pages, natif)
   Ajouter <meta name="view-transition" content="same-origin"> dans le <head>
   ========================================================================= */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: m-fade-out var(--dur-base) var(--ease-out) both; }
::view-transition-new(root) { animation: m-fade-in var(--dur-slow) var(--ease-out) both; }
@keyframes m-fade-out { to { opacity: 0; translate: 0 -8px; } }
@keyframes m-fade-in  { from { opacity: 0; translate: 0 12px; } }
/* élément partagé entre deux pages : même view-transition-name des deux côtés */
.m-shared { view-transition-name: var(--vt-name); }

/* =========================================================================
   9. ÉTATS DE CHARGEMENT
   ========================================================================= */
.m-skeleton {
  background: linear-gradient(90deg, var(--surface-sunken) 25%, var(--border) 37%, var(--surface-sunken) 63%);
  background-size: 400% 100%; border-radius: var(--radius-s);
  animation: m-skeleton 1.4s ease-in-out infinite;
}
@keyframes m-skeleton { to { background-position: -135% 0; } }

/* apparition d'un élément fraîchement affiché (popover, toast, modale) */
.m-enter { animation: m-enter var(--dur-base) var(--ease-spring) both; }
@keyframes m-enter { from { opacity: 0; scale: .96; translate: 0 8px; } }
@starting-style { .m-enter-native { opacity: 0; scale: .96; } }
