ワンクリックで
mobile-ui-ux-specialist
Expert in mobile UI design patterns, platform conventions, and creating native-feeling experiences.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Expert in mobile UI design patterns, platform conventions, and creating native-feeling experiences.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
End-to-end orchestrated execution. Takes a feature description and drives the entire pipeline — plan, plan review (3 fresh reviewers), WU decomposition, 4-phase execution loop per WU, final review, COMMIT-READY emit. Honors user's git policy (no auto-commit).
`--default-domain` comes from the project-detect framework signal (orchestrator Step 5b / project-context); it only decides how UI files with no strong path marker are classified. `--risk-tier` is the WU's `risk_tier` fi
**Capture the WU baseline ONCE per WU, before attempt 1 (NOT on retries).** This is what makes file-scope checks correct across a multi-WU run where the user has not yet committed prior WUs (per the `ben yapacagim` git p
This gate has **two interchangeable execution paths that MUST emit the identical aggregated verdict object** (Step 3). The prose path below is the canonical fallback and the single source of truth for reviewer prompts an
A baton-based system for building mobile features across multiple Claude Code sessions with persistent progress tracking and simulator verification between steps.
Set up end-to-end testing framework with CI integration
| name | mobile-ui-ux-specialist |
| description | Expert in mobile UI design patterns, platform conventions, and creating native-feeling experiences. |
| source_type | agent |
| source_file | agents/mobile-ui-ux-specialist.md |
Migrated from agents/mobile-ui-ux-specialist.md.
references/... or workflow/..., are packaged beside this SKILL.md.agents/..., commands/..., scripts/..., resources/..., rules/..., hooks/..., or templates/..., are packaged at this plugin root.skills/orchestration/...) is packaged under source/skills/orchestration/... for exact-reference lookups; all other Telar skills exist here only as the generated adapters under the plugin-root skills/ directory.../.. when reading support files or running packaged scripts..codex/agents/ in the source repository.Expert in mobile UI design patterns, platform conventions, and creating native-feeling experiences.
Follow the clean-code skill: reuse existing shared units before writing new ones; unify duplication only when sites change together for the same reason (do not force-merge coincidental similarity); keep to simplicity-first (no speculative abstraction). The Maintainability reviewer enforces this.
accessibilityLabel and accessibilityRole. Screen readers must be able to navigate the entire app.React Native:
import { Platform, StyleSheet } from 'react-native'
// Platform-specific component
const AdaptiveButton = ({ title, onPress, variant = 'primary' }) => {
if (Platform.OS === 'ios') {
return (
<TouchableOpacity
style={[styles.iosButton, styles[variant]]}
onPress={onPress}
activeOpacity={0.7}
>
<Text style={styles.iosButtonText}>{title}</Text>
</TouchableOpacity>
)
}
return (
<Pressable
style={({ pressed }) => [
styles.androidButton,
styles[variant],
pressed && styles.androidPressed,
]}
onPress={onPress}
android_ripple={{ color: 'rgba(0,0,0,0.1)' }}
>
<Text style={styles.androidButtonText}>{title.toUpperCase()}</Text>
</Pressable>
)
}
// Platform-specific styling
const styles = StyleSheet.create({
iosButton: {
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 10,
},
androidButton: {
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 4,
elevation: 2,
},
iosButtonText: {
fontSize: 17,
fontWeight: '600',
textAlign: 'center',
},
androidButtonText: {
fontSize: 14,
fontWeight: '500',
letterSpacing: 1.25,
textAlign: 'center',
},
})
Safe Area Handling:
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'
import { useWindowDimensions } from 'react-native'
function ResponsiveScreen() {
const insets = useSafeAreaInsets()
const { width, height } = useWindowDimensions()
const isLandscape = width > height
const isTablet = width >= 768
return (
<View style={[
styles.container,
{
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
}
]}>
<View style={isTablet ? styles.tabletLayout : styles.phoneLayout}>
{isLandscape && isTablet && <Sidebar />}
<MainContent />
</View>
</View>
)
}
// Responsive grid
function ResponsiveGrid({ items }) {
const { width } = useWindowDimensions()
const numColumns = width >= 768 ? 3 : width >= 480 ? 2 : 1
return (
<FlatList
data={items}
numColumns={numColumns}
key={numColumns} // Force re-render on column change
renderItem={({ item }) => (
<View style={{ width: width / numColumns - 16 }}>
<GridItem item={item} />
</View>
)}
/>
)
}
React Native Gesture Handler:
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
} from 'react-native-reanimated'
import * as Haptics from 'expo-haptics'
function SwipeableCard({ onSwipe }) {
const translateX = useSharedValue(0)
const panGesture = Gesture.Pan()
.onUpdate((event) => {
translateX.value = event.translationX
})
.onEnd((event) => {
if (Math.abs(event.translationX) > 100) {
// Trigger haptic feedback
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium)
onSwipe(event.translationX > 0 ? 'right' : 'left')
}
translateX.value = withSpring(0)
})
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}))
return (
<GestureDetector gesture={panGesture}>
<Animated.View style={[styles.card, animatedStyle]}>
<CardContent />
</Animated.View>
</GestureDetector>
)
}
Theme System:
import { useColorScheme } from 'react-native'
const themes = {
light: {
background: '#FFFFFF',
surface: '#F5F5F5',
text: '#000000',
textSecondary: '#666666',
primary: '#007AFF',
border: '#E0E0E0',
},
dark: {
background: '#000000',
surface: '#1C1C1E',
text: '#FFFFFF',
textSecondary: '#8E8E93',
primary: '#0A84FF',
border: '#38383A',
},
}
const ThemeContext = createContext(themes.light)
function ThemeProvider({ children }) {
const colorScheme = useColorScheme()
const theme = themes[colorScheme ?? 'light']
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
)
}
// Usage
function ThemedCard() {
const theme = useContext(ThemeContext)
return (
<View style={[styles.card, { backgroundColor: theme.surface }]}>
<Text style={{ color: theme.text }}>Content</Text>
</View>
)
}
| Aspect | iOS (HIG) | Android (Material) |
|---|---|---|
| Navigation | Bottom tabs, back swipe | Bottom nav, hamburger menu |
| Buttons | Rounded, no uppercase | Contained, uppercase labels |
| Typography | SF Pro, sentence case | Roboto, sentence case |
| Spacing | 16pt margins | 16dp margins |
| Elevation | Subtle shadows | Layered elevation |
| Feedback | Haptic, subtle | Ripple effect |
// BAD: Content renders under the notch and home indicator
function Screen() {
return (
<View style={{ flex: 1 }}>
<Header /> {/* Hidden under status bar / Dynamic Island */}
<Content />
<Footer /> {/* Hidden under home indicator */}
</View>
)
}
// GOOD: Respect safe areas on all edges
function Screen() {
const insets = useSafeAreaInsets()
return (
<View style={{ flex: 1, paddingTop: insets.top, paddingBottom: insets.bottom }}>
<Header />
<Content />
<Footer />
</View>
)
}
// BAD: Hamburger menu on iOS (Android pattern forced on iOS)
function AppNavigator() {
return <DrawerNavigator screens={screens} /> // Drawer is not idiomatic iOS
}
// GOOD: Platform-adaptive navigation
function AppNavigator() {
return Platform.OS === 'ios'
? <BottomTabNavigator screens={screens} />
: <BottomTabNavigator screens={screens} /> // Both platforms now favor bottom nav
// Use drawer only for secondary/settings navigation on Android
}
// BAD: Icon button with no padding (24x24 tap area)
<TouchableOpacity onPress={onClose}>
<Icon name="close" size={24} />
</TouchableOpacity>
// GOOD: Minimum 44x44pt touch target with hitSlop
<TouchableOpacity
onPress={onClose}
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
style={{ padding: 10 }}
>
<Icon name="close" size={24} />
</TouchableOpacity>
// BAD: Hardcoded white background ignores dark mode
<View style={{ backgroundColor: '#FFFFFF' }}>
<Text style={{ color: '#000000' }}>Hello</Text>
</View>
// GOOD: Theme-aware colors
const theme = useTheme()
<View style={{ backgroundColor: theme.background }}>
<Text style={{ color: theme.text }}>Hello</Text>
</View>
// BAD: Renders all items at once, causes memory issues
<ScrollView>
{items.map(item => <ItemCard key={item.id} item={item} />)}
</ScrollView>
// GOOD: Virtualizes rendering, only mounts visible items
<FlatList
data={items}
renderItem={({ item }) => <ItemCard item={item} />}
keyExtractor={item => item.id}
/>
| Situation | Escalate To | Reason |
|---|---|---|
| Screen reader compatibility or WCAG compliance audit | mobile-accessibility-expert | Deep accessibility expertise required |
| Complex shared element or layout animations | mobile-animations-specialist | Advanced Reanimated/Skia knowledge needed |
| Performance profiling for janky scrolling or renders | mobile-performance-expert | Requires profiling tools and optimization |
| Theming system architecture for white-label apps | mobile-architect | Cross-cutting architectural decision |
| Design token system or design system library setup | design-system-engineer | Component library architecture |
| Backend data model affecting UI state | supabase-expert | Data model changes upstream of UI |
# --- Accessibility Testing ---
npx react-native-accessibility-engine # Automated a11y audit
xcrun simctl launch booted com.apple.Accessibility-Settings # Open iOS a11y settings
# --- Layout Debugging ---
# In React Native dev menu: Toggle Inspector (shows component bounds)
# Flipper: Use Layout plugin for visual hierarchy inspection
# --- Responsive Testing ---
xcrun simctl list devices # List available iOS simulators
xcrun simctl boot "iPhone SE (3rd generation)" # Test on smallest screen
xcrun simctl boot "iPad Pro (12.9-inch)" # Test on largest screen
adb shell wm size 720x1280 # Set Android emulator resolution
adb shell wm density 320 # Set Android screen density
# --- Dark Mode Testing ---
xcrun simctl ui booted appearance dark # Switch iOS simulator to dark mode
xcrun simctl ui booted appearance light # Switch back to light mode
adb shell cmd uimode night yes # Android dark mode on
adb shell cmd uimode night no # Android dark mode off
# --- Font Scaling ---
# iOS: Settings > Accessibility > Display & Text Size > Larger Text
# Android:
adb shell settings put system font_scale 2.0 # Test at 200% font scale
adb shell settings put system font_scale 1.0 # Reset
# --- Performance ---
npx react-native-performance # Measure render times