Blending platform idiom (Material 3 on Android, Human Interface Guidelines on iOS) with brand identity. Use this when deciding what to converge vs diverge across platforms.
Instalación
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Blending platform idiom (Material 3 on Android, Human Interface Guidelines on iOS) with brand identity. Use this when deciding what to converge vs diverge across platforms.
Material 3 and HIG
Instructions
A brand-consistent mobile design system is not a single UI ported twice. It is a shared brand vocabulary rendered in each platform's idiom. Follow Material 3 on Android, HIG on iOS, and converge only where brand identity trumps convention.
1. What to Converge (Brand Layer)
These belong to the brand and should look the same on both platforms:
Color palette — tonal palettes and semantic aliases.
Typography family — the brand typeface and hierarchy roles (body, heading, display).
Logo and app icon (shape adjusted per platform — see adaptive-icons).
Illustration style — line weight, corner radius personality.
Empty states, error tones, voice and labels.
2. What to Diverge (Idiom Layer)
These belong to the platform and should feel native:
Pattern
Android / Material 3
iOS / HIG
Navigation primary
Bottom nav bar (3–5 destinations)
Tab bar (2–5 destinations)
Stack transition
Predictive back gesture, shared element
Push/pop with swipe-to-go-back
Modal sheet
Bottom sheet (M3 ModalBottomSheet)
.sheet with detents, drag handle
Primary CTA
Filled button, elevation tint
Prominent button, system blue by default
Typography metrics
Roboto / Roboto Flex; tight line heights
SF Pro; SF Symbols inline
Date / time pickers
M3 date picker dialog
UIDatePicker wheel / compact
Haptics
HapticFeedbackConstants.*
UIImpactFeedbackGenerator
Toast / notification
Snackbar at bottom
Banner / toast at top, respecting Dynamic Island
Overflow menu
Three-dot menu, right-aligned
"More" action sheet from the navigation bar
Switch vs checkbox
Material switch; checkbox for multi-select
iOS switch; checkmark for multi-select
3. Concrete Decisions
Use the platform control unless the brand has an explicit reason to override:
iOS Button with .borderedProminent style is preferable to a custom button when the color matches brand primary.
Android Button with M3 ButtonDefaults.buttonColors() seeded from brand is preferable to a custom drawable.
iOS NavigationStack and Android NavHost drive their own transitions; do not replace them with a bespoke animator.
Use MaterialTheme as the substrate; override with brand tokens via CompositionLocal for custom properties M3 doesn't define.
5. SwiftUI — HIG Baseline
structAppRoot: View {
@Environment(\.dsTheme) var theme
var body: someView {
NavigationStack { Home() }
.tint(theme.color.actionPrimary) // brand primary tint
.font(.custom(theme.font.body, size: 16)) // brand type with Dynamic Type
}
}
Respect .tint, system materials (.ultraThinMaterial), and Dynamic Type. Do not re-implement a navigation bar.
6. When to Override
Override an idiom only when:
The platform control physically can't render the brand visual (rare for modern M3 / SwiftUI).
The brand mandates a specific interaction (e.g., a signature swipe gesture that's core to the product).
The platform pattern conflicts with your product IA (e.g., three top-level destinations — don't force a tab bar of one).
When you override, document the exception with a link in the component docs and an ADR describing why.
7. Parity Audit
Per feature, maintain a small table:
Element
Android decision
iOS decision
Notes
Primary CTA
M3 Filled Button, brand primary
.borderedProminent, .tint brand
Converged brand color
Nav structure
Bottom bar, 4 tabs
Tab bar, 4 tabs
Same IA, platform control
Sheet
ModalBottomSheet + drag handle
.sheet + .presentationDetents
Diverged UI, converged flow
Primary typeface
Acme Sans with Dynamic Type support
Acme Sans with Dynamic Type
Converged
Back gesture
Predictive back
Swipe from left edge
Platform-native, no override
8. Brand Themes on Top
Inject brand via token overlays, not components. Both MaterialTheme and SwiftUI environments read brand tokens, so a new brand never touches component code.
9. Anti-Patterns
Shipping iOS screens that use Material bottom navigation.
Implementing your own "iOS-style segmented control" inside Compose — use M3 SegmentedButton.
Forcing SF Pro on Android for "consistency" — breaks Dynamic Type and feels alien.
Replacing the navigation animator — breaks predictive back / interactive pop.
Treating "pixel-perfect parity" as a goal across platforms.
Checklist
Brand layer (color, type, illustration, voice) is identical across platforms via tokens.
Idiom layer (nav, modals, pickers, haptics, gestures) uses the platform-native control by default.
Compose apps use MaterialTheme as the substrate, seeded by brand tokens.
SwiftUI apps use .tint, system materials, SF Symbols, and Dynamic Type.
Overrides of platform patterns are documented in ADRs with a rationale.
A per-feature parity audit records convergent / divergent decisions.