# Tasks — 032: Performance Homepage > Ordem de execução respeita dependências. Cada task é atômica e pode ser validada individualmente. --- ## FASE 1 — Fundação (sem quebra de interface) ### TASK-01: Criar hook `useInView` - **Arquivo:** `frontend/src/hooks/useInView.ts` (criar) - **Ação:** ```ts import { useEffect, useRef, useState } from 'react' export function useInView(options?: IntersectionObserverInit) { const ref = useRef(null) const [inView, setInView] = useState(false) useEffect(() => { const el = ref.current if (!el) return const observer = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { setInView(true) observer.disconnect() } }, options) observer.observe(el) return () => observer.disconnect() // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return { ref, inView } } ``` - **Validação:** `get_errors` sem erros --- ### TASK-02: Mover `@keyframes fadeDown` para `index.css` - **Arquivo:** `frontend/src/index.css` (editar — adicionar ao final) - **Conteúdo a adicionar:** ```css @keyframes fadeDown { 0%, 100% { opacity: 0; transform: translateY(-4px); } 50% { opacity: 1; transform: translateY(4px); } } ``` - **Arquivo:** `frontend/src/components/HomeScrollScene.tsx` (editar — remover o bloco `