/* ============================================================
   QuizHive – Admin Effects Layer
   Loaded after admin.css. Progressive enhancement, scoped under
   html.js so JS-disabled sessions still get the original instant
   fade-ins from admin.css.
   ============================================================ */

:root {
  --ease-out-expo: cubic-bezier(.16,1,.3,1);
  --ease-spring:   cubic-bezier(.34,1.56,.64,1);
}

/* Pure CSS fade-in — never depends on JS succeeding (see public-site effects.css for why). */
body { animation: pageFadeIn .4s var(--ease-out-expo) both; }
@keyframes pageFadeIn { from { opacity: 0; } to { opacity: 1; } }
html.js body.page-exit { opacity: 0; transition: opacity .16s ease; }

/* ── Sidebar: slide-in + glow active state ───────────────────── */
.sidebar { transition: transform .3s var(--ease-out-expo), box-shadow .3s ease; }
html.js .sidebar-brand { animation: fadeInLeft .5s var(--ease-out-expo) .05s both; }
html.js .sidebar-admin-info { animation: fadeInLeft .5s var(--ease-out-expo) .1s both; }
html.js .sidebar-nav > * { opacity: 0; animation: fadeInLeft .45s var(--ease-out-expo) forwards; }
@keyframes fadeInLeft {
  from { opacity: 0; transform: translateX(-10px); }
  to   { opacity: 1; transform: translateX(0); }
}

.sidebar-nav a {
  overflow: hidden;
}
.sidebar-nav a::before {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(99,102,241,.16), transparent);
  transform: translateX(-100%);
  transition: transform .35s var(--ease-out-expo);
}
.sidebar-nav a:hover::before { transform: translateX(0); }
.sidebar-nav a .nav-icon { transition: transform .3s var(--ease-spring); }
.sidebar-nav a:hover .nav-icon { transform: scale(1.15); }
.sidebar-nav a.active {
  box-shadow: inset 0 0 22px rgba(99,102,241,.12);
}
.brand-icon { transition: transform .4s var(--ease-spring); }
.sidebar-brand:hover .brand-icon { transform: rotate(-8deg) scale(1.08); }

/* ── Topbar ───────────────────────────────────────────────────── */
html.js .admin-topbar { animation: fadeIn .5s ease both; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ── 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.) */
.stat-card, .admin-card, .table-wrapper, .empty-state, .alert {
  animation: cardEnter .55s var(--ease-out-expo) both;
}
.stats-grid > .stat-card:nth-child(1) { animation-delay: .03s; }
.stats-grid > .stat-card:nth-child(2) { animation-delay: .08s; }
.stats-grid > .stat-card:nth-child(3) { animation-delay: .13s; }
.stats-grid > .stat-card:nth-child(4) { animation-delay: .18s; }
@keyframes cardEnter {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Stat cards: shine sweep + lift + icon pop ───────────────── */
.stat-card {
  transition: transform .3s var(--ease-out-expo), box-shadow .3s var(--ease-out-expo);
  position: relative;
}
.stat-card::before {
  content: '';
  position: absolute; top: 0; left: -60%;
  width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(99,102,241,.08), transparent);
  transform: skewX(-20deg);
  transition: left .7s var(--ease-out-expo);
  pointer-events: none;
}
.stat-card:hover::before { left: 130%; }
.stat-icon { transition: transform .35s var(--ease-spring); }
.stat-card:hover .stat-icon { transform: scale(1.12) rotate(-4deg); }
.stat-value { font-variant-numeric: tabular-nums; }

/* ── Admin cards / tables ─────────────────────────────────────── */
.admin-card { transition: box-shadow .3s ease, transform .3s var(--ease-out-expo); }
.table tr td { transition: background .2s ease; }
.table tr { transition: transform .15s ease; }

/* ── Buttons: shine sweep + ripple (shared with main site) ──── */
.btn {
  position: relative;
  overflow: hidden;
  transition: transform .3s var(--ease-out-expo), box-shadow .3s var(--ease-out-expo);
}
.btn::before {
  content: '';
  position: absolute; top: 0; left: -60%;
  width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,.32), transparent);
  transform: skewX(-20deg);
  transition: left .55s 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 .ripple {
  position: absolute; border-radius: 50%; transform: scale(0);
  background: rgba(255,255,255,.5); pointer-events: none;
  animation: rippleOut .6s ease-out forwards;
}
.btn-secondary .ripple { background: rgba(99,102,241,.22); }
@keyframes rippleOut { to { transform: scale(2.6); opacity: 0; } }

/* ── Badges: subtle pulse on pending counts ──────────────────── */
.sidebar-nav a .badge-danger { animation: badgePulse 2.2s ease-in-out infinite; }
@keyframes badgePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239,68,68,.5); }
  50%      { box-shadow: 0 0 0 5px rgba(239,68,68,0); }
}

/* ── Modal: springier ─────────────────────────────────────────── */
.modal { transition: transform .4s var(--ease-spring), opacity .3s ease; }

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

/* ── Chart card polish (dashboard.php canvas wrappers use admin-card) */
canvas { transition: opacity .4s ease; }

/* ── Sidebar mobile toggle: nicer icon flip ──────────────────── */
.sidebar-toggle { transition: transform .2s var(--ease-out-expo), box-shadow .2s ease; }
.sidebar-toggle:active { transform: scale(.92); }
.sidebar-backdrop { transition: opacity .25s ease; opacity: 0; }
.sidebar-backdrop.open { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  body { animation: none !important; opacity: 1 !important; }
  .stat-card, .admin-card, .table-wrapper, .empty-state, .alert,
  html.js .sidebar-brand, html.js .sidebar-admin-info, html.js .sidebar-nav > * {
    opacity: 1 !important; transform: none !important; animation: none !important; transition: none !important;
  }
  .stat-card::before, .btn::before, .sidebar-nav a .badge-danger { animation: none !important; }
}
