/* ==========================================================================
   ANIMATIONS  -  reveal + scroll animation styling for the WHOLE site.
   Timing numbers below are the only place you need to edit to change feel.
   (Behaviour lives in javascript/animations.js)
   ========================================================================== */
:root {
  --rv-duration: 1.1s;
  --rv-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --rv-distance: 56px;
  --rv-blur: 10px;
  --rv-word-duration: 1.05s;
}

/* Without JS, never hide content */
html:not(.js) [data-reveal] { opacity: 1; transform: none; filter: none; }

[data-reveal] {
  opacity: 0;
  filter: blur(var(--rv-blur));
  transition: opacity var(--rv-duration) var(--rv-ease), transform var(--rv-duration) var(--rv-ease),
    filter var(--rv-duration) var(--rv-ease);
  transition-delay: var(--rv-delay, 0ms);
  will-change: opacity, transform;
}
[data-reveal='up'] { transform: translate3d(0, var(--rv-distance), 0); }
[data-reveal='down'] { transform: translate3d(0, calc(var(--rv-distance) * -1), 0); }
[data-reveal='left'] { transform: translate3d(calc(var(--rv-distance) * -1.2), 0, 0); }
[data-reveal='right'] { transform: translate3d(calc(var(--rv-distance) * 1.2), 0, 0); }
[data-reveal='scale'] { transform: scale(0.92) translate3d(0, 24px, 0); }
[data-reveal='fade'] { transform: none; }
[data-reveal='rise'] { transform: translate3d(0, 110px, 0) scale(0.97); }

[data-reveal].is-in { opacity: 1; transform: none; filter: blur(0); will-change: auto; }

/* Word-mask reveal for headings: add data-split to any heading */
[data-split] .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.12em; margin-bottom: -0.12em; }
[data-split] .wi {
  display: inline-block; transform: translate3d(0, 112%, 0);
  transition: transform var(--rv-word-duration) var(--rv-ease); transition-delay: calc(var(--wi, 0) * 55ms);
}
[data-split].is-in .wi { transform: none; }
html:not(.js) [data-split] .wi { transform: none; }

/* GitHub-style stacking cards: each card sticks, the next slides over it */
[data-stack] { position: relative; }
[data-stack] > * {
  position: sticky; top: calc(var(--nav-h) + 2rem + var(--i, 0) * 1.1rem);
  transform-origin: 50% 0; will-change: transform;
}
@media (max-width: 1023px) { [data-stack] > * { top: calc(1.2rem + var(--i, 0) * 0.9rem); } }

/* Scroll progress bar */
.scroll-progress {
  position: fixed; inset: 0 0 auto 0; height: 3px; z-index: 120; transform-origin: 0 50%;
  transform: scaleX(0); background: var(--accent); box-shadow: 0 0 14px var(--accent-glow);
}

/* Continuous loops */
@keyframes floaty { 0%, 100% { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(0, -12px, 0); } }
@keyframes marquee { to { transform: translate3d(-50%, 0, 0); } }
@keyframes pulse-ring { 0% { transform: scale(0.6); opacity: 0.7; } 100% { transform: scale(1.8); opacity: 0; } }
.floaty { animation: floaty 6s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal], [data-split] .wi { opacity: 1; transform: none; filter: none; }
}
