/* assets/css/motion.css
   ─────────────────────────────────────────────────────────────────────────────
   Netpix motion utility classes.
   See docs/ux-motion-spec.md for the full standard.

   Usage:
     Forward nav  → .np-page-enter  (applied automatically by auth-global.css)
     Back nav     → add .np-page-exit via JS, then redirect after 220ms
     Success      → .np-fade-in
     Modal open   → .np-slide-up
     Modal close  → add .np-slide-down via JS, then remove element after 220ms

   All animations respect prefers-reduced-motion — they collapse to instant
   when the user has requested reduced motion at the OS level.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── Easing tokens ───────────────────────────────────────────────────────── */
/* Material standard easing — used for all directional transitions */
:root {
  --np-ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --np-ease-decelerate: cubic-bezier(0.0, 0, 0.2, 1); /* things entering */
  --np-ease-accelerate: cubic-bezier(0.4, 0, 1, 1);   /* things leaving  */

  --np-duration-fast:    200ms;
  --np-duration-default: 280ms;
  --np-duration-back:    220ms;
  --np-duration-fade:    300ms;
}

/* ── Keyframes ───────────────────────────────────────────────────────────── */

/* Forward navigation — slide in from right */
@keyframes np-enter-from-right {
  from {
    opacity: 0;
    transform: translateX(100%);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* Back navigation — slide out to right */
@keyframes np-exit-to-right {
  from {
    opacity: 1;
    transform: translateX(0);
  }
  to {
    opacity: 0;
    transform: translateX(100%);
  }
}

/* Tab switch / context change — crossfade */
@keyframes np-fade-in-kf {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes np-fade-out-kf {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* Modal / bottom sheet — slide up */
@keyframes np-slide-up-kf {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Modal close — slide down */
@keyframes np-slide-down-kf {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(24px);
  }
}

/* ── Utility classes ─────────────────────────────────────────────────────── */

/* Forward navigation (arriving at a page / step) */
.np-page-enter {
  animation: np-enter-from-right var(--np-duration-default) var(--np-ease-decelerate) both;
}

/* Back navigation — add via JS, wait 220ms, then redirect */
/* !important is deliberate here: several page containers (e.g. .auth-container
   in auth-global.css) hardcode their own forward-entry `animation` directly on
   the container's base selector, rather than solely via the .np-page-enter
   utility class the way docs/ux-motion-spec.md describes. When JS adds
   .np-page-exit alongside that base class, both rules have equal specificity
   (single class each) and whichever comes later in the CSS cascade wins —
   which silently swallowed the exit animation entirely (found 2026-07-06,
   login page back button). Since .np-page-exit is always added deliberately
   by JS as an explicit, final motion state overriding whatever came before,
   !important here is intentional and correct, not a specificity hack to be
   "cleaned up" later — it guarantees back-navigation always animates
   regardless of what a given page's base container CSS happens to set. */
.np-page-exit {
  animation: np-exit-to-right var(--np-duration-back) var(--np-ease-accelerate) both !important;
}

/* Success / confirmation / terminal states */
.np-fade-in {
  animation: np-fade-in-kf var(--np-duration-fade) ease both;
}

/* Tab switch crossfade */
.np-crossfade-in {
  animation: np-fade-in-kf var(--np-duration-fast) ease both;
}

/* Modal / bottom sheet enter */
.np-slide-up {
  animation: np-slide-up-kf var(--np-duration-default) var(--np-ease-decelerate) both;
}

/* Modal / bottom sheet close — add via JS, wait 220ms, then hide */
.np-slide-down {
  animation: np-slide-down-kf var(--np-duration-back) var(--np-ease-accelerate) both;
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */
/* Collapse all animations to instant for users who prefer reduced motion.
   The transition still happens — it's just not animated.                   */
@media (prefers-reduced-motion: reduce) {
  .np-page-enter,
  .np-page-exit,
  .np-fade-in,
  .np-crossfade-in,
  .np-slide-up,
  .np-slide-down {
    animation: none;
  }
}
