/* ============================================================
   animations.css — Sain Bellissima
   Fichier dédié : variables de timing, keyframes et classes
   utilitaires pour toutes les animations "nouvelle génération"
   (ne redéfinit jamais une keyframe déjà présente dans premium.css).

   RÈGLES (non négociables) :
   - On n'anime QUE transform et opacity.
   - will-change posé seulement pendant l'animation (sauf boucles
     d'ambiance visibles en continu, cf. premium.css).
   - Tout est coupé si prefers-reduced-motion OU si l'onglet est
     masqué (classe .tab-hidden posée par animations.js).
   - Le contenu reste visible si le JS échoue : les états masqués
     ne s'activent que sous html.js (classe posée par un script
     inline synchrone, avant le premier paint).
   ============================================================ */

:root{
  --ease-out-soft:cubic-bezier(.22,1,.36,1);
  --ease-spring:cubic-bezier(.34,1.56,.64,1);
  --ease-sheet:cubic-bezier(.32,.72,0,1);
  --dur-fast:200ms;
  --dur-base:400ms;
  --dur-slow:450ms;
}

/* ============================================================
   1. Révélation au scroll — module JS unique (animations.js),
   IntersectionObserver partagé, unobserve() après déclenchement.
   Masqué UNIQUEMENT si JS actif (html.js), sinon toujours visible.
   ============================================================ */
html.js [data-reveal]{
  opacity:0; transform:translateY(24px);
  transition:opacity var(--dur-base) var(--ease-out-soft), transform var(--dur-base) var(--ease-out-soft);
}
html.js [data-reveal].in{ opacity:1; transform:none; }
[data-reveal].in{ opacity:1; transform:none; } /* garde-fou si la classe .js n'est pas encore posée */

/* ============================================================
   2. Hero — apparition du sous-titre / CTA au chargement CSS
   (PAS au scroll). translateY(12px)+opacity, stagger 80ms.
   100% CSS : fonctionne même si le JS échoue.
   Le <h1> et la photo du hero NE SONT JAMAIS dans ce système (LCP).
   ============================================================ */
@keyframes revealLoad{ from{ opacity:0; transform:translateY(12px); } to{ opacity:1; transform:none; } }
.reveal-load{ animation:revealLoad var(--dur-base) var(--ease-out-soft) both; }
.reveal-load-1{ animation-delay:0ms; }
.reveal-load-2{ animation-delay:80ms; }
.reveal-load-3{ animation-delay:160ms; }
.reveal-load-4{ animation-delay:240ms; }

/* ============================================================
   3. Halo pulsant réutilisable (pastille "ouvert maintenant", etc.)
   Remplace les box-shadow animées : un pseudo-élément dédié,
   transform:scale + opacity uniquement.
   ============================================================ */
.pulse-halo{ position:relative; }
.pulse-halo::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  background:currentColor; opacity:.55; transform:scale(1);
  animation:pulseHalo 2s ease-out infinite;
  pointer-events:none;
}
@keyframes pulseHalo{ 0%{ transform:scale(1); opacity:.55; } 70%{ transform:scale(2.6); opacity:0; } 100%{ transform:scale(2.6); opacity:0; } }
html.tab-hidden .pulse-halo::after{ animation-play-state:paused; }

/* ============================================================
   4. Vapeur décorative au-dessus du hero (SVG inline, aria-hidden)
   3 courbes, translateY + opacity, décalages différents.
   ============================================================ */
.steam{ position:absolute; pointer-events:none; z-index:1; opacity:.55; mix-blend-mode:screen; }
.steam path{ opacity:0; transform:translateY(0); animation:steamRise 6s ease-in-out infinite; }
.steam path:nth-child(1){ animation-delay:0s; }
.steam path:nth-child(2){ animation-delay:1.4s; }
.steam path:nth-child(3){ animation-delay:2.8s; }
@keyframes steamRise{
  0%{ opacity:0; transform:translateY(0); }
  20%{ opacity:.6; }
  80%{ opacity:.25; }
  100%{ opacity:0; transform:translateY(-46px); }
}
html.tab-hidden .steam path{ animation-play-state:paused; }

/* ============================================================
   5. Cartes menu — feedback au tap (mobile, pas de hover)
   ============================================================ */
@media (hover:none){
  .dish{ transition:transform .12s var(--ease-out-soft); }
  .dish:active{ transform:scale(.98); }
}

/* ============================================================
   6. Changement de filtre de catégorie (menu) — crossfade piloté
   par animations.js. Hauteur réservée pendant la transition
   (min-height posé en JS) pour éviter tout saut de mise en page.
   ============================================================ */
.menu-cat-fade-out{ animation:catOut 120ms var(--ease-out-soft) both; }
.menu-cat-fade-in{ animation:catIn 160ms var(--ease-out-soft) both; }
@keyframes catOut{ from{ opacity:1; transform:scale(1); } to{ opacity:0; transform:scale(.97); } }
@keyframes catIn{ from{ opacity:0; transform:scale(.97); } to{ opacity:1; transform:scale(1); } }

/* ============================================================
   7. Indicateur d'onglet actif — une seule barre qui glisse
   (translateX + scaleX), pas une par onglet.
   ============================================================ */
