/* ==========================================================================
   The Hidden Leaf Cafe — motion library (2026)
   All 68 @keyframes lifted verbatim from the approved design handoff.
   Sources:
     Homepage.dc.html:19-57   (39)
     Admin.dc.html:19-39      (21)
     Sign In.dc.html:18-21     (4)
     Offers.dc.html:18-23      (6)
     Menu.dc.html:18-19        (2)

   Definitions are byte-for-byte as designed. Do not retune durations or
   easings here — they live at the call site, exactly as in the prototypes.

   NAME COLLISIONS resolved (mechanical rename, identical output):
     glowPulse  is defined twice with different techniques —
                Admin uses filter:drop-shadow  -> --glow-pulse-filter
                Sign In uses box-shadow        -> --glow-pulse-box
     riseIn / ovIn / rise  are defined identically in multiple files;
                kept once each.
     spin       is dead in the Admin prototype BUT live in the existing
                production admin loader (.spin). Kept.
   ========================================================================== */

/* ---------------------------------------------------------------- shared -- */
@keyframes spin { to { transform: rotate(360deg) } }
@keyframes ovIn { 0% { opacity: 0 } 100% { opacity: 1 } }
@keyframes rise { from { transform: translateY(40px); opacity: .4 } to { transform: none; opacity: 1 } }
@keyframes riseIn { 0% { opacity: 0; transform: translateY(26px) } 100% { opacity: 1; transform: none } }

/* ================================================================ HOMEPAGE = */
@keyframes fall { 0% { transform: translateY(-40px) rotate(0) } 100% { transform: translateY(110vh) rotate(360deg) } }
@keyframes steam { 0% { opacity: 0; transform: translateY(6px) scaleY(.8) } 40% { opacity: .8 } 100% { opacity: 0; transform: translateY(-30px) scaleY(1.2) } }
@keyframes pulse { 0%, 100% { filter: drop-shadow(0 0 14px rgba(110,232,91,.35)) } 50% { filter: drop-shadow(0 0 30px rgba(110,232,91,.7)) } }
@keyframes blink { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }
@keyframes neonflicker { 0%, 100% { opacity: 1 } 41% { opacity: 1 } 42% { opacity: .55 } 43% { opacity: 1 } 62% { opacity: 1 } 63% { opacity: .7 } 64% { opacity: 1 } 65% { opacity: .85 } 66% { opacity: 1 } }
@keyframes markglow { 0%, 100% { filter: drop-shadow(0 0 6px rgba(110,232,91,.45)) } 50% { filter: drop-shadow(0 0 14px rgba(110,232,91,.85)) } }
@keyframes ribbonpulse { 0%, 100% { box-shadow: 0 0 0 rgba(110,232,91,0) } 50% { box-shadow: 0 0 18px rgba(110,232,91,.6) } }
@keyframes gameshine { 0%, 72%, 100% { transform: translateX(-60%) } 86% { transform: translateX(160%) } }
@keyframes heroRise { 0% { opacity: 0; transform: translateY(34px) } 100% { opacity: 1; transform: translateY(0) } }
@keyframes heroClip { 0% { clip-path: inset(0 100% 0 0); filter: blur(14px); opacity: 0 } 40% { opacity: 1 } 100% { clip-path: inset(0 0 0 0); filter: blur(0); opacity: 1 } }
@keyframes glowDrift { 0%, 100% { transform: translateX(-50%) scale(1) } 50% { transform: translateX(-46%) scale(1.08) } }

/* -- the cat -- */
@keyframes catbreathe { 0%, 100% { transform: scaleY(1) } 50% { transform: scaleY(1.035) } }
@keyframes catblink { 0%, 93%, 100% { transform: scaleY(1) } 96% { transform: scaleY(.08) } }
@keyframes cattail { 0%, 100% { transform: rotate(-7deg) } 50% { transform: rotate(9deg) } }
@keyframes catsway { 0%, 100% { transform: rotate(-6deg) } 50% { transform: rotate(7deg) } }
@keyframes catplate { 0%, 100% { filter: drop-shadow(0 0 3px rgba(141,255,106,.7)) } 50% { filter: drop-shadow(0 0 9px rgba(141,255,106,1)) } }
@keyframes poofRing { 0% { transform: scale(.2); opacity: .9 } 100% { transform: scale(1.6); opacity: 0 } }
@keyframes poofLeaf { 0% { transform: translate(0,0) rotate(0); opacity: 1 } 100% { transform: translate(var(--dx), var(--dy)) rotate(320deg); opacity: 0 } }
/* slashArc has zero CSS references — the paw slash is reimplemented via WAAPI
   at Homepage.dc.html:1426-1430 with identical values. Kept for fidelity (D15). */
