docs(11): UI design contract
This commit is contained in:
parent
01f2a073a2
commit
3c5622b101
1 changed files with 251 additions and 0 deletions
251
.planning/phases/11-individual-planning/11-UI-SPEC.md
Normal file
251
.planning/phases/11-individual-planning/11-UI-SPEC.md
Normal file
|
|
@ -0,0 +1,251 @@
|
||||||
|
---
|
||||||
|
phase: 11
|
||||||
|
slug: individual-planning
|
||||||
|
status: approved
|
||||||
|
shadcn_initialized: false
|
||||||
|
preset: none
|
||||||
|
created: 2026-05-16
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 11 - UI Design Contract
|
||||||
|
|
||||||
|
> Visual and interaction contract for the first individual planning page. This phase must produce a functional, restrained agenda view, not a polished calendar product.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design System
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Tool | none |
|
||||||
|
| Preset | not applicable |
|
||||||
|
| Component library | local Go templ components in `backend/internal/web/ui` |
|
||||||
|
| Icon library | none required for this phase |
|
||||||
|
| Font | inherited system sans-serif from existing `Layout` |
|
||||||
|
|
||||||
|
Use the existing `Layout` container, `ui.Button`, link, form, border, and slate color conventions. Do not introduce shadcn, Radix, lucide, custom SVG icons, or a client-side framework.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Surface Contract
|
||||||
|
|
||||||
|
### Page Role
|
||||||
|
|
||||||
|
- Route: `/planning`.
|
||||||
|
- Protected page rendered inside the normal authenticated `Layout`.
|
||||||
|
- Page title: `Planning`.
|
||||||
|
- Supporting date-range label: a concise range such as `May 16 - May 29, 2026`.
|
||||||
|
- The page is an agenda, not a month/week/day calendar.
|
||||||
|
- Do not add a hero, marketing copy, decorative illustration, nested card layout, or explanatory feature text.
|
||||||
|
|
||||||
|
### Primary Regions
|
||||||
|
|
||||||
|
1. **Header row**
|
||||||
|
- Left: `Planning` heading and the current 14-day range label.
|
||||||
|
- Right: navigation controls.
|
||||||
|
- Must wrap cleanly on mobile with controls below the heading if needed.
|
||||||
|
|
||||||
|
2. **Navigation toolbar**
|
||||||
|
- Controls: `Previous 14 days`, `Today`, `Next 14 days`.
|
||||||
|
- Use `ui-button-soft-neutral-md` for previous/next.
|
||||||
|
- Use `ui-button-solid-default-md` for `Today` only when not already showing the current range; otherwise neutral is acceptable.
|
||||||
|
- Links should work as normal anchors and may also use HTMX if the implementation chooses a fragment refresh.
|
||||||
|
|
||||||
|
3. **Agenda list**
|
||||||
|
- A single continuous chronological list.
|
||||||
|
- No grouping headings by day and no grouping by tablo.
|
||||||
|
- Rows must be dense but readable, optimized for scanning repeated daily use.
|
||||||
|
|
||||||
|
4. **Empty state**
|
||||||
|
- Centered or left-aligned within the list area, not a large marketing panel.
|
||||||
|
- Must leave the navigation toolbar visible so users can move to a different 14-day window.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spacing Scale
|
||||||
|
|
||||||
|
Declared values (must be multiples of 4):
|
||||||
|
|
||||||
|
| Token | Value | Usage |
|
||||||
|
|-------|-------|-------|
|
||||||
|
| xs | 4px | Dot-to-label gaps, compact metadata gaps |
|
||||||
|
| sm | 8px | Row inner gaps, toolbar button gaps |
|
||||||
|
| md | 16px | Default section spacing and row padding |
|
||||||
|
| lg | 24px | Header-to-list spacing |
|
||||||
|
| xl | 32px | Page section gap when needed |
|
||||||
|
| 2xl | 48px | Empty-state vertical padding |
|
||||||
|
| 3xl | 64px | Not used in Phase 11 |
|
||||||
|
|
||||||
|
Exceptions: none.
|
||||||
|
|
||||||
|
### Layout Rules
|
||||||
|
|
||||||
|
- Page content uses the existing `max-w-5xl` layout from `Layout`.
|
||||||
|
- Use `space-y-6` or equivalent 24px gaps between header/toolbar/list sections.
|
||||||
|
- Agenda rows use 12-16px vertical padding and 12-16px horizontal padding.
|
||||||
|
- Row borders use a single bottom border or standalone row borders. Do not put row cards inside a larger card.
|
||||||
|
- Mobile rows may stack metadata under the title, but text must not overlap or force horizontal scrolling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typography
|
||||||
|
|
||||||
|
| Role | Size | Weight | Line Height |
|
||||||
|
|------|------|--------|-------------|
|
||||||
|
| Body | 16px | 400 | 1.5 |
|
||||||
|
| Label | 14px | 500 | 1.4 |
|
||||||
|
| Metadata | 14px | 400 | 1.4 |
|
||||||
|
| Heading | 28px | 600 | 1.2 |
|
||||||
|
| Row title | 16px | 600 | 1.35 |
|
||||||
|
|
||||||
|
### Typography Rules
|
||||||
|
|
||||||
|
- Use the existing dashboard heading treatment for `Planning`: `text-[28px] font-semibold leading-tight`.
|
||||||
|
- Date range label uses `text-sm text-slate-600`.
|
||||||
|
- Row title uses `text-base font-semibold text-slate-900`.
|
||||||
|
- Time uses `text-sm font-medium text-slate-700`.
|
||||||
|
- Tablo and location metadata use `text-sm text-slate-600`.
|
||||||
|
- Do not use viewport-scaled font sizes, negative letter spacing, or display-scale type inside agenda rows.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Color
|
||||||
|
|
||||||
|
| Role | Value | Usage |
|
||||||
|
|------|-------|-------|
|
||||||
|
| Dominant (60%) | `#ffffff` | Page background and agenda row surfaces |
|
||||||
|
| Secondary (30%) | `#f8fafc` / `#f1f5f9` | Header strip, empty state, hover/soft surfaces |
|
||||||
|
| Accent (10%) | `#2563eb` | `Today` action when active, focus rings, primary link affordance |
|
||||||
|
| Text primary | `#0f172a` | Main heading and event titles |
|
||||||
|
| Text secondary | `#475569` / `#64748b` | Range labels and metadata |
|
||||||
|
| Border | `#e2e8f0` | Row dividers, toolbar, empty state boundary |
|
||||||
|
| Destructive | `#b91c1c` | Not used in Phase 11 |
|
||||||
|
|
||||||
|
Accent reserved for:
|
||||||
|
- `Today` button when it is the primary navigation action.
|
||||||
|
- Focus rings inherited from `ui.Button`.
|
||||||
|
- Event deep-link hover/focus treatment if needed.
|
||||||
|
|
||||||
|
### Tablo Color Dot
|
||||||
|
|
||||||
|
- Render a small dot beside the tablo title when `tablo_color` is present.
|
||||||
|
- Dot size: 8px or 10px.
|
||||||
|
- Dot is decorative; the tablo title text must remain visible even without color.
|
||||||
|
- If `tablo_color` is absent or invalid, omit the dot or use `#cbd5e1`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Agenda Row Contract
|
||||||
|
|
||||||
|
Each event row must show:
|
||||||
|
|
||||||
|
1. Event time
|
||||||
|
- With end time: `09:30-10:30` or a similarly compact range.
|
||||||
|
- Without end time: `09:30` only.
|
||||||
|
- Do not show `no end`, `open`, or inferred duration copy.
|
||||||
|
|
||||||
|
2. Event title
|
||||||
|
- Escaped server-rendered text.
|
||||||
|
- One line on desktop where possible; wraps safely on mobile.
|
||||||
|
|
||||||
|
3. Tablo context
|
||||||
|
- Small color dot when present.
|
||||||
|
- Tablo title text.
|
||||||
|
|
||||||
|
4. Location
|
||||||
|
- Show only when the event has a non-empty location.
|
||||||
|
- Location is metadata, not a primary title.
|
||||||
|
|
||||||
|
Do not show in Phase 11 rows:
|
||||||
|
|
||||||
|
- Description snippets.
|
||||||
|
- Create/edit forms.
|
||||||
|
- Delete controls.
|
||||||
|
- Calendar day cells.
|
||||||
|
- Imports, exports, external sync, or recurrence UI.
|
||||||
|
|
||||||
|
### Row Interaction
|
||||||
|
|
||||||
|
- The event row or event title links to the tablo Events tab for that event's month.
|
||||||
|
- Link shape should follow Phase 10 handoff: `/tablos/{id}/events?month=YYYY-MM`.
|
||||||
|
- If the implementation can safely open the event edit form while preserving this context, that is optional planner discretion. The required behavior is returning to the tablo context.
|
||||||
|
- Row link must have an accessible label such as `Open event in tablo: {event title}`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Navigation Contract
|
||||||
|
|
||||||
|
The first version uses fixed 14-day windows.
|
||||||
|
|
||||||
|
### Default
|
||||||
|
|
||||||
|
- `/planning` shows today through 13 days after today.
|
||||||
|
- Date calculations use the same local-date assumptions as Phase 10.
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
- Planner may choose exact query parameter names, but the URL must be shareable and reloadable.
|
||||||
|
- Recommended shape: `/planning?start=YYYY-MM-DD`.
|
||||||
|
- Previous window decrements the start date by 14 days.
|
||||||
|
- Next window increments the start date by 14 days.
|
||||||
|
- `Today` returns to `/planning` or sets `start` to today's date.
|
||||||
|
|
||||||
|
### Copy
|
||||||
|
|
||||||
|
| Element | Copy |
|
||||||
|
|---------|------|
|
||||||
|
| Page title | `Planning` |
|
||||||
|
| Previous control | `Previous 14 days` |
|
||||||
|
| Today control | `Today` |
|
||||||
|
| Next control | `Next 14 days` |
|
||||||
|
| Empty state heading | `No events in this range` |
|
||||||
|
| Empty state body | `Use the navigation controls to browse another 14-day window.` |
|
||||||
|
| Error state | `Planning could not be loaded. Please try again.` |
|
||||||
|
| Destructive confirmation | none |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Responsive Behavior
|
||||||
|
|
||||||
|
- Desktop: time, title, tablo metadata, and location may sit in one row using flex/grid.
|
||||||
|
- Mobile: row content may stack in two lines:
|
||||||
|
- Line 1: time and title.
|
||||||
|
- Line 2: tablo title/color and location.
|
||||||
|
- Header controls wrap below the heading on narrow screens.
|
||||||
|
- No fixed-width agenda content that causes horizontal scrolling.
|
||||||
|
- Long event titles and tablo titles must wrap or truncate safely without overlapping controls.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Accessibility Contract
|
||||||
|
|
||||||
|
- `/planning` has a single `h1` with copy `Planning`.
|
||||||
|
- Navigation controls are links or buttons with accessible text matching visible copy.
|
||||||
|
- The agenda list should use semantic list markup where practical (`ul`/`li`) or equivalent landmark structure.
|
||||||
|
- Event links must be keyboard reachable and visibly focused.
|
||||||
|
- Color dot is not the only identifier for a tablo; always show the tablo title.
|
||||||
|
- Empty state must be text, not only visual whitespace.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Registry Safety
|
||||||
|
|
||||||
|
| Registry | Blocks Used | Safety Gate |
|
||||||
|
|----------|-------------|-------------|
|
||||||
|
| shadcn official | none | not required |
|
||||||
|
| third-party registry | none | prohibited for this phase |
|
||||||
|
|
||||||
|
No registry components or copied UI blocks are allowed in Phase 11.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checker Sign-Off
|
||||||
|
|
||||||
|
- [x] Dimension 1 Copywriting: PASS
|
||||||
|
- [x] Dimension 2 Visuals: PASS
|
||||||
|
- [x] Dimension 3 Color: PASS
|
||||||
|
- [x] Dimension 4 Typography: PASS
|
||||||
|
- [x] Dimension 5 Spacing: PASS
|
||||||
|
- [x] Dimension 6 Registry Safety: PASS
|
||||||
|
|
||||||
|
**Approval:** approved 2026-05-16
|
||||||
Loading…
Reference in a new issue