UX Specification Skill
Generate comprehensive UI/UX specifications with wireframes and design system for iOS/macOS apps.
Metadata
- Name: ux-spec
- Version: 1.0.0
- Role: UI/UX Designer
- Author: ProductAgent Team
Activation
This skill activates when the user says:
- "generate UI spec"
- "create UX specification"
- "design wireframes"
- "create design system"
- "generate UX spec from PRD"
Description
You are a UI/UX Designer AI agent specializing in iOS/macOS app design. Your job is to transform product requirements and architecture into comprehensive, actionable UI/UX specifications that developers can implement directly.
Prerequisites
Before activating this skill, ensure:
- PRD exists (from prd-generator skill)
- ARCHITECTURE.md exists (from architecture-spec skill)
- Product development plan with positioning and brand personality
Input Sources
Read and extract information from:
-
docs/PRD.md
- All features and requirements
- User flows and user stories
- Target audience
- Acceptance criteria
-
docs/ARCHITECTURE.md
- App structure and navigation
- Data models (to understand what to display)
- Platform (iOS/macOS)
-
Product development plan (product-plan-*.md)
- Positioning and brand personality
- Value proposition
- Target market
-
User clarifications (ask if needed):
- Preferred design style (minimalist, colorful, professional, playful)
- Any brand colors or existing branding
- Key screens to prioritize
Output
Generate two comprehensive documents:
1. docs/UX_SPEC.md
# UI/UX Specification: [App Name]
**Version**: 1.0.0
**Last Updated**: [Date]
**Status**: Draft / In Review / Approved
**Designer**: UX Designer AI
**Platform**: iOS / macOS
---
## 1. Design Principles
### 1.1 Core Principles
1. **[Principle 1]**: [e.g., "Simplicity over features - Every screen should have one primary action"]
2. **[Principle 2]**: [e.g., "Glanceable information - Users should understand content in < 5 seconds"]
3. **[Principle 3]**: [e.g., "Gesture-first interaction - Leverage native iOS gestures"]
4. **[Principle 4]**: [e.g., "Progressive disclosure - Show advanced features only when needed"]
### 1.2 Brand Personality
**From Positioning**: [e.g., "Professional, trustworthy, modern with a human touch"]
**Design Expression**:
- Visual style: [Clean, minimal, lots of whitespace]
- Tone: [Friendly but professional]
- Imagery: [Photography-based vs. illustration-based]
---
## 2. Information Architecture
### 2.1 App Structure
**Navigation Pattern**: [TabView / NavigationStack / Sidebar (iPad)]
**Screen Hierarchy**:
App Root ├── Tab 1: [Home] │ ├── [Home Screen] │ ├── [Item Detail Screen] │ └── [Edit Item Screen] ├── Tab 2: [Discover] │ ├── [Discover Screen] │ └── [Category Detail Screen] ├── Tab 3: [Profile] │ ├── [Profile Screen] │ └── [Settings Screen] └── Shared ├── [Login Screen] ├── [Onboarding Flow] └── [Error/Empty States]
### 2.2 Screen Inventory
| Screen Name | Purpose | Navigation | Priority |
|-------------|---------|------------|----------|
| Onboarding | First-time user education | Modal → Home | P0 |
| Home | Primary content view | Root tab | P0 |
| Item Detail | View single item details | Push from Home | P0 |
| Add/Edit Item | Create or modify item | Modal/Push | P0 |
| Profile | User profile and settings | Root tab | P1 |
| Settings | App preferences | Push from Profile | P1 |
### 2.3 Navigation Flow Diagram
[Splash] → [Onboarding] → [Home (Tab 1)] ↓ [Item Detail] ↓ [Edit Item]
[Profile (Tab 3)] → [Settings] → [Account]
---
## 3. Screen Specifications
### 3.1 Onboarding Flow
**Purpose**: Help new users understand value and complete initial setup
**Screens**: 3 screens + Welcome
#### Screen 1: Welcome
**Layout** (ASCII wireframe):
┌─────────────────────────────────────┐ │ │ │ │ │ [App Icon/Logo] │ │ │ │ │ │ Welcome to [AppName] │ │ │ │ [One-line value proposition] │ │ │ │ │ │ │ │ [Get Started Button] │ │ │ │ Already have an account? │ │ [Sign In] │ │ │ └─────────────────────────────────────┘
**Components**:
- **App Icon/Logo**: Centered, large (120pt)
- **Welcome Title**: .largeTitle, bold, centered
- **Value Proposition**: .title3, secondary color, centered, max 2 lines
- **Get Started Button**: Primary button style, full width with margin
- **Sign In Link**: Text button, smaller, muted color
**Interactions**:
- Tap "Get Started" → Navigate to Onboarding Screen 1
- Tap "Sign In" → Navigate to Login Screen
- Swipe not enabled (no skip on welcome)
**States**:
- Default: All elements visible
- Loading: Show activity indicator if checking auth state
**Animations**:
- Fade in on appear (0.5s)
- Button press: Scale 0.95 with haptic feedback
---
#### Screen 2: Onboarding Step 1
**Purpose**: Explain primary feature/benefit
**Layout**:
┌─────────────────────────────────────┐ │ ○ ● ○ [Skip] │ (Progress + Skip) ├─────────────────────────────────────┤ │ │ │ │ │ [Feature Illustration] │ │ or Screenshot │ │ │ │ │ ├─────────────────────────────────────┤ │ │ │ [Headline - Feature Name] │ │ │ │ [Description - 2-3 lines │ │ explaining the benefit] │ │ │ ├─────────────────────────────────────┤ │ │ │ [Next Button] │ │ │ └─────────────────────────────────────┘
**Components**:
- **Progress Indicator**: 3 dots, current = filled circle
- **Skip Button**: Text button, top-right
- **Illustration**: Hero image or screenshot, 300pt height
- **Headline**: .title2, bold, benefit-focused
- **Description**: .body, 2-3 lines, explain value not feature
- **Next Button**: Primary button, full width
**Interactions**:
- Tap "Next" → Navigate to Onboarding Step 2
- Tap "Skip" → Navigate to Home (mark onboarding complete)
- Swipe left → Next screen
- Swipe right → Previous screen
**Content Guidelines**:
- Focus on BENEFITS not features
- Use "you" language ("You can organize all your tasks")
- Keep concise (< 20 words per description)
---
#### Screen 3: Onboarding Step 2 & 3
[Repeat structure for remaining onboarding screens]
---
### 3.2 Home Screen
**Purpose**: Display primary content and enable main user actions
**Layout** (iPhone Portrait):
┌─────────────────────────────────────┐ │ ← Home [+] [⚙️] │ (Navigation Bar) ├─────────────────────────────────────┤ │ │ │ Search... [🔍] │ (Search Bar) │ │ ├─────────────────────────────────────┤ │ │ │ ┌───────────────────────────────┐ │ │ │ [Thumbnail] Card Title │ │ (Card Component) │ │ Subtitle • Meta │ │ │ │ [Status Badge] │ │ │ └───────────────────────────────┘ │ │ │ │ ┌───────────────────────────────┐ │ │ │ [Thumbnail] Card Title │ │ │ │ Subtitle • Meta │ │ │ │ [Status Badge] │ │ │ └───────────────────────────────┘ │ │ │ │ ┌───────────────────────────────┐ │ │ │ [Thumbnail] Card Title │ │ │ │ Subtitle • Meta │ │ │ │ [Status Badge] │ │ │ └───────────────────────────────┘ │ │ │ ├─────────────────────────────────────┤ │ [Tab1] [Tab2] [Tab3] [Tab4] │ (Tab Bar) └─────────────────────────────────────┘
**Components**:
**Navigation Bar**:
- Title: "Home" (.largeTitle when scrolled to top, .inline when scrolling)
- Leading: Back button (if navigated from elsewhere)
- Trailing:
- [+] Add button → Navigate to Add Item
- [⚙️] Settings button → Navigate to Settings
**Search Bar** (Optional, based on requirements):
- Placeholder: "Search [items]..."
- Style: .searchable modifier
- Clear button when text entered
- Dismiss on scroll down
**Card List**:
- Container: SwiftUI List with .plain style
- Card spacing: 12pt between cards
- Card style: See "Card Component" section below
**Tab Bar** (if using tabs):
- 3-5 tabs maximum
- Active tab: Primary color
- Inactive tabs: Secondary/gray color
- Badge: Red dot for notifications (if applicable)
**Interactions**:
- **Tap card** → Navigate to Item Detail Screen
- **Swipe left on card** → Show Delete action (red background, trash icon)
- **Swipe right on card** → Show Archive action (if applicable)
- **Pull down** → Refresh content (show activity indicator)
- **Tap [+]** → Present Add Item sheet
- **Tap [⚙️]** → Navigate to Settings
- **Search** → Filter list in real-time as user types
- **Scroll to top** → Navigation bar title animates to large title
**States**:
**Empty State**:
┌─────────────────────────────────────┐ │ │ │ │ │ [Empty Icon] │ │ (tray) │ │ │ │ No Items Yet │ │ │ │ Get started by tapping the │ │ + button above │ │ │ │ │ └─────────────────────────────────────┘
- Use ContentUnavailableView (iOS 17+)
- Icon: SF Symbol related to content type
- Title: Friendly, not error-focused
- Description: Clear call to action
**Loading State**:
┌─────────────────────────────────────┐ │ │ │ │ │ [Loading Spinner] │ │ Loading... │ │ │ │ │ └─────────────────────────────────────┘
- Full-screen overlay with .ultraThinMaterial background
- Activity indicator (.large size)
- Optional "Loading..." text below
**Error State**:
┌─────────────────────────────────────┐ │ │ │ │ │ [Error Icon] (exclamationmark) │ │ │ │ Couldn't load items │ │ │ │ [Error description message] │ │ │ │ [Try Again Button] │ │ │ └─────────────────────────────────────┘
- ContentUnavailableView with error styling
- Clear error message (user-friendly, not technical)
- Retry button to attempt reload
**Skeleton/Shimmer State** (Alternative to loading spinner):
┌─────────────────────────────────────┐ │ ┌───────────────────────────────┐ │ │ │ [▓▓▓] ▓▓▓▓▓▓▓▓▓▓ │ │ (Shimmer effect) │ │ ▓▓▓▓▓▓▓ • ▓▓▓ │ │ │ └───────────────────────────────┘ │ │ ┌───────────────────────────────┐ │ │ │ [▓▓▓] ▓▓▓▓▓▓▓▓▓▓ │ │ │ │ ▓▓▓▓▓▓▓ • ▓▓▓ │ │ │ └───────────────────────────────┘ │ └─────────────────────────────────────┘
- Show 3-5 placeholder cards
- Animated shimmer effect (subtle, not distracting)
- Replace with real content when loaded
**Data Requirements**:
- Array of items: [Item]
- Each item needs: id, title, subtitle, thumbnailURL, status, metadata
- Sorting: By date (newest first) or user preference
- Filtering: Based on search query
**Accessibility**:
- VoiceOver label for each card: "[Title], [Subtitle], [Status]"
- Add button: "Add new item"
- Settings button: "Settings"
- Swipe actions announced: "Swipe right or left for actions"
- Search bar: "Search [items]"
---
### 3.3 Item Detail Screen
**Purpose**: Display full details of a single item
**Layout**:
┌─────────────────────────────────────┐ │ ← [Item Title] [Edit] │ (Navigation Bar) ├─────────────────────────────────────┤ │ │ │ [Hero Image/Thumbnail] │ │ (Full width) │ │ │ ├─────────────────────────────────────┤ │ │ │ [Item Title] │ │ [Subtitle or Category] │ │ │ │ [Status Badge] [Metadata] │ │ │ ├─────────────────────────────────────┤ │ │ │ Description │ │ ───────────── │ │ [Full description text, can be │ │ multiple paragraphs. Lorem ipsum │ │ dolor sit amet...] │ │ │ ├─────────────────────────────────────┤ │ │ │ Details │ │ ──────── │ │ Created: [Date] │ │ Modified: [Date] │ │ Author: [Name] │ │ │ ├─────────────────────────────────────┤ │ │ │ Related Items │ │ ────────────── │ │ ┌─────────┐ ┌─────────┐ │ │ │ [Item1] │ │ [Item2] │ │ │ └─────────┘ └─────────┘ │ │ │ ├─────────────────────────────────────┤ │ │ │ [Primary Action] │ │ [Secondary Action] │ │ │ └─────────────────────────────────────┘
**Components**:
- **Navigation Bar**: Item title (truncate if > 25 chars), Edit button
- **Hero Image**: Full-width, 16:9 aspect ratio, 250pt height
- **Title Section**: .title2 bold, subtitle .subheadline
- **Status Badge**: Rounded rectangle, color-coded by status
- **Description**: .body text, full paragraph formatting
- **Details Section**: Key-value pairs, .callout size, secondary color
- **Related Items**: Horizontal scroll, 100pt width cards
- **Action Buttons**: Primary (full width), Secondary (outlined)
**Interactions**:
- Tap "Edit" → Navigate to Edit Screen
- Tap Hero Image → Open full-screen image viewer (pinch to zoom)
- Tap Related Item → Navigate to that item's detail screen
- Swipe back → Return to Home
- Scroll → Navigation bar collapses to inline title
**States**:
- **Loading**: Show skeleton for all sections while data loads
- **Error**: Show error message inline (not full-screen)
- **No Image**: Show placeholder icon/gradient
- **No Description**: Hide section entirely (don't show empty)
- **No Related Items**: Hide section
---
### 3.4 Add/Edit Item Screen
**Purpose**: Create new item or modify existing
**Layout** (Sheet/Modal):
┌─────────────────────────────────────┐ │ [Cancel] Add Item [Save] │ (Modal Header) ├─────────────────────────────────────┤ │ │ │ ┌───────────────────────────────┐ │ │ │ + Add Photo │ │ (Image Picker) │ └───────────────────────────────┘ │ │ │ │ Title │ │ ┌───────────────────────────────┐ │ │ │ [Enter title...] │ │ │ └───────────────────────────────┘ │ │ │ │ Category │ │ ┌───────────────────────────────┐ │ │ │ [Select category] [▼] │ │ │ └───────────────────────────────┘ │ │ │ │ Description │ │ ┌───────────────────────────────┐ │ │ │ [Enter description...] │ │ │ │ │ │ │ │ │ │ │ └───────────────────────────────┘ │ │ │ │ Status │ │ ○ Active ○ Pending ○ Done │ │ │ │ │ │ [Delete Item] │ (Edit only) │ │ └─────────────────────────────────────┘
**Components**:
- **Modal Header**: Cancel (leading), Title (center), Save (trailing, blue)
- **Image Picker**: Dashed border, + icon, tap to open photo picker
- **Text Fields**: Native iOS style, floating labels
- **Dropdown**: Chevron indicator, opens picker/sheet
- **Text Area**: Multiline, min 3 lines
- **Radio Group**: Horizontal segmented control or vertical radio buttons
- **Delete Button**: Destructive style, bottom of form (edit mode only)
**Interactions**:
- Tap "Cancel" → Dismiss sheet, confirm if unsaved changes
- Tap "Save" → Validate, save, dismiss, return to previous screen
- Tap Image Picker → Present photo picker (Camera + Photo Library)
- Tap Dropdown → Present selection sheet/picker
- Typing → Show character count if there's a limit
- Tap Delete → Show destructive alert confirmation
**Validation**:
- Required fields: Show red outline + error message on save attempt
- Character limits: Show count (e.g., "120/150 characters")
- Invalid format: Show inline error below field
**States**:
- **Add Mode**: Empty fields, no Delete button
- **Edit Mode**: Pre-filled fields, Delete button visible
- **Saving**: Disable Save button, show spinner
- **Error**: Show alert with error message, keep form open
---
### 3.5 Settings Screen
**Purpose**: App preferences and account management
**Layout**:
┌─────────────────────────────────────┐ │ ← Settings │ ├─────────────────────────────────────┤ │ │ │ Account │ │ ┌───────────────────────────────┐ │ │ │ [👤] [User Name] [>] │ │ │ │ user@email.com │ │ │ └───────────────────────────────┘ │ │ │ │ Preferences │ │ ┌───────────────────────────────┐ │ │ │ Notifications [○●] │ │ (Toggle) │ │ Dark Mode [○●] │ │ │ │ Language [>] │ │ │ └───────────────────────────────┘ │ │ │ │ Data & Privacy │ │ ┌───────────────────────────────┐ │ │ │ Privacy Policy [>] │ │ │ │ Terms of Service [>] │ │ │ │ Delete Account [>] │ │ │ └───────────────────────────────┘ │ │ │ │ About │ │ ┌───────────────────────────────┐ │ │ │ App Version 1.0.0 │ │ │ │ Rate Us [>] │ │ │ │ Contact Support [>] │ │ │ └───────────────────────────────┘ │ │ │ │ │ │ [Sign Out] │ │ │ └─────────────────────────────────────┘
**Components**:
- **Section Headers**: .caption uppercase, secondary color, 24pt top padding
- **Grouped List**: iOS native .insetGrouped style
- **Row**: 44pt min height, tap area full width
- **Toggle**: iOS native switch, tappable label + switch
- **Disclosure**: Chevron on trailing edge
- **Sign Out Button**: Destructive style, centered, bottom
**Interactions**:
- Tap row with [>] → Navigate to detail screen
- Tap toggle → Immediate change (save to UserDefaults/CloudKit)
- Tap "Sign Out" → Show confirmation alert
---
## 4. Component Library
### 4.1 Buttons
#### Primary Button
**Style**:
- Background: Brand Primary color
- Text: White, .headline font
- Corner radius: 12pt
- Height: 50pt
- Padding: 16pt horizontal
- Shadow: radius 4, y: 2, opacity 0.1
**States**:
- Normal: Full color
- Pressed: Opacity 0.8 + scale 0.98
- Disabled: Opacity 0.5, no interaction
- Loading: Show spinner, disable interaction
**Code Example**:
```swift
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.frame(height: 50)
.background(Color.brandPrimary)
.cornerRadius(12)
.shadow(radius: 4, y: 2)
Secondary Button
Style:
- Background: Clear
- Border: 2pt, Brand Primary color
- Text: Brand Primary color, .headline
- Corner radius: 12pt
- Height: 50pt
States: Same as Primary Button
Text Button
Style:
- Background: None
- Text: Brand Primary color, .body or .callout
- No border
- Height: Auto (text height + padding)
States:
- Normal: Primary color
- Pressed: Opacity 0.6
- Disabled: Secondary color, no interaction
4.2 Cards
Standard Card
Style:
- Background: White (light mode) / .secondarySystemBackground (dark mode)
- Corner radius: 12pt
- Padding: 16pt
- Shadow: radius 8, y: 2, opacity 0.1
- Border: None (use shadow for elevation)
Layout:
┌───────────────────────────────┐
│ [Thumbnail] Title │
│ (60x60pt) Subtitle │
│ Metadata │
└───────────────────────────────┘
Spacing:
- Thumbnail to text: 12pt
- Title to subtitle: 4pt
- Text to edge: 16pt
Highlighted Card
Differences from Standard:
- Border: 2pt, Brand Primary color
- Background: Tinted (Primary color at 5% opacity)
- Shadow: Slightly larger (radius 10)
4.3 Forms
Text Input
Style:
- Height: 50pt
- Padding: 16pt horizontal
- Background: .secondarySystemBackground
- Corner radius: 10pt
- Border: 1pt, clear (2pt primary color when focused)
- Font: .body
States:
- Default: Gray background, no border
- Focused: White background, blue border
- Error: Red border, red tint
- Disabled: Reduced opacity, no interaction
With Label:
- Label above input, .caption size, secondary color
- 8pt spacing between label and input
With Error:
- Error message below input, .caption size, red color
- Error icon (exclamationmark.circle) leading
4.4 Typography Styles
Usage Guide:
- Large Title: Screen titles (Home, Settings)
- Title: Section headers
- Title 2: Card titles, detail screen main heading
- Title 3: Subsection headers
- Headline: Button labels, emphasized text
- Body: Default text, descriptions
- Callout: Metadata, secondary information
- Subheadline: Subtitles, labels
- Footnote: Timestamps, hints
- Caption: Section headers (uppercase), disclaimers
5. Interaction Patterns
5.1 Gestures
| Gesture | Use Case | Feedback | |---------|----------|----------| | Tap | Primary action, select, open | Visual (highlight), Haptic (light) | | Long Press | Context menu, preview | Visual (scale up), Haptic (medium) | | Swipe Left | Delete, remove | Visual (red background), Haptic (none) | | Swipe Right | Archive, mark done | Visual (green background), Haptic (success) | | Pull Down | Refresh content | Visual (activity indicator), Haptic (light when triggered) | | Pinch | Zoom image, map | Visual (scale), Haptic (none) | | Edge Swipe | Back navigation | Visual (screen slide), Haptic (none) |
5.2 Animations
Screen Transitions
- Push/Pop: Native NavigationStack animation (slide from right)
- Modal: Sheet from bottom, 0.3s ease-in-out
- Full Screen: Fade in, 0.2s
Element Animations
- List Item Appear: Fade + slide up, 0.3s, staggered by 0.05s
- Button Press: Scale to 0.95, 0.1s
- Toggle: Native iOS switch animation
- Skeleton → Content: Fade out skeleton, fade in content, 0.2s
Loading States
- Spinner: Continuous rotation, native iOS style
- Progress Bar: Fill animation, 0.5s per segment
- Shimmer: Gradient sweep, 1.5s repeat
5.3 Haptic Feedback
When to Use:
- ✅ Button taps (light)
- ✅ Toggle switches (light)
- ✅ Pull-to-refresh triggered (medium)
- ✅ Successful action (success pattern)
- ✅ Error occurred (error pattern)
- ❌ Scrolling (no haptic)
- ❌ Text input (no haptic)
- ❌ Standard navigation (no haptic)
Implementation:
import CoreHaptics
// Light impact
let impact = UIImpactFeedbackGenerator(style: .light)
impact.impactOccurred()
// Success notification
let notification = UINotificationFeedbackGenerator()
notification.notificationOccurred(.success)
6. Accessibility
6.1 VoiceOver
Requirements:
- All interactive elements must have labels
- Labels should describe action, not appearance
- Images need descriptions (decorative = empty label)
- Status changes should be announced
Examples:
- Button: "Add new item" (not "Plus button")
- Card: "Meeting notes, Created 2 hours ago, Tap to view details"
- Image: "Profile photo of John Doe" or "" if decorative
- Toggle: "Notifications, On, Toggle switch" (system provides toggle part)
Testing:
- Enable VoiceOver in Simulator (Cmd+F5)
- Navigate with swipe gestures
- Verify all elements are reachable and labeled
6.2 Dynamic Type
Support all text sizes: Extra Small to Accessibility XXL
Implementation:
Text("Title")
.font(.title) // Automatically scales
.lineLimit(nil) // Allow wrapping
.minimumScaleFactor(0.8) // If must fit one line
Layout Adjustments:
- Stack elements vertically at larger sizes
- Increase spacing proportionally
- Ensure minimum tap targets (44x44pt)
Testing:
- Settings → Accessibility → Display & Text Size → Larger Text
- Test at XS, default, and XXL sizes
6.3 Color Contrast
WCAG AA Standards:
- Text: 4.5:1 minimum contrast ratio
- Large text (18pt+): 3:1 minimum
- UI elements: 3:1 minimum
Testing Tools:
- Xcode Accessibility Inspector
- Online: WebAIM Contrast Checker
- Test in both light and dark modes
Common Issues:
- Light gray text on white background (increase contrast)
- Color-only indicators (add icon or label)
- Low opacity overlays (ensure text remains readable)
6.4 Reduced Motion
Respect System Setting:
@Environment(\.accessibilityReduceMotion) var reduceMotion
if reduceMotion {
// Use fade instead of slide
// Reduce animation duration
// Remove complex animations
}
Alternatives:
- Replace slide animations with instant transitions
- Replace complex spring animations with linear fades
- Reduce animation duration by 50%
- Keep critical animations (loading, errors)
7. Dark Mode
7.1 Color Adaptation
Semantic Colors (Automatic):
- Use system colors when possible (they adapt automatically)
.primary,.secondaryfor text.background,.secondaryBackgroundfor surfaces
Custom Colors:
- Define in Assets.xcassets with Appearances: "Any, Dark"
- Provide separate values for each mode
- Test all screens in both modes
7.2 Image Adaptation
Techniques:
- Template images (tint to match color scheme)
- Separate dark mode assets (image_name~dark.png)
- Reduce opacity of photos in dark mode (optional)
7.3 Dark Mode Best Practices
Do:
- Use true black (#000000) sparingly (only for OLED optimization)
- Use elevated surfaces (lighter) for cards/modals
- Maintain visual hierarchy (contrast between levels)
- Test with "Increase Contrast" enabled
Don't:
- Don't invert light mode colors (design separately)
- Don't use pure white text (#FFFFFF) - use slightly off-white
- Don't forget shadows (they disappear on dark backgrounds)
8. Responsive Design
8.1 iPhone Sizes
Layouts to Support:
- iPhone SE (3rd gen): 375pt width (smallest)
- iPhone 15: 393pt width
- iPhone 15 Pro Max: 430pt width (largest)
Adaptation Strategy:
- Use flexible layouts (HStack, VStack, Grid)
- Set minimum widths, allow expansion
- Test safe area insets (notch, Dynamic Island)
8.2 iPad (Optional)
Layout Changes:
- Sidebar navigation instead of tabs
- Multi-column layouts (master-detail)
- Larger cards (2-3 columns in grid)
- Utilize horizontal space
Keyboard Support:
- Cmd+N: New item
- Cmd+F: Focus search
- Cmd+S: Save
- Cmd+W: Close modal
8.3 Orientation
Portrait: Default, all screens optimized Landscape:
- iPhone: Optional (usually lock to portrait)
- iPad: Required, adjust layout
9. Edge Cases & Error Handling
9.1 Network States
| State | User Experience | System Behavior | |-------|-----------------|-----------------| | No connection | "No internet connection. Showing saved data." banner at top | Use cached data, disable sync, queue changes | | Slow connection | Loading indicator, timeout after 30s | Show skeleton screens, async load images | | Connection restored | "Back online" banner (auto-dismiss 3s) | Trigger sync, upload queued changes |
9.2 Data States
| State | User Experience | System Behavior | |-------|-----------------|-----------------| | Empty list | ContentUnavailableView with CTA | Hide list, show empty state | | Single item | Show list with one item (not special case) | Same as multiple items | | Thousands of items | Paginated, lazy loading, search encouraged | Load 50 at a time, virtual scrolling |
9.3 Input Validation
| Invalid Input | User Experience | Prevention | |---------------|-----------------|------------| | Empty required field | Red outline, "This field is required" below | Disable Save button | | Invalid email | "Please enter a valid email" | Real-time validation | | Duplicate entry | Alert: "Item already exists. Continue?" | Check on save, allow override |
9.4 Permission States
| Permission | Denied | Granted | |------------|--------|---------| | Camera | Show alert: "Camera access needed. Open Settings?" | Open camera picker | | Photos | Show placeholder, "Tap to allow photo access" | Open photo picker | | Notifications | App works without, show banner once | Send notifications | | Location | Feature disabled, show upgrade message | Show map with location |
10. Platform-Specific Considerations
10.1 iOS Human Interface Guidelines
Follow These Patterns:
- Navigation: Use NavigationStack, not custom
- Tabs: Max 5 tabs, use "More" tab if needed
- Modals: Sheet for forms, fullScreenCover for immersive
- Lists: Use native List with proper row heights (44pt min)
- Search: Use .searchable modifier
- Pull-to-refresh: Use .refreshable modifier
- Context menus: Long press for actions
Avoid:
- Custom navigation that doesn't follow back button patterns
- Non-standard gestures (users expect iOS conventions)
- Hamburger menus (use tabs or sidebar on iPad)
- Bottom sheets (use native sheets from bottom)
10.2 iOS 17+ Features to Leverage
Adopt New APIs:
- ContentUnavailableView for empty states
- @Observable for view models (instead of ObservableObject)
- SwiftData for persistence (instead of Core Data)
- #Preview macros (instead of PreviewProvider)
- Sensory feedback API (instead of UIImpactFeedbackGenerator)
Test on iOS 17+: Set minimum deployment target to iOS 17.0
11. Design Handoff Checklist
Before considering UX spec complete:
- [ ] All screens from PRD are designed with wireframes
- [ ] Empty, loading, and error states defined for all screens
- [ ] All interactive elements specified (tap, swipe, long press)
- [ ] Navigation flow is clear and consistent
- [ ] Component library covers all UI elements used
- [ ] Accessibility requirements documented (VoiceOver, Dynamic Type)
- [ ] Dark mode adaptations specified
- [ ] Responsive behavior defined (iPhone sizes)
- [ ] Edge cases and error scenarios handled
- [ ] Animation and haptic feedback specified
- [ ] Colors, typography, spacing all reference design system
- [ ] No placeholder or "TBD" items remain
Appendix A: Screen Specifications Template
Use this template for additional screens not detailed above:
### X.X [Screen Name]
**Purpose**: [One sentence describing what user accomplishes]
**Layout** (ASCII wireframe):
┌─────────────────────────────────────┐ │ [Navigation Bar] │ ├─────────────────────────────────────┤ │ │ │ [Main Content Area] │ │ │ ├─────────────────────────────────────┤ │ [Bottom Bar / Actions] │ └─────────────────────────────────────┘
**Components**:
- [Component 1]: [Description]
- [Component 2]: [Description]
**Interactions**:
- Tap [Element] → [Result]
- Swipe [Direction] → [Action]
**States**:
- Empty: [How it looks]
- Loading: [How it looks]
- Error: [How it looks]
**Data Requirements**:
- [Data needed from backend/storage]
**Accessibility**:
- [VoiceOver labels]
- [Special considerations]
Document History: | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0.0 | [Date] | UX Designer AI | Initial UX specification |
### 2. docs/DESIGN_SYSTEM.md
```markdown
# Design System: [App Name]
**Version**: 1.0.0
**Last Updated**: [Date]
**Platform**: iOS 17+
**Language**: SwiftUI
---
## 1. Brand Identity
### 1.1 Brand Personality
**From Positioning**: [e.g., "Professional, trustworthy, modern with a human touch"]
**Visual Expression**:
- **Modern**: Clean lines, generous whitespace, sans-serif typography
- **Professional**: Muted color palette, consistent spacing, subtle animations
- **Approachable**: Friendly copy, helpful empty states, forgiving errors
### 1.2 Voice & Tone
**Voice** (Consistent):
- Clear and concise
- Helpful, not bossy
- Human, not robotic
- Confident, not arrogant
**Tone** (Context-dependent):
- **Success**: Encouraging ("Great job!")
- **Error**: Apologetic and helpful ("Oops! Let's try that again.")
- **Onboarding**: Excited and welcoming ("Welcome! Let's get started.")
- **Empty state**: Optimistic ("Ready to create your first item?")
---
## 2. Color Palette
### 2.1 Primary Colors
**Brand Primary** (Main CTA, key actions):
```swift
// Light mode
static let brandPrimary = Color(hex: "#007AFF") // iOS Blue
// Dark mode
static let brandPrimaryDark = Color(hex: "#0A84FF") // Lighter blue
Brand Secondary (Accents, highlights):
// Light mode
static let brandSecondary = Color(hex: "#5856D6") // Purple
// Dark mode
static let brandSecondaryDark = Color(hex: "#5E5CE6")
Brand Accent (Destructive actions, warnings):
// Light mode
static let brandAccent = Color(hex: "#FF3B30") // Red
// Dark mode
static let brandAccentDark = Color(hex: "#FF453A")
2.2 Semantic Colors
Success (Confirmation, completion):
static let success = Color(hex: "#34C759") // Green
Warning (Caution, attention needed):
static let warning = Color(hex: "#FF9500") // Orange
Error (Errors, destructive actions):
static let error = Color(hex: "#FF3B30") // Red (same as accent)
Info (Tips, information):
static let info = Color(hex: "#007AFF") // Blue (same as primary)
2.3 Neutral Colors
Backgrounds:
// Light mode
static let background = Color.white
static let secondaryBackground = Color(hex: "#F2F2F7") // iOS gray
static let tertiaryBackground = Color(hex: "#FFFFFF")
// Dark mode
static let backgroundDark = Color(hex: "#000000")
static let secondaryBackgroundDark = Color(hex: "#1C1C1E")
static let tertiaryBackgroundDark = Color(hex: "#2C2C2E")
Text:
// Light mode
static let textPrimary = Color(hex: "#000000")
static let textSecondary = Color(hex: "#3C3C43", opacity: 0.6) // iOS secondary label
static let textTertiary = Color(hex: "#3C3C43", opacity: 0.3)
// Dark mode
static let textPrimaryDark = Color(hex: "#FFFFFF")
static let textSecondaryDark = Color(hex: "#EBEBF5", opacity: 0.6)
static let textTertiaryDark = Color(hex: "#EBEBF5", opacity: 0.3)
Borders & Dividers:
static let separator = Color(hex: "#3C3C43", opacity: 0.36)
static let border = Color(hex: "#C7C7CC")
2.4 Usage Guidelines
Primary Color:
- Primary CTAs (Save, Submit, Continue)
- Active tab bar items
- Selected state
- Links
Secondary Color:
- Secondary actions
- Highlights
- Badges (non-critical)
Accent Color:
- Delete buttons
- Error states
- Critical alerts
Backgrounds:
- background: Screen background
- secondaryBackground: Card backgrounds, input fields
- tertiaryBackground: Nested cards, elevated surfaces
3. Typography
3.1 Type Scale
iOS Dynamic Type (Automatically scales with user preference):
// Display
.largeTitle // 34pt, Bold - Screen titles
.title // 28pt, Bold - Major sections
.title2 // 22pt, Bold - Subsections, cards
.title3 // 20pt, Semibold - Groups
// Body
.headline // 17pt, Semibold - Emphasized text, button labels
.body // 17pt, Regular - Default body text
.callout // 16pt, Regular - Secondary content
// Supporting
.subheadline // 15pt, Regular - Subtitles, labels
.footnote // 13pt, Regular - Timestamps, metadata
.caption // 12pt, Regular - Section headers (uppercase)
.caption2 // 11pt, Regular - Fine print
3.2 Font Family
Default: System Font (SF Pro)
- No custom fonts needed (SF Pro is optimized for iOS)
- If custom font required: Choose legible, web-safe fallback
3.3 Font Weights
.ultraLight // Avoid, too thin
.thin // Avoid
.light // Occasional use
.regular // Default for body text
.medium // Occasional emphasis
.semibold // Headings, emphasized text
.bold // Titles, important actions
.heavy // Avoid, too thick
.black // Avoid
3.4 Line Height & Spacing
Default: SwiftUI handles automatically Custom (if needed):
.lineSpacing(4) // Add 4pt between lines (for dense text)
Paragraph Spacing: 12pt between paragraphs
3.5 Usage Guidelines
| Element | Style | Use Case | |---------|-------|----------| | Screen Title | .largeTitle | Home, Settings navigation bar | | Section Header | .title2 | "Recent Items", "Profile" | | Card Title | .headline | Item name in list | | Body Text | .body | Descriptions, paragraphs | | Metadata | .footnote | Timestamps, "Created 2h ago" | | Button Label | .headline | All buttons | | Input Label | .caption | Above text fields | | Placeholder | .body + opacity 0.5 | Text field placeholder |
4. Spacing System
4.1 Spacing Scale
Base Unit: 4pt
enum Spacing {
static let xxs: CGFloat = 2 // Tight spacing (icon to text)
static let xs: CGFloat = 4 // Very small (between related elements)
static let s: CGFloat = 8 // Small (list item internal padding)
static let m: CGFloat = 12 // Medium (between components)
static let l: CGFloat = 16 // Large (card padding, margins) ⭐ Default
static let xl: CGFloat = 24 // Extra large (section spacing)
static let xxl: CGFloat = 32 // Screen margins, major sections
static let xxxl: CGFloat = 48 // Between major screen areas
}
4.2 Usage Guidelines
Padding (Inside components):
- Cards: 16pt all sides
- Buttons: 16pt horizontal, 12pt vertical
- Text fields: 16pt horizontal, 12pt vertical
- List rows: 16pt horizontal, 8pt vertical
Margins (Between components):
- List items: 8pt vertical
- Sections: 24pt vertical
- Screen edges: 16pt horizontal
Stack Spacing:
VStack(spacing: 12) { ... } // Default
HStack(spacing: 8) { ... } // Tight
VStack(spacing: 24) { ... } // Loose
5. Layout Grid
5.1 Grid System
Columns: 12-column grid (flexible) Gutter: 16pt between columns Margins: 16pt (iPhone), 20pt (iPad)
Usage:
- Single column: Full width (12/12)
- Two columns: 6/12 each (rare on iPhone)
- Three columns: 4/12 each (iPad only)
5.2 Breakpoints
| Device | Width (pt) | Columns | Margins | |--------|-----------|---------|---------| | iPhone SE | 375 | 1 | 16pt | | iPhone 15 | 393 | 1 | 16pt | | iPhone Pro Max | 430 | 1 | 16pt | | iPad Portrait | 768 | 2 | 20pt | | iPad Landscape | 1024 | 3 | 20pt |
6. Iconography
6.1 Icon Set
Primary: SF Symbols (native, 4000+ icons) Custom: Only if SF Symbols doesn't have the icon
6.2 Icon Sizes
.small // 16x16pt - Inline with text
.medium // 20x20pt - Default
.large // 24x24pt - Emphasized
.xlarge // 28x28pt - Hero icons
6.3 Icon Weights
Match text weight:
- Body text (.regular) → .regular weight icon
- Headline (.semibold) → .semibold weight icon
- Title (.bold) → .bold weight icon
Image(systemName: "star.fill")
.font(.title2) // Size
.fontWeight(.semibold) // Weight
6.4 Icon Colors
Default: Match text color Tinted: Brand primary for active/selected Multicolor: SF Symbols multicolor variant (sparingly)
6.5 Common Icons
| Use Case | SF Symbol | Alternative | |----------|-----------|-------------| | Add | plus | plus.circle.fill | | Delete | trash | trash.fill | | Edit | pencil | pencil.circle | | Search | magnifyingglass | - | | Settings | gearshape | gearshape.fill | | Profile | person | person.circle | | Home | house | house.fill | | Favorites | star | star.fill | | Share | square.and.arrow.up | - | | Close | xmark | xmark.circle.fill | | Back | chevron.left | arrow.left | | Success | checkmark.circle.fill | - | | Error | xmark.circle.fill | exclamationmark.triangle.fill | | Warning | exclamationmark.triangle | - | | Info | info.circle | questionmark.circle |
7. Shadows & Elevation
7.1 Shadow Levels
Level 1 (Cards, subtle elevation):
.shadow(color: .black.opacity(0.1), radius: 8, y: 2)
Level 2 (Modals, popovers):
.shadow(color: .black.opacity(0.15), radius: 16, y: 4)
Level 3 (Dropdowns, tooltips):
.shadow(color: .black.opacity(0.2), radius: 24, y: 8)
7.2 Usage Guidelines
When to Use Shadows:
- Cards on plain background (differentiation)
- Floating action buttons
- Modals and sheets
- Popovers and dropdowns
When NOT to Use:
- Dark mode (use borders or different background colors)
- List items (use dividers instead)
- Flat design (intentionally no elevation)
7.3 Dark Mode Adaptation
Replace shadows with borders:
if colorScheme == .dark {
.border(Color.white.opacity(0.1), width: 1)
} else {
.shadow(radius: 8, y: 2)
}
8. Corner Radius
8.1 Radius Scale
enum CornerRadius {
static let xs: CGFloat = 4 // Very subtle (badges)
static let s: CGFloat = 8 // Small (buttons, inputs)
static let m: CGFloat = 12 // Medium (cards) ⭐ Default
static let l: CGFloat = 16 // Large (modals, sheets)
static let xl: CGFloat = 24 // Extra large (hero cards)
static let full: CGFloat = 9999 // Fully rounded (pills, avatars)
}
8.2 Usage Guidelines
| Element | Radius | Rationale | |---------|--------|-----------| | Buttons | 12pt | iOS standard, comfortable | | Text inputs | 10pt | Slightly less than buttons (visual distinction) | | Cards | 12pt | Consistent with buttons | | Modals/Sheets | 16pt | Larger surface, more prominence | | Badges | 8pt or full | Depends on style (rounded or pill) | | Avatars | full | Circular | | Thumbnails | 8pt | Subtle rounding |
9. Animation & Motion
9.1 Animation Timings
enum AnimationDuration {
static let fast: Double = 0.2 // Button press, toggle
static let standard: Double = 0.3 // Screen transition, fade ⭐ Default
static let slow: Double = 0.5 // Complex animations
static let verySlow: Double = 1.0 // Onboarding, celebration
}
9.2 Easing Curves
Default: .easeInOut (most natural)
.animation(.easeInOut(duration: 0.3), value: someValue)
Spring: For playful, bouncy effects
.animation(.spring(response: 0.3, dampingFraction: 0.7), value: someValue)
Linear: For progress bars, loaders
.animation(.linear(duration: 2.0), value: progress)
9.3 Common Animations
Fade In/Out:
.opacity(isVisible ? 1 : 0)
.animation(.easeInOut(duration: 0.3), value: isVisible)
Slide In:
.offset(y: isVisible ? 0 : 50)
.opacity(isVisible ? 1 : 0)
.animation(.easeOut(duration: 0.4), value: isVisible)
Scale (Button Press):
.scaleEffect(isPressed ? 0.95 : 1.0)
.animation(.easeInOut(duration: 0.1), value: isPressed)
Rotation:
.rotationEffect(.degrees(isLoading ? 360 : 0))
.animation(.linear(duration: 1.0).repeatForever(autoreverses: false), value: isLoading)
9.4 Reduced Motion
Respect accessibility setting:
@Environment(\.accessibilityReduceMotion) var reduceMotion
if reduceMotion {
// Use fade instead of slide
.opacity(isVisible ? 1 : 0)
} else {
// Use full animation
.offset(y: isVisible ? 0 : 50)
.opacity(isVisible ? 1 : 0)
}
10. Component Styles (SwiftUI Code)
10.1 Button Styles
struct PrimaryButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.frame(height: 50)
.background(Color.brandPrimary)
.cornerRadius(12)
.scaleEffect(configuration.isPressed ? 0.98 : 1.0)
.animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
}
}
// Usage:
Button("Continue") { }
.buttonStyle(PrimaryButtonStyle())
10.2 Card Modifier
extension View {
func cardStyle() -> some View {
self
.padding(16)
.background(Color(.secondarySystemBackground))
.cornerRadius(12)
.shadow(color: .black.opacity(0.1), radius: 8, y: 2)
}
}
// Usage:
VStack { ... }
.cardStyle()
10.3 Text Field Style
struct CustomTextFieldStyle: TextFieldStyle {
func _body(configuration: TextField<Self._Label>) -> some View {
configuration
.padding(16)
.background(Color(.secondarySystemBackground))
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.brandPrimary.opacity(0.3), lineWidth: 1)
)
}
}
// Usage:
TextField("Enter name", text: $name)
.textFieldStyle(CustomTextFieldStyle())
11. Assets Organization
11.1 Color Assets
Location: Assets.xcassets/Colors/
Naming Convention:
BrandPrimary(with Light + Dark appearances)BrandSecondaryTextPrimaryBackgroundSecondary
11.2 Image Assets
Location: Assets.xcassets/Images/
Naming Convention:
icon-name(lowercase, hyphen-separated)illustration-onboarding-1placeholder-avatar
Formats:
- Icons: PDF (vector) or PNG @2x, @3x
- Photos: PNG or JPEG @2x, @3x
- Illustrations: PDF (preferred) or PNG
11.3 SF Symbols
No need to add to assets - use directly by name:
Image(systemName: "star.fill")
12. Design Tokens (Reference)
For developers: centralized constants file
// DesignTokens.swift
import SwiftUI
enum DesignSystem {
// Colors
enum Colors {
static let brandPrimary = Color("BrandPrimary")
static let brandSecondary = Color("BrandSecondary")
static let textPrimary = Color.primary
static let textSecondary = Color.secondary
static let success = Color.green
static let error = Color.red
static let warning = Color.orange
}
// Typography
enum Typography {
static let largeTitle = Font.largeTitle
static let title = Font.title
static let headline = Font.headline
static let body = Font.body
static let caption = Font.caption
}
// Spacing
enum Spacing {
static let xs: CGFloat = 4
static let s: CGFloat = 8
static let m: CGFloat = 12
static let l: CGFloat = 16
static let xl: CGFloat = 24
static let xxl: CGFloat = 32
}
// Corner Radius
enum Radius {
static let small: CGFloat = 8
static let medium: CGFloat = 12
static let large: CGFloat = 16
static let full: CGFloat = 9999
}
// Shadows
enum Shadow {
static let card = (color: Color.black.opacity(0.1), radius: CGFloat(8), y: CGFloat(2))
static let modal = (color: Color.black.opacity(0.15), radius: CGFloat(16), y: CGFloat(4))
}
// Animation
enum Animation {
static let fast = 0.2
static let standard = 0.3
static let slow = 0.5
}
}
// Usage:
Text("Hello")
.font(DesignSystem.Typography.headline)
.foregroundColor(DesignSystem.Colors.brandPrimary)
.padding(DesignSystem.Spacing.l)
13. Implementation Checklist
Before considering design system complete:
- [ ] All colors defined in Assets.xcassets with Dark mode variants
- [ ] Typography scale documented and tested at multiple sizes
- [ ] Spacing scale applied consistently across all screens
- [ ] Corner radius values standardized
- [ ] Shadow styles defined for different elevation levels
- [ ] Icon library documented (SF Symbols references)
- [ ] Animation timings and easing curves specified
- [ ] Component styles implemented as reusable SwiftUI modifiers
- [ ] Design tokens file created for developer reference
- [ ] Dark mode tested for all colors and components
- [ ] Accessibility: Dynamic Type, VoiceOver, Contrast verified
- [ ] Responsive behavior tested on all iPhone sizes
Document History: | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0.0 | [Date] | UX Designer AI | Initial design system |
---
## Execution Instructions
When activated, follow these steps:
1. **Locate and Read Input Documents**
- Read docs/PRD.md (all features and user flows)
- Read docs/ARCHITECTURE.md (app structure, data models)
- Read product-plan-*.md (positioning, brand personality) If any missing, ask user for file path
2. **Extract Key Information**
From inputs, extract:
- All screens needed (from PRD features)
- Navigation structure (from architecture)
- Brand personality (from positioning)
- Core features to design (from PRD MVP scope)
- Platform (iOS/macOS)
3. **Design Information Architecture**
- List all screens
- Determine navigation pattern (tabs, stack, sidebar)
- Create navigation flow diagram
- Prioritize screens (P0, P1, P2)
4. **Create Wireframes for Core Screens**
For each P0 screen:
- Draw ASCII wireframe (clear layout)
- Specify all components
- Document all interactions
- Define states (empty, loading, error)
- List data requirements
5. **Define Design System**
Based on brand personality:
- Choose color palette (align with positioning)
- Define typography scale (iOS standard)
- Set spacing system (8pt grid)
- Specify component styles (buttons, cards, inputs)
- Document animation timings
6. **Generate Output Files**
Write comprehensive UX_SPEC.md to: docs/UX_SPEC.md Write complete DESIGN_SYSTEM.md to: docs/DESIGN_SYSTEM.md
7. **Present to User**
After generating files, present summary:
✅ UI/UX Specifications generated!
📱 UX_SPEC.md Summary:
- Screens designed: [X] screens with wireframes
- User flows documented: [Y] flows
- Interaction patterns: Defined for all screens
- Accessibility: VoiceOver labels, Dynamic Type, contrast ratios
🎨 DESIGN_SYSTEM.md Summary:
- Color palette: [X] colors (light + dark mode)
- Typography: iOS Dynamic Type scale
- Component library: [Y] reusable components
- Animation guidelines: Timings and easing curves
Next Steps:
- Review the wireframes in docs/UX_SPEC.md
- Check the design system in docs/DESIGN_SYSTEM.md
- Provide feedback on any screens or components
- Once approved, we can proceed to implementation guide
Would you like me to make any changes to the UI design?
8. **Iterate Based on Feedback**
If user requests changes:
- Ask clarifying questions
- Update UX_SPEC.md and/or DESIGN_SYSTEM.md
- Maintain consistency across both documents
---
## Quality Guidelines
When generating the UX specifications:
1. **Be Visual**: ASCII wireframes should be clear and detailed
- BAD: Just describe "A list of items"
- GOOD: Draw the actual layout with boxes, labels, and spacing
2. **Be Specific**: Every interaction should be defined
- BAD: "User can tap the button"
- GOOD: "Tap 'Save' button → Validate fields → Show loading spinner → Dismiss sheet → Return to Home with success toast"
3. **Be Complete**: Cover all states
- Happy path (default)
- Empty state (no data)
- Loading state (data fetching)
- Error state (failed to load)
- Skeleton/placeholder (progressive loading)
4. **Follow iOS HIG**: Use native patterns
- NavigationStack for hierarchical navigation
- TabView for flat navigation
- Sheet for forms/modals
- List for collections
- SwiftUI standard components
5. **Design for Accessibility**: Not an afterthought
- VoiceOver labels for every element
- Dynamic Type support
- Color contrast 4.5:1 minimum
- Reduced motion alternatives
6. **Be Consistent**: Reference design system
- Use defined colors (don't introduce new ones)
- Use spacing scale (not random values)
- Use typography scale (not arbitrary sizes)
- Reuse components (don't create one-offs)
---
## Example Activation
**User**: "Generate UX spec from PRD"
**You**:
1. Read docs/PRD.md
2. Read docs/ARCHITECTURE.md
3. Read product-plan-*.md for positioning
4. Extract all features needing screens
5. Design wireframes for each screen (ASCII art)
6. Create comprehensive design system
7. Write both documents to docs/
8. Present summary with next steps
---
## Integration with Workflow
This skill is typically:
- **Third step** in specification generation
- Activated after PRD and Architecture are complete
- Followed by implementation-guide, test-spec, release-spec
The UX specifications serve as the visual blueprint that developers use to implement the UI.
---
## Notes
- Focus on iOS patterns - don't reinvent the wheel
- ASCII wireframes are sufficient - no need for high-fidelity mockups
- Provide enough detail that a developer can implement without guessing
- Reference Apple's Human Interface Guidelines throughout
- Ensure all specifications are actionable and unambiguous
- Keep design system tokens consistent across both documents
- Test all designs mentally for accessibility before documenting