Files
developer 9ca7473729 feat(app): route every page with wouter
Replace the single-scroll showcase and its anchor/scrollIntoView
navigation with real routes: /, /patterns, /components/*, /foundations/*,
/docs/*, plus a 404 fallback.

- src/app/routes.tsx is the route table and the only source for paths,
  section headings, sidebar entries, breadcrumbs and the rail, so
  navigation cannot drift from the pages that exist
- src/pages/* holds one component per route; App.tsx is now the shell
  (topbar, sidebar, breadcrumbs, Switch, right rail, scroll-to-top)
- the active pattern moves into the URL (/patterns?pattern=table) and the
  sidebar/palette deep-link into it; SearchPalette results now carry a path
- Sidebar/RightRail render <Link> with aria-current; Hero and Topbar use
  route links too (ButtonLink keeps the button visual)
- PATTERNS + PatternId move to src/data/patterns.ts (no non-component
  export in a component file), pattern buttons gain aria-pressed
- tests/routing.test.tsx: registry/nav invariants, per-route rendering,
  sidebar navigation, pattern deep links, 404
2026-09-15 18:50:34 +00:00

66 lines
2.4 KiB
Markdown

# Northstar Design System
A token-driven design system showcase built for AI-assisted development workflows.
React 19 · Vite 8 · TypeScript (strict) · Vitest · oxlint.
## Quick start
```bash
npm install
npm run dev # dev server on 0.0.0.0:5173
```
## The quality gate
```bash
npm run check
```
One command, four gates, in order:
1. **`oxlint`** — lint over every source file.
2. **`scripts/check-tokens.mjs`** — the token contract: bans hardcoded colors
(hex / named / `rgb()` / `hsl()` / `oklch()` / `lab()`), px font sizes and
undefined `var(--x)` references — in **both** CSS files and inline
`style={{ … }}` objects. Values may span lines; comments are ignored.
3. **`vitest run`** — unit + component tests (`tests/`).
4. **`tsc -b && vite build`** — strict typecheck, then production build.
CI runs the same gate on every push and PR (`.github/workflows/ci.yml`).
## Design tokens
`src/tokens.css` is the single source of truth. Every color, font size,
spacing, radius and shadow goes through a `var(--token)` — components never
hardcode values. Themes are plain CSS: `:root[data-theme='light']` /
`.light` and `:root[data-theme='dark']` / `.dark`, with a pre-paint script in
`index.html` that applies the saved (or OS-preferred) theme before first paint.
The global density knob is `--root-font-size` — one line scales the whole app.
## Layout
```
src/
tokens.css ← lab() design tokens, dark & light themes
index.css ← fonts, token import, base resets
utils.css ← token-compliant utility classes
App.css ← application showcase styles
app/ ← AppStateProvider + useAppState(), and the route table (wouter)
pages/ ← one page component per route
components/
ui/ ← composable primitives (Overlay, Dialog, Sheet, Tabs, Alert, …)
icon-registry.ts← the one icon name → lucide component map
examples/ ← reusable patterns (MetricsDashboard, SettingsPanel, …)
dev/ ← ErrorBoundary + dev error sink (#dev-errors)
utils/ ← cn(), useTimeout()
tests/ ← vitest suites (jsdom)
scripts/
check-tokens.mjs ← token contract guard
```
## For agents
Read [`AGENTS.md`](./AGENTS.md) before changing anything — it documents the
token contract, the overlay/icon registries, and the parallel-subagent rules.