/* ============================================================================
   Stays Locked — motion
   ----------------------------------------------------------------------------
   Keyframes lifted verbatim from the two design prototypes shipped with this
   repo (see docs/design/ for their location), then de-duplicated and grouped
   by purpose. **These are the designer's actual curves — do not retime them by
   feel.** The prototypes carried A/B copies of several identical keyframes
   (tickInA/tickInB and friends); those are merged here.

   Everything here is covered by prefers-reduced-motion at the end of the file.
   ========================================================================== */


/* ---------------------------------------------------------------- ticker */

@keyframes tickInA {
  0%{max-width:0;opacity:0;transform:scale(.6)}
  45%{max-width:520px;opacity:1;transform:scale(1.05);background:#E3FF4D;border-color:#1F1F1F}
  65%{transform:scale(.98)}
  100%{max-width:520px;transform:scale(1);background:#F3F5EE;border-color:rgba(31,31,31,0)}
}

@keyframes tickPop {
  0%{transform:translateX(-50%) scale(1);background:#fff;color:#1F1F1F}
  40%{transform:translateX(-50%) scale(1.3);background:#1F1F1F;color:#E3FF4D}
  100%{transform:translateX(-50%) scale(1);background:#1F1F1F;color:#E3FF4D}
}

@keyframes squeezeA {
  0%{transform:translateX(-18px)}
  40%{transform:translateX(8px)}
  70%{transform:translateX(-3px)}
  100%{transform:none}
}

@keyframes livePulse {
  0%,100%{box-shadow:0 0 0 0 rgba(31,31,31,.35)}
  60%{box-shadow:0 0 0 7px rgba(31,31,31,0)}
}

@keyframes blink {
  0%,100%{opacity:1}
  50%{opacity:0}
}

@keyframes popInA {
  0%{max-width:0;opacity:0;transform:scale(.4) rotate(-6deg)}
  50%{max-width:520px;opacity:1;transform:scale(1.08) rotate(2deg)}
  72%{transform:scale(.96) rotate(0)}
  100%{max-width:520px;transform:none}
}

@keyframes walletBump {
  0%,80%{transform:none}
  86%{transform:scale(1.12) rotate(-4deg)}
  93%{transform:scale(.96)}
  100%{transform:none}
}


/* ---------------------------------------------------------------- vault: deposit */

@keyframes coinFly {
  0%{transform:translate(-190px,-230px) scale(.6) rotate(-120deg);opacity:0}
  8%{opacity:1}
  50%{transform:translate(14px,-200px) scale(1.15) rotate(30deg)}
  76%{transform:translate(0,0) rotate(200deg)}
  85%{transform:translate(0,-16px) rotate(215deg)}
  100%{transform:translate(0,0) rotate(225deg)}
}

@keyframes lidDown {
  0%,66%{transform:translateY(-110px) rotate(-14deg);opacity:0}
  70%{opacity:1}
  80%{transform:translateY(5px) scaleY(.8);opacity:1}
  90%{transform:translateY(-3px)}
  100%{transform:none;opacity:1}
}

@keyframes lockPop {
  0%,86%{transform:scale(0) rotate(-20deg)}
  93%{transform:scale(1.3) rotate(6deg)}
  100%{transform:scale(1) rotate(0)}
}

@keyframes fillUp {
  0%,60%{height:0}
  100%{height:54%}
}

@keyframes capCoin {
  0%{transform:translate(180px,-140px) scale(.7);opacity:0}
  10%{opacity:1}
  55%{transform:translate(0,-10px) scale(1.1)}
  72%{transform:translate(0,30px) scale(0);opacity:1}
  100%{transform:translate(0,30px) scale(0);opacity:0}
}

@keyframes capFill {
  0%,28%{height:0}
  100%{height:60%}
}

@keyframes capJump {
  0%,80%{transform:none}
  87%{transform:translateY(-16px) scaleX(.94) scaleY(1.06)}
  94%{transform:translateY(0) scaleX(1.06) scaleY(.94)}
  100%{transform:none}
}

@keyframes coinBurst {
  0%,30%{transform:scale(0);opacity:0}
  44%{transform:scale(1.15);opacity:1}
  54%{transform:translate(0,-10px) scale(1)}
  100%{transform:translate(190px,-130px) scale(.4) rotate(300deg);opacity:0}
}


/* ---------------------------------------------------------------- vault: withdraw */

@keyframes coinOut {
  0%,44%{transform:translate(0,0) rotate(0);opacity:1}
  60%{transform:translate(20px,-150px) scale(1.15) rotate(120deg)}
  100%{transform:translate(170px,-205px) scale(.4) rotate(360deg);opacity:0}
}

@keyframes lidOff {
  0%,34%{transform:none}
  42%{transform:translateY(-36px) rotate(-10deg)}
  100%{transform:translate(150px,-210px) rotate(70deg);opacity:0}
}

@keyframes lockShake {
  0%,10%{transform:none}
  13%{transform:rotate(-12deg)}
  16%{transform:rotate(12deg)}
  19%{transform:rotate(-10deg)}
  22%{transform:rotate(8deg)}
  25%{transform:none;opacity:1}
  38%{transform:translateY(-34px) rotate(-30deg);opacity:0}
  100%{transform:translateY(-34px);opacity:0}
}

@keyframes shackleOpen {
  0%,25%{transform:none}
  31%{transform:translate(-7px,-7px) rotate(-35deg)}
  100%{transform:translate(-7px,-7px) rotate(-35deg)}
}

@keyframes jarWobble {
  0%,76%{transform:none}
  82%{transform:scaleX(1.07) scaleY(.93)}
  90%{transform:scaleX(.97) scaleY(1.03)}
  100%{transform:none}
}

@keyframes drain {
  0%,48%{height:54%}
  100%{height:0}
}

@keyframes capDrain {
  0%,36%{height:60%}
  100%{height:0}
}

@keyframes sparkOut {
  0%,34%{transform:translateY(0) scale(0);opacity:0}
  42%{transform:translateY(-38px) scale(1);opacity:1}
  58%{transform:translateY(-64px) scale(0);opacity:0}
  100%{opacity:0}
}

@keyframes badgePop {
  0%,78%{transform:scale(0);opacity:0}
  86%{transform:scale(1.2);opacity:1}
  100%{transform:scale(1);opacity:1}
}


/* ---------------------------------------------------------------- tiers and ladder */

@keyframes tierLight {
  0%{background:#E9ECE3;transform:scaleY(1)}
  40%{background:#E3FF4D;transform:scaleY(1.7)}
  100%{background:#E3FF4D;transform:scaleY(1)}
}

@keyframes arcLight {
  0%{stroke:#E9ECE3}
  40%{stroke:#E3FF4D;stroke-width:22}
  100%{stroke:#E3FF4D;stroke-width:16}
}

@keyframes arcSweep {
  0%{transform:rotate(135deg)}
  100%{transform:rotate(354deg)}
}

@keyframes sweep {
  0%{left:0}
  100%{left:81.3%}
}

@keyframes halfUp {
  0%,22%{transform:none}
  36%{transform:translateY(-46px) rotate(-7deg)}
  44%{transform:translateY(-40px) rotate(-5deg)}
  100%{transform:translateY(-40px) rotate(-5deg)}
}

@keyframes halfDown {
  0%,22%{transform:none}
  36%{transform:translateY(26px) rotate(4deg)}
  44%{transform:translateY(20px) rotate(3deg)}
  100%{transform:translateY(20px) rotate(3deg)}
}

@keyframes bandWrap {
  0%,78%{transform:scaleX(0);opacity:0}
  86%{transform:scaleX(1.12);opacity:1}
  94%{transform:scaleX(.96)}
  100%{transform:none;opacity:1}
}

@keyframes bandSnap {
  0%,8%{transform:none;opacity:1}
  16%{transform:scaleX(1.12)}
  24%{transform:scaleX(0);opacity:0}
  100%{transform:scaleX(0);opacity:0}
}

@keyframes handleHit {
  0%,54%{border-color:#E3FF4D;background:#1F1F1F}
  58%{border-color:#E8473C;background:#E8473C;transform:scale(1.35)}
  70%{transform:scale(1)}
  100%{border-color:#E8473C;background:#E8473C}
}

@keyframes swapA {
  0%{transform:scaleY(.1);opacity:0}
  45%{transform:scaleY(1.18);opacity:1}
  65%{transform:scaleY(.94)}
  100%{transform:none}
}

@keyframes underA {
  0%{transform:scaleX(0)}
  100%{transform:scaleX(1)}
}


/* ---------------------------------------------------------------- graduation wall */

@keyframes wallHit {
  0%,54%{transform:none;box-shadow:0 0 0 0 rgba(232,71,60,0)}
  58%{transform:translateX(8px) scaleX(1.12);box-shadow:0 0 0 10px rgba(232,71,60,.35)}
  66%{transform:translateX(-3px)}
  74%{transform:translateX(2px);box-shadow:0 0 0 0 rgba(232,71,60,0)}
  100%{transform:none}
}

@keyframes wallGrow {
  0%{transform:scaleX(0);opacity:0}
  60%{transform:scaleX(1.1);opacity:1}
  100%{transform:scaleX(1);opacity:1}
}

@keyframes dragToWall {
  0%,8%{left:24%}
  52%{left:calc(100% - 14px)}
  58%{left:calc(100% - 2px)}
  66%{left:calc(100% - 44px)}
  76%{left:calc(100% - 22px)}
  84%{left:calc(100% - 32px)}
  100%{left:calc(100% - 28px)}
}

@keyframes trackShake {
  0%,56%{transform:none}
  60%{transform:translateX(-5px)}
  64%{transform:translateX(5px)}
  68%{transform:translateX(-3px)}
  72%{transform:translateX(2px)}
  76%{transform:none}
}

@keyframes tipPop {
  0%,56%{opacity:0;transform:translate(-50%,10px) scale(.7)}
  64%{opacity:1;transform:translate(-50%,0) scale(1.08)}
  72%{transform:translate(-50%,0) scale(1)}
  100%{opacity:1;transform:translate(-50%,0)}
}

@keyframes shakeX {
  0%,100%{transform:none}
  15%{transform:translateX(-8px)}
  30%{transform:translateX(8px)}
  45%{transform:translateX(-6px)}
  60%{transform:translateX(5px)}
  75%{transform:translateX(-2px)}
}


/* ---------------------------------------------------------------- seals and cards */

@keyframes stampSlam {
  0%{transform:rotate(-10deg) scale(3);opacity:0}
  55%{transform:rotate(-10deg) scale(.92);opacity:1}
  75%{transform:rotate(-10deg) scale(1.06)}
  100%{transform:rotate(-10deg) scale(1);opacity:1}
}

@keyframes cardIn {
  0%{opacity:0;transform:translateY(30px) scale(.97)}
  100%{opacity:1;transform:none}
}

@keyframes modalIn {
  0%{opacity:0;transform:translateY(24px) scale(.96)}
  60%{transform:translateY(-4px) scale(1.01);opacity:1}
  100%{transform:none}
}

@keyframes fadeUp {
  0%,84%{opacity:0;transform:translateY(10px)}
  100%{opacity:1;transform:none}
}

@keyframes numPulse {
  0%{transform:scale(1)}
  50%{transform:scale(1.18)}
  100%{transform:scale(1)}
}

@keyframes readFade {
  0%,52%{opacity:1}
  58%{opacity:0}
  100%{opacity:0}
}

@keyframes spin {
  to{transform:rotate(360deg)}
}


/* ---------------------------------------------------------------- applied classes */

.anim-stamp   { animation: stampSlam .5s cubic-bezier(.2,1.3,.4,1) both; }
.anim-card    { animation: cardIn .45s cubic-bezier(.2,.9,.3,1) both; }
.anim-modal   { animation: modalIn .4s cubic-bezier(.2,1.1,.35,1) both; }
.anim-fadeup  { animation: fadeUp .35s ease both; }
.anim-tick    { animation: tickInA .62s cubic-bezier(.2,1.1,.35,1) both; }
.anim-pulse   { animation: numPulse .4s ease; }
.anim-wallhit { animation: wallHit .55s cubic-bezier(.3,.9,.3,1); }
.anim-shake   { animation: shakeX .45s ease; }
.anim-spin    { animation: spin .9s linear infinite; }
.anim-live    { animation: livePulse 2.2s ease-out infinite; }

/* Staggered entrance: set --i on each list item */
.stagger > * { animation: fadeUp .4s ease both; animation-delay: calc(var(--i, 0) * 60ms); }

@media (prefers-reduced-motion: reduce) {
  /* Coins flying and walls shaking are exactly the kind of motion that makes
     vestibular-sensitive readers ill. Collapse everything to instant while
     keeping the end state — `both` / `forwards` semantics are unaffected. */
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
