Updated
Platform Bridge
Platform Bridge lets one screen carry your brand or the platform's own look. 113 variables on two modes: Brand resolves an Apple or Material 3 role to an Appetite UI token, System returns the value Apple or Google publishes. One dropdown moves a whole screen.
Updated
How do I design one app for iOS and Android?
Set the Platform Bridge mode on a frame to Brand and every Apple and Material 3 slot reads an Appetite UI token, so one brand edit moves both platforms. Set it to System and the same slots return the values Apple and Google publish. The mode decides where a component reads its value from.
Appetite UI names the slots of the Apple and Material design systems and points each one at a token you control: 113 slots, 53 from Apple and 60 from Material, covering color, shape and type size.
| Slot group | Slots | Brand mode reads | System mode reads |
|---|---|---|---|
| iOS color roles | 34 | Color Tokens, semantic | platform/ios/* |
| iOS shape | 7 | dimensions/radius/* | Apple's own radii |
| iOS type size | 12 | typography/fontSize/* | Dynamic Type at Large |
| Material color roles | 32 | Color Tokens, semantic | platform/m3/* |
| Material shape | 6 | dimensions/radius/* | Material's own radii |
| Material state opacity | 7 | a bare number | the same number |
| Material type size | 15 | typography/fontSize/* | published typescale |
What does Brand mode do?
In Brand mode a platform slot stops being a color and becomes a pointer. iOS/tintColor points at brand/base, which points at colors/blue/500, and that primitive is the only place the hex is written down. M3/sys/color/primary ends on the same primitive, so one edit moves an iOS screen and an Android screen together.
Two platforms, one brand color, one source. Both accents end on colors/blue/500.
iOS/tintColorbrand/basecolors/blue/500#155DFCM3/sys/color/primarybrand/basecolors/blue/500#155DFC
| Platform slot | Resolves through | Brand value |
|---|---|---|
iOS/label | text/strong-950, colors/gray/950 | #0E0E0F |
M3/sys/color/on-surface | text/strong-950, colors/gray/950 | #0E0E0F |
iOS/systemRed | state/error/base-500, colors/red/500 | #FB2C36 |
M3/sys/color/error | state/error/base-500, colors/red/500 | #FB2C36 |
iOS/secondaryLabel | text/sub-700, colors/gray/700 | #48484A |
iOS/separator | border/soft-100, colors/gray/100 | #E9E9EA |
M3/sys/color/tertiary | brand/base, colors/blue/500 | #155DFC |
In Brand mode M3/sys/color/tertiary resolves to the same brand/base as primary, so the two roles share one color until you point tertiary somewhere else.
102 of the 113 slots resolve to an Appetite UI token in Brand mode. The other 11 hold a platform value or a bare number in both modes, and they are listed in the section on slots the switch does not move.
How do I return a screen to the native look?
Switch the Platform Bridge mode on the frame to System. Every slot drops its pointer and returns the value Apple and Google publish, so the screen stops being yours and becomes theirs. That is the view a native review asks to see.
Nothing is approximated. Those values sit in Color Tokens as 67 untouched platform primitives, stored once and never retyped into a component. It is one switch on the frame.
| Platform slot | Brand mode | System mode | Published as |
|---|---|---|---|
iOS/tintColor | #155DFC | #007AFF | systemBlue |
iOS/secondaryLabel | #48484A | #3C3C43 at 60% | secondaryLabel |
iOS/separator | #E9E9EA | #3C3C43 at 18% | separator |
iOS/systemGray | #8E8E93 | #8E8E93 | systemGray |
M3/sys/color/primary | #155DFC | #6750A4 | Material baseline primary |
A few slots land on the same value in both modes without being wired that way. The Appetite UI gray scale and Apple's systemGray already agree at #8E8E93.
Which type sizes does the Bridge carry?
The Bridge carries type size as well as color. 12 iOS text styles and 15 Material typescale steps each point at an Appetite UI step in Brand mode and return the platform's own published size in System mode. Only the size step is carried, and weight, line height and letter spacing stay on the Appetite UI side.
| Step | Brand points at | Brand | System |
|---|---|---|---|
iOS/sys/typography/largeTitle | fontSize/4xl | 36 | 34 |
iOS/sys/typography/title2 | fontSize/xl | 20 | 22 |
iOS/sys/typography/headline | fontSize/lg | 18 | 17 |
iOS/sys/typography/body | fontSize/lg | 18 | 17 |
iOS/sys/typography/subheadline | fontSize/sm | 14 | 15 |
iOS/sys/typography/footnote | fontSize/xs | 12 | 13 |
iOS/sys/typography/caption2 | fontSize/xs | 12 | 11 |
iOS/sys/typography/tabBarLabel | fontSize/xs | 12 | 10 |
M3/sys/typescale/display-large | fontSize/6xl | 60 | 57 |
M3/sys/typescale/headline-large | fontSize/3xl | 30 | 32 |
M3/sys/typescale/title-large | fontSize/xl | 20 | 22 |
M3/sys/typescale/label-small | fontSize/xs | 12 | 11 |
The Appetite UI scale is coarser than either platform ramp, so steps collapse in Brand mode. iOS headline and body both land on fontSize/lg, and footnote, caption1, caption2 and tabBarLabel all land on fontSize/xs. Distinctions Apple draws a point apart do not survive the switch.
iOS/sys/typography/tabBarLabel is Apple's 10 pt tab label in System mode.
Which slots does the mode switch not move?
Fourteen slots are wired to the same source in both modes. Eleven are the ones counted out of the 113 under Brand mode, and the switch cannot reach them. Three run the other way: they take an Appetite UI token like the other 102, then keep it.
| Slots | Count | Value in both modes |
|---|---|---|
M3/sys/state/* | 7 | Bare numbers: hover 8, focus 10, pressed 10, dragged 16, disabled 38 and 12, scrim 32. |
iOS/glassControliOS/segmentSelectediOS/glassCleariOS/glassBorderDark | 4 | An Apple value in Brand mode too. The last is a bare white at 12%, written into the variable itself. |
iOS/glassBorderiOS/glassEdgeiOS/glassShadow | 3 | An Appetite UI glass token in System mode too, because Apple publishes no value for them to return to. |
What do the five Platform modes do?
A frame picks one of five Platform modes, ios-md, ios-lg, android, ios-duo-outer or ios-duo-inner, and the same component then reads a 44 pt touch target on iOS and 48 dp on Android from one variable. Platform is a second collection beside this one: its 20 variables carry geometry such as touch targets, safe areas and corners. Two of the modes and four of the variables serve iPhone Duo.
| Variable | ios-md | ios-lg | android | ios-duo-outer | ios-duo-inner |
|---|---|---|---|---|---|
grid/safe-area/top | 59 | 62 | 52 | 24 | 24 |
grid/safe-area/bottom | 34 | 34 | 24 | 24 | 24 |
grid/safe-area/trailing | 0 | 0 | 0 | 96 | 96 |
grid/columns | 4 | 4 | 4 | 4 | 6 |
platform/min-touch-target | 44 | 44 | 48 | 44 | 44 |
platform/bar/top-height | 44 | 44 | 64 | 44 | 44 |
platform/bar/bottom-height | 49 | 49 | 64 | 0 | 0 |
platform/list-row/min-height | 44 | 44 | 56 | 44 | 44 |
platform/control/corner | 8 | 8 | 9999 | 8 | 8 |
platform/card/corner | 12 | 12 | 12 | 12 | 12 |
platform/sheet/corner | 12 | 12 | 28 | 12 | 12 |
platform/dialog/corner | 12 | 12 | 28 | 12 | 12 |
platform/switch/track-width | 64 | 64 | 52 | 64 | 64 |
platform/switch/track-height | 28 | 28 | 32 | 28 | 28 |
platform/screen-padding | 16 | 16 | 16 | 16 | 16 |
platform/duo/sidebar-width | 0 | 0 | 0 | 0 | 262 |
platform/duo/device-corner | 48 | 48 | 48 | 48 | 48 |
platform/duo/pane-corner | 26 | 26 | 26 | 26 | 26 |
platform/font/brand, platform/font/system | Inter | Inter | Inter | Inter | Inter |
grid/columns is 4 on every mode except ios-duo-inner, which has 6, the same counts as the five grid styles on the Dimensions page.
ios-md and ios-lg differ in exactly one variable, grid/safe-area/top, at 59 and 62.
The two Duo modes are for iPhone Duo screens: ios-duo-outer for the outer display and ios-duo-inner for the inner one. They differ in two variables: grid/columns, 4 on the outer display and 6 on the inner, and platform/duo/sidebar-width, 0 outside and 262 inside, where a sidebar stands beside the content. Both modes take the bars off the horizontal axis. The safe areas at the top and the bottom are 24, platform/bar/bottom-height is 0, and grid/safe-area/trailing is 96, the room of the vertical control rail that carries the status bar, toolbar and tab bar. The device corner of 48 and the pane corner of 26 sit in every mode.
On the touch target: platform/min-touch-target is 44 in the four iOS modes and 48 in android, so one component obeys both without a second copy.