Tokens & context
Foundations are the value layer of a system: typed tokens, arranged in layers, able to answer differently per context. Every facet in every component points at one of them, which is what makes a restyle a change in foundations rather than a sweep through components.
#Tokens are typed
A token is a name, a type and a value. The type is a closed word, and it decides what the value means: 1.5 is a ratio for a ratio token and an error for a spacing one, which needs a unit. The types:
- Colour:
color,gradient. - Length:
spacing,radius,size,border,font-size,letter-spacing. Written withpx, a density-independent unit, orscaled(n)for a length relative to the reader's text size. - Type:
font-family(a record: family, fallback, source, licence),typography(a text style record),font-weight,ratio(a line height). - Motion:
duration,easing. - Depth and layering:
shadow,elevation,tonal,ring,backdrop,blur,opacity.
The literals each type accepts are on Values & literals. In the Studio every type has an editor built around what the type is: a radius is shown on a box, a duration as frames to replay, an elevation as a light direction.
#Tokens are layered
A layer is a named group of tokens in reading order. The convention is three: Base holds the literals, Semantic holds roles that alias them, and a Component layer may alias those again for one component's needs. Resolution chains downward by substitution.
context-group ColorScheme { Light Dark } context-group Density { Compact Comfortable } foundations { layer Base { token violet/600 : color = hex(7c3aed) token violet/500 : color = hex(8b5cf6) token space/2 : spacing = 8px token space/3 : spacing = 12px } layer Semantic { token accent : color = alias by ColorScheme { default -> violet.600; Dark -> violet.500 } token gap/control : spacing = alias by Density { default -> space.3; Compact -> space.2 } } layer Component { token button/fill : color = alias by ColorScheme { default -> accent } } }
Components reference the top of the chain: fill button.fill. Change accent and the fill follows; change violet/600 and both follow.
#Context is a dimension
A context group is a dimension a token can answer differently along: colour scheme, density, platform, brand, breakpoint. Its members are contexts. A token answers per context with an alias by block, and default is the fallback for every context the block does not name.
Several active dimensions resolve by chaining: in the file above, button.fill aliases by scheme and points at accent, which aliases by scheme again, while a spacing aliases by density alone. There is never a composite key like dark+compact, which would multiply with every dimension added. Platform is a context group like any other, and the outermost one when it exists: it picks the mechanism, the scheme picks the value.
context-group Platform { Web iOS Android } foundations { token shadow/lg : shadow = raw "0 10px 15px rgba(0,0,0,.1)" token tonal/3 : tonal = 3 token elevation/overlay : elevation = alias by Platform { Web -> shadow.lg; Android -> tonal.3; iOS -> none; default -> shadow.lg } } component Popover { archetype Popover part Popover: container { } part surface: container { elevation elevation.overlay } }
That is the whole of per-platform styling. elevation is an abstract facet type whose alias may point at tokens of different concrete types per platform (a shadow on the web, a tonal step on Android, nothing on iOS), and the component says elevation elevation.overlay once. There is no per-platform style block in the language.
#A prop can be a dimension
A context group's value can come from a prop instead of the environment. A prop typed by a group (variant : context Variant, or just variant : Variant) takes the group's contexts as its values and, when set, shadows the ambient context for that component's subtree. That single rule is what variant, size, a per-instance accent and responsive props all are: token aliasing with the dimension's value supplied per instance. Resolution precedence: the prop on the nearest instance, then the ambient value, then the group's default.
A prop the whole system shares, such as a control size, is declared once as a and taken with global size, so every component agrees on its name, type and default:
context-group Size { Small Medium Large } foundations { token space/1 : spacing = 4px token space/2 : spacing = 8px token space/3 : spacing = 12px token control/inset : spacing = alias by Size { Small -> space.1; Medium -> space.2; Large -> space.3; default -> space.2 } } global-prop size : Size = Medium "The control size, shared by every input." component Button { archetype Button props { global size label : string = "Save" } part Button: container { inset control.inset } part label: text { content bind label } }
#Computed and composite values
A token can be derived from another, live: compute accent in oklch { darken 10% }. The steps a token accepts follow its type (lighten, darken, mix, alpha and rotate for colours; scale, offset and round for lengths), so a colour step on a length is an error rather than a no-op. A text style and a font family are records, edited as a unit; their shape is on Values & literals.
#What the targets do with them
- React emits a
theme.cssof custom properties, one per token, with a block per context ([data-color-scheme="dark"]) that re-points the aliased ones. Components reference the properties, so a theme change reaches them without regeneration. - Figma emits Variables with a mode per context, and a W3C DTCG token file.
Which of these a project produces is its choice of targets, kept beside the document.
New projects import tokens from DTCG, Tokens Studio, Style Dictionary, Tailwind and Figma exports; every path converts to .milda text first.
These words, in the reference
- A dimension a token can answer differently along: colour scheme, density, platform, brand.
- The design tokens.
- A named layer of tokens, such as primitives and then the semantic tokens that alias them.
- Declares a design token.
- A token whose value depends on a context.
- A value derived from another one, live: "the accent, 20% lighter".
Open a word for its entry, or read them all in the reference.
See it built in the tour2. Layers and context10. Type, motion and computed values