@keyframes slashArc { 0% { opacity: 0; transform: rotate(-24deg) scale(.6) } 18% { opacity: 1 } 100% { opacity: 0; transform: rotate(26deg) scale(1.25) } }

/* -- modals / drawer -- */
@keyframes modalIn { 0% { opacity: 0; transform: translateY(26px) scale(.97) } 100% { opacity: 1; transform: none } }
@keyframes drawerIn { 0% { transform: translateX(100%) } 100% { transform: translateX(0) } }

/* -- intro overlay -- */
@keyframes hlcFocusIn { 0% { filter: blur(26px); transform: scale(1.14); opacity: 0 } 55% { opacity: 1 } 100% { filter: blur(0); transform: scale(1); opacity: 1 } }
@keyframes hlcClipReveal { 0% { clip-path: inset(0 100% 0 0); filter: blur(16px); opacity: 0 } 38% { opacity: 1 } 100% { clip-path: inset(0 0 0 0); filter: blur(0); opacity: 1 } }
@keyframes hlcRise { 0% { opacity: 0; transform: translateY(40px) } 100% { opacity: 1; transform: translateY(0) } }
@keyframes hlcFade { 0% { opacity: 0; transform: translateY(14px) } 100% { opacity: 1; transform: translateY(0) } }
@keyframes hlcLeafFall { 0% { transform: translateY(-60px) rotate(0) } 100% { transform: translateY(116vh) rotate(400deg) } }
@keyframes hlcDot { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
@keyframes hlcBob { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-9px) } }
@keyframes hlcLeap { 0% { opacity: 0; transform: translateY(160px) scale(.8) } 55% { opacity: 1; transform: translateY(-20px) scale(1.05) } 100% { opacity: 1; transform: translateY(0) scale(1) } }
@keyframes hlcScanBeam { 0% { transform: rotate(-6deg) translateY(-140%); opacity: 0 } 22% { opacity: 1 } 100% { transform: rotate(-6deg) translateY(360%); opacity: 0 } }
@keyframes hlcEmblemPop { 0% { opacity: 0; transform: scale(.2) rotate(-28deg) } 60% { opacity: 1; transform: scale(1.13) rotate(7deg) } 100% { opacity: 1; transform: scale(1) rotate(0) } }
@keyframes hlcRingDraw { 0% { stroke-dashoffset: 360; opacity: 0 } 40% { opacity: 1 } 100% { stroke-dashoffset: 0; opacity: 1 } }
@keyframes hlcGlitch { 0%, 46%, 54%, 100% { text-shadow: 0 0 38px rgba(110,232,91,.35) } 48% { text-shadow: 3px 0 rgba(255,46,110,.6), -3px 0 rgba(41,255,227,.6) } 50% { text-shadow: -3px 0 rgba(255,46,110,.6), 3px 0 rgba(41,255,227,.6) } }
@keyframes hlcKalShake { 0%, 100% { transform: translate(0,0) } 20% { transform: translate(-3px,2px) } 40% { transform: translate(3px,-2px) } 60% { transform: translate(-2px,-1px) } 80% { transform: translate(2px,1px) } }
@keyframes hlcWipe { 0% { transform: scaleX(0) } 100% { transform: scaleX(1) } }
@keyframes hlcCta { 0%, 100% { box-shadow: 0 0 0 rgba(110,232,91,0) } 50% { box-shadow: 0 0 30px rgba(110,232,91,.5) } }
@keyframes hlcCaret { 0%, 100% { opacity: 1 } 50% { opacity: 0 } }

/* =================================================================== ADMIN = */
@keyframes pageIn { 0% { opacity: 0; transform: translateY(14px) } 100% { opacity: 1; transform: none } }
@keyframes sheetUp { 0% { transform: translateY(56px); opacity: 0 } 100% { transform: none; opacity: 1 } }
@keyframes sheetCenter { 0% { transform: translateY(26px) scale(.97); opacity: 0 } 100% { transform: none; opacity: 1 } }
@keyframes toastIn { 0% { opacity: 0; transform: translate(-50%,12px) } 100% { opacity: 1; transform: translate(-50%,0) } }
@keyframes pcpulse { 0%, 100% { box-shadow: 0 0 18px rgba(217,154,43,.16) } 50% { box-shadow: 0 0 34px rgba(217,154,43,.42) } }
@keyframes holdBlink { 0%, 100% { opacity: 1 } 50% { opacity: .55 } }
@keyframes fabIn { 0% { transform: scale(.6); opacity: 0 } 100% { transform: scale(1); opacity: 1 } }

/* Admin's glowPulse — filter technique (sidebar logo, settle spinner leaf) */
@keyframes glowPulseFilter { 0%, 100% { filter: drop-shadow(0 0 8px rgba(110,232,91,.35)) } 50% { filter: drop-shadow(0 0 20px rgba(110,232,91,.75)) } }

