/* ============================================================
   fun.css — CardQuiz · Playful Animation Layer (kids PWA)
   ------------------------------------------------------------
   Loads LAST (after variables / base / components / screens).
   ONLY adds animations, transitions, transforms, glows, and
   pseudo-element shine sweeps — no layout or structural changes.

   All keyframes are namespaced with the `fun-` prefix to avoid
   collisions with base.css (which owns: fadeIn, popIn, shake,
   spin, slideDown, pulse, fadeInUp).

   Score pop (JS toggles .score-pop on the .quiz-score container):
   ============================================================ */
.quiz-score.score-pop { animation: fun-pop var(--dur-base) var(--ease-spring); }

/* ============================================================
   Tokens only for colours / shadows / radii / spacing / motion.
   Literal rgba() white/black are the sole exception (shine &
   glow sweeps).
   ============================================================ */


/* ════════════════════════════════════════════════════════════
   §0  KEYFRAMES — all prefixed `fun-`
   ════════════════════════════════════════════════════════════ */

/* Springy entrance: scale up → slight overshoot → settle */
@keyframes fun-bounce-in {
  0%   { transform: scale(0.5);  opacity: 0; }
  55%  { transform: scale(1.08); opacity: 1; }
  78%  { transform: scale(0.96);             }
  100% { transform: scale(1);    opacity: 1; }
}

/* Quick delight pop: 1 → 1.18 → 1 */
@keyframes fun-pop {
  0%   { transform: scale(1);    }
  45%  { transform: scale(1.18); }
  100% { transform: scale(1);    }
}

/* Gentle left-right rotation wiggle */
@keyframes fun-wiggle {
  0%,  100% { transform: rotate(0deg);  }
  20%        { transform: rotate(-5deg); }
  40%        { transform: rotate(5deg);  }
  60%        { transform: rotate(-4deg); }
  80%        { transform: rotate(3deg);  }
}

/* Slow idle up-down float */
@keyframes fun-float {
  0%,  100% { transform: translateY(0px);  }
  50%        { transform: translateY(-6px); }
}

/* Squash-and-stretch jelly press */
@keyframes fun-jelly {
  0%   { transform: scale(1,    1   ); }
  20%  { transform: scale(0.91, 1.1 ); }
  45%  { transform: scale(1.1,  0.91); }
  70%  { transform: scale(0.96, 1.04); }
  100% { transform: scale(1,    1   ); }
}

/* Celebratory tada: burst + rotation swings */
@keyframes fun-tada {
  0%   { transform: scale(1)    rotate(0deg);  }
  10%  { transform: scale(0.95) rotate(-3deg); }
  25%  { transform: scale(1.1)  rotate(3deg);  }
  40%  { transform: scale(1.1)  rotate(-3deg); }
  55%  { transform: scale(1.1)  rotate(3deg);  }
  70%  { transform: scale(1.05) rotate(-1deg); }
  85%  { transform: scale(1.02) rotate(1deg);  }
  100% { transform: scale(1)    rotate(0deg);  }
}

/* Hue-rotate loop — used sparingly */
@keyframes fun-rainbow {
  0%   { filter: hue-rotate(0deg);   }
  100% { filter: hue-rotate(360deg); }
}

/* Sweeping translucent-white highlight (moves via translateX) */
@keyframes fun-shine {
  0%   { transform: translateX(-160%) skewX(-18deg); }
  100% { transform: translateX(280%)  skewX(-18deg); }
}

/* Subtle scale heartbeat pulse */
@keyframes fun-heartbeat {
  0%,  100% { transform: scale(1);    }
  50%        { transform: scale(1.03); }
}

/* Star reward burst: zero → overshoot → settle, with spin */
@keyframes fun-star-burst {
  0%   { transform: scale(0)   rotate(-40deg); opacity: 0; }
  55%  { transform: scale(1.4) rotate(12deg);  opacity: 1; }
  100% { transform: scale(1)   rotate(0deg);   opacity: 1; }
}

