# S03 Research — Homepage Stats Scorecard

**Depth:** Light — straightforward UI addition using existing data patterns.

**Target Requirement:** R034 — Homepage Stats Scorecard (active)

## Summary

Add a visual stats scorecard to the homepage showing article (technique) count and creator count. No new models or migrations needed — just a lightweight backend stats endpoint and a new frontend section.

## Recommendation

Add a `GET /api/v1/stats` endpoint returning `{technique_count, creator_count}`. Render a scorecard section on `Home.tsx` between the nav-cards and the random-technique button (or between featured and recently-added — planner decides placement). Style with existing dark/cyan design tokens.

## Implementation Landscape

### Backend — New Stats Endpoint

**File:** `backend/routers/stats.py` (new router, ~30 lines)

Create a simple router with one endpoint:
```
GET /api/v1/stats → { technique_count: int, creator_count: int }
```

Implementation: Two `SELECT COUNT(*)` queries against `TechniquePage` and `Creator` tables. Both models already exist in `backend/models.py`.

**Registration:** Add `stats.router` to `backend/main.py` alongside existing routers (pattern: `app.include_router(stats.router, prefix="/api/v1")`).

Existing router registration pattern in `main.py`:
```python
app.include_router(techniques.router, prefix="/api/v1")
app.include_router(creators.router, prefix="/api/v1")
# ... etc
```

**Alternative considered:** Reusing existing list endpoints with `limit=0` to extract `total` — rejected because it runs full query pipelines (joins, subqueries for counts per item) when we only need two simple COUNTs.

### Frontend — API Client Addition

**File:** `frontend/src/api/public-client.ts`

Add:
- `StatsResponse` interface: `{ technique_count: number; creator_count: number }`
- `fetchStats()` function: `GET ${BASE}/stats`

Pattern matches existing functions like `fetchTopics()`, `fetchRandomTechnique()`.

### Frontend — Homepage Scorecard Section

**File:** `frontend/src/pages/Home.tsx`

Add a new `useEffect` + state for stats (`useState<StatsResponse | null>(null)`). Render a scorecard section. Placement: between the nav-cards section and the random-technique button — this puts it in the "discovery" zone of the page.

The scorecard should show two metrics: technique count and creator count. Each metric: large number + label below. Use `card-stagger` animation class already present on other homepage sections.

### Frontend — CSS Styling

**File:** `frontend/src/App.css`

Add `.home-stats` section styles. Design tokens already in use:
- Background: `var(--surface-1)` or similar dark surface
- Accent: cyan (`var(--accent)` / `#00e5ff` range used throughout)
- Text: `var(--text-primary)` / `var(--text-secondary)`
- Border: `1px solid var(--border)` pattern used on cards

The scorecard should be subtle — communicating volume without being boastful (per R034 requirement). Two numbers in a horizontal row with small labels, possibly with a subtle border or background.

Existing homepage section naming pattern: `.home-hero`, `.home-featured`, `.home-popular-topics`, `.home-how-it-works`.

### Existing Patterns to Follow

- **Router pattern:** See `backend/routers/creators.py` lines 24-106 for the simplest existing router
- **Frontend fetch pattern:** See `fetchTopics()` in `public-client.ts` (line 311) — same shape needed
- **Homepage section pattern:** Each section in `Home.tsx` has its own `useEffect` with cancellation flag, own state, and a `<section>` block with BEM-style classes
- **Stagger animation:** `card-stagger` class + `--stagger-index` CSS variable already used on nav-cards and recent-cards

### Key Files

| File | Action | Notes |
|------|--------|-------|
| `backend/routers/stats.py` | Create | New router, ~30 lines |
| `backend/main.py` | Edit | Register stats router |
| `frontend/src/api/public-client.ts` | Edit | Add StatsResponse + fetchStats |
| `frontend/src/pages/Home.tsx` | Edit | Add stats state + scorecard section |
| `frontend/src/App.css` | Edit | Add .home-stats styles |

### Natural Task Seams

1. **Backend stats endpoint** (stats.py + main.py registration) — verify with curl
2. **Frontend scorecard** (public-client.ts + Home.tsx + App.css) — verify with browser

Two tasks. Backend first since frontend depends on it. Both are small.

### Verification

- `curl http://ub01:8096/api/v1/stats` returns `{"technique_count": N, "creator_count": N}` with N > 0
- Homepage at `http://ub01:8096` shows scorecard block with real counts
- `npm run build` succeeds (frontend compiles)
