/* ============================================================================
   ENOK Transitions Kit — copy-paste motion for real apps.
   Zero dependencies. CSP-safe. No build step.

   Use the classes on their own, or pair with transitions.js for scroll reveals
   and modal wiring. Every recipe respects prefers-reduced-motion.

   Free to use, copy, and ship in your projects — see LICENSE.txt.
   ENOK · the open media company · enok.com
   ============================================================================ */

:root {
  /* ---- Named easing curves (reuse anywhere) ---- */
  --tx-ease-soft:   cubic-bezier(.22, .61, .36, 1);   /* gentle ease-out       */
  --tx-ease-quint:  cubic-bezier(.22, 1, .36, 1);     /* long-tail ease-out    */
  --tx-ease-spring: cubic-bezier(.34, 1.56, .64, 1);  /* overshoot spring      */
  --tx-ease-inout:  cubic-bezier(.65, 0, .35, 1);     /* symmetric in-out      */

  /* ---- Durations ---- */
  --tx-fast: 180ms;
  --tx-base: 320ms;
  --tx-slow: 520ms;

  /* ---- Travel + stagger ---- */
  --tx-rise: 14px;   /* how far reveals translate before settling */
  --tx-step: 60ms;   /* delay added per staggered item (--tx-i)   */
}

/* ----------------------------------------------------------------------------
   1 · PAGE ENTER
   Fade + rise the whole view on load. Put .tx-page on a wrapper.
   Also opts into the native View Transitions API where supported (progressive).
   ---------------------------------------------------------------------------- */
.tx-page {
  animation: tx-page-in var(--tx-slow) var(--tx-ease-quint) both;
}
@keyframes tx-page-in {
  from { opacity: 0; transform: translateY(var(--tx-rise)); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}

/* ----------------------------------------------------------------------------
   2 · REVEAL ON SCROLL
   Elements start hidden; add .is-in (transitions.js does this via
   IntersectionObserver) to reveal. Direction modifiers + per-item stagger.
   ---------------------------------------------------------------------------- */
.tx-reveal {
  opacity: 0;
  transform: translateY(var(--tx-rise));
  transition:
    opacity   var(--tx-base) var(--tx-ease-quint),
    transform var(--tx-base) var(--tx-ease-quint);
  transition-delay: calc(var(--tx-i, 0) * var(--tx-step));
  will-change: opacity, transform;
}
.tx-reveal.tx-left  { transform: translateX(calc(-1 * var(--tx-rise))); }
.tx-reveal.tx-right { transform: translateX(var(--tx-rise)); }
.tx-reveal.tx-scale { transform: scale(.94); }
.tx-reveal.is-in    { opacity: 1; transform: none; }

/* ----------------------------------------------------------------------------
   3 · LIST SPRING
   Items pop in with a little overshoot, staggered by --tx-i.
   ---------------------------------------------------------------------------- */
.tx-spring {
  opacity: 0;
  transform: translateY(10px) scale(.98);
  transition:
    opacity   var(--tx-base) var(--tx-ease-spring),
    transform var(--tx-base) var(--tx-ease-spring);
  transition-delay: calc(var(--tx-i, 0) * var(--tx-step));
  will-change: opacity, transform;
}
.tx-spring.is-in { opacity: 1; transform: none; }

/* ----------------------------------------------------------------------------
   4 · MODAL PHYSICS
   Backdrop fades; panel springs up + scales in. Toggle .is-open on .tx-modal.
   Structure:  .tx-modal > .tx-modal__scrim + .tx-modal__panel
   ---------------------------------------------------------------------------- */
.tx-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: grid; place-items: center; padding: 20px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition:
    opacity    var(--tx-base) var(--tx-ease-soft),
    visibility 0s linear var(--tx-base);
}
.tx-modal__scrim {
  position: absolute; inset: 0;
  background: rgba(24, 20, 16, .42);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.tx-modal__panel {
  position: relative;
  transform: translateY(12px) scale(.96);
  transition: transform var(--tx-base) var(--tx-ease-spring);
  will-change: transform;
}
.tx-modal.is-open {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition-delay: 0s;
}
.tx-modal.is-open .tx-modal__panel { transform: none; }

/* ----------------------------------------------------------------------------
   5 · ONE-SHOT HELPERS
   Fire once on insert. Add the class; remove/re-add to replay.
   ---------------------------------------------------------------------------- */
.tx-fade { animation: tx-fade var(--tx-base) var(--tx-ease-soft) both; }
.tx-pop  { animation: tx-pop  var(--tx-base) var(--tx-ease-spring) both; }
@keyframes tx-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes tx-pop  {
  from { opacity: 0; transform: scale(.9); }
  to   { opacity: 1; transform: none; }
}

/* ----------------------------------------------------------------------------
   ACCESSIBILITY — honour reduced-motion. Content still shows; motion is cut.
   ---------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .tx-page,
  .tx-reveal,
  .tx-spring,
  .tx-modal,
  .tx-modal__panel,
  .tx-fade,
  .tx-pop {
    animation: none !important;
    transition-duration: 1ms !important;
    transition-delay: 0s !important;
  }
  .tx-reveal,
  .tx-spring { opacity: 1 !important; transform: none !important; }
}
