diff --git a/skills/mobile-design/SKILL.md b/skills/mobile-design/SKILL.md index 0218363b..f4109e76 100644 --- a/skills/mobile-design/SKILL.md +++ b/skills/mobile-design/SKILL.md @@ -1,394 +1,284 @@ --- 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. +description: Mobile-first design and engineering doctrine for iOS and Android apps. Covers touch interaction, performance, platform conventions, offline behavior, and mobile-specific decision-making. Teaches principles and constraints, not fixed layouts. Use for React Native, Flutter, or native mobile apps. allowed-tools: Read, Glob, Grep, Bash --- - # Mobile Design System +**(Mobile-First Β· Touch-First Β· Platform-Respectful)** + > **Philosophy:** Touch-first. Battery-conscious. Platform-respectful. Offline-capable. -> **Core Principle:** Mobile is NOT a small desktop. THINK mobile constraints, ASK platform choice. +> **Core Law:** Mobile is NOT a small desktop. +> **Operating Rule:** Think constraints first, aesthetics second. + +This skill exists to **prevent desktop-thinking, AI-defaults, and unsafe assumptions** when designing or building mobile applications. --- -## πŸ”§ Runtime Scripts +## 1. Mobile Feasibility & Risk Index (MFRI) -**Execute these for validation (don't read, just run):** +Before designing or implementing **any mobile feature or screen**, assess feasibility. -| Script | Purpose | Usage | -|--------|---------|-------| -| `scripts/mobile_audit.py` | Mobile UX & Touch Audit | `python scripts/mobile_audit.py ` | +### MFRI Dimensions (1–5) + +| Dimension | Question | +| -------------------------- | ----------------------------------------------------------------- | +| **Platform Clarity** | Is the target platform (iOS / Android / both) explicitly defined? | +| **Interaction Complexity** | How complex are gestures, flows, or navigation? | +| **Performance Risk** | Does this involve lists, animations, heavy state, or media? | +| **Offline Dependence** | Does the feature break or degrade without network? | +| **Accessibility Risk** | Does this impact motor, visual, or cognitive accessibility? | + +### Score Formula + +``` +MFRI = (Platform Clarity + Accessibility Readiness) + βˆ’ (Interaction Complexity + Performance Risk + Offline Dependence) +``` + +**Range:** `-10 β†’ +10` + +### Interpretation + +| MFRI | Meaning | Required Action | +| -------- | --------- | ------------------------------------- | +| **6–10** | Safe | Proceed normally | +| **3–5** | Moderate | Add performance + UX validation | +| **0–2** | Risky | Simplify interactions or architecture | +| **< 0** | Dangerous | Redesign before implementation | --- -## πŸ”΄ MANDATORY: Read Reference Files Before Working! +## 2. Mandatory Thinking Before Any Work -**β›” DO NOT start development until you read the relevant files:** +### β›” STOP: Ask Before Assuming (Required) -### Universal (Always Read) +If **any of the following are not explicitly stated**, you MUST ask before proceeding: -| 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 | +| Aspect | Question | Why | +| ---------- | ------------------------------------------ | ---------------------------------------- | +| Platform | iOS, Android, or both? | Affects navigation, gestures, typography | +| Framework | React Native, Flutter, or native? | Determines performance and patterns | +| Navigation | Tabs, stack, drawer? | Core UX architecture | +| Offline | Must it work offline? | Data & sync strategy | +| Devices | Phone only or tablet too? | Layout & density rules | +| Audience | Consumer, enterprise, accessibility needs? | Touch & readability | -> 🧠 **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!** +🚫 **Never default to your favorite stack or pattern.** --- -## ⚠️ CRITICAL: ASK BEFORE ASSUMING (MANDATORY) +## 3. Mandatory Reference Reading (Enforced) -> **STOP! If the user's request is open-ended, DO NOT default to your favorites.** +### Universal (Always Read First) -### You MUST Ask If Not Specified: +| File | Purpose | Status | +| ----------------------------- | ---------------------------------- | ----------------- | +| **mobile-design-thinking.md** | Anti-memorization, context-forcing | πŸ”΄ REQUIRED FIRST | +| **touch-psychology.md** | Fitts’ Law, thumb zones, gestures | πŸ”΄ REQUIRED | +| **mobile-performance.md** | 60fps, memory, battery | πŸ”΄ REQUIRED | +| **mobile-backend.md** | Offline sync, push, APIs | πŸ”΄ REQUIRED | +| **mobile-testing.md** | Device & E2E testing | πŸ”΄ REQUIRED | +| **mobile-debugging.md** | Native vs JS debugging | πŸ”΄ REQUIRED | -| 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 | +### Platform-Specific (Conditional) -### β›” AI MOBILE ANTI-PATTERNS (YASAK LΔ°STESΔ°) +| Platform | File | +| -------------- | ------------------- | +| iOS | platform-ios.md | +| Android | platform-android.md | +| Cross-platform | BOTH above | -> 🚫 **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 | +> ❌ If you haven’t read the platform file, you are not allowed to design UI. --- -## πŸ“± Platform Decision Matrix +## 4. AI Mobile Anti-Patterns (Hard Bans) -### When to Unify vs Diverge +### 🚫 Performance Sins (Non-Negotiable) -``` - 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 | +| ❌ Never | Why | βœ… Always | +| ------------------------- | -------------------- | --------------------------------------- | +| ScrollView for long lists | Memory explosion | FlatList / FlashList / ListView.builder | +| Inline renderItem | Re-renders all rows | useCallback + memo | +| Index as key | Reorder bugs | Stable ID | +| JS-thread animations | Jank | Native driver / GPU | +| console.log in prod | JS thread block | Strip logs | +| No memoization | Battery + perf drain | React.memo / const widgets | --- -## 🧠 Mobile UX Psychology (Quick Reference) +### 🚫 Touch & UX Sins -### 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) +| ❌ Never | Why | βœ… Always | +| --------------------- | -------------------- | ----------------- | +| Touch <44–48px | Miss taps | Min touch target | +| Gesture-only action | Excludes users | Button fallback | +| No loading state | Feels broken | Explicit feedback | +| No error recovery | Dead end | Retry + message | +| Ignore platform norms | Muscle memory broken | iOS β‰  Android | --- -## ⚑ Performance Principles (Quick Reference) +### 🚫 Security Sins -### React Native Critical Rules +| ❌ Never | Why | βœ… Always | +| ---------------------- | ------------------ | ---------------------- | +| Tokens in AsyncStorage | Easily stolen | SecureStore / Keychain | +| Hardcoded secrets | Reverse engineered | Env + secure storage | +| No SSL pinning | MITM risk | Cert pinning | +| Log sensitive data | PII leakage | Never log secrets | -```typescript -// βœ… CORRECT: Memoized renderItem + React.memo wrapper -const ListItem = React.memo(({ item }: { item: Item }) => ( - - {item.title} - +--- + +## 5. Platform Unification vs Divergence Matrix + +``` +UNIFY DIVERGE +────────────────────────── ───────────────────────── +Business logic Navigation behavior +Data models Gestures +API contracts Icons +Validation Typography +Error semantics Pickers / dialogs +``` + +### Platform Defaults + +| Element | iOS | Android | +| --------- | ------------ | -------------- | +| Font | SF Pro | Roboto | +| Min touch | 44pt | 48dp | +| Back | Edge swipe | System back | +| Sheets | Bottom sheet | Dialog / sheet | +| Icons | SF Symbols | Material Icons | + +--- + +## 6. Mobile UX Psychology (Non-Optional) + +### Fitts’ Law (Touch Reality) + +* Finger β‰  cursor +* Accuracy is low +* Reach matters more than precision + +**Rules:** + +* Primary CTAs live in **thumb zone** +* Destructive actions pushed away +* No hover assumptions + +--- + +## 7. Performance Doctrine + +### React Native (Required Pattern) + +```ts +const Row = React.memo(({ item }) => ( + {item.title} )); const renderItem = useCallback( - ({ item }: { item: Item }) => , + ({ item }) => , [] ); -// βœ… CORRECT: FlatList with all optimizations item.id} // Stable ID, NOT index - getItemLayout={(data, index) => ({ + keyExtractor={(i) => i.id} + getItemLayout={(_, i) => ({ length: ITEM_HEIGHT, - offset: ITEM_HEIGHT * index, - index, + offset: ITEM_HEIGHT * i, + index: i, })} - removeClippedSubviews={true} - maxToRenderPerBatch={10} - windowSize={5} /> ``` -### Flutter Critical Rules +### Flutter (Required Pattern) ```dart -// βœ… CORRECT: const constructors prevent rebuilds -class MyWidget extends StatelessWidget { - const MyWidget({super.key}); // CONST! +class Item extends StatelessWidget { + const Item({super.key}); @override Widget build(BuildContext context) { - return const Column( // CONST! - children: [ - Text('Static content'), - MyConstantWidget(), - ], - ); + return const Text('Static'); } } - -// βœ… 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) +* `const` everywhere possible +* Targeted rebuilds only --- -## πŸ“ CHECKPOINT (MANDATORY Before Any Mobile Work) +## 8. Mandatory Mobile Checkpoint -> **Before writing ANY mobile code, you MUST complete this checkpoint:** +Before writing **any code**, you must complete this: ``` -🧠 CHECKPOINT: +🧠 MOBILE CHECKPOINT -Platform: [ iOS / Android / Both ] -Framework: [ React Native / Flutter / SwiftUI / Kotlin ] -Files Read: [ List the skill files you've read ] +Platform: ___________ +Framework: ___________ +Files Read: ___________ 3 Principles I Will Apply: -1. _______________ -2. _______________ -3. _______________ +1. +2. +3. Anti-Patterns I Will Avoid: -1. _______________ -2. _______________ +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.** +❌ Cannot complete β†’ go back and read. --- -## πŸ”§ Framework Decision Tree +## 9. Framework Decision Tree (Canonical) ``` -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 +Need OTA + web team β†’ React Native + Expo +High-perf UI β†’ Flutter +iOS only β†’ SwiftUI +Android only β†’ Compose ``` -For complete decision trees: [decision-trees.md](decision-trees.md) +No debate without justification. --- -## πŸ“‹ Pre-Development Checklist +## 10. Release Readiness Checklist -### Before Starting ANY Mobile Project +### Before Shipping -- [ ] **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?** +* [ ] Touch targets β‰₯ 44–48px +* [ ] Offline handled +* [ ] Secure storage used +* [ ] Lists optimized +* [ ] Logs stripped +* [ ] Tested on low-end devices +* [ ] Accessibility labels present +* [ ] MFRI β‰₯ 3 --- -## πŸ“š Reference Files +## 11. Related Skills -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 | +* **frontend-design** – Visual systems & components +* **frontend-dev-guidelines** – RN/TS architecture +* **backend-dev-guidelines** – Mobile-safe APIs +* **error-tracking** – Crash & performance telemetry --- -> **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. +> **Final Law:** +> Mobile users are distracted, interrupted, and impatientβ€”often using one hand on a bad network with low battery. +> **Design for that reality, or your app will fail quietly.** + +---