/* Dependency-free motion tokens and reveal utilities. Copy and adapt per project. */
:root {
  --dur-quick: 160ms;
  --dur-standard: 300ms;
  --dur-slow: 700ms;
  --ease-expo-out: cubic-bezier(.16,1,.3,1);
  --ease-quart-out: cubic-bezier(.25,1,.5,1);
  --ease-expo-inout: cubic-bezier(.87,0,.13,1);
  --ease-standard: cubic-bezier(.2,0,0,1);
  --ease-float: cubic-bezier(.4,0,.2,1);
  --stagger: 80ms;
  --reveal-y: 28px;
}

.js-alive [data-alive] {
  opacity: 0;
  transform: translateY(var(--reveal-y));
  transition:
    opacity var(--dur-slow) var(--ease-quart-out),
    transform var(--dur-slow) var(--ease-expo-out);
  transition-delay: calc(var(--alive-i, 0) * var(--stagger));
  will-change: opacity, transform;
  animation: alive-failsafe .5s var(--ease-quart-out) 2.5s forwards;
}

@keyframes alive-failsafe { to { opacity: 1; transform: none; } }

.js-alive [data-alive].is-in { opacity: 1; transform: none; animation: none; }
.js-alive [data-alive="reveal-left"] { transform: translateX(-36px); }
.js-alive [data-alive="reveal-scale"] { transform: scale(.94) translateY(12px); }
.js-alive [data-alive].is-done { will-change: auto; }

.js-alive [data-load] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 600ms var(--ease-quart-out), transform 600ms var(--ease-expo-out);
  animation: alive-failsafe .5s var(--ease-quart-out) 2.5s forwards;
}

.js-alive [data-load="1"] { transition-delay: 0ms; }
.js-alive [data-load="2"] { transition-delay: 200ms; }
.js-alive [data-load="3"] { transition-delay: 400ms; }
.js-alive [data-load="4"] { transition-delay: 600ms; }
.js-alive [data-load="5"] { transition-delay: 800ms; }
.js-alive [data-load="6"] { transition-delay: 1000ms; }
.js-alive.is-loaded [data-load] { opacity: 1; transform: none; animation: none; }

.js-alive .alive-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(.6em);
  transition: opacity 500ms var(--ease-quart-out), transform 500ms var(--ease-expo-out);
  transition-delay: calc(var(--alive-i, 0) * var(--stagger) + 200ms);
  animation: alive-failsafe .5s var(--ease-quart-out) 2.5s forwards;
}

.js-alive.is-loaded .alive-word { opacity: 1; transform: none; animation: none; }
.alive-press { transition: transform var(--dur-quick) var(--ease-standard); }
.alive-press:active { transform: scale(.97); }
.alive-lift {
  transition: transform var(--dur-quick) var(--ease-standard),
    box-shadow var(--dur-quick) var(--ease-standard);
}
.alive-lift:hover { transform: translateY(-3px); }

@keyframes alive-drift {
  0%, 100% { transform: translate3d(0,0,0); }
  50% { transform: translate3d(0,-14px,0); }
}
.alive-ambient { animation: alive-drift 9s var(--ease-float) infinite; }

@media (prefers-reduced-motion: reduce) {
  .js-alive [data-alive], .js-alive [data-load], .js-alive .alive-word {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .alive-ambient { animation: none !important; }
  .alive-press, .alive-lift { transition: none; }
}

