Skip to content

  14 min read  Last verified

How to rebrand a mobile app in Figma with variables

Repoint one brand variable and a mobile app follows in light, dark, iOS and Android. Counted in a real Figma file, with what stays and an orange contrast check.

The same Appetite UI finance app in blue and in orange side by side, with a Color Tokens card showing the brand/base variable switching from colors/blue/500 to colors/orange/500
On this page
  1. Why one variable works
  2. What it reaches
  3. The ramp swap
  4. The procedure
  5. What stays
  6. iOS and Material
  7. In code
  8. Contrast check
  9. What to take
  10. Questions
  11. Sources

To rebrand a mobile app in Figma with variables, repoint the variable the brand color lives in and let every layer bound to it follow. In the Appetite UI file that variable is brand/base: moving it from colors/blue/500 to colors/orange/500 recolors 1,110 layers across components, app screens and charts, in Light and in Dark. The rest of the brand ramp is separate variables, so a complete rebrand repoints ten more tokens, and anything not bound to a variable stays as drawn.

Appetite UI is a Figma UI kit for iOS and Android apps, built like a design system. One token source drives Apple and Material components in light and dark mode, and exports to SwiftUI, Jetpack Compose, Flutter and CSS. I build it, so the counts below come from its file, read with a script that changes nothing, and the tables say what each number counts.

Why can one variable recolor a whole app?

Because the color is written down once, and everything else holds a pointer to it. Figma calls the pointer an alias: "A variable can reference another variable. That is, you can apply a variable to another variable. Also called, 'aliasing,' this gives you the ability to implement design tokens." Appetite UI uses three levels of it.

The chain from a hex value to a button, with the brand color as the example
LevelCollectionExampleModes
PrimitiveFoundations, 202 variablescolors/blue/500, #155DFCDefault
Semantic tokenColor Tokens, 190 variablesbrand/base points at colors/blue/500 in Light and at colors/blue/400 in DarkLight, Dark
Platform slotPlatform Bridge, 113 variablesiOS/tintColor points at brand/baseBrand, System
LayerAny component or screenA button fill, a focus ring, a progress bar bound to brand/baseFollows the frame

The hex #155DFC exists in one place. Repoint brand/base and the semantic level moves, the platform slots that point at it move, and every layer bound to it moves, with each mode keeping its own target. How this two-mode setup is built is the subject of Dark mode with Figma variables, not duplicate frames; this article starts where that one ends, with the brand color already on a token.

To make the pointer in Figma, open the Variables modal, right-click a variable's value and select Create alias, as Figma's help describes.

What does brand/base reach in the Appetite UI file?

It reaches 1,110 layers. I counted every page of the Appetite UI file (release 2.5) on October 8, 2026, entering every node except the insides of instances, which take their colors from the component they come from, and reading which variable each fill, stroke and effect color is bound to.

Layers bound directly to brand/base, by part of the file
Part of the filePagesLayers bound to brand/baseComponents and variants holding one
Core components38409277
Apple components202720
Material 3 components17149132
App screens11260not counted, they hold instances
Together845429

Checked on , against the Appetite UI file (release 2.5), read with a script that changes nothing.

The app screens hold 2,506 instances at their top level, and each takes its color from the component it comes from. That is why a screen needs no edit of its own: 260 layers on the screens are bound to brand/base themselves, and everything else on them arrives through components.

Three other variables point at brand/base, and a rebrand reaches their layers too:

Layers that reach brand/base through another variable
VariablePoints atLayers bound
iOS/tintColorbrand/base in Brand mode67
M3/sys/color/primarybrand/base in Brand mode107
M3/sys/color/tertiarybrand/base in Brand mode12
chart/series-1brand/base in both modes79

845 plus 186 plus 79 is 1,110. The focus ring is among them: the Focused variants of Button, Chip and Input draw it as a 4 point shadow in brand/base, and the Neutral buttons do too, so a focus ring follows the brand even where the button fill does not. No token in Color Tokens is named for a link or an action. Components bind the brand color itself, which is the reason one variable is enough for them.

Which tokens change when you swap the whole ramp?

Eleven tokens, because the brand has more than one step. brand/base is the solid color. Beside it the file keeps a lighter, a light, a dark, a darker and a pressed step, three translucent tints that alias the blue alpha set, and two stronger translucent steps typed as raw values. Move only brand/base and 403 layers stay blue: hover and pressed states, soft tints, selected backgrounds. That is just over a quarter of the layers that use the brand family.

