--- 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 */} {/* Mobile: icon-only 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