/* ==========================================================================
   ANIMATIONS.CSS — Keyframes & transition classes (§9 Animation Spec)
   Respect prefers-reduced-motion throughout (§6.4).
   ========================================================================== */

/* ---- Question -> question slide/fade (~300ms) ---- */
.qf-enter {
  animation: qf-slide-in var(--transition-base) var(--ease-standard) both;
}
.qf-exit {
  animation: qf-slide-out var(--transition-fast) var(--ease-standard) both;
}
@keyframes qf-slide-in {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes qf-slide-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(-24px); }
}

/* ---- Answer selected: micro bounce/scale ---- */
@keyframes option-bounce {
  0%   { transform: scale(1); }
  40%  { transform: scale(0.96); }
  100% { transform: scale(1); }
}
.quiz-option.is-selected {
  animation: option-bounce var(--transition-fast) var(--ease-out-back);
}

/* ---- Calculating screen: themed icon spin/float + rotating status text ---- */
@keyframes calc-float {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50%      { transform: translateY(-10px) rotate(4deg); }
}
.quiz-calculating__icon {
  animation: calc-float 1.6s ease-in-out infinite;
}
[data-tone="serious"] .quiz-calculating__icon {
  animation: calc-pulse 2.2s ease-in-out infinite;
}
@keyframes calc-pulse {
  0%, 100% { opacity: 0.6; transform: scale(1); }
  50%      { opacity: 1; transform: scale(1.06); }
}

.status-fade {
  animation: status-fade-in var(--transition-base) var(--ease-standard) both;
}
@keyframes status-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ---- Result reveal: card fade-in + scale, staggered content (JS timeline hooks) ---- */
@keyframes result-card-in {
  from { opacity: 0; transform: translateY(16px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.quiz-result.is-revealed {
  animation: result-card-in var(--transition-slow) var(--ease-out-back) both;
}

@keyframes stagger-item-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.stagger-item {
  opacity: 0;
  animation: stagger-item-in var(--transition-base) var(--ease-standard) both;
}

/* ---- Share CTA pulse (skip on serious tone, §9) ---- */
@keyframes share-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(232, 135, 63, 0.35); }
  50%      { box-shadow: 0 0 0 8px rgba(232, 135, 63, 0); }
}
.quiz-share__btn--primary { animation: share-pulse 2.4s ease-in-out infinite; }
[data-tone="serious"] .quiz-share__btn--primary { animation: none; }

/* ---- Confetti burst (playful tone only, skipped entirely for serious) ---- */
.confetti-piece {
  position: fixed;
  top: -10px;
  width: 8px;
  height: 14px;
  opacity: 0.9;
  pointer-events: none;
  z-index: 999;
  animation: confetti-fall linear forwards;
}
@keyframes confetti-fall {
  to { transform: translateY(110vh) rotate(540deg); opacity: 0; }
}

/* ---- Count-up number tween wrapper (value swapped by JS) ---- */
.count-up { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Reduced motion: disable non-essential motion, keep functional transitions
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .confetti-piece { display: none; }
}
