# S06: Landing Page Personality Pass

**Goal:** Homepage gets animated stat count-up, unified section headings, tighter above-fold content, and header brand accent line.
**Demo:** After this: Homepage: animated stat count-up, consistent section headings, content above fold, header brand accent with logo.

## Tasks
- [x] **T01: Created generic useCountUp hook with IntersectionObserver-triggered rAF animation and wired it into Home.tsx stats section** — 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
  - Estimate: 30m
  - Files: frontend/src/hooks/useCountUp.ts, frontend/src/pages/Home.tsx
  - Verify: cd frontend && npx tsc --noEmit && npm run build && test -f src/hooks/useCountUp.ts && grep -q 'useCountUp' src/pages/Home.tsx
- [x] **T02: Added .section-heading utility class to unify four heading styles, tightened hero/how-it-works spacing for above-fold content, and added 2px cyan border-bottom to header** — Three CSS/JSX changes to polish the homepage personality.

Steps:
1. **Unified section headings** — In `frontend/src/App.css`:
   - Add a `.section-heading` utility class: `font-size: 0.8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); margin: 0 0 0.75rem;`
   - Add `.section-heading--accent` modifier: `color: var(--color-accent);`
   - Simplify `.home-popular-topics__title`, `.home-trending__title`, `.home-featured__label`, `.recent-section__title` — remove duplicated font-size/weight/transform/spacing declarations, keeping only section-specific overrides (if any)
   - In `frontend/src/pages/Home.tsx`, add `section-heading` className to all four heading elements. For `.home-featured__label`, also add `section-heading--accent`. For `.recent-section__title`, also add `section-heading` (it currently has larger font-size 1.125rem and weight 700 — these get replaced by the unified style).

2. **Above-fold tightening** — In `frontend/src/App.css`:
   - Reduce `.home-hero` padding from `2rem 1rem 2.5rem` to `1.5rem 1rem 1.5rem`
   - Reduce `.home-hero__value-prop` margin-top from `1.5rem` to `1rem`
   - Reduce `.home-how-it-works` margin-top from `2rem` to `1.25rem` and gap from `1rem` to `0.75rem`
   - The goal is to get the search bar + value prop + start of popular topics visible on a 900px viewport without scrolling.

3. **Header brand accent** — In `frontend/src/App.css`:
   - Add `border-bottom: 2px solid var(--color-accent);` to `.app-header`
   - This ties the header to the cyan brand color already in the logo SVG

Constraints:
- The `.section-heading` class must be additive — don't break any section-specific positioning (margins, text-align)
- Keep the featured label's accent color via the modifier class
- Don't touch the card-stagger animation (it already works)
  - Estimate: 25m
  - Files: frontend/src/App.css, frontend/src/pages/Home.tsx
  - Verify: cd frontend && npm run build && grep -q 'section-heading' src/App.css && grep -q 'section-heading' src/pages/Home.tsx && grep -q 'border-bottom.*accent' src/App.css
