/* ============================================================
   QuizHive – Effects Layer
   Loaded after style.css. Adds scroll reveals, hero motion,
   button/card micro-interactions, quiz feedback polish, page
   transitions and a confetti canvas. Everything here is scoped
   under html.js so sites with JS disabled still get the original
   instant fade-in from style.css — this is progressive enhancement,
   not a replacement.
   ============================================================ */

:root {
  --ease-out-expo: cubic-bezier(.16,1,.3,1);
  --ease-spring:   cubic-bezier(.34,1.56,.64,1);
  --glow-primary:  0 0 0 rgba(99,102,241,0);
}

/* ── Page transition overlay ─────────────────────────────────── */
/* Page fade-in is pure CSS — it can NEVER depend on JS succeeding, or a JS/network
   hiccup would leave the page invisible. JS only handles the (optional) fade-OUT
   when navigating away, which is safe because it only ever runs after a successful
   click — if JS never loads, navigation just happens normally with no transition. */
body { animation: pageFadeIn .45s var(--ease-out-expo) both; }
@keyframes pageFadeIn { from { opacity: 0; } to { opacity: 1; } }
html.js body.page-exit {
  opacity: 0;
  transition: opacity .18s ease;
}

/* ── Scroll-reveal system ────────────────────────────────────── */
/* ── Scroll reveal for content blocks ────────────────────────── */
/* Self-contained CSS animation — plays automatically on load, no JS required
   to become visible. (An earlier version hid these until JS added a class;
   that meant a JS error anywhere on the page could leave them invisible
   forever. Never again — content visibility must never depend on JS.) */
.card, .quiz-card, .premium-plan-card, .auth-card, .animate-in,
.category-card, .result-stat, .quiz-detail-meta-item, .filter-bar,
.empty-state, .table-wrapper {
  animation: cardEnter .6s var(--ease-out-expo) both;
}
@keyframes cardEnter {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
.quiz-grid > *:nth-child(1), .category-grid > *:nth-child(1) { animation-delay: .02s; }
.quiz-grid > *:nth-child(2), .category-grid > *:nth-child(2) { animation-delay: .07s; }
.quiz-grid > *:nth-child(3), .category-grid > *:nth-child(3) { animation-delay: .12s; }
.quiz-grid > *:nth-child(4), .category-grid > *:nth-child(4) { animation-delay: .17s; }
.quiz-grid > *:nth-child(5), .category-grid > *:nth-child(5) { animation-delay: .22s; }
.quiz-grid > *:nth-child(6), .category-grid > *:nth-child(6) { animation-delay: .27s; }

/* Hero / dark banners still get an immediate, punchier entrance */
html.js .hero-badge   { animation: popIn .6s var(--ease-spring) .05s both; }
html.js .hero h1       { animation: fadeInUp .7s var(--ease-out-expo) .12s both; }
html.js .hero p        { animation: fadeInUp .7s var(--ease-out-expo) .22s both; }
html.js .hero-actions  { animation: fadeInUp .7s var(--ease-out-expo) .3s both; }
html.js .hero-stats    { animation: fadeIn .8s ease .5s both; }

/* ── Hero: crossfading image slideshow ───────────────────────── */
.hero-visual-frame { position:relative; }
.hero-slide {
  transition: opacity 1.2s var(--ease-out-expo), transform 6s ease-out;
  opacity: 0;
}
.hero-slide:not(.is-active) { position:absolute; inset:0; }
.hero-slide.is-active { opacity: 1; transform: scale(1.04); }

/* ── Floating cards: gentle hover/bob ────────────────────────── */
.hero-float-card { animation: floatBob 4.5s ease-in-out infinite; }
.hero-float-streak { animation-delay: .8s; }
@keyframes floatBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}

