mobile-ui · git:20261029.1aa6bef · 2026-10-29 · sha256 6250bdd590bd45b7
mobile-ui git:20261029.1aa6befA
Immutable. This exact content never changes and is served at /api/v1/blob/6250bdd590bd45b7.
---
description: Native mobile UI/UX craftsmanship, kinetic motion, and tactile engineering skill for iOS (SwiftUI/HIG 18/19), Android (Material 3 Expressive/Jetpack Compose), React Native, and Flutter.
globs: *
alwaysApply: false
---
# Mobile UI/UX Craftsmanship & Native Engineering
The `mobile-ui` skill enforces ultra-premium craftsmanship across native iOS, Android, and cross-platform mobile applications. It replaces stiff layouts and generic web-wrapped interfaces with fluid spring physics, continuous spatial layout morphing, tactile haptics, and strict touch ergonomics.
---
## 1. Quick Navigation & Progressive Disclosure
| Resource Type | Document | Description |
| :--- | :--- | :--- |
| **Reference** | [references/apple-hig-and-material3.md](references/apple-hig-and-material3.md) | Apple HIG 44pt touch targets, Material 3 48dp metrics, dynamic type, safe areas. |
| **Reference** | [references/native-motion-and-gestures.md](references/native-motion-and-gestures.md) | Damped spring physics, matchedGeometryEffect, tactile haptic feedback levels. |
| **Utility** | [scripts/verify_mobile_ui_hygiene.py](scripts/verify_mobile_ui_hygiene.py) | Audits mobile code for missing safe area wrappers, hardcoded touch target violations, and linear animations. |
---
## 2. Apple iOS 18/19 HIG & SwiftUI Craftsmanship
### Spatial Layout Morphing (`matchedGeometryEffect`)
Eliminate jarring navigation pushes and abrupt modal takeovers. Coordinate seamless geometry morphs between compact card surfaces and fullscreen viewports:
```swift
struct FeedCardView: View {
let item: FeedItem
var namespace: Namespace.ID
@Binding var selectedID: String?
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Image(item.heroImage)
.matchedGeometryEffect(id: "image_\(item.id)", in: namespace)
.frame(maxWidth: .infinity, maxHeight: 240)
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
Text(item.title)
.matchedGeometryEffect(id: "title_\(item.id)", in: namespace)
.font(.system(.headline, design: .rounded))
}
.padding(16)
.background(.ultraThinMaterial)
.clipShape(RoundedRectangle(cornerRadius: 24, style: .continuous))
.overlay(
RoundedRectangle(cornerRadius: 24, style: .continuous)
.stroke(Color.white.opacity(0.12), lineWidth: 1) // 1px specular top highlight
)
}
}
```
### Apple Harmonic Spring Physics
Prohibit linear ease-in/ease-out curves. Calibrate physical mass-spring-damper parameters:
- **Default Interactive Springs**: `response: 0.32s`, `dampingFraction: 0.72`, `blendDuration: 0s`.
- **Bouncy Confirmation Pop**: `response: 0.28s`, `dampingFraction: 0.64`.
- **Smooth Sheet Retract**: `response: 0.42s`, `dampingFraction: 0.82`.
### Cupertino Materials & Specular Lighting
- Layer translucency using `.background(.ultraThinMaterial)`.
- Enforce continuous Apple squircles: `RoundedRectangle(cornerRadius: 24, style: .continuous)`.
- Apply a single-zenith top specular hairline: 1px border with `Color.white.opacity(0.12)` in dark mode to simulate physical Fresnel reflection.
### Sensory & Tactile Cues (Haptics)
- **State Toggles & Card Expansion**:
```swift
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.prepare()
generator.impactOccurred()
```
- **Discrete Rotary Detents**: Enforce `CoreHaptics` (`CHHapticEngine`) or `UISelectionFeedbackGenerator` on drag thresholds and wheel scrubbing.
---
## 2. Android Material 3 Expressive & Jetpack Compose
### Lookahead Bounds Mapping (`SharedTransitionLayout`)
Leverage Compose's `LookaheadScope` to compute destination bounds ahead of time, decoupling measurement from drawing to guarantee zero dropped frames:
```kotlin
@Composable
fun SharedElementFeedCard(
item: FeedItem,
sharedTransitionScope: SharedTransitionScope,
animatedVisibilityScope: AnimatedVisibilityScope
) {
with(sharedTransitionScope) {
Surface(
shape = RoundedCornerShape(24.dp),
tonalElevation = 2.dp,
modifier = Modifier
.sharedBounds(
rememberSharedContentState(key = "card_${item.id}"),
animatedVisibilityScope = animatedVisibilityScope,
boundsTransform = { _, _ ->
spring(
dampingFraction = 0.78f,
stiffness = Spring.StiffnessMediumLow
)
}
)
) {
// Card Content
}
}
}
```
### Predictive Back Gesture Navigation
Support Android 14+ Predictive Back with real-time gesture feedback:
```kotlin
PredictiveBackHandler { progress ->
try {
progress.collect { backEvent ->
// Interpolate scale down to 0.92f and soften alpha during gesture progress
val scale = lerp(1f, 0.92f, backEvent.progress)
val cornerRadius = lerp(0.dp, 32.dp, backEvent.progress)
currentSheetScale = scale
currentSheetCorners = cornerRadius
}
navigator.popBackStack()
} catch (e: CancellationException) {
// User aborted swipe: spring back smoothly to 1.0f
resetSheetPhysics()
}
}
```
### Edge-to-Edge System Inset Geometry
Enforce seamless edge-to-edge drawing:
- Bind window insets via `WindowInsets.systemBars.asPaddingValues()`.
- Dynamically absorb virtual keyboards using `Modifier.imePadding()`.
---
## 3. Kinetic Typography & Touch Ergonomics
### Kinetic Variable Fonts & Tabular Numerals
- Variable axes (`wght`, `opsz`, `wdth`): Dynamically interpolate font weight (`wght` 300 $\rightarrow$ 700) during touch drag or pull-to-refresh.
- Tabular figures (`tnum`, `zero`): Always format numerical counters, stock tickers, and stopwatch readouts with monospaced numbers to eliminate horizontal layout jitter.
### Touch Target & Ergonomics Matrix
- **iOS Minimum**: `44x44 pt` interactive touch bounds.
- **Android Minimum**: `48x48 dp` interactive touch bounds.
- **Thumb Zone Distribution**: Place primary interactive triggers (tabs, primary action buttons, FABs) within the bottom 60% of the display viewport.
- **Anti-Trap Guardrail**: Strictly prohibit hardcoded viewport widths (`width: 375`, `width: 414px`). Always anchor layouts to relative safe areas and dynamic flex/grid constraints.
---
## 4. Cross-Platform Guidelines (React Native & Flutter)
### React Native / Expo
- Execute all touch-driven spring gestures on the UI thread via `react-native-reanimated` worklets (`withSpring({ damping: 15, stiffness: 120 })`) and `react-native-gesture-handler`.
- Always wrap screen roots in `<SafeAreaProvider>` and `<SafeAreaView edges={['top', 'bottom']}>`.
### Flutter
- Guarantee 120Hz compositor stability on the **Impeller** rendering engine.
- Implement `Hero` widgets using `MaterialRectArcTween` for natural curved flight paths.
- Bind haptics via `HapticFeedback.lightImpact()` on drag thresholds and sheet snap points.