---
estimated_steps: 21
estimated_files: 2
skills_used: []
---

# T01: Add useCountUp hook and wire animated stats in Home.tsx

Create a `useCountUp(target, duration)` React hook that animates from 0 to target using requestAnimationFrame with ease-out timing. Use IntersectionObserver to trigger the animation when the stats section enters the viewport. Wire it into Home.tsx so that `.home-stats__number` elements display the animated count instead of raw numbers.

Steps:
1. Create `frontend/src/hooks/useCountUp.ts`:
   - Accept `target: number` and `duration: number` (default 1200ms)
   - Use `useRef` for rAF id and start timestamp, `useState` for current display value
   - Ease-out function: `1 - Math.pow(1 - t, 3)` where t is progress 0→1
   - Return `{ value: number, ref: React.RefObject<HTMLElement> }` where ref is for the IntersectionObserver target
   - Use IntersectionObserver with `threshold: 0.3` — start animation when element is 30% visible
   - Only animate once (use a `hasAnimated` ref flag)
   - Clean up rAF and observer on unmount
2. Modify `frontend/src/pages/Home.tsx`:
   - Import `useCountUp` from hooks
   - Replace static `{stats.technique_count}` with the hook's animated value
   - Replace static `{stats.creator_count}` with a second hook instance
   - Attach the ref to the `.home-stats` section element so observer fires correctly
   - Handle the case where stats is null (don't call hook conditionally — initialize with 0 and update when stats load)
3. The hook should handle target changing (e.g., when stats load async) — reset and re-trigger animation if target changes from 0 to a real value.

Constraints:
- No external libraries
- Hook must be reusable (not Home-specific)
- TypeScript strict — proper typing on the ref generic

## Inputs

- ``frontend/src/pages/Home.tsx` — current Home component with static stats display`

## Expected Output

- ``frontend/src/hooks/useCountUp.ts` — new reusable count-up animation hook`
- ``frontend/src/pages/Home.tsx` — modified to use useCountUp for stats numbers`

## Verification

cd frontend && npx tsc --noEmit && npm run build && test -f src/hooks/useCountUp.ts && grep -q 'useCountUp' src/pages/Home.tsx
