/* ============================================================
   motion-local.css — Couche motion des 28 pages locales
   desle.immo · Loïc Deslé · Intelligence liquide
   ------------------------------------------------------------
   OÙ LE PLACER : à la fin du bloc <style> du HEAD généré
   (tools/build-communes.mjs, constante HEAD, juste avant la
   media query prefers-reduced-motion existante), ou en fichier
   séparé chargé après site.css. Voir HOOKS.md.

   Règle de sûreté : tout état « caché » de ce bloc est verrouillé
   derrière .ml-on, une classe posée sur <html> par
   assets/shared/motion-local.js UNIQUEMENT si le mouvement est
   autorisé. Sans JS, ou en prefers-reduced-motion, aucune de ces
   règles ne s'applique : la page reste exactement telle qu'elle
   est aujourd'hui.

   Les entrées qui pourraient masquer du contenu (lignes du profil,
   hero, panneau d'adresse) ne sont PAS ici : elles sont pilotées en
   WAAPI depuis le moteur, à partir de l'état visible.
   transform + opacity uniquement.
   ============================================================ */

/* ── 1 · Rythme des sections : le filet Lagon du chapeau se tire ──
   Cible générique : le <span> vide de 26px qui ouvre chaque chapeau. */
.ml-on .reveal > span:first-child:empty{
  transform:scaleX(0); transform-origin:left center;
  transition:transform .7s cubic-bezier(.76,0,.24,1) .06s;
}
.ml-on .reveal.in > span:first-child:empty{ transform:none; }

/* ── 2 · Statistiques : la barre de gauche se remplit en Lagon ──
   Purement décoratif : le filet gris de .stat reste sous cette barre. */
.ml-on .stat{ position:relative; }
.ml-on .stat::after{
  content:''; position:absolute; left:-1px; top:0; width:1px; height:100%;
  background:var(--lagon); opacity:.6;
  transform:scaleY(0); transform-origin:top center;
  transition:transform .9s cubic-bezier(.76,0,.24,1) .1s;
}
.ml-on .stat.in::after{ transform:none; }
.ml-on .stat .stat-v{ font-variant-numeric:tabular-nums; }

/* ── 3 · Sparkline : le point d'arrivée se pose, un cercle s'ouvre ──
   .ml-spark-halo est un <circle> décoratif injecté par le moteur. */
@keyframes ml-dot{
  0%{ transform:scale(.35); } 62%{ transform:scale(1.55); } 100%{ transform:scale(1); }
}
@keyframes ml-halo{
  0%{ transform:scale(.5); opacity:.5; } 100%{ transform:scale(3.6); opacity:0; }
}
.ml-on .reveal.in .spark-dot{
  transform-box:fill-box; transform-origin:center;
  animation:ml-dot .72s cubic-bezier(.16,1,.3,1) 1.46s both;
}
.ml-spark-halo{ fill:none; stroke:var(--lagon); stroke-width:1.5; opacity:0; }
.ml-on .reveal.in .ml-spark-halo{
  transform-box:fill-box; transform-origin:center;
  animation:ml-halo 1.1s cubic-bezier(.16,1,.3,1) 1.5s both;
}

/* ── 4 · PROFIL (section sombre) : le lavis Lagon ──
   .ml-lavis est injecté par le moteur, jamais dans le HTML généré. */
.ml-profil{ position:relative; overflow:hidden; }
.ml-profil > div:not(.ml-lavis){ position:relative; z-index:1; }
.ml-profil > .ml-lavis{
  position:absolute; inset:-12% -6%; z-index:0; pointer-events:none;
  background:radial-gradient(52% 46% at 26% 32%, rgba(21,158,145,.20), rgba(21,158,145,0) 68%),
             radial-gradient(44% 38% at 82% 74%, rgba(21,158,145,.12), rgba(21,158,145,0) 70%);
  opacity:0; transform:translate3d(0,4%,0);
  transition:opacity 1.3s ease;
  will-change:transform, opacity;
}
.ml-profil.ml-vu .ml-lavis{ opacity:1; }

/* ── 5 · PROFIL : les lignes verrouillées donnent envie ── */
.ml-on .ml-verrou{ position:relative; }
.ml-on .ml-verrou::after{
  content:''; position:absolute; left:0; right:0; bottom:-1px; height:1px;
  background:#8ACEC8; opacity:.8;
  transform:scaleX(0); transform-origin:left center;
  transition:transform .6s cubic-bezier(.76,0,.24,1);
}
.ml-on .ml-verrou:hover::after,
.ml-on .ml-verrou:focus-within::after{ transform:none; }
.ml-on .ml-verrou > span{ transition:transform .45s cubic-bezier(.16,1,.3,1), opacity .3s ease; }
.ml-on .ml-verrou:hover > span:first-child{ transform:translateX(4px); }
.ml-on .ml-verrou:hover > span:last-child{ transform:translateX(-3px); }
.ml-on .ml-verrou:hover > span:last-child > span[aria-hidden]{ opacity:.5; }