The brand tokens of Color Tokens before and after an orange rebrand, with the layers bound to each
TokenLight, before to afterDark, before to afterLayers bound
brand/lighterblue/50 to orange/50, #EFF6FF to #FFF7EDblue/950 to orange/950, #132150 to #44130648
brand/lightblue/100 to orange/100, #DBEAFE to #FFEDD4blue/900 to orange/900, #0D2673 to #7E2A0C61
brand/baseblue/500 to orange/500, #155DFC to #FF6900blue/400 to orange/400, #2B7FFF to #FF8904845
brand/darkblue/700 to orange/700, #193CB8 to #CA3500blue/300 to orange/300, #82BFFF to #FFB86A8
brand/darkerblue/800 to orange/800, #1C398E to #9F2D00blue/200 to orange/200, #BEDBFF to #FFD6A70
brand/pressedblue/700 to orange/700, #193CB8 to #CA3500blue/500 to orange/500, #155DFC to #FF690010
brand/alpha-10, alpha-16, alpha-24colors/alpha/blue/* to colors/alpha/orange/*, #2B7FFF to #FF6900 at 10, 16 and 24 percentthe same in both modes203, 10, 16
brand/alpha-48, alpha-72typed values, #2B7FFF at 48 and 72 percent, to #FF6900 at the same alphasthe same in both modes22, 25

Checked on , against the Appetite UI file (release 2.5), Foundations and Color Tokens.

The six solid brand tokens brand/lighter, light, base, dark, darker and pressed in Light and in Dark, blue above orange, each cell labelled with its colors/blue or colors/orange step and hex; a white label on brand/base measures 5.25:1 on blue and 2.89:1 on orange in Light, and 3.76:1 on blue and 2.38:1 on orange in Dark
The solid brand ramp before and after the swap, with the primitive and hex each token points at.

Three things in that table are worth reading twice.

  • Dark is its own column. brand/base points at blue/400 in Dark, so its orange equivalent is orange/400. Copying the Light step across is the first thing a rushed rebrand gets wrong, and the reasons for a separate Dark step are in the dark mode article.
  • The last row is the one a ramp edit cannot find. brand/alpha-48 and brand/alpha-72 hold the color as a raw value instead of an alias, so retype them. The color docs mark roles like these as direct.
  • Some steps have no layers. brand/darker binds nothing outside the documentation pages, so on screens it changes only through the Material roles that alias it.

How do you make the edit in Figma?

  1. Duplicate the file, then open the Variables modal

    Work on a copy. Open the Variables modal and check that the ramp you are moving to exists in the primitive collection with the same steps, here colors/orange/50 to colors/orange/950.

  2. Repoint the solid steps in Light

    In Color Tokens, right-click the Light value of each brand token and select Create alias, then choose the matching step of the new ramp, as in the table above. Figma's help describes the action as "Right-click a variable's value and select Create alias."

  3. Repoint the same tokens in Dark

    Use the Dark column of the table, not the Light step. The Dark targets are lighter, so the brand keeps its contrast on a near-black ground.

  4. Repoint the tints and retype the raw values

    Point brand/alpha-10, alpha-16 and alpha-24 at the new alpha set, then type the two stronger steps by hand.

  5. Check both modes and both platforms

    Set a frame to Dark with Apply variable mode in the Appearance section of the right sidebar, and check one screen in Brand mode on each platform mirror.

  6. Sweep for what did not move

    Select one layer that should have changed and still shows the old color. Figma's Edit menu lets you select all other layers with the same fill, stroke or effect; bind the selection to the right token with Apply styles and variables, as Figma's help describes, or redraw it.

  7. Run the contrast check and export

    The next sections cover contrast and code. Then regenerate the outputs from the source.

What does not follow a variable?

Anything that is not bound to one. A variable recolors fills, strokes and effects that reference it, and nothing else. These are the cases to look for, with the numbers I found in the Appetite UI file where the file has them.

What stays when a brand variable moves, and how to find it
What staysWhyHow to find it
Photos, illustrations and raster brand artA picture has no variableLook for image fills in the Layers panel and decide per picture whether to redraw it
A fill or stroke typed as a hexOnly bound values followSelect a layer that stayed old, then select all with the same fill from the Edit menu
Gradients whose stops are not boundEach stop is a color of its ownCheck every gradient fill on a brand surface
Icons and logos from other setsTheir colors live inside the vectorRecolor the vector or bind its fill
Other semantic colors that happen to be blueThey are separate decisionsIn Appetite UI, state/information/* binds 70 layers and colors/blue/200 and /900 bind 54 avatar layers, and none follow
System mode valuesSystem returns what Apple and Google publishPlatform Bridge in System mode keeps #007AFF and #6750A4
The app icon, store art and websiteOutside the Figma variablesRedraw them from the new color

The Information status stays blue on purpose. A brand that turns orange does not make an informational banner orange, and a rebrand that did would blur the status colors, a point Apple makes about color generally: "Avoid using the same color to mean different things." Decide that one deliberately, token by token.

Do the iOS tint color and Material primary follow?

Yes in Brand mode, and no in System mode, by design. The Platform Bridge names the Apple and Material slots and points each one at a token. Twelve slots end on the brand family; three of them point at brand/base itself.

Platform Bridge slots that end on the brand family, with the value in each mode
SlotBrand mode, blue to orange (Light)System mode, unchangedLayers bound
iOS/tintColorbrand/base, #155DFC to #FF6900#007AFF67
iOS/tintColor-pressedbrand/pressed, #193CB8 to #CA3500#0051D5not counted
M3/sys/color/primarybrand/base, #155DFC to #FF6900#6750A4107
M3/sys/color/tertiarybrand/base, #155DFC to #FF6900#7D526012
M3/sys/color/primary-containerbrand/lighter, #EFF6FF to #FFF7ED#EADDFFnot counted

Checked on , against the Appetite UI file (release 2.5), Platform Bridge collection.

Seven more Material slots follow the same way through brand/lighter, brand/light, brand/dark and brand/darker: on-primary-container, secondary, secondary-container, on-secondary-container, tertiary-container, on-tertiary-container and inverse-primary. The slot names are the platforms' own, which is the point: Apple's tint and Material's primary are where each platform expects the brand to arrive, and the Platform Bridge docs list all 113 slots.

Both platforms document where a brand color goes. Apple documents the tintColor of a view as: "The first nondefault tint color value in the view's hierarchy, ascending from and starting with the view itself." Its color guidelines add that the system applies the app accent color to the background in prominent buttons. Google's Material 3 documentation says "Primary is the base color, used for main components like prominent buttons, active states, and the tint of elevated surfaces." One brand edit lands in both, because both slots end on brand/base.

What does the same edit look like in code?

One reference changes. In the token source, a semantic token holds a reference to a primitive, and the code docs print the smallest file that shows it. The orange edit swaps the primitive that brand.base points at:

The token file, after the editthe smallest form the code docs print, blue replaced by orange
{
  "colors": {
    "orange": {
      "500": { "$type": "color", "$value": "#FF6900" }
    }
  },
  "brand": {
    "base": { "$type": "color", "$value": "{colors.orange.500}" }
  }
}

The full source carries Light and Dark as two values on the same token, so the Dark value moves to colors.orange.400 in the same edit. The outputs are generated from the source, and the code docs say to change a value there and leave the outputs alone. Regenerate, and the CSS output, in the structure the docs print, carries the new values:

What the CSS export would carry after the editthe docs' structure, the two orange values
:root {
  --ap-brand-base: #FF6900;
}

[data-theme="dark"],
.dark {
  --ap-brand-base: #FF8904;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not(.light) {
    --ap-brand-base: #FF8904;
  }
}

The names stay: var(--ap-brand-base) in CSS, Color.apBrandBase in SwiftUI, AppetiteTheme.colors.brandBase in Compose and apBrandBase in Flutter. A developer receives new values under names the code already uses, so a rebrand reaches the project as a regenerated file and needs no search through the code. The code output docs print all four outputs, and How one Figma token becomes SwiftUI, Compose, Flutter and CSS follows one token through them.

Will the new brand color pass contrast?

Not automatically, and an orange is the case that shows it. The label of a filled brand button is bound to static/static-white-0, which is white in Light and in Dark, and its fill to brand/base. White on the default blue measures 5.25:1; on colors/orange/500 it measures 2.89:1.

WCAG 2 contrast of a white label and of the brand as text, before and after
PairRatio
White label on colors/blue/500, #155DFC (Light today)5.25:1
White label on colors/orange/500, #FF69002.89:1
White label on colors/orange/600, #F549003.60:1
White label on colors/orange/700, #CA35005.22:1
White label on colors/blue/400, #2B7FFF (Dark today)3.76:1
White label on colors/orange/400, #FF8904 (Dark after)2.38:1
Near-black label, #0E0E0F, on colors/orange/5006.68:1
colors/orange/400 as text on the near-black ground, #0E0E0F8.11:1

Checked on , against hex values read from the Appetite UI file (release 2.5), ratios computed with the WCAG 2 formula.

WCAG 2.2 asks for "a contrast ratio of at least 4.5:1" for standard text and at least 3:1 for large-scale text, which is at least 18 point or 14 point bold. Apple's accessibility guidelines give the same pair of numbers for iOS: 4.5:1 for text up to 17 points in all weights, 3:1 at 18 points and for bold text. A white label at 2.89:1 fails both, and the default blue in Dark, at 3.76:1, meets the large text threshold only. The swap is therefore two decisions in one: pick the step, then check the label on it.

Three ways out. Point brand/base in Light at orange/700, a token edit, which gives white a ratio of 5.22:1 on a deeper orange. Keep orange/500 and rebind the label of the filled brand variants to a near-black color, which gives 6.68:1 but is an edit to the components, since the label is bound to the white primitive and not to the brand. Or keep the bright orange for large text and graphics, and use a darker step wherever a small label sits on it. The first choice moves every screen with one variable, which is the property that made the rebrand a one-variable job.

For the dark ground, the numbers go the other way: colors/orange/400 as text on #0E0E0F measures 8.11:1, a lighter and more legible brand there than the blue it replaces.

What to take from the file

A rebrand is as short as the file is wired. In this file the brand arrives at the layers through one semantic token, the platform slots alias that token, and the other steps of the brand are named and counted, so the work is eleven edits and a contrast decision instead of a sweep through 1,513 layers. Check any file the same way before you promise a client a one-day rebrand: open the Variables modal, follow the brand color to the layers, and list what is typed in by hand.

The color docs show every ramp and role in both modes, the tokens page switches the same chain on a phone screen, the platforms page shows the two mirrors side by side, the read-only preview opens the whole file, and pricing lists what each license includes.

Questions

How do I change the brand color across a whole Figma file?

Put the brand color on a variable, bind every component to it, and change the variable. In Figma, open the Variables modal, right-click the variable's value and select Create alias to point it at a new color; every layer bound to the variable follows. Layers with a typed hex do not, so sweep for them afterwards.

Do I need a paid Figma plan to rebrand with variables?

Variables are available on any plan, according to Figma's help. Modes need a paid plan: Education, Professional, Organization or Enterprise. A rebrand of one theme works without modes, and a file with Light and Dark needs two.

How do I find the layers that did not change after a rebrand?

Select a layer that still shows the old color, then use the Edit menu to select all other layers with the same fill, stroke or effect, as Figma's help documents. Bind the selection to a variable with Apply styles and variables, or redraw it. In Appetite UI the usual leftovers are typed alpha values, avatar colors that bind the blue ramp directly, and pictures.

Does changing the brand variable change the iOS tint and Material primary?

In Appetite UI's Brand mode, yes. iOS/tintColor, M3/sys/color/primary and M3/sys/color/tertiary all point at brand/base, and nine more Material and iOS slots end on the other brand steps. In System mode the slots return Apple's #007AFF and Google's #6750A4 and stay put.

Does white text pass contrast on an orange brand color?

Not on the bright orange. White on colors/orange/500, #FF6900, measures 2.89:1 against the 4.5:1 WCAG asks for at standard sizes. White on colors/orange/700, #CA3500, measures 5.22:1, and a near-black label on colors/orange/500 measures 6.68:1.

Can one Figma file hold several brands?

Yes, in two ways. Modes in one collection store one value per brand and switch a whole frame. On the Enterprise plan, extended collections let each brand extend a parent collection and override only the values that differ, while inheriting the rest.

Sources

  1. Figma Learn: Create and manage variables and collections, read October 8, 2026
  2. Figma Learn: Overview of variables, collections, and modes, read October 8, 2026
  3. Figma Learn: Modes for variables, read October 8, 2026
  4. Figma Learn: Extending variable collections, read October 8, 2026
  5. Figma Learn: Apply variables to designs, read October 8, 2026
  6. Figma Learn: Select layers and objects, read October 8, 2026
  7. Apple Human Interface Guidelines: Color, read October 8, 2026
  8. Apple Human Interface Guidelines: Accessibility, read October 8, 2026
  9. Apple Developer: UIView.tintColor, read October 8, 2026
  10. Android Developers: Material Design 3 in Compose, read October 8, 2026
  11. W3C: Understanding WCAG 2.2, Contrast (Minimum), read October 8, 2026

Written by

Bob Poláček

Designer of Appetite UI. Builds the Figma file, the token architecture and the code output, and answers the support inbox.

Keep reading

  • Guide · Sep 24, 2026 · 10 min read

    Dark mode with Figma variables, not duplicate frames

    Dark mode in Figma without a second set of frames: semantic variables with a Light and a Dark mode, one frame per screen, and the checks to run before handoff.

  • Tokens · Sep 24, 2026 · 11 min read

    How one Figma token becomes SwiftUI, Compose, Flutter and CSS

    One Figma variable, brand/base, followed into CSS, SwiftUI, Compose and Flutter: where each code name comes from, what a mode becomes, what cannot translate.

  • Guide · Sep 24, 2026 · 11 min read

    How to design one app for iOS and Android in Figma

    Keep one token set, share the components that behave alike, draw bars and sheets once per platform, and switch touch targets with a Figma variable mode.

Your next rebrand is one edit.

One-time payment, Lifetime updates, Unlimited client projects