# Phase 13: Design System Foundation - Context

**Gathered:** 2026-05-16
**Status:** Ready for planning

<domain>
## Phase Boundary

Phase 13 delivers the CSS layer of the design system. All templ components already exist in `backend/internal/web/ui` (button, badge, card, modal, input, textarea, select, table, empty-state, icon-button, form-field). The work is:
1. Replace `base.css` with the full token vocabulary from `go-backend/internal/web/ui/base.css` (verbatim port)
2. Port all missing component CSS files (modal, input, textarea, select, table, empty-state, icon-button, form-field, spacing) from go-backend — stripping any page-level selectors
3. Update `backend/tailwind.input.css` to import all component CSS files (no app shell yet)
4. Align each component's Go-side Props structs with go-backend (add missing fields like disabled, size, placeholder)
5. Add `ButtonVariantGhost` and `BadgeVariantPrimary` to the variant surfaces
6. Extend `ui_test.go` to cover class-generation logic for all component types
7. Add a dev-only `/ui-catalog` route (build-tag gated) with sidebar/anchor nav, showing rendered components + templ call for each variant

Phase 13 does NOT port `app.css` (1896-line app shell CSS) — that is deferred to Phases 14–17 where each surface is styled. The catalog page uses a hand-built fake shell for visual context.

</domain>

<decisions>
## Implementation Decisions

### Token Values
- **D-T01:** Port `go-backend/internal/web/ui/base.css` token values verbatim — no adjustments to brand palette, typography, or spacing scale before Phase 13 lands
- **D-T02:** Port ALL tokens — full 223-line vocabulary — not just the subset referenced by current component CSS files
- **D-T03:** Replace `backend/internal/web/ui/base.css` entirely (do not merge); go-backend version already includes the same box-sizing/reset foundation
- **D-T04:** Phase 13 ships the token vocabulary as CSS custom properties; wiring existing component CSS to consume `var(--…)` tokens is Phase 14–17 work — component CSS may still use hardcoded values in Phase 13

### app.css Scope
- **D-A01:** `app.css` (the 1896-line shell) is deferred to Phases 14–17; Phase 13 ships component CSS only
- **D-A02:** `backend/tailwind.input.css` imports `base.css` + all component CSS files; no app shell import in Phase 13
- **D-A03:** When porting component CSS, strip page-level selectors (`body`, `:root` overrides, `.app-layout`); component CSS stays scoped to `.ui-*` class selectors
- **D-A04:** Catalog page uses a hand-built fake shell (sidebar column + content area) for visual context, even though the real `app.css` shell is not yet in backend

### Catalog Route
- **D-C01:** Catalog route is guarded by a Go build tag (`//go:build catalog`); production binary never includes the route — zero attack surface
- **D-C02:** Catalog page layout: sidebar/anchor nav with section links (`#buttons`, `#badges`, `#cards`, etc.) matching the fake shell layout
- **D-C03:** Each component section shows rendered variants + the templ call used to produce each variant (rendered + source, not rendered-only)
- **D-C04:** Static HTML only — no JavaScript interaction; all variants pre-rendered at page load

### Component API
- **D-CA01:** Add `ButtonVariantGhost` to the `ButtonVariant` enum; DS-02 explicitly lists ghost as a required button variant
- **D-CA02:** Add `BadgeVariantPrimary` to the `BadgeVariant` enum; DS-05 explicitly lists primary as a required badge tone
- **D-CA03:** Review and align each component's Go-side Props struct with the go-backend equivalent — fill in missing fields (e.g., `Disabled bool`, `Placeholder string`, `Size Size` where missing)
- **D-CA04:** Extend `ui_test.go` to cover class-generation logic for all 9+ component types (each gets at least one smoke test for variant/class generation)

### Claude's Discretion
- Exact migration of CSS variable names: if go-backend component CSS uses slightly different class names (`.ui-button` vs `.btn`), match go-backend exactly
- Exact fake-shell HTML in the catalog: should mimic the sidebar+main-content layout visible in go-backend's catalog but is not bound to pixel-perfect reproduction
- Order of anchor sections in the catalog sidebar: alphabetical or by component importance
- Exact test coverage depth: at minimum one test per component type for the happy path; error/edge cases at planner discretion

</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

### Product Scope
- `.planning/ROADMAP.md` — Phase 13 goal, success criteria (5 criteria), and user-in-loop requirements (catalog visual sign-off before Phase 14)
- `.planning/REQUIREMENTS.md` — DS-01 through DS-09 (full component library requirements)
- `.planning/PROJECT.md` — v3.0 scope: visual polish only, no new routes or data models; go-backend is the visual reference

