ADR-0004 — Three Page Layout Wrappers
Every page MUST use WorkspacePage, StandardPage, or ControlPage. Three sharp tools beat one Swiss Army knife. AppBreadcrumb mounted consistently; rail-to-rail layout enforced.
| Field | Value |
|---|---|
| Status | 🟢 Accepted |
| Date | 2026-03-16 |
| Deciders | @aphaiboon |
| Related ADRs | (none — design system decisions are typically standalone) |
Context
Section titled “Context”By early 2026, CMMD had ~40 top-level pages. Each was built ad hoc — some used <UnifiedHeader> directly, some wrapped their own headers, some used a deprecated zone system (setZ3/Z4/Z5). Visual inconsistency was creeping in: different gutters per page, different breadcrumb behavior, different empty states, different loading spinners.
The “rail-to-rail” layout principle (both vertical rails defined by the unified header at px-4 md:px-6) was being broken by half the pages adding their own max-w-* or mx-auto. This collapsed content away from the rails on wide screens, creating a “narrow column floating in the middle of the screen” look that conflicts with our Linear/Notion/Stripe minimalism reference (see Design System).
We needed to consolidate to a small fixed set of layout shapes that:
- Enforce rail-to-rail
- Mount
AppBreadcrumbconsistently - Standardize empty + loading states
- Cover all real use cases without needing escape hatches
Decision
Section titled “Decision”Every new page MUST use one of three wrappers from @/components/layout/page-wrappers:
| Wrapper | When | Examples |
|---|---|---|
WorkspacePage | Split-view apps with custom panels/sidebars | Chat, Comms, Tasks |
StandardPage (default) | Header + content grid | App Store / Marketplace, Admin, Projects, Brain |
ControlPage | Settings / configuration forms (narrow centered max-w-4xl) | Settings, Billing |
StandardPage.Content provides w-full px-4 md:px-6 automatically. The UnifiedHeader Z3/Z4/Z5 zones are deprecated — setZ3/Z4/Z5 is banned in new pages.
→ Full implementation rules: Page Layout Wrappers standard
Alternatives considered
Section titled “Alternatives considered”Option A — One mega-wrapper with config props
Section titled “Option A — One mega-wrapper with config props”<Page mode="workspace" hasSidebar={true} narrow={false} />- ✅ Single component to learn
- ❌ Config combinations explode; many are invalid (e.g. ControlPage should always be narrow)
- Rejected: Three sharp tools beat one Swiss Army knife.
Option B — Compound components only (<Page.Header>, <Page.Body>, …)
Section titled “Option B — Compound components only (<Page.Header>, <Page.Body>, …)”- ✅ Maximum flexibility
- ❌ Doesn’t enforce the layout choice — every page can compose differently
- ❌ Doesn’t solve the original problem (visual inconsistency)
- Rejected: Flexibility was the problem, not the solution
Option C — Style guide alone (no wrappers)
Section titled “Option C — Style guide alone (no wrappers)”- Was the status quo. Didn’t work.
Consequences
Section titled “Consequences”Positive
Section titled “Positive”- ✅ Three layout shapes cover 100% of real use cases (verified by porting all existing pages)
- ✅ AppBreadcrumb always mounted in the right slot — consistent navigation
- ✅ Rail-to-rail enforced —
StandardPage.Contentdoes the padding - ✅ Single place to update layout-level behavior (e.g. adding right rail for Sidekick)
- ✅ Easier code review — “which wrapper?” is the first question
Negative / trade-offs
Section titled “Negative / trade-offs”- ⚠️ Custom-shaped pages need to live within one of the three shells; very unusual layouts may need an additional wrapper later
- ⚠️
ControlPageis the only placemax-w-*is allowed on outer wrapper — slight rule inconsistency
- 🟡 New engineers building their own wrapper instead of using these — mitigation: code review + ESLint custom rule planned
Implementation plan
Section titled “Implementation plan”- Build the three wrappers — 2026-03-16
- Migrate existing pages — 2026-03-16 to 2026-04-01
- Deprecate
setZ3/Z4/Z5zones, document migration path — 2026-04 - Add rule to CLAUDE.md (#13) — 2026-04
- Plan written at
docs/plans/2026-03-16-page-layout-standard.md
Review
Section titled “Review”Next review: When we ship our 100th distinct page OR if a recurring layout need can’t be served by any of the three.
References
Section titled “References”- Page Layout Wrappers standard — implementation rules
- Design System — design context
- Standards — rule #13 in the canonical list
docs/plans/2026-03-16-page-layout-standard.mdin repo- CLAUDE.md rule #13