/* =========================================================
   VMQ animations.css
   Purpose:
   - Provide motion/transition primitives used across VMQ
   - Support common state classes (active/open/show/hidden)
   - Animate known UI elements (loading screen, progress fill,
     overlays, panels, toasts, status badges)
   - Respect prefers-reduced-motion

   Notes:
   - Uses CSS variables when available; includes safe fallbacks.
   - Avoids global rules that could break aria-hidden icons.
   ========================================================= */

/* ----------------------------
   Motion tokens (fallbacks)
   ---------------------------- */
:root {
  --vmq-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --vmq-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --vmq-ease-in: cubic-bezier(0.7, 0, 0.84, 0);

  --vmq-dur-xxfast: 120ms;
  --vmq-dur-xfast: 180ms;
  --vmq-dur-fast: 240ms;
  --vmq-dur-med: 320ms;
  --vmq-dur-slow: 520ms;

  /* Fallback “semantic” colors if base.css doesn’t define them */
  --vmq-ok: var(--success, #16a34a);
  --vmq-warn: var(--warning, #f59e0b);
  --vmq-bad: var(--danger, #ef4444);
  --vmq-focus: var(--primary, #3b82f6);

  /* For subtle shadows if not defined elsewhere */
  --vmq-shadow: 0 10px 30px rgba(0,0,0,0.18);
}

/* ----------------------------
   Reduced motion: disable
   ---------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* =========================================================
   Generic state utilities (safe defaults)
   ========================================================= */

/* Hidden helpers (only when class is present) */
.hidden {
  display: none !important;
}

.invisible {
  opacity: 0 !important;
  visibility: hidden !important;
}

/* “Show/hide” transitions: use opacity/transform so layout stays stable */
.fade {
  opacity: 0;
  transform: translateY(2px);
  transition:
    opacity var(--vmq-dur-fast) var(--vmq-ease),
    transform var(--vmq-dur-fast) var(--vmq-ease);
}

.fade.show,
.show .fade,
.fade.active,
.active .fade {
  opacity: 1;
  transform: translateY(0);
}

/* Slide up panel primitive */
.slide-up {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity var(--vmq-dur-med) var(--vmq-ease-out),
    transform var(--vmq-dur-med) var(--vmq-ease-out);
  will-change: opacity, transform;
}

.slide-up.show,
.slide-up.active,
.is-open .slide-up,
.open .slide-up {
  opacity: 1;
  transform: translateY(0);
}

/* Scale pop primitive (good for badges/toasts) */
.pop {
  opacity: 0;
  transform: scale(0.98);
  transition:
    opacity var(--vmq-dur-fast) var(--vmq-ease),
    transform var(--vmq-dur-fast) var(--vmq-ease);
  will-change: opacity, transform;
}

.pop.show,
.pop.active,
.is-open .pop,
.open .pop {
  opacity: 1;
  transform: scale(1);
}

/* =========================================================
   Loading screen + bootstrap shell
   (index.html uses .loading-screen.active)
   ========================================================= */

.loading-screen {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity var(--vmq-dur-med) var(--vmq-ease-out),
    visibility 0s linear var(--vmq-dur-med);
}

.loading-screen.active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition:
    opacity var(--vmq-dur-med) var(--vmq-ease-out),
    visibility 0s linear 0s;
}

/* Spinner animation (only if your base/components define .loading-spinner shape) */
.loading-spinner {
  animation: vmq-spin 900ms linear infinite;
}

@keyframes vmq-spin {
  to { transform: rotate(360deg); }
}

/* Progress fill: index.html sets --width via JS */
.progress-fill {
  width: var(--width, 0%);
  transition: width var(--vmq-dur-fast) var(--vmq-ease-out);
  will-change: width;
}

/* Loading status “soft pulse” */
.loading-status {
  animation: vmq-softpulse 2.2s var(--vmq-ease) infinite;
}

@keyframes vmq-softpulse {
  0%, 100% { opacity: 0.88; }
  50% { opacity: 1; }
}

/* =========================================================
   Status badges: ok / warn (seen in offline/import/share)
   ========================================================= */

.ok,
.warn {
  transition:
    transform var(--vmq-dur-xfast) var(--vmq-ease),
    opacity var(--vmq-dur-xfast) var(--vmq-ease),
    background-color var(--vmq-dur-fast) var(--vmq-ease),
    border-color var(--vmq-dur-fast) var(--vmq-ease),
    color var(--vmq-dur-fast) var(--vmq-ease);
  will-change: transform, opacity;
}

/* A little “pop” feedback when the class is applied */
.ok {
  animation: vmq-badge-in var(--vmq-dur-fast) var(--vmq-ease-out) both;
}

.warn {
  animation: vmq-badge-in var(--vmq-dur-fast) var(--vmq-ease-out) both;
}

@keyframes vmq-badge-in {
  from { opacity: 0; transform: translateY(2px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* If your HTML badge elements have borders, these help without forcing layout */
.ok {
  border-color: color-mix(in srgb, var(--vmq-ok) 55%, transparent);
}

.warn {
  border-color: color-mix(in srgb, var(--vmq-warn) 55%, transparent);
}

/* =========================================================
   Answer feedback helpers (common patterns)
   ========================================================= */

.correct {
  animation: vmq-correct-flash 520ms var(--vmq-ease-out) both;
}

.wrong {
  animation: vmq-wrong-shake 420ms var(--vmq-ease-out) both;
}

@keyframes vmq-correct-flash {
  0%   { box-shadow: 0 0 0 0 rgba(22,163,74,0.0); }
  35%  { box-shadow: 0 0 0 6px rgba(22,163,74,0.18); }
  100% { box-shadow: 0 0 0 0 rgba(22,163,74,0.0); }
}

@keyframes vmq-wrong-shake {
  0%   { transform: translateX(0); }
  20%  { transform: translateX(-4px); }
  40%  { transform: translateX(4px); }
  60%  { transform: translateX(-3px); }
  80%  { transform: translateX(3px); }
  100% { transform: translateX(0); }
}

/* =========================================================
   Overlays / panels (Bieler mastery overlay + generic)
   You have: .mastery-overlay, .mastery-panel
   ========================================================= */

.mastery-overlay {
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity var(--vmq-dur-med) var(--vmq-ease-out),
    transform var(--vmq-dur-med) var(--vmq-ease-out);
  will-change: opacity, transform;
}

.mastery-panel {
  opacity: 0;
  transform: translateY(10px) scale(0.995);
  transition:
    opacity var(--vmq-dur-med) var(--vmq-ease-out),
    transform var(--vmq-dur-med) var(--vmq-ease-out);
  will-change: opacity, transform;
}

/* If your JS conditionally renders these, they’ll appear instantly.
   If your app toggles a parent class like .open or .active, these rules kick in. */
.active .mastery-overlay,
.open .mastery-overlay,
.is-open .mastery-overlay,
.mastery-overlay.active,
.mastery-overlay.open,
.mastery-overlay.is-open {
  opacity: 1;
  transform: translateY(0);
}

.active .mastery-panel,
.open .mastery-panel,
.is-open .mastery-panel,
.mastery-panel.active,
.mastery-panel.open,
.mastery-panel.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* =========================================================
   Toasts (supports several common naming schemes)
   ========================================================= */

/* Container safety: prevents layout jump during animation */
.toast-container {
  contain: layout paint;
}

/* Base toast motion (works even if your toast markup differs) */
.toast,
.toast-message,
.toast-item {
  animation: vmq-toast-in var(--vmq-dur-med) var(--vmq-ease-out) both;
}

.toast--enter {
  animation: vmq-toast-in var(--vmq-dur-med) var(--vmq-ease-out) both;
}

.toast--exit,
.toast.is-leaving,
.toast[data-state="closing"] {
  animation: vmq-toast-out var(--vmq-dur-fast) var(--vmq-ease-in) both;
}

@keyframes vmq-toast-in {
  from { opacity: 0; transform: translateY(10px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes vmq-toast-out {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(8px) scale(0.99); }
}

/* =========================================================
   Modal-ish helpers (if you use .open/.is-open patterns)
   ========================================================= */

.modal,
.dialog,
.sheet {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--vmq-dur-med) var(--vmq-ease-out),
    transform var(--vmq-dur-med) var(--vmq-ease-out);
  will-change: opacity, transform;
}

.modal.is-open,
.modal.open,
.dialog.is-open,
.dialog.open,
.sheet.is-open,
.sheet.open,
.open .modal,
.is-open .modal {
  opacity: 1;
  transform: translateY(0);
}