### Reference Implementation (source)
- `go-backend/internal/web/ui/base.css` — MUST read; source token vocabulary to port verbatim (223 lines, full `:root` CSS custom properties)
- `go-backend/internal/web/ui/button.css` — button component CSS reference
- `go-backend/internal/web/ui/card.css` — card component CSS reference
- `go-backend/internal/web/ui/badge.css` — badge component CSS reference
- `go-backend/internal/web/ui/modal.css` — modal component CSS reference
- `go-backend/internal/web/ui/input.css` — input component CSS reference
- `go-backend/internal/web/ui/textarea.css` — textarea component CSS reference
- `go-backend/internal/web/ui/select.css` — select component CSS reference
- `go-backend/internal/web/ui/table.css` — table component CSS reference
- `go-backend/internal/web/ui/empty-state.css` — empty-state component CSS reference
- `go-backend/internal/web/ui/icon-button.css` — icon-button component CSS reference
- `go-backend/internal/web/ui/form-field.css` — form-field component CSS reference
- `go-backend/internal/web/ui/spacing.css` — spacing utilities CSS reference
- `go-backend/internal/web/ui/button.templ` — button Props API reference
- `go-backend/internal/web/ui/badge.templ` — badge Props API reference
- `go-backend/internal/web/ui/card.templ` — card Props API reference
- `go-backend/internal/web/ui/modal.templ` — modal Props API reference
- `go-backend/internal/web/ui/input.templ` — input Props API reference
- `go-backend/internal/web/ui/select.templ` — select Props API reference
- `go-backend/internal/web/ui/textarea.templ` — textarea Props API reference
- `go-backend/internal/web/ui/table.templ` — table Props API reference
- `go-backend/internal/web/ui/empty_state.templ` — empty-state Props API reference
- `go-backend/internal/web/ui/icon_button.templ` — icon-button Props API reference
- `go-backend/internal/web/ui/form_field.templ` — form-field Props API reference
- `go-backend/internal/web/ui/tokens.go` — Go-side token constants reference
- `go-backend/internal/web/ui/variants.go` — Go-side variant enum reference
- `go-backend/internal/web/ui/helpers.go` — Go-side class generation helpers reference

### Current Backend State
- `backend/internal/web/ui/base.css` — current 28-line stub to be replaced
- `backend/internal/web/ui/button.templ` — existing button Props (verify Ghost variant needed)
- `backend/internal/web/ui/badge.templ` — existing badge Props (verify Primary variant needed)
- `backend/internal/web/ui/variants.go` — existing ButtonVariant/BadgeVariant enums to extend
- `backend/internal/web/ui/tokens.go` — existing token constants (already forward-compatible)
- `backend/internal/web/ui/helpers.go` — existing class-generation helpers
- `backend/internal/web/ui/ui_test.go` — existing tests to extend
- `backend/tailwind.input.css` — current 4-import config to extend with all component CSS

### Existing Templates (regression check)
- `backend/templates/` — existing Go templates that already use ui components; all must still compile and render with no regressions after Phase 13

</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- All 11 templ components already exist in `backend/internal/web/ui` — work is CSS-only plus Props alignment and variant additions
- `helpers.go` has class-generation functions (`ButtonClass`, `BadgeClass`, etc.) used by templ files — extend these when adding Ghost/Primary variants
- `variants.go` has the canonical enum definitions — add `ButtonVariantGhost` and `BadgeVariantPrimary` here
- `ui_test.go` tests `ButtonClass()` output — extend pattern for all component types

### Established Patterns
- Component CSS uses BEM-style `.ui-*` class naming (`.ui-button`, `.ui-card`, `.ui-badge`) — match go-backend class names exactly
- `templ.Attributes` pass-through pattern allows HTMX attrs without modifying Props struct
- All `*_templ.go` files are generated by `just generate`; never hand-edit them
- Backend CSS is included via `@import` statements in `backend/tailwind.input.css`; Tailwind v4 picks up `.templ` and `.go` source files via `@source` directives

### Integration Points
- `backend/tailwind.input.css` is the import manifest — add `@import "./internal/web/ui/{component}.css"` for each new CSS file
- The build-tag catalog handler registers a route in `backend/internal/web/router.go` only when built with `-tags catalog`
- Catalog templ template lives in `backend/internal/web/ui/catalog/` (matches go-backend pattern)

</code_context>

<specifics>
## Specific Ideas

- Catalog fake shell: sidebar column on the left with section anchor links, main content area on the right showing component groups — mimics the app's eventual two-column layout without importing real app.css
- Each catalog section header shows the component name + DS requirement number (e.g., "Button — DS-02"), followed by a grid of rendered variants, each annotated with the templ call that produces it
- The build-tag guard means running the server normally (`just run`) shows no catalog route; running with `go run -tags catalog ./cmd/web` enables it — document this in the catalog handler or README

</specifics>

<deferred>
## Deferred Ideas

- `app.css` shell port (sidebar layout, topbar, nav shell, content area) — deferred to Phases 14–17 per-surface styling work
- Wiring component CSS to consume `var(--…)` tokens (replacing hardcoded hex values in button.css, badge.css, etc.) — deferred to Phase 14–17 as surfaces are restyled
- Dark mode tokens / `prefers-color-scheme` counterparts — explicitly listed in REQUIREMENTS.md as Future requirement DARK-01
- Responsive sidebar and mobile layout — explicitly listed as Future requirement RESP-01..03

</deferred>

---

*Phase: 13-Design System Foundation*
*Context gathered: 2026-05-16*
