---
phase: "{N}"
slug: "{phase-slug}"
status: draft
shadcn_initialized: false
preset: none
created: "{date}"
---

# Phase {N} — UI Design Contract

> Visual and interaction contract for frontend phases. Generated by gsd-ui-researcher, verified by gsd-ui-checker.

---

## Design System

| Property | Value |
|----------|-------|
| Tool | {shadcn / none} |
| Preset | {preset string or "not applicable"} |
| Component library | {radix / base-ui / none} |
| Icon library | {library} |
| Font | {font} |

---

## Component Inventory

> What the project's design system actually provides. **Enumerate this from the installed
> package — never from recall.** Delete whichever provenance line below does not apply.

Enumerated by `<command>` — <N> components — <package>@<version> — <YYYY-MM-DD>.
Could not enumerate: <reason>.

Without a provenance line this table is a **non-exhaustive** list of known-good components and
never a closed allowlist — the executor may use anything the design system exports, and
`gsd-ui-checker` Dimension 7 reports the missing line as a defect. Checking for a component
outside the table is the expected path, not an exception.

| Component | Import path | Notes |
|-----------|-------------|-------|
| {name} | {import path} | {when to reach for it} |

Omit this section entirely when the project has no design system (`Tool: none`).

---

## Spacing Scale

Declared values (must be multiples of 4):

| Token | Value | Usage |
|-------|-------|-------|
| xs | 4px | Icon gaps, inline padding |
| sm | 8px | Compact element spacing |
| md | 16px | Default element spacing |
| lg | 24px | Section padding |
| xl | 32px | Layout gaps |
| 2xl | 48px | Major section breaks |
| 3xl | 64px | Page-level spacing |

Exceptions: {list any, or "none"}

---

## Typography

| Role | Size | Weight | Line Height |
|------|------|--------|-------------|
| Body | {px} | {weight} | {ratio} |
| Label | {px} | {weight} | {ratio} |
| Heading | {px} | {weight} | {ratio} |
| Display | {px} | {weight} | {ratio} |

---

## Color

| Role | Value | Usage |
|------|-------|-------|
| Dominant (60%) | {hex} | Background, surfaces |
| Secondary (30%) | {hex} | Cards, sidebar, nav |
| Accent (10%) | {hex} | {list specific elements only} |
| Destructive | {hex} | Destructive actions only |

Accent reserved for: {explicit list — never "all interactive elements"}

---

## Copywriting Contract

| Element | Copy |
|---------|------|
| Primary CTA | {specific verb + noun} |
| Empty state heading | {copy} |
| Empty state body | {copy + next step} |
| Error state | {problem + solution path} |
| Destructive confirmation | {action name}: {confirmation copy} |

---

## UI Considerations

> Populated by the ui-phase UI-consideration probe (Step 9.5) and lifted by plan-phase's
> `## UI Considerations` lift rule via the identical rule as SPEC `## Edge Coverage`. Shape-rooted UI *state*
> coverage (empty / loading / error / populated / partial / overflow / zero-one-many / long-text).
> Empty-state and error-state COPY live in `## Copywriting Contract` above — this section covers
> state coverage and REFERENCES those rows rather than restating the copy (de-dup).

Applicable state considerations resolved: {N covered, M backstop, K unresolved — or "none applicable"}

| Category | Element(s) | Status | Resolution / Reason |
|----------|------------|--------|---------------------|
| {empty} | {list-collection} | ✅ covered | {concrete truth string — e.g. "Empty results render the documented 'No results' copy"} |
| {long-text} | {static-content} | 🧪 backstop | {held-out/visual UI-state test — lifts as `{ statement, verification: backstop }`} |
| {overflow} | {list-collection} | ⚠ unresolved | {planner treats as assumption} |

<!-- Status vocabulary (locked by probe-core projectTruths):
     ✅ covered   → a plain truth string lifted into must_haves.truths
     🧪 backstop  → a flat scalar { statement, verification: backstop }; at verify time, no explicit
                    evidence → insufficient_spec → human_needed (never a silent pass, #1154)
     ⚠ unresolved → an explicit planner assumption (surfaced, never silently dropped)
     Rows are REPLACED (not appended) on a probe re-run — idempotent. -->

---

## Registry Safety

| Registry | Blocks Used | Safety Gate |
|----------|-------------|-------------|
| shadcn official | {list} | not required |
| {third-party name} | {list} | shadcn view + diff required |

---

## Checker Sign-Off

- [ ] Dimension 1 Copywriting: PASS
- [ ] Dimension 2 Visuals: PASS
- [ ] Dimension 3 Color: PASS
- [ ] Dimension 4 Typography: PASS
- [ ] Dimension 5 Spacing: PASS
- [ ] Dimension 6 Registry Safety: PASS
- [ ] Dimension 7 Inventory Provenance: PASS

**Approval:** {pending / approved YYYY-MM-DD}
