/* ════════════════════════════════════════════════════════════════════════
   Grom Warez — animations du site
   La couche d'expérience manquante — DÉCLARATIVE (pilotée par data-attributs).
   On n'écrit plus le "vivant" à la main par projet : on ajoute des attributs.
   C'est ce qui rend la claque PLUS FACILE à coder que le "beau" statique.

   Graceful-degrade intégral :
   - touch / pointer:coarse → curseur, tilt, depth, breath désactivés (CSS + JS)
   - prefers-reduced-motion → tout fige sur l'état final (aucune animation)
   - JS absent → le site reste lisible (aucun état caché load-bearing ici)

   Couplage : tokens ré-exposés (--ease-*) ; n'écrase JAMAIS --bg/--fg du projet
   sans data-invert. Cohabite avec GSAP/Lenis (voir aliveness.js).
   ════════════════════════════════════════════════════════════════════════ */

:root{
  /* Easings tactiles nommés — JAMAIS "ease"/"ease-in-out" */
  --ease-cinema: cubic-bezier(.22,1,.36,1);     /* glisse lourde, révélations */
  --ease-snap:   cubic-bezier(.34,1.56,.64,1);  /* overshoot ressort, hovers   */
  --ease-exit:   cubic-bezier(.7,0,.84,0);       /* sorties sèches              */
  /* Le moteur JS lit/écrit ces variables — valeurs de repli si JS off */
  --alv-cursor: 1;          /* 0 quand curseur custom monté (cache le natif)   */
  --alv-bg: var(--fond, #fff);
  --alv-fg: var(--txt,  #111);
}

/* ── 1. CURSEUR VIVANT ─────────────────────────────────────────────────────
   Dot rapide (quasi-instant) + Ring à inertie (lerp lent). mix-blend-mode
   s'adapte à tout fond. Monté UNIQUEMENT sur pointeur fin (JS ajoute .alv-cursor-on). */
.alv-cursor-on, .alv-cursor-on a, .alv-cursor-on button,
.alv-cursor-on [data-magnetic], .alv-cursor-on [data-cursor]{ cursor:none; }

.alv-dot, .alv-ring{
  position:fixed; top:0; left:0; z-index:99999; pointer-events:none;
  border-radius:50%; mix-blend-mode:difference; opacity:0;
  transform:translate3d(-50%,-50%,0); will-change:transform,width,height,opacity;
}
.alv-dot{ width:7px;  height:7px; background:#fff; }
.alv-ring{
  width:38px; height:38px; border:1.5px solid #fff; background:transparent;
  transition:width .32s var(--ease-snap), height .32s var(--ease-snap),
             background-color .3s var(--ease-cinema), opacity .3s ease;
}
.alv-cursor-on .alv-dot, .alv-cursor-on .alv-ring{ opacity:1; }
/* États : survol d'un lien/bouton → l'anneau gonfle et se remplit */
.alv-ring.is-hot{ width:64px; height:64px; background:rgba(255,255,255,.18); }
/* Survol d'un élément magnétique → contraction agressive (il "aspire") */
.alv-ring.is-magnet{ width:54px; height:54px; }
/* Texte sélectionnable → l'anneau devient un faisceau vertical */
.alv-ring.is-text{ width:3px; height:34px; border-radius:2px; background:#fff; }

/* ── 2. PROFONDEUR RÉACTIVE SOURIS (ambient — "ça bouge sans qu'on scrolle") ─
   data-depth="0.4" : l'élément suit la souris à 40% (parallaxe de couches).
   Le JS écrit --alv-px/--alv-py (-1..1). transform composable avec le reste. */
[data-depth]{ will-change:transform; }

/* ── 3. RESPIRATION (le climax/les héros respirent en continu, jamais figés) ─
   data-breath ou data-breath="1.4" : amplitude. Le JS écrit --alv-breath (sin). */
[data-breath]{ will-change:transform; }

/* ── 4. TYPO VITALE ─
   data-vital sur un titre en variable font. Le JS écrit --alv-wght (200..760)
   piloté par la vélocité + la position de scroll : le titre RESPIRE au scroll. */
[data-vital]{
  font-variation-settings:"wght" var(--alv-wght, 600), "opsz" var(--alv-opsz, 40);
  transition:font-variation-settings .12s linear; /* lissage micro, pas un saut */
}

/* ── 5. INVERSION DE FOND CHORÉGRAPHIÉE ──────────────────────
   data-invert sur <body> : le JS lerp --alv-bg/--alv-fg selon l'acte traversé.
   On ne bascule pas brutalement : on FOND clair↔sombre en continu. */
[data-invert]{
  background-color:var(--alv-bg); color:var(--alv-fg);
  transition:background-color .9s var(--ease-cinema), color .9s var(--ease-cinema);
}
/* Chaque acte déclare sa cible : data-act-bg / data-act-fg (lus par le JS) */

/* ── 6. TACTILITÉ — TILT + PRESS (le poids, le ressort : domaine emil) ──────
   data-tilt : suit le pointeur en rotation 3D + s'enfonce au clic. */
[data-tilt]{
  transform-style:preserve-3d; will-change:transform;
  transition:transform .5s var(--ease-cinema);
}
[data-tilt].is-pressed{ transition:transform .14s var(--ease-snap); }

/* Hover à ressort universel sur les CTA — remplace translateY(-2px) plat */
[data-spring]{ transition:transform .42s var(--ease-snap), box-shadow .42s var(--ease-cinema); }
[data-spring]:hover{ transform:translateY(-3px) scale(1.015); }
[data-spring]:active{ transform:translateY(-1px) scale(.99); transition-duration:.12s; }

/* ── 7. CLIMAX (le moment-5 qu'on screenshote — UN par site) ────────────────
   data-climax : caché-prêt par défaut, révélé par le JS (intègre le pin GSAP
   si présent). Failsafe : visible si JS off (jamais d'écran vide). */
[data-climax]{ will-change:transform,opacity,filter; }
html.alv-ready [data-climax]{ opacity:0; transform:scale(1.06); filter:blur(6px); }
html.alv-ready [data-climax].is-revealed{
  opacity:1; transform:none; filter:none;
  transition:opacity 1.1s var(--ease-cinema), transform 1.1s var(--ease-cinema),
             filter 1.1s var(--ease-cinema);
}

/* ── 8. RÉCOMPENSE DU PATIENT (idle glow — micro-délice après inactivité) ───
   Le JS ajoute .alv-rested sur [data-reward] après N s d'immobilité. */
[data-reward].alv-rested{ animation:alv-pulse 3.2s var(--ease-cinema) infinite; }
@keyframes alv-pulse{ 50%{ filter:brightness(1.08) saturate(1.06); } }

/* ════════════════ GARDE-FOUS NON-NÉGOCIABLES ════════════════ */
/* Pointeur grossier / tactile : aucune des couches "souris" ne tourne */
@media (hover:none), (pointer:coarse){
  .alv-dot, .alv-ring{ display:none !important; }
  [data-tilt]{ transform:none !important; }
}
/* Respect absolu de reduced-motion : on fige TOUT sur l'état final */
@media (prefers-reduced-motion:reduce){
  .alv-dot, .alv-ring{ display:none !important; }
  [data-breath], [data-depth], [data-tilt]{ transform:none !important; }
  [data-vital]{ font-variation-settings:"wght" 600; transition:none; }
  [data-invert]{ transition:none; }
  html.alv-ready [data-climax]{ opacity:1; transform:none; filter:none; }
  [data-reward].alv-rested{ animation:none; }
  [data-spring]:hover{ transform:none; }
}
