Parent
#1
What to build
Add subtle scroll-triggered fade-in-up animations to all sections on the portfolio page. Implement a custom useIntersectionObserver hook that observes a ref and adds an is-visible CSS class when the element enters the viewport. Define a CSS @keyframes fadeInUp animation and a utility class that applies it when the is-visible class is present. Apply the hook to each section (Introduction, Skills, Experience, Education, Projects).
The animation should be subtle: translateY(20px) → translateY(0), opacity 0 → 1, duration ~0.5s with a slight stagger delay per section.
This is a progressive enhancement — the page is fully functional without JavaScript; animations only activate after hydration.
Acceptance criteria
Blocked by
Parent
#1
What to build
Add subtle scroll-triggered fade-in-up animations to all sections on the portfolio page. Implement a custom
useIntersectionObserverhook that observes a ref and adds anis-visibleCSS class when the element enters the viewport. Define a CSS@keyframes fadeInUpanimation and a utility class that applies it when theis-visibleclass is present. Apply the hook to each section (Introduction, Skills, Experience, Education, Projects).The animation should be subtle: translateY(20px) → translateY(0), opacity 0 → 1, duration ~0.5s with a slight stagger delay per section.
This is a progressive enhancement — the page is fully functional without JavaScript; animations only activate after hydration.
Acceptance criteria
useIntersectionObserverhook exists and returns a ref + isVisible booleanIntersectionObserverinstance (reuses it for all observed elements)@keyframes fadeInUpdefined with translateY(20px)→translateY(0) and opacity 0→1is-visibleclassnpm run typecheckpassesBlocked by