diff --git a/.planning/phases/11-individual-planning/11-UI-SPEC.md b/.planning/phases/11-individual-planning/11-UI-SPEC.md new file mode 100644 index 0000000..369dff8 --- /dev/null +++ b/.planning/phases/11-individual-planning/11-UI-SPEC.md @@ -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