/* -- THE SETTLE ANIMATION -- */
@keyframes stSpin { to { transform: rotate(360deg) } }
@keyframes stOrbit { 0% { transform: rotate(0) translateX(34px) rotate(0) } 100% { transform: rotate(360deg) translateX(34px) rotate(-360deg) } }
@keyframes stStepIn { 0% { opacity: 0; transform: translateX(-10px) } 100% { opacity: 1; transform: none } }
@keyframes stRing { 0% { stroke-dashoffset: 302 } 100% { stroke-dashoffset: 0 } }
@keyframes stCheck { 0% { stroke-dashoffset: 48 } 100% { stroke-dashoffset: 0 } }
@keyframes stPop { 0% { transform: scale(.4); opacity: 0 } 55% { transform: scale(1.12) } 100% { transform: scale(1); opacity: 1 } }
@keyframes stPrint { 0% { transform: translateY(-104%) } 100% { transform: translateY(0) } }
@keyframes stRise { 0% { opacity: 0; transform: translateY(18px) } 100% { opacity: 1; transform: none } }
@keyframes stLeaf { 0% { transform: translate(0,0) rotate(0); opacity: 1 } 100% { transform: translate(var(--dx), var(--dy)) rotate(300deg); opacity: 0 } }
/* stRowIn and stGlowBar are defined in the prototype but never referenced (D15). */

/* ================================================================= SIGN IN = */
@keyframes cardSwap { 0% { opacity: 0; transform: translateY(14px) scale(.985) } 100% { opacity: 1; transform: none } }
@keyframes coinSpin { 0%, 100% { transform: rotateY(0) } 50% { transform: rotateY(180deg) } }
/* Sign In's glowPulse — box-shadow technique (58px avatar) */
@keyframes glowPulseBox { 0%, 100% { box-shadow: 0 0 14px rgba(110,232,91,.15) } 50% { box-shadow: 0 0 30px rgba(110,232,91,.4) } }

/* ================================================================== OFFERS = */
@keyframes coinFlip { 0%, 100% { transform: rotateY(0) } 50% { transform: rotateY(180deg) } }
@keyframes coinGlow { 0%, 100% { box-shadow: 0 0 18px rgba(110,232,91,.25) } 50% { box-shadow: 0 0 34px rgba(110,232,91,.55) } }
@keyframes shimmer { 0% { background-position: -200% 0 } 100% { background-position: 200% 0 } }
@keyframes floatLeaf { 0% { transform: translateY(-40px) rotate(0) } 100% { transform: translateY(110vh) rotate(360deg) } }
@keyframes pulseDot { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }

/* ==================================================================== MENU = */
@keyframes steamUp { 0% { opacity: 0; transform: translateY(4px) scaleY(.8) } 40% { opacity: .7 } 100% { opacity: 0; transform: translateY(-16px) scaleY(1.2) } }

/* ==========================================================================
   Reduced motion
   README Motion spec: "Reduced motion: honor prefers-reduced-motion by
   disabling parallax/tilt/leaves (prototype does not, production should)."
   See DEVIATIONS.md D19.

   Ambient/decorative motion is switched off. Meaningful state-change motion
   (sheets opening, settle steps advancing, toasts) is kept but shortened, so
   the interface still communicates what changed.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {

  /* ambient loops — off entirely */
  .fx-leaves,
  #hlLeaves,
  #ofLeaves,
  #hlcLeaves,
  [data-sweeper] {
    display: none !important;
  }

  [style*="animation:fall"],
  [style*="animation:floatLeaf"],
  [style*="animation:hlcLeafFall"] {
    animation: none !important;
  }

  /* parallax + tilt are transform-driven from JS; fx.js checks this too */
  [data-tilt],
  [data-tiltimg],
  [data-mag] {
    transform: none !important;
    transition: none !important;
  }

  /* decorative infinite loops */
  [style*="glowDrift"], [style*="markglow"], [style*="neonflicker"],
  [style*="ribbonpulse"], [style*="gameshine"], [style*="pulseDot"],
  [style*="coinFlip"], [style*="coinSpin"], [style*="coinGlow"],
  [style*="shimmer"], [style*="steam"], [style*="steamUp"],
  [style*="catbreathe"], [style*="catblink"], [style*="cattail"],
  [style*="catsway"], [style*="catplate"], [style*="pcpulse"],
  [style*="holdBlink"], [style*="glowPulse"], [style*="hlcBob"],
  [style*="hlcDot"], [style*="hlcCta"], [style*="hlcGlitch"],
  [style*="hlcCaret"], [style*="blink"], [style*="pulse"] {
    animation: none !important;
  }

  /* entrance/state motion — kept, but near-instant */
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-delay: 0ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  /* reveals must not stay stuck at opacity:0 when their animation is skipped */
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
}
