Skip to content
Components
/
Code output
Dark

Code output

One token source generates CSS, SwiftUI, Compose and Flutter. The same file is what a coding agent reads, so the name in the design and the name in the code are the same name.

Preview

Appetite UI holds its values once, as a token file, and generates the rest. One variable, four languages, no second copy to keep in step.

brand/base, from one variable to four generated names
6 collections, 2 modes on colour, 1 source file
Source, Color Tokens, Light
brand/base
aliases colors/blue/500
#155DFC
CSS
var(--ap-brand-base)
SwiftUI
Color.apBrandBase
Compose
AppetiteTheme.colors .brandBase
Flutter
apBrandBase

The first three names are not chosen here. Every variable in the file stores its own code name for web, iOS and Android, and the export reads them off the variable rather than deriving them.

The source

One JSON file in the W3C Design Tokens format, run through Style Dictionary v5. Primitives hold the values. Semantic tokens point at primitives. Nothing holds a value twice.

The token file
two entries, one reference
{
  "colors": {
    "blue": {
      "500": { "$type": "color", "$value": "#155DFC" }
    }
  },
  "brand": {
    "base": { "$type": "color", "$value": "{colors.blue.500}" }
  }
}
Collection
Variables
Modes
Foundations
196
Default
Color Tokens
160
Light, Dark
Typography
28
Default
Motion
31
Default
Platform
16
ios-md, ios-lg, android
Platform Bridge
112
Brand, System

Figma writes a path with slashes, brand/base. The token file writes the same path with dots, so the reference reads {colors.blue.500}. Same token, two notations, and the export is where they meet.

Targets

Four outputs off the one source. These are examples of what the export produces, cut to three tokens so the four sit side by side: a colour, a spacing step and a duration.

CSS custom properties
web
:root {
  --ap-brand-base: #155DFC;
  --ap-space-4: 16px;
  --ap-duration-fast: 120ms;
}
SwiftUI
iOS
extension Color {
  static let apBrandBase = Color(
    red: 0.082, green: 0.365, blue: 0.988)
}
enum AppetiteSpacing { static let space4: CGFloat = 16 }
enum AppetiteMotion { static let durationFast = 0.12 }
Jetpack Compose
Android
internal val BrandBase = Color(0xFF155DFC)
internal val Space4 = 16.dp
internal val DurationFast = 120

// read as AppetiteTheme.colors.brandBase
Flutter
Dart
const apBrandBase = Color(0xFF155DFC);
const apSpace4 = 16.0;
const apDurationFast = Duration(milliseconds: 120);

The file has no slot for Dart, so the Flutter names above follow the same transform rather than coming out of the source. The other three are read off the variables.

Modes

A mode is a second value on the same token, not a second file. Light and Dark on colour, Brand and System on the platform mirrors, three device modes on the platform metrics. One source carries all of them.

Token
Mode
Resolves to
Value
brand/base
Light
colors/blue/500
#155DFC
brand/base
Dark
colors/blue/400
#2B7FFF
M3/sys/color/primary
Brand
brand/base
#155DFC
M3/sys/color/primary
System
platform/m3/primary
#6750A4
What the CSS export does with two modes
one name, two values
:root {
  --ap-brand-base: #155DFC;
}

@media (prefers-color-scheme: dark) {
  :root { --ap-brand-base: #2B7FFF; }
}

Agents

The Appetite Core Skill is a free instruction file that teaches a coding agent which token and which pattern to use. Add it to your project and Claude, Cursor or anything else that reads project instructions works from the same source the export runs on.

What a variable says about itself
three examples
brand/base
Primary buttons, active states, links. Maps to iOS tint and M3 primary.
border/soft-100
Hairline divider. Decorative separation only. Contrast 1.22:1, so never rely on it to convey structure.
platform/font/system
The face used by surfaces the operating system draws. Never point a branded component at this variable.

Those descriptions are carried on the variables themselves, which is the whole trick: the guidance travels with the value instead of living in a document nobody opens. The Core Skill replaced Figma Code Connect, which is not available on our plan and was the wrong tool anyway. Code Connect maps one component to one snippet. What an agent is missing is not the snippet, it is knowing which token to reach for.