/* ============================================================
   Animations: keyframes, entry transitions, micro-interactions,
   modal open/close, page transitions, scroll reveals.
   Loads after components.css.
   ============================================================ */

/* ================================================================
   KEYFRAMES
   ================================================================ */

@keyframes fade-in       { from { opacity: 0; }                            to { opacity: 1; } }
@keyframes fade-out      { from { opacity: 1; }                            to { opacity: 0; } }
@keyframes slide-up      { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes slide-down    { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes slide-in-right{ from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } }
@keyframes slide-in-left { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } }
@keyframes scale-in      { from { opacity: 0; transform: scale(0.92); }    to { opacity: 1; transform: scale(1); } }
@keyframes scale-bounce  { from { opacity: 0; transform: scale(0.7); }     to { opacity: 1; transform: scale(1); } }
@keyframes sheet-up      { from { opacity: 0; transform: translateY(100%); } to { opacity: 1; transform: translateY(0); } }
@keyframes sheet-down    { from { opacity: 1; transform: translateY(0); }   to { opacity: 0; transform: translateY(100%); } }

/* Backdrop fade */
@keyframes backdrop-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes backdrop-out { from { opacity: 1; } to { opacity: 0; } }

/* Toast */
@keyframes toast-in  { from { opacity: 0; transform: translateX(calc(100% + 1rem)); } to { opacity: 1; transform: translateX(0); } }
@keyframes toast-out { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(calc(100% + 1rem)); } }

/* Heartbeat */
@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  15%       { transform: scale(1.25); }
  30%       { transform: scale(1); }
  45%       { transform: scale(1.15); }
}

/* Wiggle */
@keyframes wiggle {
  0%, 100% { transform: rotate(0deg); }
  20%       { transform: rotate(-8deg); }
  40%       { transform: rotate(8deg); }
  60%       { transform: rotate(-5deg); }
  80%       { transform: rotate(5deg); }
}

/* Float */
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-6px); }
}

/* Pop */
@keyframes pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.2); }
  100% { transform: scale(1); }
}

/* Confetti burst (used on success) */
@keyframes confetti-fall {
  0%   { transform: translateY(-10px) rotate(0deg);   opacity: 1; }
  100% { transform: translateY(80px)  rotate(360deg); opacity: 0; }
}

/* Checkmark draw */
@keyframes check-draw {
  from { stroke-dashoffset: 50; }
  to   { stroke-dashoffset: 0; }
}

/* Ripple */
@keyframes ripple {
  0%   { transform: scale(0); opacity: 0.5; }
  100% { transform: scale(4); opacity: 0; }
}


/* ================================================================
   UTILITY ANIMATION CLASSES
   ================================================================ */

.anim-fade-in       { animation: fade-in       var(--t-base) var(--ease-out) both; }
.anim-slide-up      { animation: slide-up      var(--t-base) var(--ease-out) both; }
.anim-slide-down    { animation: slide-down    var(--t-base) var(--ease-out) both; }
.anim-slide-in-right{ animation: slide-in-right var(--t-base) var(--ease-out) both; }
.anim-slide-in-left { animation: slide-in-left  var(--t-base) var(--ease-out) both; }
.anim-scale-in      { animation: scale-in      var(--t-base) var(--ease-bounce) both; }
.anim-float         { animation: float 3s var(--ease-inout) infinite; }
.anim-heartbeat     { animation: heartbeat 1.2s ease-in-out infinite; }
.anim-wiggle        { animation: wiggle 0.6s ease-in-out; }

/* Stagger children: first 8 children get delay */
.stagger-children > *:nth-child(1) { animation-delay:  40ms; }
.stagger-children > *:nth-child(2) { animation-delay:  80ms; }
.stagger-children > *:nth-child(3) { animation-delay: 120ms; }
.stagger-children > *:nth-child(4) { animation-delay: 160ms; }
.stagger-children > *:nth-child(5) { animation-delay: 200ms; }
.stagger-children > *:nth-child(6) { animation-delay: 240ms; }
.stagger-children > *:nth-child(7) { animation-delay: 280ms; }
.stagger-children > *:nth-child(8) { animation-delay: 320ms; }


/* ================================================================
   MODAL ENTER / EXIT
   JS adds .is-open to .modal-backdrop, .is-closing triggers exit.
   ================================================================ */

.modal-backdrop {
  animation: backdrop-in var(--t-fast) var(--ease-out) both;
}
.modal-backdrop .modal {
  animation: scale-in var(--t-base) var(--ease-bounce) both;
}

/* Bottom sheet variant */
.modal-backdrop.sheet-mode .modal {
  animation: sheet-up var(--t-base) var(--ease-out) both;
}

/* Closing */
.modal-backdrop.is-closing {
  animation: backdrop-out var(--t-fast) var(--ease-in) both;
}
.modal-backdrop.is-closing .modal {
  animation: scale-in var(--t-fast) var(--ease-in) reverse both;
}
.modal-backdrop.is-closing.sheet-mode .modal {
  animation: sheet-down var(--t-fast) var(--ease-in) both;
}


