/* Motion: the only @keyframes in the project, plus the scroll-reveal system. */

/* ---------- Keyframes ---------- */

/* Entrance: fade in while rising 24px. */
@keyframes rise {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: none; }
}

/* Breathing indicator dot. */
@keyframes pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.75); }
}

/* Fire jitter for embers and flames. */
@keyframes flicker {
  0%, 100% { opacity: 1;    transform: scale(1)    translateY(0); }
  30%      { opacity: 0.8;  transform: scale(0.96) translateY(-1px); }
  60%      { opacity: 0.95; transform: scale(1.03) translateY(-2px); }
  80%      { opacity: 0.85; transform: scale(0.98) translateY(0); }
}

/* Scan line: the element's bottom edge travels top to bottom of its box.
   Size the element to the area it should sweep (for example inset: 0). */
@keyframes scan {
  from { transform: translateY(-100%); }
  to   { transform: translateY(100%); }
}

/* Ticker: the track holds the phrase twice, so -50% is a seamless loop. */
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Slow float up and down for orbs and chips. */
@keyframes drift {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-12px); }
}

/* Full rotation for rings. */
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Progress bar fill. Set transform-origin: left on the bar. */
@keyframes fill-bar {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Loading sweep for .button-progress. */
@keyframes indeterminate {
  from { transform: translateX(-100%); }
  to   { transform: translateX(250%); }
}

/* Route bar under the header: draws across, then fades. */
@keyframes route-sweep {
  0%   { opacity: 1; transform: scaleX(0); }
  65%  { opacity: 1; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(1); }
}

/* ---------- Scroll reveal ---------- */

/* reveal.js adds .is-visible on entry. Staggered items get --reveal-delay inline from JS. */
[data-reveal] {
  --reveal-y: 32px;
  opacity: 0;
  transform: translateY(var(--reveal-y));
  transition:
    opacity var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* ---------- Reduced motion ---------- */

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

  [data-reveal] {
    opacity: 1;
    transform: none;
  }

  .cursor-glow {
    display: none;
  }
}