/* Gentle horizontal wobble — kinder replacement for harsh shake */
@keyframes fun-gentle-shake {
  0%,  100% { transform: translateX(0);    }
  18%        { transform: translateX(-7px); }
  38%        { transform: translateX(7px);  }
  58%        { transform: translateX(-4px); }
  78%        { transform: translateX(4px);  }
}


/* ════════════════════════════════════════════════════════════
   §1  CARD ENTRANCE — stagger bounce-in pop
   ════════════════════════════════════════════════════════════ */

.flag-flip-card,
.text-card,
.mode-card {
  animation: fun-bounce-in var(--dur-slow) var(--ease-spring) both;
}

/* 40 ms increment stagger, capped at 8 children */
:is(.flag-flip-card, .text-card, .mode-card):nth-child(1) { animation-delay:   0ms; }
:is(.flag-flip-card, .text-card, .mode-card):nth-child(2) { animation-delay:  40ms; }
:is(.flag-flip-card, .text-card, .mode-card):nth-child(3) { animation-delay:  80ms; }
:is(.flag-flip-card, .text-card, .mode-card):nth-child(4) { animation-delay: 120ms; }
:is(.flag-flip-card, .text-card, .mode-card):nth-child(5) { animation-delay: 160ms; }
:is(.flag-flip-card, .text-card, .mode-card):nth-child(6) { animation-delay: 200ms; }
:is(.flag-flip-card, .text-card, .mode-card):nth-child(7) { animation-delay: 240ms; }
:is(.flag-flip-card, .text-card, .mode-card):nth-child(8) { animation-delay: 280ms; }


/* ════════════════════════════════════════════════════════════
   §2  FLAG FLIP CARD — delightful hover & flip
   ════════════════════════════════════════════════════════════ */

/* Add spring to the transform transition (was ease-out only) */
.flag-flip-card {
  transition:
    box-shadow var(--dur-fast) var(--ease-out),
    transform  var(--dur-base) var(--ease-spring);
}

/* Hover: springy lift + slight scale */
.flag-flip-card:hover {
  transform: translateY(-4px) scale(1.03);
  box-shadow: var(--sh-md);
}

/* Flip reveal: spring timing gives a satisfying overshoot */
.flag-flip-card.flipped .flag-flip-inner {
  transition-timing-function: var(--ease-spring);
}

/* Difficulty stars on back face feel alive (only when visible) */
.flag-flip-card.flipped .flag-back-diff {
  display: inline-block;
  animation: fun-heartbeat 2.2s ease-in-out infinite;
}


/* ════════════════════════════════════════════════════════════
   §3  TEXT CARDS — hover lift & reveal pop
   ════════════════════════════════════════════════════════════ */

/* Springier transform transition */
.text-card {
  transition:
    box-shadow   var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    transform    var(--dur-base) var(--ease-spring);
}

/* Enhanced hover lift */
.text-card:hover {
  transform: translateY(-3px) scale(1.01);
}

/* Hanja big-character: slow gentle idle bob */
.text-hanja {
  display: inline-block; /* transform needs block context */
  animation: fun-float 3.4s ease-in-out infinite;
}

/* Revealed meaning pops in after the slideDown settles */
.text-card.open .back-meaning {
  animation: fun-pop var(--dur-base) var(--ease-spring) both;
  animation-delay: calc(var(--dur-base) * 0.55);
}


/* ════════════════════════════════════════════════════════════
   §4  BUTTONS — squishy, inviting, rewarding
   ════════════════════════════════════════════════════════════ */

/* Primary & large: gentle scale on hover */
.btn-primary:hover:not(:disabled),
.btn-lg:hover:not(:disabled) {
  transform: scale(1.04);
}

/* Primary active press: jelly squash overrides base scale(0.97) */
.btn-primary:active:not(:disabled) {
  animation: fun-jelly var(--dur-base) var(--ease-spring);
}

