/* ============================================================
   Puck Flip — Socle d'animations (chargé par layout.php ET
   layout_public.php, APRÈS leur <style> inline).
   Classes additives uniquement (préfixe mo-/data-*) : ne jamais
   redéfinir une classe existante des vues depuis ce fichier.
   ============================================================ */

:root {
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-shine: cubic-bezier(0.2, 0.8, 0.2, 1);
  --dur-1: 150ms;
  --dur-2: 250ms;
  --dur-3: 450ms;
  --dur-4: 700ms;
}

/* ---- Keyframes centralisés (préfixe mo- anti-collision) ---- */

@keyframes mo-spin {
  to { transform: rotate(360deg); }
}

@keyframes mo-shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

@keyframes mo-fade-up {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes mo-slide-in-right {
  from { opacity: 0; transform: translateX(24px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes mo-glow-pulse {
  0%, 100% { box-shadow: 0 0 0 rgba(56, 189, 248, 0); }
  50% { box-shadow: 0 0 24px var(--glow-cyan, rgba(56, 189, 248, 0.45)); }
}

@keyframes mo-glow-pulse-success {
  0%, 100% { box-shadow: 0 0 0 rgba(52, 211, 153, 0); }
  50% { box-shadow: 0 0 20px rgba(52, 211, 153, 0.45); }
}

@keyframes mo-glow-pulse-amber {
  0%, 100% { box-shadow: 0 0 0 rgba(251, 191, 36, 0); }
  50% { box-shadow: 0 0 20px rgba(251, 191, 36, 0.5); }
}

@keyframes mo-flash {
  from { opacity: 0.85; }
  to { opacity: 0; }
}

@keyframes mo-pop {
  from { opacity: 0; transform: scale(0.96); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes mo-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes mo-vt-out {
  to { opacity: 0; transform: translateY(-8px); }
}

@keyframes mo-vt-in {
  from { opacity: 0; transform: translateY(8px); }
}

/* ---- Utilitaires reveal-on-scroll (piloté par motion.js) ---- */
/* État initial conditionné à html.js-motion : si le JS est bloqué (CSP,
   désactivé), le contenu reste visible par défaut — pas de FOUC. */
html.js-motion .reveal,
html.js-motion [data-reveal] {
  opacity: 0;
  transform: translateY(16px);
}

html.js-motion .reveal.is-visible,
html.js-motion [data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--dur-3) var(--ease-out-quart),
    transform var(--dur-3) var(--ease-out-quart);
}

/* Stagger : motion.js pose --i (index, cap 8) sur chaque enfant */
[data-stagger] > * {
  transition-delay: calc(var(--i, 0) * 60ms);
}

/* ---- Micro-interactions ---- */

.hover-lift {
  transition: transform var(--dur-2) var(--ease-out-quart),
    box-shadow var(--dur-2) var(--ease-out-quart);
}

@media (hover: hover) {
  .hover-lift:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-glow, 0 4px 16px rgba(56, 189, 248, 0.12));
  }
}

.pressable {
  transition: transform var(--dur-1) var(--ease-out-quart);
}

.pressable:active {
  transform: scale(0.97);
}

/* Halo discret en boucle (CTA principaux) : en pause au survol pour ne pas
   distraire pendant l'interaction. */
.mo-cta-pulse {
  animation: mo-glow-pulse 4s ease-in-out infinite;
}

.mo-cta-pulse--amber {
  animation-name: mo-glow-pulse-amber;
}

.mo-cta-pulse--success {
  animation-name: mo-glow-pulse-success;
}

@media (hover: hover) {
  .mo-cta-pulse:hover {
    animation-play-state: paused;
  }
}

/* ---- Skeleton néon unifié ---- */
/* .skeleton (app.css/public.css) délègue son rendu ici : source unique du
   shimmer, structure (dimensions/radius des modificateurs --text/--card)
   reste définie dans les 2 feuilles de composants. */

.mo-skeleton,
.skeleton {
  position: relative;
  overflow: hidden;
  background: #12161e;
  background-image: linear-gradient(
    90deg,
    transparent 0%,
    rgba(56, 189, 248, 0.10) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: mo-shimmer 1.6s ease-in-out infinite;
}

.mo-skeleton {
  border-radius: var(--radius, 12px);
}

/* ---- View Transitions (navigation cross-document) ---- */
/* Navigateurs sans support : navigation classique, aucune régression. */
@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: var(--dur-2) var(--ease-out-quart) both mo-vt-out;
}

::view-transition-new(root) {
  animation: var(--dur-3) var(--ease-out-quart) both mo-vt-in;
}

/* Header épinglé : pas de transition propre, il reste stable à l'écran. */
::view-transition-group(pf-header) {
  animation-duration: 0s;
}

/* ---- Accessibilité : mouvement réduit ---- */
@media (prefers-reduced-motion: reduce) {
  html.js-motion .reveal,
  html.js-motion [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .mo-skeleton,
  .skeleton {
    animation: none;
    background-image: none;
  }

  .mo-cta-pulse {
    animation: none;
  }

  .hover-lift:hover {
    transform: none;
  }

  .pressable:active {
    transform: none;
  }

  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}
