Agent Skill
2/7/2026

ios-native-expert

MANDATORY: Enforces iOS 26 native design compliance including Liquid Glass, PlatformColor for all system colors, centralized theming via useTheme()/useThemeColors(), SF Symbols, haptic feedback, contentInsetAdjustmentBehavior on all scroll views, and native navigation headers. Use this skill whenever touching any file in /mobile. Every iOS component MUST comply -- violations MUST be reported and fixed immediately. NEVER modifies web code or Android-only implementations. Reference docs: docs/IOS_26_IMPLEMENTATION_GUIDE.md

A
armanisadeghi
0GitHub Stars
2Views
npx skills add armanisadeghi/real-singles

SKILL.md

Nameios-native-expert
DescriptionMANDATORY: Enforces iOS 26 native design compliance including Liquid Glass, PlatformColor for all system colors, centralized theming via useTheme()/useThemeColors(), SF Symbols, haptic feedback, contentInsetAdjustmentBehavior on all scroll views, and native navigation headers. Use this skill whenever touching any file in /mobile. Every iOS component MUST comply -- violations MUST be reported and fixed immediately. NEVER modifies web code or Android-only implementations. Reference docs: docs/IOS_26_IMPLEMENTATION_GUIDE.md

name: ios-native-expert description: "MANDATORY: Enforces iOS 26 native design compliance including Liquid Glass, PlatformColor for all system colors, centralized theming via useTheme()/useThemeColors(), SF Symbols, haptic feedback, contentInsetAdjustmentBehavior on all scroll views, and native navigation headers. Use this skill whenever touching any file in /mobile. Every iOS component MUST comply -- violations MUST be reported and fixed immediately. NEVER modifies web code or Android-only implementations. Reference docs: docs/IOS_26_IMPLEMENTATION_GUIDE.md"

iOS Native Expert -- MANDATORY COMPLIANCE

Your job: Enforce total iOS 26 native design compliance across the entire mobile app. These rules are NOT optional. They are REQUIRED for every component, every screen, every PR.

If you identify ANY component or page that violates these rules, you are RESPONSIBLE for reporting it and fixing it.


REFERENCE DOCUMENTATION

Before making changes, search and read these files for detailed patterns and API references:

DocumentPathContains
Implementation Guidedocs/IOS_26_IMPLEMENTATION_GUIDE.mdComplete component-by-component patterns, library decisions, migration checklist, known issues
API Reference.cursor/skills/ios-native-expert/reference.mdQuick-reference for PlatformColor names, expo-glass-effect API, expo-symbols API, haptics API, spring presets, HIG sizing
Design Researchdocs/IOS_26_DESIGN_RESEARCH.mdLiquid Glass design properties, visual tokens, community-derived values
Native Researchdocs/IOS_26_NATIVE_RESEARCH.mdUI patterns research, library comparisons, common patterns

When in doubt, search these docs first. Run: Search for "GlassView" in docs/IOS_26_IMPLEMENTATION_GUIDE.md


MANDATORY RULES -- ZERO EXCEPTIONS

Rule 1: NO Hardcoded Hex Colors for System UI

Every background, text color, separator, and fill that corresponds to a system semantic color MUST use PlatformColor() on iOS or useThemeColors() from context.

// VIOLATION -- hardcoded colors don't adapt to light/dark/glass/high-contrast
backgroundColor: '#FFFFFF'
color: '#000000'
borderColor: '#E5E5EA'
backgroundColor: isDark ? '#1C1C1E' : '#FFFFFF'

// CORRECT -- use PlatformColor on iOS, theme colors on Android
backgroundColor: Platform.OS === 'ios'
  ? PlatformColor('systemBackground')
  : colors.background
color: Platform.OS === 'ios'
  ? PlatformColor('label')
  : colors.onSurface
borderColor: Platform.OS === 'ios'
  ? PlatformColor('separator')
  : colors.outline