/* ── #btn-start — invite tapping with heartbeat + shine ──── */

#btn-start {
  position: relative;
  overflow: hidden;
  animation: fun-heartbeat 2.2s ease-in-out infinite;
}

/* Pause heartbeat on interaction so scale transitions feel clean */
#btn-start:hover,
#btn-start:focus-visible {
  animation-play-state: paused;
}

/* Periodic shine sweep across the start button */
#btn-start::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    105deg,
    transparent              30%,
    rgba(255, 255, 255, 0.28) 50%,
    transparent              70%
  );
  pointer-events: none;
  animation: fun-shine 3.2s ease-in-out infinite;
  animation-delay: 0.8s;
}

/* ── Nav icon: pop once when tab becomes active ──────────── */

.nav-tab--active .nav-tab__icon {
  animation: fun-pop var(--dur-base) var(--ease-spring);
}


/* ════════════════════════════════════════════════════════════
   §5  STAR / FAVOURITE BUTTON — reward feedback
   ════════════════════════════════════════════════════════════ */

/* Burst when star activates */
.star-btn.active .material-symbols-rounded {
  animation: fun-star-burst var(--dur-slow) var(--ease-spring) both;
}

/* Warm accent glow — flag card variant */
.flag-flip-card .star-btn.active {
  box-shadow: 0 0 0 3px var(--accent-soft), 0 0 10px var(--accent);
}

/* Warm accent glow — text card variant */
.text-card .star-btn.active {
  box-shadow: 0 0 0 3px var(--accent-soft);
}


/* ════════════════════════════════════════════════════════════
   §6  QUIZ ANSWER FEEDBACK — expressive but kind
   ════════════════════════════════════════════════════════════ */

/* Correct: celebratory tada + soft green glow ring */
.answer-btn.correct {
  animation: fun-tada var(--dur-slow) var(--ease-spring) both !important;
  box-shadow: 0 0 0 4px var(--success-soft) !important;
}

.flag-grid-btn.correct {
  animation: fun-tada var(--dur-slow) var(--ease-spring) both !important;
  box-shadow: 0 0 0 4px var(--success-soft) !important;
}

/* Wrong: gentle spring wobble (replaces the base harsh shake) */
.answer-btn.wrong {
  animation: fun-gentle-shake 0.45s var(--ease-spring) !important;
}

.flag-grid-btn.wrong {
  animation: fun-gentle-shake 0.45s var(--ease-spring) !important;
}

/* ── Streak HUD ──────────────────────────────────────────── */

/* Hot streak container: subtle heartbeat */
.quiz-streak.hot {
  animation: fun-heartbeat 0.9s ease-in-out infinite;
}

/* Fire icon: lively wiggle flicker */
.quiz-streak.hot .material-symbols-rounded {
  display: inline-block;
  animation: fun-wiggle 0.75s ease-in-out infinite;
}

/* Score: spring transition so JS-driven updates feel smooth */
.quiz-score {
  transition: transform var(--dur-fast) var(--ease-spring);
}


/* ════════════════════════════════════════════════════════════
   §7  HOME HERO — friendly & lively
   ════════════════════════════════════════════════════════════ */

/* Logo icon: idle float + occasional wiggle offset in time */
.home-logo .material-symbols-rounded {
  display: inline-block;
  animation:
    fun-float  3s ease-in-out infinite,
    fun-wiggle 7s ease-in-out infinite 4s;
}

/* Mode cards: bouncier spring transition */
.mode-card {
  transition:
    box-shadow var(--dur-fast) var(--ease-out),
    transform  var(--dur-base) var(--ease-spring);
}

/* Enhanced hover lift for mode cards */
.mode-card:hover {
  transform: translateY(-4px) scale(1.02);
}

/* Mode icon wiggles once on card hover */
.mode-card:hover .mode-card-icon .material-symbols-rounded {
  display: inline-block;
  animation: fun-wiggle var(--dur-slow) var(--ease-spring);
}

