Files
GearBox/.planning/milestones/v2.2-phases/31-mobile-polish/31-UI-SPEC.md
Jean-Luc Makiola 2853477a75
All checks were successful
CI / ci (push) Successful in 1m15s
CI / e2e (push) Has been skipped
CI / deploy (push) Has been skipped
chore: archive v2.2 User Experience Polish milestone
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>
2026-04-13 16:00:35 +02:00

4.8 KiB

phase, slug, status, shadcn_initialized, preset, created
phase slug status shadcn_initialized preset created
31 mobile-polish draft false none 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:

{/* 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