/* ============================================
   Visual Effects — scroll reveal, motion
   ============================================ */

/* ---- Fade In Up on Scroll ----
   Only hidden when JS is active (html.js), so no-JS users always see content
   and the animation is pure progressive enhancement. */
.js .fade-in-up {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

.js .fade-in-up.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ---- Stagger children ---- */
.js .fade-in-up-stagger > * {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}

/* Catch-all reveal: every child becomes visible; nth-child rules below only stagger the delay.
   Children beyond the 6th reveal together at the max delay rather than staying hidden. */
.js .fade-in-up-stagger.is-visible > * { transition-delay: 500ms; opacity: 1; transform: translateY(0); }
.js .fade-in-up-stagger.is-visible > *:nth-child(1) { transition-delay:   0ms; }
.js .fade-in-up-stagger.is-visible > *:nth-child(2) { transition-delay: 100ms; }
.js .fade-in-up-stagger.is-visible > *:nth-child(3) { transition-delay: 200ms; }
.js .fade-in-up-stagger.is-visible > *:nth-child(4) { transition-delay: 300ms; }
.js .fade-in-up-stagger.is-visible > *:nth-child(5) { transition-delay: 400ms; }

/* ---- Gradient text accent ---- */
.text-gradient {
  background: linear-gradient(135deg, var(--brand), var(--brand-deep));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ---- Reduced Motion ----
   Selectors carry the .js prefix so they match the specificity of the hide
   rules above — without it those rules win and reduced-motion users still
   get the hide-then-animate reveal. */
@media (prefers-reduced-motion: reduce) {
  .js .fade-in-up,
  .js .fade-in-up-stagger > * {
    opacity: 1;
    transform: none;
    transition: none;
  }
  html { scroll-behavior: auto; }
}
