From 3b9bd62a24b0804fc137e3e154aaa6b300af59a1 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sat, 16 May 2026 12:41:28 +0200 Subject: [PATCH] docs(13): capture phase context --- .../13-design-system-foundation/13-CONTEXT.md | 155 +++++++++++++++ .../13-DISCUSSION-LOG.md | 185 ++++++++++++++++++ 2 files changed, 340 insertions(+) create mode 100644 .planning/phases/13-design-system-foundation/13-CONTEXT.md create mode 100644 .planning/phases/13-design-system-foundation/13-DISCUSSION-LOG.md diff --git a/.planning/phases/13-design-system-foundation/13-CONTEXT.md b/.planning/phases/13-design-system-foundation/13-CONTEXT.md new file mode 100644 index 0000000..d81bf15 --- /dev/null +++ b/.planning/phases/13-design-system-foundation/13-CONTEXT.md @@ -0,0 +1,155 @@ +# Phase 13: Design System Foundation - Context + +**Gathered:** 2026-05-16 +**Status:** Ready for planning + + +## 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. + + + + +## 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 + + + + +## 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 + + + + +## 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) + + + + +## 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 + + + + +## 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 + + + +--- + +*Phase: 13-Design System Foundation* +*Context gathered: 2026-05-16* diff --git a/.planning/phases/13-design-system-foundation/13-DISCUSSION-LOG.md b/.planning/phases/13-design-system-foundation/13-DISCUSSION-LOG.md new file mode 100644 index 0000000..65b46e3 --- /dev/null +++ b/.planning/phases/13-design-system-foundation/13-DISCUSSION-LOG.md @@ -0,0 +1,185 @@ +# Phase 13: Design System Foundation - Discussion Log + +> **Audit trail only.** Do not use as input to planning, research, or execution agents. +> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered. + +**Date:** 2026-05-16 +**Phase:** 13-design-system-foundation +**Areas discussed:** Token values, app.css scope, Catalog route, Component API + +--- + +## Token Values + +| Option | Description | Selected | +|--------|-------------|----------| +| Port verbatim | Copy go-backend/base.css token values as-is. Adjust later after seeing catalog. | ✓ | +| Adjust first | User has specific color/style changes in mind before tokens are baked in. | | +| You decide | Claude ports verbatim and notes obviously unfinished token groups. | | + +**User's choice:** Port verbatim + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Port all tokens | Full 223-line base.css copied to backend. | ✓ | +| Component-referenced only | Only port tokens that component CSS actually consumes. | | +| You decide | Claude ports all tokens. | | + +**User's choice:** Port all tokens + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Replace entirely | go-backend's base.css already includes the same resets. | ✓ | +| Merge carefully | Keep existing resets, add :root block below. | | +| You decide | Claude replaces entirely. | | + +**User's choice:** Replace entirely + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Token consumption required | Component CSS must use var(…). | | +| Tokens sufficient for Phase 13 | Port token vocabulary now; wire component CSS in Phases 14–17. | ✓ | +| You decide | Claude wires component CSS to tokens. | | + +**User's choice:** Tokens sufficient for Phase 13 + +--- + +## app.css Scope + +| Option | Description | Selected | +|--------|-------------|----------| +| Foundation — Phase 13 | Port app.css now as the app shell. | | +| Per-surface — Phases 14–17 | Phase 13 ships component-level CSS only. | ✓ | +| Split it | Port shell skeleton in Phase 13; surface decoration in 14–17. | | + +**User's choice:** Per-surface — Phases 14–17 + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Component files only | tailwind.input.css imports base.css + component CSS. No app shell. | ✓ | +| Minimal shell too | Add a thin app.css with layout primitives only. | | + +**User's choice:** Component files only + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Strip page-level rules | Component CSS stays .ui-* scoped. Page rules wait for Phase 14. | ✓ | +| Include if needed | Keep page-level rules if a component needs them. | | + +**User's choice:** Strip page-level rules + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Plain page, no shell | Components in isolation on minimal layout. | | +| Fake shell | Catalog mimics app layout (sidebar + content area). | ✓ | + +**User's choice:** Fake shell + +--- + +## Catalog Route + +| Option | Description | Selected | +|--------|-------------|----------| +| Env var check (DEV_MODE=true) | Handler checks env. Routes registered but 404 in production. | | +| Build tag | //go:build catalog gates the handler. Zero attack surface in prod. | ✓ | +| Config flag (APP_ENV=development) | Reads existing APP_ENV config. | | + +**User's choice:** Build tag + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Single long-scroll page | One page, all components visible when scrolling. | | +| Sidebar/anchor nav | Left nav with #buttons, #badges, #cards etc. section links. | ✓ | + +**User's choice:** Sidebar/anchor nav + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Rendered only | Visual inspection only. | | +| Rendered + templ call | Shows templ call used to produce each variant. | ✓ | + +**User's choice:** Rendered + templ call + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Static HTML only | No JS. All variants pre-rendered. | ✓ | +| Simple variant toggles | JavaScript toggles for size/tone variants. | | + +**User's choice:** Static HTML only + +--- + +## Component API + +| Option | Description | Selected | +|--------|-------------|----------| +| Keep existing variants only | DS-02 covered by current Variant+Tone. | | +| Add Ghost variant | Ghost explicitly listed in DS-02. Add ButtonVariantGhost. | ✓ | +| You decide | Claude maps DS-02 to existing surface, adds Ghost only if missing. | | + +**User's choice:** Add Ghost variant + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Add BadgeVariantPrimary | Brand-colored badge variant. Matches DS-05 exactly. | ✓ | +| Keep existing | Info already maps to blue/brand. Primary can be added in Phase 14. | | +| You decide | Claude adds Primary if go-backend badge has it. | | + +**User's choice:** Add BadgeVariantPrimary + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Fill CSS, leave Props unchanged | If a component compiles, don't touch the API. | | +| Align Props with go-backend | Review each component's Props against go-backend version. | ✓ | +| You decide | Claude extends Props only where DS requirement clearly needs a new prop. | | + +**User's choice:** Align Props with go-backend + +--- + +| Option | Description | Selected | +|--------|-------------|----------| +| Extend tests for all components | Each component gets at least a smoke test for class-generation logic. | ✓ | +| Catalog + regression only | Verify catalog route works and existing tests stay green. | | + +**User's choice:** Extend tests for all components + +--- + +## Claude's Discretion + +- Exact CSS class naming: match go-backend class names exactly +- Order of anchor sections in catalog sidebar +- Exact fake-shell HTML structure in catalog +- Test coverage depth beyond the happy-path smoke test per component + +## Deferred Ideas + +- `app.css` shell port — deferred to Phases 14–17 +- Wiring component CSS to CSS custom properties — deferred to Phases 14–17 +- Dark mode tokens — future requirement DARK-01 +- Responsive layout — future requirements RESP-01..03