Phases 28-31 archived to milestones/v2.2-phases/ Requirements and roadmap snapshots archived to milestones/ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
162 lines
4.8 KiB
Markdown
162 lines
4.8 KiB
Markdown
---
|
|
phase: 31
|
|
slug: mobile-polish
|
|
status: draft
|
|
shadcn_initialized: false
|
|
preset: none
|
|
created: 2026-04-12
|
|
---
|
|
|
|
# Phase 31 — UI Design Contract
|
|
|
|
> Visual and interaction contract for mobile icon-based action buttons. Generated by gsd-ui-researcher, verified by gsd-ui-checker.
|
|
|
|
---
|
|
|
|
## Design System
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| Tool | none |
|
|
| Preset | not applicable |
|
|
| Component library | none (plain Tailwind) |
|
|
| Icon library | lucide-react via LucideIcon component |
|
|
| Font | System default (Tailwind default stack) |
|
|
|
|
---
|
|
|
|
## Spacing Scale
|
|
|
|
Declared values (must be multiples of 4):
|
|
|
|
| Token | Value | Usage |
|
|
|-------|-------|-------|
|
|
| xs | 4px | Icon gaps, inline padding |
|
|
| sm | 8px | Compact element spacing, icon button padding |
|
|
| md | 16px | Default element spacing |
|
|
| lg | 24px | Section padding |
|
|
| xl | 32px | Layout gaps |
|
|
| 2xl | 48px | Major section breaks |
|
|
| 3xl | 64px | Page-level spacing |
|
|
|
|
Exceptions: Touch targets minimum 44x44px (11 Tailwind units) for icon-only buttons on mobile
|
|
|
|
---
|
|
|
|
## Typography
|
|
|
|
| Role | Size | Weight | Line Height |
|
|
|------|------|--------|-------------|
|
|
| Body | 14px (text-sm) | 400 | 1.5 |
|
|
| Label | 12px (text-xs) | 500 | 1.5 |
|
|
| Heading | 24px (text-2xl) | 700 (bold) | 1.2 |
|
|
| Display | 20px (text-xl) | 600 (semibold) | 1.2 |
|
|
|
|
Note: Icon-only buttons have no text labels on mobile. Tooltips (if added) use text-xs (12px).
|
|
|
|
---
|
|
|
|
## Color
|
|
|
|
| Role | Value | Usage |
|
|
|------|-------|-------|
|
|
| Dominant (60%) | white (#ffffff) | Background, surfaces |
|
|
| Secondary (30%) | gray-50 (#f9fafb) / gray-100 (#f3f4f6) | Cards, hover states, icon button hover bg |
|
|
| Accent (10%) | gray-700 (#374151) | Primary action icon buttons (Edit) |
|
|
| Destructive | red-500 (#ef4444) | Delete/Remove icon buttons only |
|
|
|
|
Accent reserved for: Edit button (primary action), icon button active/pressed states
|
|
|
|
### Icon Button Color Mapping
|
|
|
|
| Action | Icon Color | Hover BG | Notes |
|
|
|--------|-----------|----------|-------|
|
|
| Edit | gray-700 (white bg variant) | gray-100 | Primary action, most prominent |
|
|
| Duplicate | gray-500 | gray-50 | Secondary action |
|
|
| Delete/Remove | red-400 | red-50 | Destructive — matches existing pattern |
|
|
| Pick as Winner | amber-700 | amber-100 | Matches existing candidate resolve pattern |
|
|
| Add to Collection | white (on gray-700 bg) | gray-800 | Primary CTA on catalog detail |
|
|
| Add to Thread | gray-700 | gray-50 | Secondary CTA on catalog detail |
|
|
|
|
---
|
|
|
|
## Copywriting Contract
|
|
|
|
| Element | Copy |
|
|
|---------|------|
|
|
| Primary CTA | n/a (icon-only on mobile, text preserved on desktop) |
|
|
| Empty state heading | n/a (no new empty states in this phase) |
|
|
| Empty state body | n/a |
|
|
| Error state | n/a (no new error states in this phase) |
|
|
| Destructive confirmation | Existing ConfirmDialog patterns unchanged |
|
|
|
|
### Icon-to-Action Mapping (Mobile)
|
|
|
|
| Action | Lucide Icon Name | Size | aria-label |
|
|
|--------|-----------------|------|------------|
|
|
| Edit | `pencil` | 16px | "Edit" |
|
|
| Delete | `trash-2` | 16px | "Delete" |
|
|
| Remove from Collection | `trash-2` | 16px | "Remove from Collection" |
|
|
| Duplicate | `copy` | 16px | "Duplicate" |
|
|
| Pick as Winner | `trophy` | 14px | "Pick as winner" |
|
|
| Add to Collection | `plus` | 16px | "Add to Collection" |
|
|
| Add to Thread | `message-square-plus` | 16px | "Add to Thread" |
|
|
| Add Items (setup) | `plus` | 16px | "Add Items" |
|
|
| Toggle Public | `globe` | 16px | "Toggle public" |
|
|
| Delete Setup | `trash-2` | 16px | "Delete Setup" |
|
|
|
|
### Accessibility
|
|
|
|
- Every icon-only button MUST have `aria-label` matching the action text shown on desktop
|
|
- Icon buttons use `title` attribute matching `aria-label` for hover tooltip on touch-and-hold
|
|
- Minimum touch target: 44x44px (achieved via `min-w-[44px] min-h-[44px]` or equivalent padding)
|
|
|
|
---
|
|
|
|
## Responsive Breakpoint Contract
|
|
|
|
| Breakpoint | Behavior |
|
|
|------------|----------|
|
|
| Below `md:` (< 768px) | Icon-only buttons, no text labels |
|
|
| `md:` and above (>= 768px) | Full text buttons (current behavior, unchanged) |
|
|
|
|
Implementation pattern:
|
|
```tsx
|
|
{/* Desktop: text button */}
|
|
<button className="hidden md:inline-flex items-center gap-1.5 px-3 py-1.5 text-sm ...">
|
|
<LucideIcon name="pencil" size={14} />
|
|
Edit
|
|
</button>
|
|
{/* Mobile: icon-only button */}
|
|
<button
|
|
className="md:hidden inline-flex items-center justify-center min-w-[44px] min-h-[44px] p-2 rounded-lg ..."
|
|
aria-label="Edit"
|
|
title="Edit"
|
|
>
|
|
<LucideIcon name="pencil" size={16} />
|
|
</button>
|
|
```
|
|
|
|
---
|
|
|
|
## Registry Safety
|
|
|
|
| Registry | Blocks Used | Safety Gate |
|
|
|----------|-------------|-------------|
|
|
| n/a | none | not required |
|
|
|
|
No shadcn or third-party registries. All components are hand-rolled with Tailwind CSS.
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
**Approval:** pending
|