/* ============================================
   BASE: Animations — Obsidian Aurora
   ============================================ */

/* Slide in from right */
@keyframes slideIn {
  from { transform: translateX(100%); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

/* Slide in from bottom (toasts) */
@keyframes slideInBottom {
  from { transform: translateY(100%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* Modal fade in — subtle slide-up + fade (no scale = no pop) */
@keyframes modalFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Fade in with slide (table rows) */
@keyframes fadeInSlide {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Highlight animation for new items — Obsidian Aurora emerald glow */
@keyframes highlightPair {
  0% {
    background-color: var(--bg-secondary);
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4);
  }
  50% {
    background-color: rgba(34, 197, 94, 0.08);
    box-shadow: 0 0 24px 6px rgba(34, 197, 94, 0.3);
  }
  100% {
    background-color: var(--bg-secondary);
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
  }
}

/* Pulse glow — Online status */
@keyframes pulseGlow {
  0%, 100% {
    box-shadow: 0 0 8px rgba(34, 197, 94, 0.4);
  }
  50% {
    box-shadow: 0 0 18px rgba(34, 197, 94, 0.6);
  }
}

/* Pulse opacity (loading states) */
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* Spin animation (spinners) */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* Fade in up — generic entrance */
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Shimmer — skeleton loading */
@keyframes shimmer {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* ── "This just changed" cues ────────────────────────────────────────────────
   Deliberately quiet. These replace the old accidental feedback, where the whole
   table rebuilt itself on a timer and the top row flashed whether or not anything
   had happened. Now only the cell (or KPI) that actually moved is marked, so the
   motion carries information. Background-only — no transform, no layout shift, so
   a cell updating never nudges its neighbours.

   Both use a `from`-only keyframe on purpose: with no explicit `to`, the 100% frame
   is the element's own underlying value, so the flash always resolves back to
   whatever the active theme (or an active :hover) is painting. Hardcoding
   `transparent` here would fight the row-hover background on the way out. */
@keyframes cellFlash {
  from { background-color: var(--color-success-light); }
}

.accounts-table tbody td.cell-flash {
  animation: cellFlash 0.9s ease-out;
}

/* KPI tiles: colour only, no scale — these sit in a fixed grid and a transform
   would make the row twitch. */
@keyframes kpiFlash {
  from { color: var(--color-success); }
}

.kpi-flash {
  animation: kpiFlash 0.8s ease-out;
}

/* Respect the OS "reduce motion" setting for all three of the above. */
@media (prefers-reduced-motion: reduce) {
  .accounts-table tbody tr.row-enter,
  .accounts-table tbody td.cell-flash,
  .kpi-flash {
    animation: none;
  }
}
