Documentation.
Reference for designers, developers, and anyone using the platform.
What's fixed and what's yours
Zaklad is flexible about how you structure your tokens. Two things are fixed by the platform: the layer order (Foundation feeds Semantic, Semantic feeds Component) and the XS–XL sizing context. Everything else is up to you: naming conventions, which layers you actually use, whether you adopt calculated dimensions.
Fixed by the platform
- Layer order: Foundation feeds Semantic, Semantic feeds Component
- XS–XL sizing context for responsive and cross-platform outputs
Up to you
- Token naming convention and depth
- Which layers to populate: Foundation only, Foundation + Semantic, or all three
- Whether to use calculated dimensions or set values manually
The sections below describe how the wizard and built-in templates are set up, and why. They are explanations of an approach, not requirements.
Token Naming Schema
This is the naming schema the wizard and all built-in templates use. You are not required to follow it; any naming convention works in Zaklad.
Category
Defines the type of token. It sets the domain.
Examples:
Property
Often maps to a CSS property, but can also represent a broader target or subcategory.
Examples:
Variant / Modifier
Describes the variant of the target. If no variant is needed, this slot serves as the modifier instead.
Examples:
Modifier (Optional)
Adds nuance like state, tone, or relative behaviors. Always includes a default.
Examples:
The Modifier slot is optional. When a token has no distinct variant, the third slot acts as the modifier and the path stays three segments: color.text.default. When both variant and modifier are present, paths are four segments: color.background.primary.default.
The three-layer cascade
The layer order is fixed: Foundation feeds Semantic, Semantic feeds Component. Which layers you actually populate is up to you. Foundation is the only requirement. Add Semantic to unlock theming. Add Component to enable per-component fine-tuning. Most projects benefit from all three.
Actual values: a hex color, a pixel number, a font name. Values can be calculated (e.g. base × 4) and calculations chain infinitely. Color values are theme-aware; the same path resolves to a different hex in light vs. dark.
References a foundation token by name. Has no value of its own; one name resolves to different foundation values per theme, making light/dark and any other theme automatic.
A private token map for a single component. Not globally accessible. Encouraged to reference semantic tokens. Edit a component's slots in the editor and it updates everywhere, no developer or designer required.
An edit flows downward through the chain: update a foundation value and every semantic token referencing it resolves the new value immediately, carrying that change into every component token, every theme, every platform output, and every Figma variable in one operation.
Foundation
↓
Semantic
↓
Component
Foundation
↓
Foundation
↓
Semantic
↓
Component
Why aliases, not raw values in semantics
Semantic tokens reference foundation tokens by path, not by value. The reason is cognitive load. When a developer or designer looks at the chain:
button.bg.default → color.bg.primary → foundation.color.brand.500They can trace the intent at every level without needing to know the hex. Debugging a theme inconsistency means following a chain of named references, not grepping for a color value through hundreds of files.
It also means changing the entire system's primary color is a single edit to one foundation token. Every semantic and component token that references it via the chain updates automatically, across every theme, every platform, every output simultaneously.
The XS–XL sizing context
The XS–XL sizing context is a fixed part of the platform. It is how Zaklad handles responsive and cross-platform sizing: a single mechanism that covers every device class, from smartwatch to 4K, without any platform-specific logic. We settled on this because it solves all real-world responsive use cases on both web and React Native under one model.
It does not correspond to viewport widths. It describes the density and spatial intent of a surface. Text styles and components carry a separate set of dimension tokens per tier, so font size, line height, spacing, and icon size all step together as the active tier changes.
- XSIoT, smartwatch, and extremely space-constrained surfaces
- SPhone-sized UIs where density matters
- MTablet or compact desktop
- LStandard desktop
- XLLarge desktop and 4K displays
Text styles and components each carry a separate set of dimension tokens per tier: font size, line height, spacing, and icon size all step up or down as the active tier changes. You can lock a platform or screen to specific tiers: use only XS for a smartwatch, XS–S for a mobile-only product, or the full XS–XL spread for a responsive web app. On web, the provider maps viewport widths to tiers automatically; on React Native you supply the active tier directly.
The system is deliberately open-ended. If you are building web only, treat the tiers like CSS breakpoints and let container width drive which tier is active. On cross-platform products, use the tier to communicate intended density independent of the viewport.
Dimension calculations
All foundation dimension steps derive from a single anchor: dimension.base, which is 16px — the same as 1rem in CSS. Every step is a calculated multiple of that base, so changing the base shifts the entire scale proportionally with no manual updates.
The step names are the multiplier value. dimension.100 means 100 × base ÷ 100 = 16px. dimension.50 = 8px, dimension.200 = 32px, and so on.
| Token | Expression | Value |
|---|---|---|
| dimension.25 | base × 0.25 | 4px |
| dimension.50 | base × 0.5 | 8px |
| dimension.75 | base × 0.75 | 12px |
| dimension.100 | base × 1 | 16px |
| dimension.150 | base × 1.5 | 24px |
| dimension.200 | base × 2 | 32px |
| dimension.300 | base × 3 | 48px |
Semantic tokens like spacing.margin.small, spacing.margin.large, and spacing.margin.larger reference these foundation steps by path rather than hardcoding a pixel value. Component tokens then reference those semantic tokens. The result is a single change to dimension.base cascades through every spacing value in the system at once.
Why this approach scales
When you use semantic aliases and calculated foundations together, the system ends up with very few genuine inputs: brand colors, a base dimension, a type scale ratio, a few key font choices. Everything else is derived from those.
A brand refresh becomes a small, predictable changeset. Update the brand colors and the dimension base; the entire system follows. No manual audit of hundreds of token values for inconsistencies.
A new component slots into the existing semantic vocabulary rather than inventing new names. It uses color.bg.primary (the same token as everything else) rather than a new newComponent.primaryBackground that would need to be kept in sync manually.
Motion and numeric token types
Beyond color, dimension, string, and the typography types, the token system covers numeric and motion values so a design system can describe how it moves, not just how it looks.
Primitive types
- Number: a unitless number, for values like opacity (0 to 1), a line-height multiplier, or an aspect ratio.
- Duration: a length of time in
msors(for example,150ms). The Motion Builder generates a named ramp of five steps:instant,fast,normal,slow,slower. These live atmotion.duration.*. - Easing (cubicBezier): a curve stored as four control points
[x1, y1, x2, y2], the shape an animation follows over time. Every easing set emits exactly three directional curves, named for their role:in(entering the screen, decelerates to rest),out(leaving the screen, accelerates away), andinOut(balanced, for most UI transitions). These live atmotion.easing.*.
Easing families
Two easing families are available, both using the same directional names (in/out/inOut) but with different curve values:
- Material: Material Design 3 spatial curves. Expressive and physically grounded; the
incurve is cubic-bezier(0, 0, 0, 1),outis cubic-bezier(0.3, 0, 1, 1),inOutis cubic-bezier(0.2, 0, 0, 1). - Classic CSS: the browser-native ease-in/ease-out equivalents. Widely understood and safe for all audiences.
Transition composites
A Transition composite wires a duration token and an easing token (plus an optional delay token) into one named token. The full set generated by the Motion Builder is 5 speed groups × 3 directions = 15 composites. Speed groups are default, fast, faster, slow, and slower; each has an in, out, and inOut variant. Paths follow the pattern motion.transition.<speedGroup>.<direction> — for example, motion.transition.default.in or motion.transition.fast.out.
Transition tokens are edited in place: the edit modal shows RefPickers for the duration, easing, and optional delay tokens — there is no need to delete and recreate a transition to change which curve it uses.
createAnimations helper with prefers-reduced-motion support built in. The Figma API does not support motion variables, so motion tokens are deliberately excluded from Figma sync.Effects and fills: shadow, gradient, border, blur
Effects and fills are composite tokens: a single named token that binds several parts together, with each part referencing another token so the whole thing stays in sync with your palette and themes. They live at the semantic layer.
- Shadow: offset, blur, spread, and a color (plus optional inset), for example a card or dropdown elevation. Layered shadows stack several of these. Keep a small elevation ladder rather than a bespoke shadow per component; the color part references a color token, so shadows follow the theme.
- Gradient: a kind (linear, radial, or conic), an angle, and a list of color stops, each stop a color token plus a position. Only linear gradients port to mobile; radial and conic are web-only.
- Border: a width (a dimension token), a style, and a color token, bound as one token so the three never drift apart.
- Blur: a radius and a kind (layer blur, or a background/backdrop blur for glass surfaces). Web-first: on mobile, blur is a wrapping component rather than a style.
- Stroke style: the line style a border uses (solid, dashed, or dotted), with an optional custom dash pattern. Dashed and dotted borders are inconsistent on mobile.
In the generated package, shadows and gradients emit as named maps (with theme-aware color variables); borders and blur flow through the usual style props.
These effect types also reflect into Figma. Shadows and blur become effect styles, gradients become paint styles, and borders become variable-aliased strokes with a dash pattern. Each style is published to your file's style library (so it is reusable) and bound automatically on any synced component that uses it. One difference to know: a Figma effect or paint style cannot point at a color variable the way a normal fill can, so a shadow or gradient style stores the color it resolves to in your default theme and is refreshed on every sync. Your token stays the single source of truth; Figma keeps a copy in step with it. Borders are the exception: their weight and color stay live variable aliases, so they update with the theme like any other variable.
Creating and editing composite tokens
To add a composite token, click the add button inside an Effects group in the token canvas and choose the composite kind (Shadow, Gradient, Border, or Blur). A dedicated inline editor appears with the relevant fields. Shadow needs X offset, Y offset, blur radius, spread, and a color token reference; Gradient needs at least two color-token stops and a direction; Border needs a dimension token for width, a stroke style, and a color token reference; Blur needs a dimension token for radius and a kind choice (element blur or background blur).
Editing works through the same inline editor: click the token to open it. The Save button is disabled until all required references are filled. Locked composite tokens display a rich read-only preview of their parts rather than raw values.