/*
 * animations.css — Keyframes, reveal states, prefers-reduced-motion fallbacks.
 */

/* ========================================
   KEYFRAMES
   ======================================== */
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(22px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Soft drop-shadow breathing for the colorful App Store CTA pill.
 * Just the indigo drop shadow growing and fading slightly — no spread
 * ring around the edge so the pill stays a clean single shape. */
@keyframes pill-pop-glow {
  0%, 100% {
    box-shadow: 0 14px 32px -12px rgba(79, 70, 229, 0.50);
  }
  50% {
    box-shadow: 0 18px 40px -14px rgba(79, 70, 229, 0.75);
  }
}


/* ========================================
   REVEAL STATES (controlled by JS)
   ---
   Opacity-only — DO NOT use `transform` here, and DO NOT add
   `will-change: opacity`. Both create a new stacking context on the
   reveal element (the will-change because opacity itself creates one
   when its value is non-initial), which traps any `mix-blend-mode:
   difference` on descendant text and prevents the inversion from
   reaching the dot-grid canvas behind the page.
   ======================================== */
.reveal {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-spring);
}

.reveal.is-revealed {
  opacity: 1;
}

/* Stagger children with CSS variable */
.reveal-stagger > * {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-spring);
  transition-delay: calc(var(--stagger) * var(--i, 0));
}

.reveal-stagger.is-revealed > * {
  opacity: 1;
}

/* ========================================
   PAGE LOAD ENTRANCE (hero) — bounced fade-up
   ======================================== */
.hero-name,
.hero-tagline,
.hero-cta {
  opacity: 0;
  animation: fade-up var(--dur-page) var(--ease-spring) forwards;
}

.hero-name { animation-delay: 220ms; }
.hero-tagline { animation-delay: 480ms; }
.hero-cta { animation-delay: 640ms; }

/* The avatar gets its OWN entrance animation that only touches opacity,
 * not transform. Reason: CSS animations override rules like :hover in the
 * cascade, and `forwards` fill mode keeps the final keyframe values in
 * effect after the animation ends. If fade-up (which has `transform` in
 * its keyframes) were applied to the avatar, any `.hero-avatar:hover`
 * transform would be ignored — the held `translateY(0) scale(1)` from
 * fade-up would always win. Splitting the avatar into a transform-free
 * entrance frees the transform property up for hover. */
.hero-avatar {
  opacity: 0;
  animation: hero-avatar-in var(--dur-page) var(--ease-out-soft) 480ms forwards;
}

@keyframes hero-avatar-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Phone float idle animation removed — the new hover lift in components.css
 * is the primary motion. A still resting state reads more polished against
 * the editorial B/W aesthetic. */

/* ========================================
   THEME TOGGLE — View Transitions API radial wipe
   ======================================== */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-new(root) {
  animation: theme-reveal 700ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
  clip-path: circle(0% at var(--theme-x, 50%) var(--theme-y, 50%));
}

::view-transition-old(root) {
  animation: theme-fade-out 700ms ease-out forwards;
  z-index: 0;
}

::view-transition-new(root) {
  z-index: 1;
}

@keyframes theme-reveal {
  from {
    clip-path: circle(0% at var(--theme-x, 50%) var(--theme-y, 50%));
  }
  to {
    clip-path: circle(150% at var(--theme-x, 50%) var(--theme-y, 50%));
  }
}

@keyframes theme-fade-out {
  from { opacity: 1; }
  to   { opacity: 1; }
}

/* ========================================
   PREFERS-REDUCED-MOTION FALLBACKS
   ======================================== */
@media (prefers-reduced-motion: reduce) {
  .pill.pill-pop {
    animation: none;
  }

  .hero-name,
  .hero-avatar,
  .hero-tagline,
  .hero-cta {
    opacity: 1;
    animation: none;
  }

  .phone-frame { animation: none; }

  .reveal,
  .reveal-stagger > * {
    opacity: 1;
    transform: none;
    transition: none;
  }

  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }
}
