---
id: T02
parent: S03
milestone: M015
provides: []
requires: []
affects: []
key_files: ["frontend/src/api/public-client.ts", "frontend/src/pages/Home.tsx", "frontend/src/App.css"]
key_decisions: ["Used existing --color-* CSS custom properties to match real codebase conventions"]
patterns_established: []
drill_down_paths: []
observability_surfaces: []
duration: ""
verification_result: "npm run build exits 0. API returns 200 with technique_count:21 and creator_count:7. Browser assertion confirms scorecard visible with correct text and selector (.home-stats). All slice-level curl checks pass."
completed_at: 2026-04-03T04:29:08.090Z
blocker_discovered: false
---

# T02: Homepage displays a stats scorecard showing live article and creator counts from /api/v1/stats in cyan-on-dark design

> Homepage displays a stats scorecard showing live article and creator counts from /api/v1/stats in cyan-on-dark design

## What Happened
---
id: T02
parent: S03
milestone: M015
key_files:
  - frontend/src/api/public-client.ts
  - frontend/src/pages/Home.tsx
  - frontend/src/App.css
key_decisions:
  - Used existing --color-* CSS custom properties to match real codebase conventions
duration: ""
verification_result: passed
completed_at: 2026-04-03T04:29:08.090Z
blocker_discovered: false
---

# T02: Homepage displays a stats scorecard showing live article and creator counts from /api/v1/stats in cyan-on-dark design

**Homepage displays a stats scorecard showing live article and creator counts from /api/v1/stats in cyan-on-dark design**

## What Happened

Added StatsResponse interface and fetchStats() to public-client.ts, wired up Home.tsx with state/effect/render for a scorecard section between nav-cards and random button, and added CSS using existing design tokens (--color-accent, --color-bg-surface, --color-border, --color-text-muted). Build passes, container rebuilt on ub01, and browser verification confirms "21 ARTICLES" and "7 CREATORS" rendering correctly.

## Verification

npm run build exits 0. API returns 200 with technique_count:21 and creator_count:7. Browser assertion confirms scorecard visible with correct text and selector (.home-stats). All slice-level curl checks pass.

## Verification Evidence

| # | Command | Exit Code | Verdict | Duration |
|---|---------|-----------|---------|----------|
| 1 | `cd frontend && npm run build` | 0 | ✅ pass | 3200ms |
| 2 | `curl -s http://ub01:8096/api/v1/stats | python3 assert counts > 0` | 0 | ✅ pass | 200ms |
| 3 | `curl -s -o /dev/null -w '%{http_code}' http://ub01:8096/api/v1/stats` | 0 | ✅ pass | 100ms |
| 4 | `browser_assert: 5 checks (text_visible + selector_visible)` | 0 | ✅ pass | 500ms |


## Deviations

Used real CSS custom property names (--color-accent not --accent). Used correct compose service name (chrysopedia-web not chrysopedia-web-8096).

## Known Issues

None.

## Files Created/Modified

- `frontend/src/api/public-client.ts`
- `frontend/src/pages/Home.tsx`
- `frontend/src/App.css`


## Deviations
Used real CSS custom property names (--color-accent not --accent). Used correct compose service name (chrysopedia-web not chrysopedia-web-8096).

## Known Issues
None.