The ONLY exceptions are brand colors (#B06D1E, #FFBA70, #E91E63, #FFFAF2) which should use DynamicColorIOS for light/dark adaptation.

Color mapping reference:

HardcodedReplace With
#FFFFFF, whitePlatformColor('systemBackground')
#F2F2F7, #F5F5F5, #FAFAFAPlatformColor('secondarySystemBackground')
#000000, #333333, #1A1A1APlatformColor('label')
#666666, #8E8E93, #6B7280PlatformColor('secondaryLabel')
#9CA3AF, #AEAEB2PlatformColor('tertiaryLabel')
#E5E5EA, #D1D1D6, #E0E0E0PlatformColor('separator')
#C6C6C8, #38383APlatformColor('opaqueSeparator')
#1C1C1E, #2C2C2EPlatformColor('secondarySystemBackground') or PlatformColor('tertiarySystemBackground')
#3A3A3CPlatformColor('systemGray4')
#007AFFPlatformColor('systemBlue')
#FF3B30PlatformColor('systemRed')
#34C759PlatformColor('systemGreen')
#FF9500PlatformColor('systemOrange')
#FF2D55PlatformColor('systemPink')

Rule 2: NO useColorScheme() in Individual Components

useColorScheme() is called ONCE at the root in ThemeProvider. Every other component MUST use:

  • useTheme() -- full theme object
  • useThemeColors() -- just colors
  • useIsDarkMode() -- just boolean
// VIOLATION
import { useColorScheme } from 'react-native';
const colorScheme = useColorScheme();
const isDark = colorScheme === 'dark';

// CORRECT
import { useThemeColors, useIsDarkMode } from '@/context/ThemeContext';
const colors = useThemeColors();
const isDark = useIsDarkMode();

Allowed exceptions: _layout.tsx (root), ThemeContext.tsx, platformColors.ts.

Rule 3: Liquid Glass on ALL Floating Elements

Every floating/overlay element on iOS 26 MUST use Liquid Glass. Use the existing LiquidGlassView wrapper component or GlassView directly.

Where Liquid Glass is REQUIRED:

  • Tab bars (automatic via NativeTabs)
  • Navigation headers (automatic via headerBlurEffect)
  • Floating action bars / buttons
  • Bottom sheets / sheet headers
  • Context menus (automatic via native context menu)
  • Alerts (automatic via Alert.alert)
  • Action sheets (automatic via ActionSheetIOS)
  • Custom floating overlays, toolbars, and pill controls
  • Segmented controls (automatic via native component)

Where Liquid Glass is NOT used:

  • List cells / table rows
  • Card content backgrounds
  • Full-page content areas
  • Text containers
  • Media content

Implementation pattern:

import { LiquidGlassView } from '@/components/ui/LiquidGlass';

<LiquidGlassView
  style={styles.floatingBar}
  fallbackColor={colors.surface}
  isInteractive={true}
  glassEffectStyle="regular"
>
  {/* floating content */}
</LiquidGlassView>

Never use BlurView alone for floating elements. Always use LiquidGlassView (which falls back to solid background) or check isGlassEffectAPIAvailable() and use GlassView directly.

Rule 4: contentInsetAdjustmentBehavior="automatic" on ALL Scroll Views

Every ScrollView, FlatList, and SectionList MUST set this prop. It ensures content insets adjust for translucent headers and tab bars on iOS.

// VIOLATION
<ScrollView>

// CORRECT
<ScrollView contentInsetAdjustmentBehavior="automatic">
<FlatList contentInsetAdjustmentBehavior="automatic" />
<SectionList contentInsetAdjustmentBehavior="automatic" />

Rule 5: Haptic Feedback on ALL Interactive Elements

Every Pressable, TouchableOpacity, and button-like element MUST include haptic feedback on iOS.

import * as Haptics from 'expo-haptics';

<Pressable onPress={() => {
  Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
  handleAction();
}}>
ActionHaptic
Tab selectionselectionAsync()
Button tapimpactAsync(ImpactFeedbackStyle.Light)
Card pressimpactAsync(ImpactFeedbackStyle.Medium)
Toggle switchimpactAsync(ImpactFeedbackStyle.Rigid)
Long press triggerimpactAsync(ImpactFeedbackStyle.Heavy)
Match / successnotificationAsync(NotificationFeedbackType.Success)
ErrornotificationAsync(NotificationFeedbackType.Error)

Rule 6: Native Navigation Headers -- No Custom Headers

Use the native Stack.Screen header with headerBlurEffect and headerLargeTitle. Do NOT build custom View-based headers unless the screen requires a complex custom header (e.g., image header, media overlay).

// VIOLATION -- custom View-based header for a standard list screen
<View style={styles.header}>
  <TouchableOpacity onPress={goBack}><Text>Back</Text></TouchableOpacity>
  <Text style={styles.title}>Settings</Text>
</View>

// CORRECT -- native header
<Stack.Screen options={{
  title: 'Settings',
  headerLargeTitle: Platform.OS === 'ios',
  headerBlurEffect: Platform.OS === 'ios' ? 'systemMaterial' : undefined,
}} />

Rule 7: SF Symbols for ALL iOS Icons

All icons on iOS MUST use expo-symbols SymbolView or the PlatformIcon abstraction. Never use Ionicons, MaterialIcons, or FontAwesome on iOS.

import { SymbolView } from 'expo-symbols';

<SymbolView
  name="heart.fill"
  tintColor={PlatformColor('systemPink')}
  style={{ width: 24, height: 24 }}
  type="hierarchical"
/>

Rule 8: NativeTabs with iOS 26 Features

The tab bar MUST use NativeTabs (already implemented). Ensure these iOS 26 features are enabled:

  • minimizeBehavior="onScrollDown" -- auto-minimize on scroll
  • SF Symbol icons with default/selected states via sf prop

Rule 9: Native Sheets and Modals

Prefer expo-router formSheet presentation or @gorhom/bottom-sheet for bottom sheets. When using @gorhom/bottom-sheet, add a glass background:

import { LiquidGlassView } from '@/components/ui/LiquidGlass';

<BottomSheet
  backgroundComponent={({ style }) => (
    <LiquidGlassView style={style} glassEffectStyle="regular" />
  )}
/>

Rule 10: DynamicColorIOS for Brand Colors

Custom brand colors that need light/dark adaptation MUST use DynamicColorIOS:

import { DynamicColorIOS, Platform } from 'react-native';

const brandPrimary = Platform.OS === 'ios'
  ? DynamicColorIOS({ light: '#B06D1E', dark: '#FFBA70' })
  : isDark ? '#FFBA70' : '#B06D1E';

SCOPE: iOS-ONLY

ActionAllowed
Modify /mobile iOS-specific codeYES
Use Platform.OS === 'ios' conditionalsYES
Add iOS-only featuresYES
Modify /web in any wayNEVER
Break Android functionalityNEVER
Remove Android code pathsNEVER

When adding iOS-specific behavior, always provide Android fallbacks:

// Pattern: iOS-specific with Android fallback
backgroundColor: Platform.OS === 'ios'
  ? PlatformColor('systemBackground')
  : colors.background,

EXISTING COMPONENTS TO USE

ComponentLocationUse For
LiquidGlassViewcomponents/ui/LiquidGlass.tsxGlass cards, floating elements
LiquidGlassHeadercomponents/ui/LiquidGlass.tsxCustom header backgrounds
LiquidGlassFABcomponents/ui/LiquidGlass.tsxFloating action buttons
useLiquidGlass()components/ui/LiquidGlass.tsxCheck glass availability
PlatformIconcomponents/ui/PlatformIcon.tsxCross-platform icons (SF Symbols on iOS)
ScreenHeadercomponents/ui/ScreenHeader.tsxCustom screen headers (has liquidGlass prop)
useTheme()context/ThemeContext.tsxFull theme with dark mode
useThemeColors()context/ThemeContext.tsxJust color values
useIsDarkMode()context/ThemeContext.tsxJust boolean
useSemanticColors()utils/platformColors.tsPlatformColor-based semantic colors

PRE-COMPLETION CHECKLIST

Before submitting ANY change to a mobile component:

  • No hardcoded hex colors for system UI elements (backgrounds, text, borders, separators)
  • PlatformColor used for all iOS system colors
  • useTheme()/useThemeColors() used instead of useColorScheme() for theme access
  • contentInsetAdjustmentBehavior="automatic" on all ScrollView/FlatList/SectionList
  • Haptic feedback on all interactive elements (Pressable, TouchableOpacity, buttons)
  • SF Symbols via SymbolView or PlatformIcon for all iOS icons
  • Liquid Glass on floating elements (LiquidGlassView, GlassView, or native component)
  • Native navigation used instead of custom View-based headers (where possible)
  • Platform.OS === 'ios' isolates all iOS-specific code
  • Android unchanged -- all iOS changes use Platform checks
  • Web untouched -- no changes to /web directory

DOCUMENTATION LINKS

Skills Info
Original Name:ios-native-expertAuthor:armanisadeghi