/* ── Reusable floating badge for secondary page banners ──────── */
.media-frame { position:relative; border-radius:var(--radius-lg); overflow:hidden; box-shadow:var(--shadow-xl); }
.media-frame img {
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity 1.2s var(--ease-out-expo), transform 6s ease-out;
}
.media-frame img.is-active { opacity:1; position:relative; transform:scale(1.04); }
.media-frame img:not(.is-active) { position:absolute; }
.float-badge {
  position:absolute;
  display:flex; align-items:center; gap:.6rem;
  background:rgba(15,23,42,.72);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.14);
  border-radius:var(--radius);
  padding:.6rem .9rem;
  box-shadow:0 16px 32px rgba(0,0,0,.35);
  color:#fff; font-size:.78rem; font-weight:700;
  animation: floatBob 4.5s ease-in-out infinite;
}
.float-badge svg { flex-shrink:0; color:var(--primary-light,#a5b4fc); }

/* ── Hero: animated aurora + parallax orbs ───────────────────── */
.hero { --mx: 50%; --my: 30%; }
.hero::before {
  animation: heroBlob 10s ease-in-out infinite alternate,
             heroDrift 22s ease-in-out infinite;
}
.hero::after { animation: none; }

.hero-aurora {
  position: absolute; inset: -20%;
  background:
    radial-gradient(480px 480px at calc(var(--mx)) calc(var(--my)), rgba(99,102,241,.30), transparent 60%),
    radial-gradient(420px 420px at 80% 75%, rgba(6,182,212,.22), transparent 60%),
    radial-gradient(380px 380px at 12% 80%, rgba(129,140,248,.18), transparent 60%);
  filter: blur(6px);
  pointer-events: none;
  transition: background-position .4s ease;
  z-index: 0;
}
@keyframes heroDrift {
  0%, 100% { filter: blur(6px) hue-rotate(0deg); }
  50%      { filter: blur(8px) hue-rotate(12deg); }
}

.hero h1 .gradient-text {
  background-size: 200% auto;
  animation: shimmerText 6s ease-in-out infinite;
}
@keyframes shimmerText {
  0%, 100% { background-position: 0% center; }
  50%      { background-position: 100% center; }
}

.hero-badge {
  position: relative;
}
.hero-badge::before {
  content: '';
  position: absolute; inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(120deg, rgba(165,180,252,.7), rgba(56,189,248,.7), rgba(165,180,252,.7));
  background-size: 200% auto;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  animation: shimmerText 3.5s linear infinite;
  pointer-events: none;
}

/* ── Buttons: shine sweep, magnetic lift, ripple ─────────────── */
.btn {
  position: relative;
  overflow: hidden;
  transition: transform .35s var(--ease-out-expo), box-shadow .35s var(--ease-out-expo), background .35s ease, color .35s ease;
}
.btn::before {
  content: '';
  position: absolute; top: 0; left: -60%;
  width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,.35), transparent);
  transform: skewX(-20deg);
  transition: left .6s var(--ease-out-expo);
  pointer-events: none;
}
.btn:hover::before { left: 130%; }

.btn-primary:hover, .btn-success:hover, .btn-danger:hover, .btn-warning:hover {
  transform: translateY(-2px) scale(1.015);
}
.btn-outline:hover { transform: translateY(-2px) scale(1.015); }

.btn .ripple {
  position: absolute;
  border-radius: 50%;
  transform: scale(0);
  background: rgba(255,255,255,.55);
  pointer-events: none;
  animation: rippleOut .6s ease-out forwards;
}
.btn-outline .ripple, .btn-secondary .ripple, .btn-ghost .ripple { background: rgba(99,102,241,.25); }
@keyframes rippleOut {
  to { transform: scale(2.6); opacity: 0; }
}

/* ── Cards: tilt + glow border on hover (desktop, JS-driven) ─── */
html.effects-ready .card, html.effects-ready .quiz-card, html.effects-ready .premium-plan-card {
  transform-style: preserve-3d;
  will-change: transform;
}
html.effects-ready .tilt-active {
  transition: transform .12s ease-out !important;
  transform: perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(-6px) scale(1.012) !important;
  box-shadow: var(--shadow-xl);
}
.quiz-card, .card, .premium-plan-card {
  position: relative;
}
.quiz-card::after, .card::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: linear-gradient(135deg, rgba(99,102,241,0), rgba(99,102,241,0));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  transition: background .35s ease;
  pointer-events: none;
}
.quiz-card:hover::after, .card:hover::after {
  background: linear-gradient(135deg, rgba(99,102,241,.55), rgba(6,182,212,.45));
}

.quiz-card-header::after {
  transition: transform .5s var(--ease-out-expo);
}
.quiz-card:hover .quiz-card-header::after { transform: scale(1.35) translate(-6%, 6%); }

