/* ============================================================
   tajwalia.com · 2026 — Layer 3: MOTION
   Entrance choreography, scroll-linked ambient effects.
   CSS owns every animation; JS (motion.js) only toggles the
   `.in` class and assigns the --i stagger index.
   All effects are opacity / transform / clip-path only —
   compositor-composited, zero layout shift.
   ============================================================ */

/* ---------- Reveal primitives ---------- */
/* All hidden "pre-animation" states are gated behind html.js
   (a class set by an inline script in <head>). If JavaScript
   ever fails to load — file:// preview, blocked script, old
   browser — every element stays fully visible. Content can
   never be trapped at opacity:0. */

/* Default reveal: fade + rise */
html.js .reveal{
  opacity:0;
  transform:translateY(24px);
  transition:
    opacity var(--t-reveal) var(--ease-out-expo),
    transform var(--t-reveal) var(--ease-out-expo);
  transition-delay:calc(var(--i, 0) * var(--stagger-step));
  will-change:opacity, transform;
}
html.js .reveal.in{
  opacity:1;
  transform:none;
  will-change:auto;
}

/* Heading variant: clip-path wipe upward + rise */
html.js .reveal-clip{
  opacity:0;
  transform:translateY(24px);
  clip-path:inset(0 0 100% 0);
  transition:
    opacity var(--t-reveal) var(--ease-out-expo),
    transform var(--t-reveal) var(--ease-out-expo),
    clip-path var(--t-reveal) var(--ease-out-expo);
  transition-delay:calc(var(--i, 0) * var(--stagger-step));
}
html.js .reveal-clip.in{
  opacity:1;
  transform:none;
  clip-path:inset(0 0 -8% 0); /* slight over-reveal protects descenders */
}

/* Rule / divider variant: draw from left */
html.js .reveal-rule{
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform var(--t-slow) var(--ease-out-expo);
  transition-delay:calc(var(--i, 0) * var(--stagger-step) + 160ms);
}
html.js .reveal-rule.in{transform:scaleX(1)}

/* Eyebrow tick: the ::before dash draws in with the reveal */
html.js .section-head .eyebrow::before{
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform var(--t-slow) var(--ease-out-expo) 120ms;
}
html.js .section-head.in .eyebrow::before,
html.js .section-head .eyebrow.in::before{transform:scaleX(1)}

/* ---------- Ambient scroll-driven effects (progressive) ---------- */
/* Browsers without animation-timeline silently skip this block;
   the IntersectionObserver reveals above remain the baseline. */
@supports (animation-timeline: view()){
  .hero-grid{
    animation:heroExit linear both;
    animation-timeline:view();
    animation-range:exit 0% exit 100%;
  }
  @keyframes heroExit{
    to{opacity:.25;transform:translateY(-32px)}
  }
}

/* ---------- Reduced motion ---------- */
/* base.css already kills all transitions/animations globally.
   These rules additionally guarantee revealed content is VISIBLE
   (transition:none alone would leave opacity:0 stuck states). */
@media (prefers-reduced-motion:reduce){
  .reveal,
  .reveal-clip,
  .reveal-rule{
    opacity:1;
    transform:none;
    clip-path:none;
  }
  .section-head .eyebrow::before{transform:none}
}