@keyframes ml-frisson{
  0%,100%{ transform:translateX(0) rotate(0deg); }
  18%{ transform:translateX(-1.6px) rotate(-5deg); }
  42%{ transform:translateX(1.6px) rotate(5deg); }
  68%{ transform:translateX(-1px) rotate(-2.5deg); }
  86%{ transform:translateX(.6px) rotate(1deg); }
}
.ml-on .ml-verrou svg{ transform-origin:center; }
.ml-on .ml-verrou:hover svg{ animation:ml-frisson .52s cubic-bezier(.76,0,.24,1); }

/* ── 6 · PROFIL : le CTA le plus vivant de la page ──
   Le remplissage .dl-cta-fill existant sert de matière : au survol il
   monte (règle de la page), au repos le moteur lui fait un clin d'œil,
   et pendant qu'une ligne verrouillée est survolée il affleure. */
.ml-on .ml-cta-profil{ transition:transform .3s cubic-bezier(.16,1,.3,1); }
.ml-on .ml-cta-profil:active{ transform:scale(.985); }
.ml-on .ml-cta-profil .dl-cta-label:last-child{ transition:transform .35s cubic-bezier(.76,0,.24,1); }
.ml-on .ml-cta-profil:hover .dl-cta-label:last-child,
.ml-on .ml-cta-profil:focus-visible .dl-cta-label:last-child{ transform:translateX(5px); }
.ml-on .ml-profil.ml-teasing .ml-cta-profil{ transform:scale(1.012); }
.ml-on .ml-profil.ml-teasing .ml-cta-profil .dl-cta-fill{ transform:translateY(90%); }

/* ── 7 · Dossier : champs qui accusent réception, bouton qui confirme ──
   !important sur border-color seulement : le style inline du champ
   généré gagne autrement. Rien d'autre n'est forcé. */
.ml-on [data-dossier-form] input:focus,
.ml-on [data-adresse-form] input:focus{ border-color:var(--lagon) !important; }
.ml-on .ml-champ{ position:relative; }
.ml-on .ml-champ::after{
  content:''; position:absolute; left:0; right:0; bottom:0; height:2px;
  background:var(--lagon);
  transform:scaleX(0); transform-origin:left center;
  transition:transform .45s cubic-bezier(.76,0,.24,1);
}
.ml-on .ml-champ:focus-within::after{ transform:none; }
.ml-check{
  position:absolute; right:12px; bottom:14px; display:block; line-height:0;
  opacity:0; transform:scale(.6); pointer-events:none;
  transition:opacity .28s ease, transform .35s cubic-bezier(.16,1,.3,1);
}
.ml-check.on{ opacity:1; transform:none; }

.ml-on [data-dossier-form] button[type="submit"],
.ml-on [data-adresse-form] button[type="submit"]{
  position:relative; overflow:hidden;
  transition:transform .25s cubic-bezier(.16,1,.3,1), opacity .25s ease;
}
.ml-on [data-dossier-form] button[type="submit"]:active,
.ml-on [data-adresse-form] button[type="submit"]:active{ transform:scale(.982); }
@keyframes ml-sheen{ from{ transform:translateX(-105%); } to{ transform:translateX(105%); } }
.ml-on [data-dossier-form] button.ml-envoi::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.32), rgba(255,255,255,0));
  animation:ml-sheen 1s linear infinite;
}
@keyframes ml-confirme{
  0%{ transform:scale(1); } 32%{ transform:scale(.972); }
  66%{ transform:scale(1.022); } 100%{ transform:scale(1); }
}
.ml-on [data-dossier-form] button.ml-ok{ animation:ml-confirme .52s cubic-bezier(.76,0,.24,1); }

/* ── 8 · FAQ et cartes : la lecture reste vivante ── */
.ml-on .faq-item{ position:relative; }
.ml-on .faq-item::before{
  content:''; position:absolute; top:-1px; left:0; right:0; height:1px;
  background:var(--lagon);
  transform:scaleX(0); transform-origin:left center;
  transition:transform .65s cubic-bezier(.76,0,.24,1);
}
.ml-on .faq-item:hover::before{ transform:none; }
.ml-on .faq-q{ transition:transform .4s cubic-bezier(.16,1,.3,1); }
.ml-on .faq-item:hover .faq-q{ transform:translateX(5px); }

/* ── 9 · prefers-reduced-motion : preuve ──
   .ml-on n'est jamais posé dans ce mode (le moteur s'en assure, y compris
   si le réglage change en cours de session). Ce bloc est la ceinture. */
@media (prefers-reduced-motion: reduce){
  .ml-lavis{ display:none !important; }
  .ml-on .reveal > span:first-child:empty,
  .ml-on .stat::after,
  .ml-on .reveal.in .spark-dot,
  .ml-on .ml-spark-halo,
  .ml-on .ml-verrou,
  .ml-on .ml-verrou > span,
  .ml-on .ml-verrou svg,
  .ml-on .ml-verrou::after,
  .ml-on .ml-cta-profil,
  .ml-on .ml-cta-profil .dl-cta-label:last-child,
  .ml-on .ml-champ::after,
  .ml-check,
  .ml-on [data-dossier-form] button[type="submit"],
  .ml-on [data-adresse-form] button[type="submit"],
  .ml-on [data-dossier-form] button.ml-envoi::after,
  .ml-on .faq-item::before,
  .ml-on .faq-q{
    transition:none !important; animation:none !important; transform:none !important;
  }
  .ml-check{ opacity:1 !important; }
  .ml-spark-halo{ display:none !important; }
}