.menu-tabs{ position:relative; }
.tab-indicator{
  position:absolute; left:0; bottom:-8px; height:3px; width:1px; border-radius:999px;
  background:var(--red); transform-origin:left center;
  transform:translateX(0) scaleX(0);
  transition:transform var(--dur-fast) var(--ease-out-soft), opacity var(--dur-fast);
  opacity:0; pointer-events:none;
}
.tab-indicator.ready{ opacity:1; }

/* ============================================================
   8. FAQ / accordéon — ouverture fluide grid-template-rows,
   pilotée par animations.js tout en gardant <details>/<summary>.
   ============================================================ */
.qa:not([open]) .qa-body{ display:grid; } /* défait le display:none UA pour permettre la transition */
.qa .qa-body{ display:grid; grid-template-rows:0fr; transition:grid-template-rows var(--dur-base) var(--ease-out-soft); }
.qa .qa-body-inner{ overflow:hidden; min-height:0; }
.qa[open] .qa-body{ grid-template-rows:1fr; }
.qa .qa-body p{ margin-top:12px; }

/* ============================================================
   9. Bouton "retour en haut"
   ============================================================ */
.to-top{
  position:fixed; right:16px; bottom:24px; z-index:180;
  width:46px; height:46px; border-radius:50%; border:0; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  background:var(--ink); color:#fff; box-shadow:0 16px 34px -12px rgba(0,0,0,.5);
  opacity:0; transform:scale(.6); pointer-events:none;
  transition:opacity var(--dur-fast) var(--ease-out-soft), transform var(--dur-fast) var(--ease-spring);
}
.to-top.show{ opacity:1; transform:scale(1); pointer-events:auto; }
@media(max-width:920px){ .to-top{ bottom:78px; } }

/* ============================================================
   10. Confirmation "copié" — coche dessinée (stroke-dashoffset)
   ============================================================ */
.check-draw{ width:16px; height:16px; flex:none; }
.check-draw path{
  fill:none; stroke:currentColor; stroke-width:3; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:20; stroke-dashoffset:20;
  transition:stroke-dashoffset var(--dur-base) var(--ease-out-soft);
}
.check-draw.on path{ stroke-dashoffset:0; }

/* ============================================================
   11. Label de champ — accent au focus (nudge micro, pas de
   restructuration du markup existant)
   ============================================================ */
.fld label{ transition:color var(--dur-fast) ease, transform var(--dur-fast) ease; transform-origin:left center; }
.fld:focus-within label{ color:var(--red); transform:translateY(-2px); }

/* ============================================================
   12. Shake utilitaire (erreur de validation) — réutilisable
   ============================================================ */
@keyframes shakeX{
  10%,90%{ transform:translateX(-1px); }
  20%,80%{ transform:translateX(2px); }
  30%,50%,70%{ transform:translateX(-4px); }
  40%,60%{ transform:translateX(4px); }
}
.shake{ animation:shakeX 300ms var(--ease-out-soft); }

/* ============================================================
   13. Menu mobile — fondu + translateY, liens en stagger 40ms
   ============================================================ */
.navlinks{
  opacity:0; visibility:hidden; transform:translateY(-8px);
  transition:opacity var(--dur-fast) var(--ease-out-soft), transform var(--dur-fast) var(--ease-out-soft), visibility 0s linear var(--dur-fast);
}
@media(min-width:921px){ .navlinks{ opacity:1; visibility:visible; transform:none; transition:none; } }
.navlinks.open{ opacity:1; visibility:visible; transform:none; transition:opacity var(--dur-fast) var(--ease-out-soft), transform var(--dur-fast) var(--ease-out-soft); }
@media(max-width:920px){
  .navlinks.open a{ opacity:0; transform:translateY(-6px); animation:revealLoad var(--dur-fast) var(--ease-out-soft) both; }
  .navlinks.open a:nth-child(1){ animation-delay:40ms; }
  .navlinks.open a:nth-child(2){ animation-delay:80ms; }
  .navlinks.open a:nth-child(3){ animation-delay:120ms; }
  .navlinks.open a:nth-child(4){ animation-delay:160ms; }
  .navlinks.open a:nth-child(5){ animation-delay:200ms; }
  .navlinks.open a:nth-child(6){ animation-delay:240ms; }
  .navlinks.open a:nth-child(7){ animation-delay:280ms; }
}

/* ============================================================
   14. Bandeau défilant — pause au survol ET au focus clavier
   ============================================================ */
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track{ animation-play-state:paused; }
html.tab-hidden .marquee-track,
html.tab-hidden .hero-photo,
html.tab-hidden .hero-ember{ animation-play-state:paused; }

/* ============================================================
   15. View Transitions (MPA) — dégradation silencieuse si non
   supporté par le navigateur (règle CSS ignorée).
   ============================================================ */
@view-transition{ navigation:auto; }
::view-transition-old(root),::view-transition-new(root){ animation-duration:200ms; }

/* ============================================================
   0. Réduction des animations — surcouche spécifique aux
   nouveaux éléments (le bloc global reste dans index.html/premium.css)
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  .pulse-halo::after,.steam path{ display:none; }
  .navlinks.open a{ animation:none!important; opacity:1!important; transform:none!important; }
  .reveal-load{ animation-duration:.001ms!important; }
}