/* Progress fills: periodic shine sweep to reward progress */
.progress-bar-fill,
.mode-progress-fill {
  position: relative;
  overflow: hidden;
}

.progress-bar-fill::after,
.mode-progress-fill::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    transparent              0%,
    rgba(255, 255, 255, 0.45) 50%,
    transparent              100%
  );
  pointer-events: none;
  animation: fun-shine 2.8s ease-in-out infinite;
  animation-delay: 0.5s;
}


/* ════════════════════════════════════════════════════════════
   §8  RESULT SCREEN — celebration energy
   ════════════════════════════════════════════════════════════ */

/* Banner: tada entrance + slow repeating shine */
.result-banner {
  position: relative;
  overflow: hidden;
  animation: fun-tada var(--dur-slow) var(--ease-spring) both;
}

.result-banner::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    105deg,
    transparent              25%,
    rgba(255, 255, 255, 0.32) 50%,
    transparent              75%
  );
  pointer-events: none;
  animation: fun-shine 3.5s ease-in-out infinite;
  animation-delay: 0.6s;
}

/* Score grade: bounce-in entrance, then slow heartbeat */
.score-grade {
  display: inline-block;
  animation:
    fun-bounce-in var(--dur-slow) var(--ease-spring) both,
    fun-heartbeat 3s             ease-in-out        1s infinite;
}

/* Stat pills: springy hover micro-lift */
.stat-pill {
  transition: transform var(--dur-fast) var(--ease-spring);
}

.stat-pill:hover {
  transform: translateY(-3px) scale(1.05);
}


/* ════════════════════════════════════════════════════════════
   §9  GLOBAL NICETIES
   ════════════════════════════════════════════════════════════ */

/* Spring-flavoured focus transitions on key interactive elements */
.btn:focus-visible,
.chip:focus-visible,
.answer-btn:focus-visible,
.flag-grid-btn:focus-visible,
.nav-tab:focus-visible,
.mode-card:focus-visible,
.flag-flip-card:focus-visible,
.text-card:focus-visible {
  transition:
    box-shadow var(--dur-fast) var(--ease-spring),
    transform  var(--dur-fast) var(--ease-spring);
}


/* ════════════════════════════════════════════════════════════
   §10 REDUCED MOTION
   ------------------------------------------------------------
   Respects prefers-reduced-motion: reduce.
   Infinite/idle animations are fully disabled.
   One-shot entrance and feedback animations are also
   neutralised to avoid any motion discomfort.
   ════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {

  /* ── Idle / infinite animations → off ───────────────────── */
  .home-logo .material-symbols-rounded,
  .text-hanja,
  .flag-flip-card.flipped .flag-back-diff,
  #btn-start,
  #btn-start::after,
  .quiz-streak.hot,
  .quiz-streak.hot .material-symbols-rounded,
  .progress-bar-fill::after,
  .mode-progress-fill::after,
  .result-banner::after,
  .score-grade {
    animation: none !important;
  }

  /* ── One-shot entrance / feedback animations → off ────────── */
  .flag-flip-card,
  .text-card,
  .mode-card,
  .result-banner,
  .answer-btn.correct,
  .answer-btn.wrong,
  .flag-grid-btn.correct,
  .flag-grid-btn.wrong,
  .star-btn.active .material-symbols-rounded,
  .text-card.open .back-meaning,
  .nav-tab--active .nav-tab__icon {
    animation: none !important;
  }

  /* ── Remove springy hover transforms ────────────────────── */
  .flag-flip-card:hover,
  .text-card:hover,
  .mode-card:hover,
  .stat-pill:hover,
  .btn-primary:hover:not(:disabled),
  .btn-lg:hover:not(:disabled) {
    transform: none;
  }

  /* ── Flatten flip-card spring timing back to ease-out ───── */
  .flag-flip-card.flipped .flag-flip-inner {
    transition-timing-function: var(--ease-out);
  }
}
