/*
  animations.css
  Shared, reusable animation classes: scroll-triggered reveals (paired
  with scroll-reveal.js), the homepage entrance sequence (paired with
  hero-animation.js), and the cursor-proximity headline magnification
  (paired with headline-magnification.js). Keyframes and transition
  timing are centralized here so no other stylesheet needs to redefine
  them.
*/

/* ---- Scroll reveal system (IntersectionObserver driven) ---- */

.reveal-on-scroll {
  opacity: 0;
  transition: opacity var(--comrade-transition-slow),
    transform var(--comrade-transition-slow);
}

.reveal-up {
  transform: translateY(28px);
}

.reveal-left {
  transform: translateX(-28px);
}

.reveal-right {
  transform: translateX(28px);
}

.reveal-scale {
  transform: scale(0.94);
}

.reveal-on-scroll.is-visible {
  opacity: 1;
  transform: translate(0, 0) scale(1);
}

/* ---- Homepage hero entrance sequence ---- */

.hero-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--comrade-transition-slow),
    transform var(--comrade-transition-slow);
}

.hero-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.hero-reveal-scale {
  opacity: 0;
  transform: scale(0.92);
  transition: opacity var(--comrade-transition-slow),
    transform var(--comrade-transition-slow);
}

.hero-reveal-scale.is-visible {
  opacity: 1;
  transform: scale(1);
}

/* Staggered entrance delays, applied as classes so no inline styles
   are needed anywhere in the templates. */
.comrade-delay-1 {
  transition-delay: 80ms;
}

.comrade-delay-2 {
  transition-delay: 180ms;
}

.comrade-delay-3 {
  transition-delay: 280ms;
}

.comrade-delay-4 {
  transition-delay: 380ms;
}

.comrade-delay-5 {
  transition-delay: 480ms;
}

.comrade-delay-6 {
  transition-delay: 580ms;
}

@media (prefers-reduced-motion: reduce) {
  .reveal-on-scroll,
  .hero-reveal,
  .hero-reveal-scale {
    transition: opacity var(--comrade-transition-fast);
    transform: none !important;
  }
}

/* ---- Cursor-proximity headline magnification ----
   headline-magnification.js wraps each character of every targeted
   large display headline (hero, footer statement, About hero, About
   section headings, Vision and Products headlines — see
   HEADLINE_SELECTORS in that file) in a .headline-char span at
   runtime, only on devices this media query also matches — a second,
   independent guarantee alongside the JS's own capability check — and
   drives its scale every frame from pointer distance. inline-block
   gives each character its own stable transform-origin without ever
   pulling neighboring characters out of normal text flow.

   .headline-word (also written by that same JS) is not decorative: an
   atomic inline-level box like inline-block gets an implicit soft-wrap
   opportunity on both sides per the CSS Text spec, so without
   grouping each word's character spans under one nowrap wrapper, the
   browser is free to break a line between any two letters, not just
   at real spaces — which is exactly what once split "taking" into
   "taki" / "ng" mid-word. The word span itself stays plain inline
   (non-atomic), so only real spaces between words remain valid break
   points, same as normal text.

   No transition is declared here on purpose: the magnification's
   smoothing (easing each character's scale toward its target over
   several frames) is done in JS, in step with its own
   requestAnimationFrame loop. A CSS transition racing that same
   per-frame value would fight it rather than help it, the same reason
   the orbit dot's position (orbit.css) is never CSS-transitioned
   either. */
@media (hover: hover) and (pointer: fine) {
  .headline-word {
    white-space: nowrap;
  }

  .headline-char {
    display: inline-block;
    transform: scale(1);
    transform-origin: center center;
    will-change: transform;
  }
}
