@ericrisco/rsc 3.3.1 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/manifest.json +43 -22
- package/package.json +1 -1
- package/scripts/lib/default-skill-floor.js +5 -1
- package/scripts/lib/domains.js +2 -2
- package/scripts/lib/retired-skills.js +4 -0
- package/skills/design/SKILL.md +4 -3
- package/skills/design/evals/cases.yaml +2 -2
- package/skills/react/SKILL.md +2 -1
- package/skills/ux/SKILL.md +149 -0
- package/skills/ux/THIRD_PARTY.md +32 -0
- package/skills/ux/evals/cases.yaml +40 -0
- package/skills/ux/references/flows.md +124 -0
- package/skills/ux/upstream/UPSTREAM.json +59 -0
- package/skills/ux/upstream/ux-designer/GUIDE.md +180 -0
- package/skills/ux/upstream/ux-designer/LICENSE +21 -0
- package/skills/ux/upstream/ux-designer/references/01-core-principles.md +251 -0
- package/skills/ux/upstream/ux-designer/references/02-laws-of-ux.md +330 -0
- package/skills/ux/upstream/ux-designer/references/03-accessibility.md +411 -0
- package/skills/ux/upstream/ux-designer/references/04-visual-design.md +433 -0
- package/skills/ux/upstream/ux-designer/references/05-information-architecture.md +432 -0
- package/skills/ux/upstream/ux-designer/references/06-interaction-design.md +495 -0
- package/skills/ux/upstream/ux-designer/references/07-forms-and-inputs.md +491 -0
- package/skills/ux/upstream/ux-designer/references/08-mobile-ux.md +539 -0
- package/skills/ux/upstream/ux-designer/references/09-ux-writing.md +493 -0
- package/skills/ux/upstream/ux-designer/references/10-user-research.md +533 -0
- package/skills/ux/upstream/ux-designer/references/11-design-systems.md +618 -0
- package/skills/ux/upstream/ux-designer/references/12a-presence-awareness.md +395 -0
- package/skills/ux/upstream/ux-designer/references/12b-conflict-resolution-sync.md +420 -0
- package/skills/ux/upstream/ux-designer/references/13a-canvas-navigation.md +388 -0
- package/skills/ux/upstream/ux-designer/references/13b-canvas-objects-performance.md +559 -0
- package/skills/ux/upstream/ux-designer/references/14-ai-ux-patterns.md +511 -0
- package/skills/ux/upstream/ux-designer/references/15-ethical-design.md +419 -0
- package/skills/ux/upstream/ux-designer/references/16-onboarding.md +430 -0
- package/skills/ux/upstream/ux-designer/references/17-notifications.md +461 -0
- package/skills/ux/upstream/ux-designer/references/18-data-visualization.md +453 -0
- package/skills/ux/upstream/ux-designer/references/19-search-ux.md +479 -0
- package/skills/ux/upstream/ux-designer/references/20-emotional-design.md +382 -0
- package/skills/ux/upstream/ux-designer/references/21-data-tables.md +629 -0
- package/skills/ux/upstream/ux-designer/references/22-performance-ux.md +626 -0
- package/skills/ux/upstream/ux-designer/references/23-internationalization.md +347 -0
- package/skills/ux/upstream/ux-designer/references/24-voice-and-multimodal.md +308 -0
- package/skills/ux/upstream/ux-designer/references/25a-barcode-camera-scanning.md +342 -0
- package/skills/ux/upstream/ux-designer/references/25b-barcode-scanner-workflows.md +412 -0
- package/skills/ux/upstream/ux-designer/references/25c-barcode-display.md +277 -0
- package/skills/ux/upstream/ux-usability-foundations/GUIDE.md +285 -0
- package/skills/ux/upstream/ux-usability-foundations/LICENSE +21 -0
- package/skills/ux/upstream/ux-usability-foundations/references/anti-patterns.md +267 -0
- package/skills/ux/upstream/ux-usability-foundations/references/checklists.md +130 -0
- package/skills/ux/upstream/ux-usability-foundations/references/decision-prompts.md +340 -0
- package/skills/ux/upstream/ux-usability-foundations/references/principle-cards.md +449 -0
- package/targets/clone-bootstrap.mjs +1 -1
- package/skills/ui-engineering/SKILL.md +0 -113
- package/skills/ui-engineering/evals/cases.yaml +0 -38
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
# Mobile UX Design
|
|
2
|
+
|
|
3
|
+
Mobile-first design is essential in 2026, with over 60% of web traffic coming from mobile devices.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- The Thumb Zone
|
|
10
|
+
- Touch Target Sizes
|
|
11
|
+
- Mobile Navigation Patterns
|
|
12
|
+
- Responsive Gestures
|
|
13
|
+
- Mobile Forms
|
|
14
|
+
- Performance on Mobile
|
|
15
|
+
- Touch Feedback
|
|
16
|
+
- Safe Areas
|
|
17
|
+
- Orientation and Adaptation
|
|
18
|
+
- Common Mobile Mistakes
|
|
19
|
+
- Testing Checklist
|
|
20
|
+
- Sources
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## The Thumb Zone
|
|
25
|
+
|
|
26
|
+
### Understanding Thumb Reach
|
|
27
|
+
|
|
28
|
+
Coined by mobile UX expert Steven Hoober, the Thumb Zone defines how users interact with phones using one hand.
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
┌─────────────────────────────┐
|
|
32
|
+
│ HARD │ HARD │ ← Top corners: Avoid CTAs
|
|
33
|
+
│ │ │
|
|
34
|
+
├────────────┼───────────────┤
|
|
35
|
+
│ │ │
|
|
36
|
+
│ STRETCH │ STRETCH │ ← Middle: Secondary actions
|
|
37
|
+
│ │ │
|
|
38
|
+
├────────────┼───────────────┤
|
|
39
|
+
│ │ │
|
|
40
|
+
│ EASY │ EASY │ ← Bottom: Primary actions
|
|
41
|
+
│ │ │
|
|
42
|
+
└─────────────────────────────┘
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Zone Definitions
|
|
46
|
+
|
|
47
|
+
| Zone | Location | Usage |
|
|
48
|
+
|------|----------|-------|
|
|
49
|
+
| **Easy** | Bottom center/left | Primary actions, frequent navigation |
|
|
50
|
+
| **Stretch** | Middle, far left/right | Secondary actions |
|
|
51
|
+
| **Hard** | Top corners | Rarely used actions |
|
|
52
|
+
|
|
53
|
+
### Modern Device Considerations
|
|
54
|
+
|
|
55
|
+
- Screen sizes exceed 6.5 inches
|
|
56
|
+
- One-handed use dominates
|
|
57
|
+
- Bottom navigation 20-30% faster than top
|
|
58
|
+
- Foldable devices require flexible layouts
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Touch Target Sizes
|
|
63
|
+
|
|
64
|
+
### Platform Guidelines
|
|
65
|
+
|
|
66
|
+
| Platform | Minimum Size | Recommended |
|
|
67
|
+
|----------|--------------|-------------|
|
|
68
|
+
| Apple iOS | 44×44pt | 44-48pt |
|
|
69
|
+
| Material Design | 48×48dp | 48dp |
|
|
70
|
+
| WCAG 2.2 | 24×24px | 44×44px |
|
|
71
|
+
|
|
72
|
+
### Implementation
|
|
73
|
+
|
|
74
|
+
```css
|
|
75
|
+
/* Touch-friendly buttons */
|
|
76
|
+
.button {
|
|
77
|
+
min-width: 44px;
|
|
78
|
+
min-height: 44px;
|
|
79
|
+
padding: 12px 24px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Tap target expansion for small visual elements */
|
|
83
|
+
.small-icon {
|
|
84
|
+
position: relative;
|
|
85
|
+
width: 24px;
|
|
86
|
+
height: 24px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.small-icon::before {
|
|
90
|
+
content: '';
|
|
91
|
+
position: absolute;
|
|
92
|
+
top: -10px;
|
|
93
|
+
left: -10px;
|
|
94
|
+
right: -10px;
|
|
95
|
+
bottom: -10px;
|
|
96
|
+
/* Invisible but tappable */
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Adequate spacing between targets */
|
|
100
|
+
.button-group .button + .button {
|
|
101
|
+
margin-left: 8px; /* Minimum 8px */
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Touch vs. Click Considerations
|
|
106
|
+
|
|
107
|
+
```css
|
|
108
|
+
/* Remove touch delay on mobile */
|
|
109
|
+
touch-action: manipulation;
|
|
110
|
+
|
|
111
|
+
/* Prevent accidental double-tap zoom */
|
|
112
|
+
html {
|
|
113
|
+
touch-action: manipulation;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Mobile Navigation Patterns
|
|
120
|
+
|
|
121
|
+
### Bottom Navigation Bar
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<nav class="bottom-nav" role="navigation">
|
|
125
|
+
<a href="/" class="nav-item active">
|
|
126
|
+
<span class="icon">🏠</span>
|
|
127
|
+
<span class="label">Home</span>
|
|
128
|
+
</a>
|
|
129
|
+
<a href="/search" class="nav-item">
|
|
130
|
+
<span class="icon">🔍</span>
|
|
131
|
+
<span class="label">Search</span>
|
|
132
|
+
</a>
|
|
133
|
+
<a href="/add" class="nav-item">
|
|
134
|
+
<span class="icon">➕</span>
|
|
135
|
+
<span class="label">Add</span>
|
|
136
|
+
</a>
|
|
137
|
+
<a href="/saved" class="nav-item">
|
|
138
|
+
<span class="icon">❤️</span>
|
|
139
|
+
<span class="label">Saved</span>
|
|
140
|
+
</a>
|
|
141
|
+
<a href="/profile" class="nav-item">
|
|
142
|
+
<span class="icon">👤</span>
|
|
143
|
+
<span class="label">Profile</span>
|
|
144
|
+
</a>
|
|
145
|
+
</nav>
|
|
146
|
+
|
|
147
|
+
<style>
|
|
148
|
+
.bottom-nav {
|
|
149
|
+
position: fixed;
|
|
150
|
+
bottom: 0;
|
|
151
|
+
left: 0;
|
|
152
|
+
right: 0;
|
|
153
|
+
display: flex;
|
|
154
|
+
justify-content: space-around;
|
|
155
|
+
background: white;
|
|
156
|
+
padding: 8px 0;
|
|
157
|
+
padding-bottom: env(safe-area-inset-bottom); /* iPhone notch */
|
|
158
|
+
box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.nav-item {
|
|
162
|
+
display: flex;
|
|
163
|
+
flex-direction: column;
|
|
164
|
+
align-items: center;
|
|
165
|
+
min-width: 64px;
|
|
166
|
+
padding: 8px;
|
|
167
|
+
}
|
|
168
|
+
</style>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Best Practices:**
|
|
172
|
+
- 3-5 items maximum
|
|
173
|
+
- Icons with labels (not icons alone)
|
|
174
|
+
- Clear active state
|
|
175
|
+
- Thumb-reachable position
|
|
176
|
+
- Consider safe areas for notched devices
|
|
177
|
+
|
|
178
|
+
### Hamburger Menu
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<button class="menu-toggle" aria-expanded="false" aria-controls="menu">
|
|
182
|
+
<span class="sr-only">Menu</span>
|
|
183
|
+
<span class="hamburger-icon"></span>
|
|
184
|
+
</button>
|
|
185
|
+
|
|
186
|
+
<nav id="menu" class="slide-menu" aria-hidden="true">
|
|
187
|
+
<!-- Menu content -->
|
|
188
|
+
</nav>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**When to Use:**
|
|
192
|
+
- Many navigation items (6+)
|
|
193
|
+
- Secondary/utility navigation
|
|
194
|
+
- Space-constrained headers
|
|
195
|
+
|
|
196
|
+
**When to Avoid:**
|
|
197
|
+
- Primary navigation (use bottom bar)
|
|
198
|
+
- When discoverability is crucial
|
|
199
|
+
- E-commerce main categories
|
|
200
|
+
|
|
201
|
+
### Floating Action Button (FAB)
|
|
202
|
+
|
|
203
|
+
```css
|
|
204
|
+
.fab {
|
|
205
|
+
position: fixed;
|
|
206
|
+
bottom: 80px; /* Above bottom nav */
|
|
207
|
+
right: 16px;
|
|
208
|
+
width: 56px;
|
|
209
|
+
height: 56px;
|
|
210
|
+
border-radius: 50%;
|
|
211
|
+
background: var(--accent);
|
|
212
|
+
color: white;
|
|
213
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
|
|
214
|
+
display: flex;
|
|
215
|
+
align-items: center;
|
|
216
|
+
justify-content: center;
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Use For:**
|
|
221
|
+
- Single primary action (create, compose, add)
|
|
222
|
+
- Actions available on every screen
|
|
223
|
+
- Thumb-friendly access
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Responsive Gestures
|
|
228
|
+
|
|
229
|
+
### Standard Mobile Gestures
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
Tap → Select, activate
|
|
233
|
+
Double tap → Zoom, like
|
|
234
|
+
Long press → Context menu, drag start
|
|
235
|
+
Swipe → Navigate, dismiss, reveal actions
|
|
236
|
+
Pinch → Zoom in/out
|
|
237
|
+
Pull down → Refresh
|
|
238
|
+
Edge swipe → Back navigation
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Swipe Actions
|
|
242
|
+
|
|
243
|
+
```html
|
|
244
|
+
<!-- Swipe-to-reveal actions -->
|
|
245
|
+
<div class="list-item swipeable">
|
|
246
|
+
<div class="content">Item content</div>
|
|
247
|
+
<div class="actions hidden">
|
|
248
|
+
<button class="action-edit">Edit</button>
|
|
249
|
+
<button class="action-delete">Delete</button>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<!-- Always provide alternatives (WCAG 2.5.7) -->
|
|
254
|
+
<button class="action-menu">•••</button>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Pull-to-Refresh
|
|
258
|
+
|
|
259
|
+
```css
|
|
260
|
+
.pull-indicator {
|
|
261
|
+
height: 0;
|
|
262
|
+
transition: height 200ms;
|
|
263
|
+
overflow: hidden;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.pulling .pull-indicator {
|
|
267
|
+
height: 60px;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.refreshing .pull-indicator .spinner {
|
|
271
|
+
animation: spin 1s linear infinite;
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Mobile Forms
|
|
278
|
+
|
|
279
|
+
### Keyboard Optimization
|
|
280
|
+
|
|
281
|
+
```html
|
|
282
|
+
<!-- Appropriate keyboard types -->
|
|
283
|
+
<input type="email" inputmode="email" />
|
|
284
|
+
<input type="tel" inputmode="tel" />
|
|
285
|
+
<input type="number" inputmode="decimal" />
|
|
286
|
+
<input type="text" inputmode="numeric" pattern="[0-9]*" />
|
|
287
|
+
|
|
288
|
+
<!-- Prevent zoom on focus (iOS) -->
|
|
289
|
+
<input type="text" style="font-size: 16px;" />
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Form Layout
|
|
293
|
+
|
|
294
|
+
```css
|
|
295
|
+
/* Stack labels above inputs */
|
|
296
|
+
.form-field {
|
|
297
|
+
display: flex;
|
|
298
|
+
flex-direction: column;
|
|
299
|
+
margin-bottom: 16px;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* Full-width inputs */
|
|
303
|
+
.form-field input {
|
|
304
|
+
width: 100%;
|
|
305
|
+
padding: 12px;
|
|
306
|
+
font-size: 16px; /* Prevent zoom */
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* Sticky submit button */
|
|
310
|
+
.submit-area {
|
|
311
|
+
position: sticky;
|
|
312
|
+
bottom: 0;
|
|
313
|
+
background: white;
|
|
314
|
+
padding: 16px;
|
|
315
|
+
padding-bottom: calc(16px + env(safe-area-inset-bottom));
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Mobile-Specific Patterns
|
|
320
|
+
|
|
321
|
+
```html
|
|
322
|
+
<!-- Date picker alternatives -->
|
|
323
|
+
<select name="month">
|
|
324
|
+
<option>January</option>
|
|
325
|
+
<!-- ... -->
|
|
326
|
+
</select>
|
|
327
|
+
|
|
328
|
+
<!-- Stepper for quantities -->
|
|
329
|
+
<div class="stepper">
|
|
330
|
+
<button>−</button>
|
|
331
|
+
<input type="number" value="1" />
|
|
332
|
+
<button>+</button>
|
|
333
|
+
</div>
|
|
334
|
+
|
|
335
|
+
<!-- Toggle instead of checkbox -->
|
|
336
|
+
<label class="toggle">
|
|
337
|
+
<input type="checkbox" />
|
|
338
|
+
<span class="toggle-slider"></span>
|
|
339
|
+
Enable notifications
|
|
340
|
+
</label>
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Performance on Mobile
|
|
346
|
+
|
|
347
|
+
### Key Metrics
|
|
348
|
+
|
|
349
|
+
| Metric | Target | Impact |
|
|
350
|
+
|--------|--------|--------|
|
|
351
|
+
| First Contentful Paint | < 1.8s | User perceives loading |
|
|
352
|
+
| Largest Contentful Paint | < 2.5s | Main content visible |
|
|
353
|
+
| Time to Interactive | < 3.8s | Users can interact |
|
|
354
|
+
| Cumulative Layout Shift | < 0.1 | Visual stability |
|
|
355
|
+
|
|
356
|
+
### Mobile Performance Tips
|
|
357
|
+
|
|
358
|
+
```html
|
|
359
|
+
<!-- Lazy load images -->
|
|
360
|
+
<img loading="lazy" src="image.jpg" alt="" />
|
|
361
|
+
|
|
362
|
+
<!-- Preload critical resources -->
|
|
363
|
+
<link rel="preload" href="font.woff2" as="font" crossorigin />
|
|
364
|
+
|
|
365
|
+
<!-- Reduce JavaScript -->
|
|
366
|
+
<script defer src="app.js"></script>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
```css
|
|
370
|
+
/* Optimize animations */
|
|
371
|
+
.animated {
|
|
372
|
+
transform: translateZ(0);
|
|
373
|
+
will-change: transform;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* Reduce motion for performance/preference */
|
|
377
|
+
@media (prefers-reduced-motion: reduce) {
|
|
378
|
+
* {
|
|
379
|
+
animation: none !important;
|
|
380
|
+
transition: none !important;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Touch Feedback
|
|
388
|
+
|
|
389
|
+
### Response Time
|
|
390
|
+
|
|
391
|
+
- **< 100ms** - Perceived as instant
|
|
392
|
+
- **100-300ms** - Noticeable but acceptable
|
|
393
|
+
- **> 300ms** - Feels sluggish
|
|
394
|
+
|
|
395
|
+
### Visual Feedback
|
|
396
|
+
|
|
397
|
+
```css
|
|
398
|
+
/* Touch feedback */
|
|
399
|
+
.button:active {
|
|
400
|
+
transform: scale(0.98);
|
|
401
|
+
opacity: 0.9;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/* Ripple effect (Material) */
|
|
405
|
+
.ripple {
|
|
406
|
+
position: relative;
|
|
407
|
+
overflow: hidden;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.ripple::after {
|
|
411
|
+
content: '';
|
|
412
|
+
position: absolute;
|
|
413
|
+
background: rgba(255,255,255,0.3);
|
|
414
|
+
border-radius: 50%;
|
|
415
|
+
transform: scale(0);
|
|
416
|
+
animation: ripple 0.6s linear;
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Haptic Feedback
|
|
421
|
+
|
|
422
|
+
```javascript
|
|
423
|
+
// Simple vibration
|
|
424
|
+
if ('vibrate' in navigator) {
|
|
425
|
+
navigator.vibrate(10); // Light tap
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Success pattern
|
|
429
|
+
navigator.vibrate([10, 50, 10]);
|
|
430
|
+
|
|
431
|
+
// Error pattern
|
|
432
|
+
navigator.vibrate([50, 50, 50]);
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
## Safe Areas
|
|
438
|
+
|
|
439
|
+
### Handling Device Notches
|
|
440
|
+
|
|
441
|
+
```css
|
|
442
|
+
/* iPhone notch and home indicator */
|
|
443
|
+
.container {
|
|
444
|
+
padding-left: env(safe-area-inset-left);
|
|
445
|
+
padding-right: env(safe-area-inset-right);
|
|
446
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* Fixed bottom elements */
|
|
450
|
+
.bottom-bar {
|
|
451
|
+
padding-bottom: calc(16px + env(safe-area-inset-bottom));
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/* Enable safe area support */
|
|
455
|
+
<meta name="viewport" content="viewport-fit=cover" />
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Orientation and Adaptation
|
|
461
|
+
|
|
462
|
+
### Responsive Layouts
|
|
463
|
+
|
|
464
|
+
```css
|
|
465
|
+
/* Portrait (default) */
|
|
466
|
+
.container {
|
|
467
|
+
flex-direction: column;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/* Landscape */
|
|
471
|
+
@media (orientation: landscape) {
|
|
472
|
+
.container {
|
|
473
|
+
flex-direction: row;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/* Hide bottom nav, show sidebar */
|
|
477
|
+
.bottom-nav {
|
|
478
|
+
display: none;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.sidebar-nav {
|
|
482
|
+
display: block;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Foldable Devices
|
|
488
|
+
|
|
489
|
+
```css
|
|
490
|
+
/* Detect foldable screen */
|
|
491
|
+
@media (horizontal-viewport-segments: 2) {
|
|
492
|
+
/* Dual-screen layout */
|
|
493
|
+
.main {
|
|
494
|
+
display: grid;
|
|
495
|
+
grid-template-columns: 1fr 1fr;
|
|
496
|
+
gap: env(viewport-segment-width 0 0);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Common Mobile Mistakes
|
|
504
|
+
|
|
505
|
+
1. **Touch targets too small** - Use 44px minimum
|
|
506
|
+
2. **Important actions at top** - Place in thumb zone
|
|
507
|
+
3. **Too much content** - Prioritize ruthlessly
|
|
508
|
+
4. **Desktop forms on mobile** - Optimize for touch
|
|
509
|
+
5. **Ignoring safe areas** - Content hidden by notches
|
|
510
|
+
6. **No offline support** - Users lose connectivity
|
|
511
|
+
7. **Heavy animations** - Drains battery, causes jank
|
|
512
|
+
8. **Zoom disabled** - Accessibility violation
|
|
513
|
+
9. **Horizontal scrolling** - Confusing navigation
|
|
514
|
+
10. **Pop-ups covering content** - Interstitials annoy users
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Testing Checklist
|
|
519
|
+
|
|
520
|
+
- [ ] Test on real devices (not just simulators)
|
|
521
|
+
- [ ] Check various screen sizes
|
|
522
|
+
- [ ] Test in portrait and landscape
|
|
523
|
+
- [ ] Verify touch targets are large enough
|
|
524
|
+
- [ ] Test with slow network (3G)
|
|
525
|
+
- [ ] Check offline behavior
|
|
526
|
+
- [ ] Verify safe area handling
|
|
527
|
+
- [ ] Test form keyboard interaction
|
|
528
|
+
- [ ] Check gesture conflicts
|
|
529
|
+
- [ ] Verify haptic feedback works
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## Sources
|
|
534
|
+
|
|
535
|
+
- [Material Design - Mobile Guidelines](https://m3.material.io/)
|
|
536
|
+
- [Apple HIG - iOS](https://developer.apple.com/design/human-interface-guidelines/)
|
|
537
|
+
- [Nielsen Norman - Mobile UX](https://www.nngroup.com/topic/mobile-usability/)
|
|
538
|
+
- Hoober, S. (2017). "Touch Bigger"
|
|
539
|
+
- [Google Web Fundamentals - Mobile](https://developers.google.com/web/fundamentals)
|