/* ============================================================
   Granvo Motion v2.1 — librairie d'animations réutilisable (drop-in)
   Style « Obrio » : raffiné, sobre, jamais gadget.

   CONVENTION RÉUTILISABLE (sites clients du Builder) :
     - [data-reveal]            → fondu + montée au scroll
     - [data-reveal="left"|"right"|"scale"|"fade"]
     - .section-head[data-reveal] → cascade : ses enfants se révèlent en séquence
     - [data-count="40"] [data-suffix="+"]  → compteur qui monte
     - [data-parallax=".12"]    → parallaxe légère (desktop ≥768 px seulement)
     - .gm-lift                 → soulèvement au survol
     - .gm-progress             → barre de progression de lecture (transform GPU)

   INTENSITÉ (manifeste du site) — à poser sur :root dans le styles.css du site :
     --gm-y (montée), --gm-x (glissement), --gm-dur (durée), --gm-stagger (décalage frères)
     discrète : 22px / 26px / .7s / 75ms   ·   moyenne : 28px / 32px / .85s / 90ms
     Les courbes ne changent jamais (signature qualité) ; seule l'amplitude varie.

   Garde-fous :
     - Ne cache du contenu QUE si <html class="gm-on"> (script inline en <head>).
     - Respecte prefers-reduced-motion ET la classe `html.reduce` (convention
       Granvo, posée par le <head> sur OS-reduce ou `?reduce=1`) :
       tout visible, zéro animation, zéro transition.
     - Sécurité : si le JS ne charge pas, le <head> retire gm-on → contenu visible.
     - Le H1 du hero (LCP) n'est JAMAIS caché.
     - v2.1 : une fois révélé (.gm-done), l'élément retrouve son état naturel —
       les survols (.gm-lift, :hover) fonctionnent. En v2, le « !important »
       de .gm-in les bloquait pour toujours.
   ============================================================ */

:root {
  --gm-y: 22px;
  --gm-x: 26px;
  --gm-dur: .7s;
  --gm-stagger: 75ms;
  --gm-ease: cubic-bezier(.16, 1, .3, 1);
}

/* ---- État caché (avant reveal) — jamais après .gm-done ---- */
html.gm-on [data-reveal]:not(.gm-done)          { opacity: 0; transform: translateY(var(--gm-y)); }
html.gm-on [data-reveal="fade"]:not(.gm-done)   { transform: none; }
html.gm-on [data-reveal="left"]:not(.gm-done)   { transform: translateX(calc(var(--gm-x) * -1)); }
html.gm-on [data-reveal="right"]:not(.gm-done)  { transform: translateX(var(--gm-x)); }
html.gm-on [data-reveal="scale"]:not(.gm-done)  { transform: scale(.965); }

/* ---- État révélé (posé par le JS) — transition, puis .gm-done libère ---- */
html.gm-on .gm-in:not(.gm-done) {
  opacity: 1 !important;
  transform: none !important;
  transition: opacity var(--gm-dur) var(--gm-ease),
              transform var(--gm-dur) var(--gm-ease);
  transition-delay: var(--gm-d, 0ms);
}

/* ---- Cascade d'en-tête : le bloc ne bouge pas, ses enfants se suivent ---- */
html.gm-on .section-head[data-reveal]:not(.gm-done) { opacity: 1; transform: none; }
html.gm-on .section-head[data-reveal]:not(.gm-done) > * { opacity: 0; transform: translateY(calc(var(--gm-y) * .6)); }
html.gm-on .section-head.gm-in:not(.gm-done) > * {
  opacity: 1; transform: none;
  transition: opacity var(--gm-dur) var(--gm-ease), transform var(--gm-dur) var(--gm-ease);
}
html.gm-on .section-head.gm-in:not(.gm-done) > :nth-child(2)    { transition-delay: 110ms; }
html.gm-on .section-head.gm-in:not(.gm-done) > :nth-child(3)    { transition-delay: 220ms; }
html.gm-on .section-head.gm-in:not(.gm-done) > :nth-child(n+4)  { transition-delay: 330ms; }

/* ---- Parallaxe : le JS pose un translate3d ; ici on ne fait que l'annoncer au GPU ---- */
html.gm-on [data-parallax] { will-change: transform; }

/* ---- Micro-interactions ---- */
.gm-lift { transition: transform .18s ease; }
.gm-lift:hover { transform: translateY(-4px); }

@keyframes gm-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.gm-pulse { animation: gm-pulse 2s ease-in-out infinite; }

/* Barre de progression de lecture — transform GPU (jamais animer width) */
.gm-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 100%; z-index: 300;
  transform: scaleX(0); transform-origin: 0 50%;
  background: var(--navy, #1A2842);
}

/* ---- Accessibilité : aucune animation si réduit ----
   DEUX entrées, strictement équivalentes :
   (a) @media (prefers-reduced-motion: reduce) — réglage OS, fonctionne sans JS ;
   (b) html.reduce — classe posée par le <head> (OS *ou* ?reduce=1), même
       convention que le moteur JS. Sans (b), `?reduce=1` coupait le JS mais
       laissait tourner le CSS. Tout bloc ajouté en (a) doit être doublé en (b). */
@media (prefers-reduced-motion: reduce) {
  html.gm-on [data-reveal],
  html.gm-on .section-head[data-reveal] > * {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
  html.gm-on [data-parallax] { transform: none !important; will-change: auto; }
  .gm-lift, .gm-pulse { transition: none !important; animation: none !important; }
}
html.reduce.gm-on [data-reveal],
html.reduce.gm-on .section-head[data-reveal] > * {
  opacity: 1 !important; transform: none !important; transition: none !important;
}
html.reduce.gm-on [data-parallax] { transform: none !important; will-change: auto; }
html.reduce .gm-lift, html.reduce .gm-pulse { transition: none !important; animation: none !important; }