/* ── Filter tabs / search: springier feedback ────────────────── */
.filter-tab { transition: transform .25s var(--ease-out-expo), background .25s ease, color .25s ease, box-shadow .25s ease; }
.filter-tab:active { transform: scale(.94); }
.filter-tab.active { animation: popIn .35s var(--ease-spring) both; }

/* ── Quiz taking: option select / correctness feedback ───────── */
.option-item {
  transition: transform .25s var(--ease-out-expo), border-color .25s ease, background .25s ease, box-shadow .25s ease;
}
.option-item:hover { transform: translateX(3px); }
.option-item.selected { animation: optionPulse .4s var(--ease-out-expo); }
.option-item.selected .option-letter,
.option-item.correct .option-letter,
.option-item.wrong .option-letter {
  animation: letterPop .4s var(--ease-spring);
}
@keyframes optionPulse {
  0%   { box-shadow: 0 0 0 0 rgba(99,102,241,.35); }
  100% { box-shadow: 0 0 0 10px rgba(99,102,241,0); }
}
@keyframes letterPop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.28); }
  100% { transform: scale(1); }
}
.option-item.correct { animation: correctFlash .5s ease; }
.option-item.wrong   { animation: wrongShake .45s ease; }
@keyframes correctFlash {
  0%   { box-shadow: 0 0 0 0 rgba(16,185,129,.4); }
  60%  { box-shadow: 0 0 0 8px rgba(16,185,129,0); }
}
@keyframes wrongShake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

/* ── Progress bar + timer: more alive ────────────────────────── */
#progress-bar {
  background-size: 200% 100% !important;
  animation: progressShimmer 2.5s linear infinite;
}
@keyframes progressShimmer {
  0%   { background-position: 0% 0; }
  100% { background-position: -200% 0; }
}
.quiz-timer { transition: background .3s ease, color .3s ease, transform .2s ease; }
.quiz-timer.warning { animation: timerPulse 1s ease-in-out infinite, timerShake 1s ease-in-out infinite; }
@keyframes timerShake {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* ── Result page: ring glow + confetti canvas ────────────────── */
.result-score-circle .progress-ring { filter: drop-shadow(0 0 10px rgba(99,102,241,.55)); }
.result-score-circle { animation: popIn .6s var(--ease-spring) both; }
.result-grade { animation: fadeInUp .5s var(--ease-out-expo) .15s both; }

#confetti-canvas {
  position: fixed; inset: 0; z-index: 9998;
  pointer-events: none;
}

/* ── Number count-up targets: subtle settle ──────────────────── */
.hero-stat-number, .result-stat-number { font-variant-numeric: tabular-nums; }

/* ── Nav link underline sweep ─────────────────────────────────── */
.navbar-nav a { position: relative; }
.navbar-nav a::after {
  content: ''; position: absolute; left: .9rem; right: .9rem; bottom: .28rem;
  height: 2px; background: var(--primary); border-radius: 2px;
  transform: scaleX(0); transform-origin: left;
  transition: transform .3s var(--ease-out-expo);
}
.navbar-nav a:hover::after, .navbar-nav a.active::after { transform: scaleX(1); }

/* ── Theme toggle: rotate on switch ──────────────────────────── */
.theme-toggle svg { transition: transform .4s var(--ease-spring); }
.theme-toggle:active svg { transform: rotate(180deg) scale(.85); }

/* ── Focus / links polish ────────────────────────────────────── */
.auth-footer a, footer a { transition: color .2s ease; }

/* ── Reduced motion: strip everything extra ──────────────────── */
@media (prefers-reduced-motion: reduce) {
  body { animation: none !important; opacity: 1 !important; }
  .card, .quiz-card, .premium-plan-card,
  .auth-card, .animate-in, .category-card,
  .result-stat, .quiz-detail-meta-item, .filter-bar,
  .empty-state, .table-wrapper {
    opacity: 1 !important; transform: none !important; animation: none !important;
  }
  .hero-aurora, .hero::before, .hero h1 .gradient-text, .hero-badge::before,
  .btn::before, .quiz-timer.warning, #progress-bar, .hero-word-bg { animation: none !important; }
}

@media (max-width: 768px) {
  html.effects-ready .tilt-active { transform: none !important; }
}
