/* ==========================================================================
   TypingSwift — Animations
   ========================================================================== */

/* --------------------------------------------------------------------------
   Core keyframes
   -------------------------------------------------------------------------- */
@keyframes ts-fade-up {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes ts-fade-down {
  from { opacity: 0; transform: translateY(-24px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes ts-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes ts-slide-right {
  from { opacity: 0; transform: translateX(-24px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes ts-slide-left {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes ts-scale-in {
  from { opacity: 0; transform: scale(.92); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes ts-float {
  0%, 100% { transform: translateY(0px); }
  50%       { transform: translateY(-20px); }
}
@keyframes ts-pulse-ring {
  0%, 100% { box-shadow: 0 0 0 0 rgba(6,182,212,.4); }
  50%       { box-shadow: 0 0 0 8px rgba(6,182,212,0); }
}
@keyframes ts-spin {
  to { transform: rotate(360deg); }
}
@keyframes ts-caret-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}
@keyframes ts-scroll-anim {
  0%  { opacity: 1; transform: translateY(0); }
  75% { opacity: 0; transform: translateY(10px); }
  76% { opacity: 0; transform: translateY(0); }
  100%{ opacity: 1; }
}
@keyframes ts-shake {
  0%, 100% { transform: translateX(0); }
  20%       { transform: translateX(-6px); }
  40%       { transform: translateX(6px); }
  60%       { transform: translateX(-4px); }
  80%       { transform: translateX(4px); }
}
@keyframes ts-pop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
@keyframes ts-glow-pulse {
  0%, 100% { box-shadow: 0 0 32px rgba(124,58,237,.4); }
  50%       { box-shadow: 0 0 64px rgba(124,58,237,.65); }
}
@keyframes ts-word-correct {
  0%   { color: var(--ts-success); }
  100% { color: var(--ts-muted); }
}
@keyframes ts-char-error {
  0%   { background: rgba(239,68,68,.3); }
  100% { background: transparent; }
}
@keyframes ts-counter-up {
  from { transform: translateY(100%); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
@keyframes ts-line-slide-up {
  from { transform: translateY(0); }
  to   { transform: translateY(calc(-1 * var(--line-h, 48px))); }
}
@keyframes ts-result-reveal {
  from { opacity: 0; transform: translateY(40px) scale(.96); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}
@keyframes ts-trophy-bounce {
  0%, 100% { transform: scale(1); }
  30%       { transform: scale(1.25) rotate(-5deg); }
  60%       { transform: scale(1.1)  rotate(3deg); }
}
@keyframes ts-progress-fill {
  from { width: 0; }
  to   { width: var(--progress, 0%); }
}
@keyframes ts-number-flip {
  0%   { transform: perspective(300px) rotateX(0deg);   }
  50%  { transform: perspective(300px) rotateX(-90deg); }
  100% { transform: perspective(300px) rotateX(0deg);   }
}
@keyframes ts-particles-drift {
  0%    { transform: translateY(0)  translateX(0) rotate(0deg); opacity: .6; }
  33%   { transform: translateY(-30px) translateX(20px)  rotate(120deg); opacity: .4; }
  66%   { transform: translateY(-20px) translateX(-15px) rotate(240deg); opacity: .7; }
  100%  { transform: translateY(0)  translateX(0) rotate(360deg); opacity: .6; }
}

/* --------------------------------------------------------------------------
   Reveal on scroll (.ts-reveal)
   -------------------------------------------------------------------------- */
.ts-reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .6s cubic-bezier(.22,1,.36,1),
              transform .6s cubic-bezier(.22,1,.36,1);
  transition-delay: calc(var(--delay, 0) * 1ms);
}
.ts-reveal.ts-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Opt-out if user prefers reduced motion */
@media (prefers-reduced-motion: reduce) {
  .ts-reveal { transition: none; opacity: 1; transform: none; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* Animation disabled via customizer */
body.ts-no-animations .ts-reveal { opacity: 1; transform: none; transition: none; }

/* --------------------------------------------------------------------------
   Named reveal variants
   -------------------------------------------------------------------------- */
.ts-reveal--delay-1 { transition-delay: 100ms; }
.ts-reveal--delay-2 { transition-delay: 200ms; }
.ts-reveal--delay-3 { transition-delay: 300ms; }
.ts-reveal--delay-4 { transition-delay: 450ms; }
.ts-reveal--delay-5 { transition-delay: 600ms; }

[data-animate="fade-up"]    { animation: ts-fade-up   .7s cubic-bezier(.22,1,.36,1) forwards; }
[data-animate="fade-in"]    { animation: ts-fade-in   .7s ease forwards; }
[data-animate="scale-in"]   { animation: ts-scale-in  .6s cubic-bezier(.22,1,.36,1) forwards; }
[data-animate="slide-right"]{ animation: ts-slide-right .7s cubic-bezier(.22,1,.36,1) forwards; }

/* --------------------------------------------------------------------------
   Page transition overlay
   -------------------------------------------------------------------------- */
#ts-page-transition {
  position: fixed;
  inset: 0;
  background: var(--ts-bg);
  z-index: 99999;
  pointer-events: none;
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform .4s cubic-bezier(.76,0,.24,1);
}
#ts-page-transition.entering {
  transform: scaleY(1);
  transform-origin: bottom;
}
#ts-page-transition.leaving {
  transform: scaleY(0);
  transform-origin: top;
}

/* --------------------------------------------------------------------------
   Particle canvas
   -------------------------------------------------------------------------- */
#ts-particles {
  opacity: .45;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Hero demo animation
   -------------------------------------------------------------------------- */
@keyframes ts-demo-wpm {
  0%   { content: '0'; }
  20%  { content: '42'; }
  50%  { content: '87'; }
  80%  { content: '115'; }
  100% { content: '142'; }
}

/* --------------------------------------------------------------------------
   Keyboard key press
   -------------------------------------------------------------------------- */
.ts-key.ts-key--pressing {
  animation: ts-key-press .12s ease forwards;
}
@keyframes ts-key-press {
  0%   { transform: translateY(0)  scale(1); background: var(--ts-bg-card); }
  40%  { transform: translateY(3px) scale(.95); background: var(--ts-accent); border-color: var(--ts-accent); color: #fff; }
  100% { transform: translateY(0)  scale(1); }
}

/* --------------------------------------------------------------------------
   Score save badge animation
   -------------------------------------------------------------------------- */
.ts-results-badge.new-best {
  animation: ts-trophy-bounce .6s ease forwards;
}

/* --------------------------------------------------------------------------
   Live WPM counter pop
   -------------------------------------------------------------------------- */
.ts-live-stat__val.ts-val-change {
  animation: ts-counter-up .25s cubic-bezier(.22,1,.36,1) forwards;
}

/* --------------------------------------------------------------------------
   Challenge results
   -------------------------------------------------------------------------- */
.ts-results-panel.open {
  animation: ts-result-reveal .5s cubic-bezier(.22,1,.36,1) forwards;
}

/* --------------------------------------------------------------------------
   Belt scroll (duplicated in main.css, keep for override)
   -------------------------------------------------------------------------- */
.ts-features-belt:hover .ts-belt-list { animation-play-state: paused; }

/* --------------------------------------------------------------------------
   Typing cursor styles
   -------------------------------------------------------------------------- */
.ts-caret {
  display: inline-block;
  position: absolute;
  pointer-events: none;
  z-index: 10;
  transition: left .04s, top .04s;
}
.ts-caret--line {
  width: 2px;
  background: var(--ts-accent);
  animation: ts-caret-blink 1s step-end infinite;
  border-radius: 1px;
}
.ts-caret--block {
  background: rgba(124,58,237,.35);
  border-radius: var(--ts-radius-sm);
}

/* --------------------------------------------------------------------------
   Glow button pulse
   -------------------------------------------------------------------------- */
.ts-btn-glow:not(:hover) {
  animation: ts-glow-pulse 3s ease-in-out infinite;
}

/* --------------------------------------------------------------------------
   Smooth counter
   -------------------------------------------------------------------------- */
.ts-counter { display: inline-block; }
