What gets generated
Each brand emits a directory undergenerated/brands/<brand>/swift/:
The token files
Every per-mode file declares the same two top-level types: aSubstrateSystemTokenSet struct of exactly three colors, and a SubstrateSystemTokens enum of intent roles. This is example output for a fictional acme brand — generated/brands/acme/swift/system.light.gen.swift:
- Colors are Display P3, not sRGB. The
Color(.displayP3, …)initializer is deliberate — the solver works in a wide gamut and the output preserves it. - Every intent is a surface/text/border triple. There are no
primary/onPrimarypairs and no separate foreground roles. - There are no spacing or type-size constants. Those live in component style descriptors and are resolved by the kernel.
surface, surfaceElevated, brand, neutral, danger, warning, and success, plus whatever custom intents the brand declares.
Selecting a mode
Because all four files declare the same top-level names, they are alternative artifacts, not siblings. Adding two to one target collides on duplicate declarations. Pick one per build configuration, or wrap them behind your own conditional compilation.SubstrateKernel
packages/kernel-swift is a SwiftPM package holding a pure-math port of the TypeScript kernel — no UI dependencies:
UserPreferences mirrors the web vector exactly, with the same defaults:
Component descriptors
Component styling ships as data, not code. Descriptors live ingenerated/global/swift/components/, with brand-specific overrides under the brand’s own swift/components/ directory. Each imports SubstrateKernel and describes a component as a tree of nodes and properties:
.spatial(2) — a multiple of the space unit, resolved against the current densityFactor — rather than a fixed point value. That indirection is what lets density stay continuous.
The per-brand index.gen.swift aggregates brand data and the resolved descriptor for each component into one entry point, keyed by component name.
Every generated file carries a
@generated-substrate header and is a build artifact. Never edit one — changes belong in the brand YAML, then regenerate with npm run generate:tokens:swift from a Substrate checkout.Android / Kotlin
The Compose mirror of this output, plus the Material ColorScheme bridge.
Modes Overview
Why four files exist and dimmed doesn’t, and what the preference vector controls.