/* ============================================================
   WeVote Kit — Animations
   All @keyframes + entrance utilities + the global
   reduced-motion reset. Load last.

   Convention: the visible END state is the BASE style; we
   animate FROM hidden, gated on [data-active] + no-preference,
   so print / reduced-motion / SSR always show content.
   ============================================================ */

@keyframes wv-fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes wv-fade {
  from { opacity: 0; } to { opacity: 1; }
}
@keyframes wv-pop {
  0%   { opacity: 0; transform: scale(.96) translateY(6px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes wv-check-ring {
  0%   { transform: scale(.6); opacity: 0; }
  60%  { transform: scale(1.05); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes wv-check-draw { to { stroke-dashoffset: 0; } }
@keyframes wv-collapse-spin { to { transform: rotate(180deg); } }
@keyframes wv-ping {
  0%   { transform: scale(1); opacity: .45; }
  70%  { transform: scale(1.75); opacity: 0; }
  100% { transform: scale(1.75); opacity: 0; }
}
@keyframes wv-typing {
  0%, 60%, 100% { transform: translateY(0); opacity: .4; }
  30% { transform: translateY(-4px); opacity: 1; }
}
@keyframes wv-shimmer { to { background-position: -200% 0; } }

/* ---- hero accents ---- */
@keyframes wv-hero-twinkle {
  0%, 100% { opacity: .82; transform: rotate(0deg) scale(1); }
  50%      { opacity: 1;   transform: rotate(5deg) scale(1.045); }
}
@keyframes wv-count-pop {
  0%   { opacity: 0; transform: translateY(7px) scale(.88); }
  62%  { opacity: 1; transform: translateY(0) scale(1.05); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: no-preference) {
  .hero-deco { animation: wv-hero-twinkle 7s ease-in-out infinite; transform-origin: 70% 30%; }
  .hero-count { animation: wv-count-pop .6s .12s cubic-bezier(.22,.61,.36,1) both; display: inline-block; }
}

/* ---- entrance utilities ---- */
.anim-fade-up { animation: wv-fade-up .42s cubic-bezier(.22,.61,.36,1) both; }
.anim-fade    { animation: wv-fade .4s ease both; }
.anim-pop     { animation: wv-pop .4s cubic-bezier(.22,.61,.36,1) both; }

/* stagger helpers */
.stagger > * { animation: wv-fade-up .5s cubic-bezier(.22,.61,.36,1) both; }
.stagger > *:nth-child(1){ animation-delay: .02s; }
.stagger > *:nth-child(2){ animation-delay: .07s; }
.stagger > *:nth-child(3){ animation-delay: .12s; }
.stagger > *:nth-child(4){ animation-delay: .17s; }
.stagger > *:nth-child(5){ animation-delay: .22s; }
.stagger > *:nth-child(6){ animation-delay: .27s; }

/* success check — animate from hidden only when motion is welcome */
@media (prefers-reduced-motion: no-preference) {
  .success-ring { animation: wv-check-ring .5s cubic-bezier(.22,.61,.36,1) both; }
  .success-check path {
    stroke-dashoffset: 30;
    animation: wv-check-draw .4s .35s cubic-bezier(.65,0,.35,1) forwards;
  }
}

/* ---- image lightbox pop-in (styles live in components.css) ---- */
@media (prefers-reduced-motion: no-preference) {
  .lb .lb-img { animation: lbpop .26s cubic-bezier(.22, .61, .36, 1) both; }
}
@keyframes lbpop {
  from { opacity: 0; transform: scale(.96); }
  to { opacity: 1; transform: none; }
}

/* ---- global reduced-motion reset ---- */
@media (prefers-reduced-motion: reduce) {
  *, .anim-fade-up, .anim-fade, .anim-pop, .stagger > *,
  .success-ring, .success-check path {
    animation: none !important;
    transition-duration: .01ms !important;
  }
  .collapse-body, .nav-aside, .drawer-wrap .drawer-backdrop,
  .drawer-wrap .drawer-panel, .widget-panel { transition: none; }
  .fab-ping { animation: none; opacity: 0; }
  .skel { animation: none; }
}
