/* ============================================================
   Brake Swap — Animation Stylesheet (dependency-free)
   Implements an Animate.css-style class set + the discrete
   "steps()" engine visuals used by the micro-animation player.
   Replaces external Anime.js / Animate.css per the
   "no external CDN" requirement — same class names & semantics.
   ============================================================ */

/* ---- Animate.css-style entrance / emphasis ---- */
.animate__animated { animation-duration: .7s; animation-fill-mode: both; }
.animate__faster { animation-duration: .4s; }
.animate__fast { animation-duration: .5s; }
.animate__slow { animation-duration: 1.1s; }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeInUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fadeInDown { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes zoomIn { from { opacity: 0; transform: scale(.9); } to { opacity: 1; transform: scale(1); } }
@keyframes pulse {
  0% { transform: scale(1); } 50% { transform: scale(1.06); } 100% { transform: scale(1); }
}
@keyframes bounce { 0%,100% { transform: translateY(0); } 40% { transform: translateY(-10px); } 70% { transform: translateY(-5px); } }
@keyframes flash { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes wobble {
  0% { transform: translateX(0); } 20% { transform: translateX(-6px) rotate(-2deg); }
  40% { transform: translateX(6px) rotate(2deg); } 60% { transform: translateX(-4px) rotate(-1deg); }
  80% { transform: translateX(4px) rotate(1deg); } 100% { transform: translateX(0); }
}
@keyframes hs-pulse {
  0% { box-shadow: 0 0 0 0 rgba(232,138,60,.5); }
  70% { box-shadow: 0 0 0 12px rgba(232,138,60,0); }
  100% { box-shadow: 0 0 0 0 rgba(232,138,60,0); }
}

.animate__fadeIn { animation-name: fadeIn; }
.animate__fadeInUp { animation-name: fadeInUp; }
.animate__fadeInDown { animation-name: fadeInDown; }
.animate__zoomIn { animation-name: zoomIn; }
.animate__pulse { animation-name: pulse; }
.animate__bounce { animation-name: bounce; }
.animate__flash { animation-name: flash; }
.animate__spin { animation-name: spin; }
.animate__wobble { animation-name: wobble; }

/* ---- Discrete steps() engine ----
   The JS sets `--step` (0..N) and toggles `is-playing`. Frames are
   rendered by instantly snapping transform to the discrete keyframe
   (no interpolation), replicating Anime.js easing: steps(N). */
.stepfx { position: relative; }

/* generic classes the player toggles */
.fx-hidden { opacity: 0; }
.fx-shown { opacity: 1; }
.fx-dim { opacity: .25; }

/* discrete jump helper: applied per-frame by JS via inline transform,
   this just makes the change feel intentional */
.stepfx.is-stepping * { transition: none !important; }

/* progress dots */
.step-dots { display: inline-flex; gap: 6px; }
.step-dots .d { width: 9px; height: 9px; border-radius: 50%; background: var(--g-700); transition: background .15s; }
.step-dots .d.on { background: var(--o-500); }
.step-dots .d.done { background: var(--o-800); }

/* error demo shake */
@keyframes shakeX {
  0%,100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}
.fx-shake { animation: shakeX .4s ease; }

/* success check pop */
@keyframes popIn { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: scale(1); } }
.fx-pop { animation: popIn .35s ease both; }