/* ================================================================
   TOAST ENTER / EXIT
   JS adds .is-leaving class before DOM removal.
   ================================================================ */

.toast {
  animation: toast-in var(--t-base) var(--ease-bounce) both;
}
.toast.is-leaving {
  animation: toast-out var(--t-fast) var(--ease-in) both;
}


/* ================================================================
   VIEW TRANSITION API
   Native browser page transitions, no JS needed beyond router.
   ================================================================ */

/* Default cross-fade */
::view-transition-old(root) {
  animation: fade-out var(--t-fast) var(--ease-in) both;
}
::view-transition-new(root) {
  animation: fade-in  var(--t-fast) var(--ease-out) both;
}

/* Slide for forward navigation */
:root.nav-forward::view-transition-old(root) {
  animation: slide-in-right var(--t-base) var(--ease-in) reverse both;
}
:root.nav-forward::view-transition-new(root) {
  animation: slide-in-right var(--t-base) var(--ease-out) both;
}

/* Slide for back navigation */
:root.nav-back::view-transition-old(root) {
  animation: slide-in-left var(--t-base) var(--ease-in) both;
}
:root.nav-back::view-transition-new(root) {
  animation: slide-in-left var(--t-base) var(--ease-out) reverse both;
}

/* Named view transitions for header logo (stays in place) */
.app-header__logo {
  view-transition-name: header-logo;
}
::view-transition-old(header-logo),
::view-transition-new(header-logo) {
  animation: none;
}


/* ================================================================
   SCROLL REVEAL
   JS adds .is-visible when element enters viewport (IntersectionObserver).
   Default: hidden. Visible: animated in.
   ================================================================ */

.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity var(--t-slow) var(--ease-out),
    transform var(--t-slow) var(--ease-out);
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.reveal-scale {
  opacity: 0;
  transform: scale(0.95);
  transition:
    opacity var(--t-slow) var(--ease-out),
    transform var(--t-slow) var(--ease-out);
}
.reveal-scale.is-visible {
  opacity: 1;
  transform: scale(1);
}


/* ================================================================
   RIPPLE on .btn
   JS injects <span class="ripple-wave"> on click.
   ================================================================ */

.btn { isolation: isolate; }
.ripple-wave {
  position: absolute;
  border-radius: var(--r-circle);
  background: rgba(255, 255, 255, 0.35);
  width: 4px;
  height: 4px;
  pointer-events: none;
  transform-origin: center;
  animation: ripple 0.55s var(--ease-out) forwards;
}


/* ================================================================
   MICRO-INTERACTIONS
   ================================================================ */

/* Like / save button pulse */
.btn-like.is-liked {
  animation: heartbeat 0.5s ease-out;
  color: var(--c-danger);
}

/* Add-to-cart pop */
.btn-cart.did-add {
  animation: pop 0.4s var(--ease-bounce);
}

/* Form field success check flash */
.form-input.is-valid {
  border-color: var(--c-success);
  transition: border-color var(--t-fast);
}

/* Boost badge glow pulse */
.card-listing--boosted .card-listing__boost-badge {
  animation: heartbeat 2.5s ease-in-out infinite;
}

/* Tabbar icon bounce on tap */
.tabbar__item:active .tabbar__icon {
  animation: scale-bounce 0.3s var(--ease-bounce);
}

/* Chip selection bounce */
.chip.is-active {
  animation: scale-bounce 0.25s var(--ease-bounce);
}

/* Avatar hover float */
.avatar-wrap:hover .avatar {
  animation: float 2s var(--ease-inout) infinite;
}


/* ================================================================
   SUCCESS ANIMATION (checkmark overlay, shown after purchase)
   Usage: <div class="success-anim"><svg ...checkmark.../></div>
   ================================================================ */

.success-anim {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  animation: scale-bounce var(--t-base) var(--ease-bounce) both;
}
.success-anim__circle {
  width: 5rem;
  height: 5rem;
  border-radius: var(--r-circle);
  background: var(--c-success-bg);
  display: flex;
  align-items: center;
  justify-content: center;
}
.success-anim__check {
  stroke: var(--c-success);
  stroke-dasharray: 50;
  stroke-dashoffset: 50;
  animation: check-draw 0.4s var(--ease-out) 0.15s both;
}


/* ================================================================
   CONFETTI BURST
   JS renders .confetti-piece elements inside .confetti-container.
   ================================================================ */

.confetti-container {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: var(--z-toast);
  overflow: hidden;
}
.confetti-piece {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  animation: confetti-fall 1.2s ease-in forwards;
}


/* ================================================================
   REDUCED MOTION: disable all decorative animations
   ================================================================ */

@media (prefers-reduced-motion: reduce) {
  .anim-fade-in,
  .anim-slide-up,
  .anim-slide-down,
  .anim-slide-in-right,
  .anim-slide-in-left,
  .anim-scale-in,
  .anim-float,
  .anim-heartbeat,
  .anim-wiggle,
  .reveal,
  .reveal-scale,
  .toast,
  .modal-backdrop,
  .modal-backdrop .modal,
  .card-listing--boosted .card-listing__boost-badge {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .ripple-wave { display: none; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}
