--- name: mobile-design description: Mobile-first design thinking and decision-making for iOS and Android apps. Touch interaction, performance patterns, platform conventions. Teaches principles, not fixed values. Use when building React Native, Flutter, or native mobile apps. allowed-tools: Read, Glob, Grep, Bash --- # Mobile Design System > **Philosophy:** Touch-first. Battery-conscious. Platform-respectful. Offline-capable. > **Core Principle:** Mobile is NOT a small desktop. THINK mobile constraints, ASK platform choice. --- ## πŸ”§ Runtime Scripts **Execute these for validation (don't read, just run):** | Script | Purpose | Usage | |--------|---------|-------| | `scripts/mobile_audit.py` | Mobile UX & Touch Audit | `python scripts/mobile_audit.py ` | --- ## πŸ”΄ MANDATORY: Read Reference Files Before Working! **β›” DO NOT start development until you read the relevant files:** ### Universal (Always Read) | File | Content | Status | |------|---------|--------| | **[mobile-design-thinking.md](mobile-design-thinking.md)** | **⚠️ ANTI-MEMORIZATION: Forces thinking, prevents AI defaults** | **⬜ CRITICAL FIRST** | | **[touch-psychology.md](touch-psychology.md)** | **Fitts' Law, gestures, haptics, thumb zone** | **⬜ CRITICAL** | | **[mobile-performance.md](mobile-performance.md)** | **RN/Flutter performance, 60fps, memory** | **⬜ CRITICAL** | | **[mobile-backend.md](mobile-backend.md)** | **Push notifications, offline sync, mobile API** | **⬜ CRITICAL** | | **[mobile-testing.md](mobile-testing.md)** | **Testing pyramid, E2E, platform-specific** | **⬜ CRITICAL** | | **[mobile-debugging.md](mobile-debugging.md)** | **Native vs JS debugging, Flipper, Logcat** | **⬜ CRITICAL** | | [mobile-navigation.md](mobile-navigation.md) | Tab/Stack/Drawer, deep linking | ⬜ Read | | [mobile-typography.md](mobile-typography.md) | System fonts, Dynamic Type, a11y | ⬜ Read | | [mobile-color-system.md](mobile-color-system.md) | OLED, dark mode, battery-aware | ⬜ Read | | [decision-trees.md](decision-trees.md) | Framework/state/storage selection | ⬜ Read | > 🧠 **mobile-design-thinking.md is PRIORITY!** This file ensures AI thinks instead of using memorized patterns. ### Platform-Specific (Read Based on Target) | Platform | File | Content | When to Read | |----------|------|---------|--------------| | **iOS** | [platform-ios.md](platform-ios.md) | Human Interface Guidelines, SF Pro, SwiftUI patterns | Building for iPhone/iPad | | **Android** | [platform-android.md](platform-android.md) | Material Design 3, Roboto, Compose patterns | Building for Android | | **Cross-Platform** | Both above | Platform divergence points | React Native / Flutter | > πŸ”΄ **If building for iOS β†’ Read platform-ios.md FIRST!** > πŸ”΄ **If building for Android β†’ Read platform-android.md FIRST!** > πŸ”΄ **If cross-platform β†’ Read BOTH and apply conditional platform logic!** --- ## ⚠️ CRITICAL: ASK BEFORE ASSUMING (MANDATORY) > **STOP! If the user's request is open-ended, DO NOT default to your favorites.** ### You MUST Ask If Not Specified: | Aspect | Ask | Why | |--------|-----|-----| | **Platform** | "iOS, Android, or both?" | Affects EVERY design decision | | **Framework** | "React Native, Flutter, or native?" | Determines patterns and tools | | **Navigation** | "Tab bar, drawer, or stack-based?" | Core UX decision | | **State** | "What state management? (Zustand/Redux/Riverpod/BLoC?)" | Architecture foundation | | **Offline** | "Does this need to work offline?" | Affects data strategy | | **Target devices** | "Phone only, or tablet support?" | Layout complexity | ### β›” AI MOBILE ANTI-PATTERNS (YASAK LΔ°STESΔ°) > 🚫 **These are AI default tendencies that MUST be avoided!** #### Performance Sins | ❌ NEVER DO | Why It's Wrong | βœ… ALWAYS DO | |-------------|----------------|--------------| | **ScrollView for long lists** | Renders ALL items, memory explodes | Use `FlatList` / `FlashList` / `ListView.builder` | | **Inline renderItem function** | New function every render, all items re-render | `useCallback` + `React.memo` | | **Missing keyExtractor** | Index-based keys cause bugs on reorder | Unique, stable ID from data | | **Skip getItemLayout** | Async layout = janky scroll | Provide when items have fixed height | | **setState() everywhere** | Unnecessary widget rebuilds | Targeted state, `const` constructors | | **Native driver: false** | Animations blocked by JS thread | `useNativeDriver: true` always | | **console.log in production** | Blocks JS thread severely | Remove before release build | | **Skip React.memo/const** | Every item re-renders on any change | Memoize list items ALWAYS | #### Touch/UX Sins | ❌ NEVER DO | Why It's Wrong | βœ… ALWAYS DO | |-------------|----------------|--------------| | **Touch target < 44px** | Impossible to tap accurately, frustrating | Minimum 44pt (iOS) / 48dp (Android) | | **Spacing < 8px between targets** | Accidental taps on neighbors | Minimum 8-12px gap | | **Gesture-only interactions** | Motor impaired users excluded | Always provide button alternative | | **No loading state** | User thinks app crashed | ALWAYS show loading feedback | | **No error state** | User stuck, no recovery path | Show error with retry option | | **No offline handling** | Crash/block when network lost | Graceful degradation, cached data | | **Ignore platform conventions** | Users confused, muscle memory broken | iOS feels iOS, Android feels Android | #### Security Sins | ❌ NEVER DO | Why It's Wrong | βœ… ALWAYS DO | |-------------|----------------|--------------| | **Token in AsyncStorage** | Easily accessible, stolen on rooted device | `SecureStore` / `Keychain` / `EncryptedSharedPreferences` | | **Hardcode API keys** | Reverse engineered from APK/IPA | Environment variables, secure storage | | **Skip SSL pinning** | MITM attacks possible | Pin certificates in production | | **Log sensitive data** | Logs can be extracted | Never log tokens, passwords, PII | #### Architecture Sins | ❌ NEVER DO | Why It's Wrong | βœ… ALWAYS DO | |-------------|----------------|--------------| | **Business logic in UI** | Untestable, unmaintainable | Service layer separation | | **Global state for everything** | Unnecessary re-renders, complexity | Local state default, lift when needed | | **Deep linking as afterthought** | Notifications, shares broken | Plan deep links from day one | | **Skip dispose/cleanup** | Memory leaks, zombie listeners | Clean up subscriptions, timers | --- ## πŸ“± Platform Decision Matrix ### When to Unify vs Diverge ``` UNIFY (same on both) DIVERGE (platform-specific) ─────────────────── ────────────────────────── Business Logic βœ… Always - Data Layer βœ… Always - Core Features βœ… Always - Navigation - βœ… iOS: edge swipe, Android: back button Gestures - βœ… Platform-native feel Icons - βœ… SF Symbols vs Material Icons Date Pickers - βœ… Native pickers feel right Modals/Sheets - βœ… iOS: bottom sheet vs Android: dialog Typography - βœ… SF Pro vs Roboto (or custom) Error Dialogs - βœ… Platform conventions for alerts ``` ### Quick Reference: Platform Defaults | Element | iOS | Android | |---------|-----|---------| | **Primary Font** | SF Pro / SF Compact | Roboto | | **Min Touch Target** | 44pt Γ— 44pt | 48dp Γ— 48dp | | **Back Navigation** | Edge swipe left | System back button/gesture | | **Bottom Tab Icons** | SF Symbols | Material Symbols | | **Action Sheet** | UIActionSheet from bottom | Bottom Sheet / Dialog | | **Progress** | Spinner | Linear progress (Material) | | **Pull to Refresh** | Native UIRefreshControl | SwipeRefreshLayout | --- ## 🧠 Mobile UX Psychology (Quick Reference) ### Fitts' Law for Touch ``` Desktop: Cursor is precise (1px) Mobile: Finger is imprecise (~7mm contact area) β†’ Touch targets MUST be 44-48px minimum β†’ Important actions in THUMB ZONE (bottom of screen) β†’ Destructive actions AWAY from easy reach ``` ### Thumb Zone (One-Handed Usage) ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ HARD TO REACH β”‚ ← Navigation, menu, back β”‚ (stretch) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ OK TO REACH β”‚ ← Secondary actions β”‚ (natural) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ EASY TO REACH β”‚ ← PRIMARY CTAs, tab bar β”‚ (thumb's natural arc) β”‚ ← Main content interaction β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ [ HOME ] ``` ### Mobile-Specific Cognitive Load | Desktop | Mobile Difference | |---------|-------------------| | Multiple windows | ONE task at a time | | Keyboard shortcuts | Touch gestures | | Hover states | NO hover (tap or nothing) | | Large viewport | Limited space, scroll vertical | | Stable attention | Interrupted constantly | For deep dive: [touch-psychology.md](touch-psychology.md) --- ## ⚑ Performance Principles (Quick Reference) ### React Native Critical Rules ```typescript // βœ… CORRECT: Memoized renderItem + React.memo wrapper const ListItem = React.memo(({ item }: { item: Item }) => ( {item.title} )); const renderItem = useCallback( ({ item }: { item: Item }) => , [] ); // βœ… CORRECT: FlatList with all optimizations item.id} // Stable ID, NOT index getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index, })} removeClippedSubviews={true} maxToRenderPerBatch={10} windowSize={5} /> ``` ### Flutter Critical Rules ```dart // βœ… CORRECT: const constructors prevent rebuilds class MyWidget extends StatelessWidget { const MyWidget({super.key}); // CONST! @override Widget build(BuildContext context) { return const Column( // CONST! children: [ Text('Static content'), MyConstantWidget(), ], ); } } // βœ… CORRECT: Targeted state with ValueListenableBuilder ValueListenableBuilder( valueListenable: counter, builder: (context, value, child) => Text('$value'), child: const ExpensiveWidget(), // Won't rebuild! ) ``` ### Animation Performance ``` GPU-accelerated (FAST): CPU-bound (SLOW): β”œβ”€β”€ transform β”œβ”€β”€ width, height β”œβ”€β”€ opacity β”œβ”€β”€ top, left, right, bottom └── (use these ONLY) β”œβ”€β”€ margin, padding └── (AVOID animating these) ``` For complete guide: [mobile-performance.md](mobile-performance.md) --- ## πŸ“ CHECKPOINT (MANDATORY Before Any Mobile Work) > **Before writing ANY mobile code, you MUST complete this checkpoint:** ``` 🧠 CHECKPOINT: Platform: [ iOS / Android / Both ] Framework: [ React Native / Flutter / SwiftUI / Kotlin ] Files Read: [ List the skill files you've read ] 3 Principles I Will Apply: 1. _______________ 2. _______________ 3. _______________ Anti-Patterns I Will Avoid: 1. _______________ 2. _______________ ``` **Example:** ``` 🧠 CHECKPOINT: Platform: iOS + Android (Cross-platform) Framework: React Native + Expo Files Read: touch-psychology.md, mobile-performance.md, platform-ios.md, platform-android.md 3 Principles I Will Apply: 1. FlatList with React.memo + useCallback for all lists 2. 48px touch targets, thumb zone for primary CTAs 3. Platform-specific navigation (edge swipe iOS, back button Android) Anti-Patterns I Will Avoid: 1. ScrollView for lists β†’ FlatList 2. Inline renderItem β†’ Memoized 3. AsyncStorage for tokens β†’ SecureStore ``` > πŸ”΄ **Can't fill the checkpoint? β†’ GO BACK AND READ THE SKILL FILES.** --- ## πŸ”§ Framework Decision Tree ``` WHAT ARE YOU BUILDING? β”‚ β”œβ”€β”€ Need OTA updates + rapid iteration + web team β”‚ └── βœ… React Native + Expo β”‚ β”œβ”€β”€ Need pixel-perfect custom UI + performance critical β”‚ └── βœ… Flutter β”‚ β”œβ”€β”€ Deep native features + single platform focus β”‚ β”œβ”€β”€ iOS only β†’ SwiftUI β”‚ └── Android only β†’ Kotlin + Jetpack Compose β”‚ β”œβ”€β”€ Existing RN codebase + new features β”‚ └── βœ… React Native (bare workflow) β”‚ └── Enterprise + existing Flutter codebase └── βœ… Flutter ``` For complete decision trees: [decision-trees.md](decision-trees.md) --- ## πŸ“‹ Pre-Development Checklist ### Before Starting ANY Mobile Project - [ ] **Platform confirmed?** (iOS / Android / Both) - [ ] **Framework chosen?** (RN / Flutter / Native) - [ ] **Navigation pattern decided?** (Tabs / Stack / Drawer) - [ ] **State management selected?** (Zustand / Redux / Riverpod / BLoC) - [ ] **Offline requirements known?** - [ ] **Deep linking planned from day one?** - [ ] **Target devices defined?** (Phone / Tablet / Both) ### Before Every Screen - [ ] **Touch targets β‰₯ 44-48px?** - [ ] **Primary CTA in thumb zone?** - [ ] **Loading state exists?** - [ ] **Error state with retry exists?** - [ ] **Offline handling considered?** - [ ] **Platform conventions followed?** ### Before Release - [ ] **console.log removed?** - [ ] **SecureStore for sensitive data?** - [ ] **SSL pinning enabled?** - [ ] **Lists optimized (memo, keyExtractor)?** - [ ] **Memory cleanup on unmount?** - [ ] **Tested on low-end devices?** - [ ] **Accessibility labels on all interactive elements?** --- ## πŸ“š Reference Files For deeper guidance on specific areas: | File | When to Use | |------|-------------| | [mobile-design-thinking.md](mobile-design-thinking.md) | **FIRST! Anti-memorization, forces context-based thinking** | | [touch-psychology.md](touch-psychology.md) | Understanding touch interaction, Fitts' Law, gesture design | | [mobile-performance.md](mobile-performance.md) | Optimizing RN/Flutter, 60fps, memory/battery | | [platform-ios.md](platform-ios.md) | iOS-specific design, HIG compliance | | [platform-android.md](platform-android.md) | Android-specific design, Material Design 3 | | [mobile-navigation.md](mobile-navigation.md) | Navigation patterns, deep linking | | [mobile-typography.md](mobile-typography.md) | Type scale, system fonts, accessibility | | [mobile-color-system.md](mobile-color-system.md) | OLED optimization, dark mode, battery | | [decision-trees.md](decision-trees.md) | Framework, state, storage decisions | --- > **Remember:** Mobile users are impatient, interrupted, and using imprecise fingers on small screens. Design for the WORST conditions: bad network, one hand, bright sun, low battery. If it works there, it works everywhere.