Skip to main content
DOCS

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:

colorspacingtypographyfoundation

Property

Often maps to a CSS property, but can also represent a broader target or subcategory.

Examples:

backgroundtextbordermarginpaddingutility

Variant / Modifier

Describes the variant of the target. If no variant is needed, this slot serves as the modifier instead.

Examples:

primaryinversesecondarybranddanger

Modifier (Optional)

Adds nuance like state, tone, or relative behaviors. Always includes a default.

Examples:

defaultdisabledhoverstrongestlargest

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.

This is the schema Zaklad uses by default in the wizard and every built-in template, and it suits most design systems. The platform does not enforce this structure. You can use any naming convention and any depth that fits your team. The default is a starting point, not a constraint. Multi-word names (like a palette called Burning Orange) are stored in camelCase by default, so the exported token object stays dot-navigable (color.burningOrange). Prefer hyphens? Switch a project to kebab-case in Project Settings; existing names are left as they are.

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.

Foundationrequired · raw values

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.

Semanticoptional · named intent

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.

Componentoptional · scoped slots

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.

Color

Foundation

foundation.color.brand.500 #2563EB light
foundation.color.brand.600 #1d4ed8 dark

Semantic

color.background.primary
light dark

Component

button.background.default
Spacing

Foundation

dimension.base16px

Foundation

dimension.100dimension.base × 1 = 16px

Semantic

spacing.margin.default

Component

button.padding.horizontal
Tutorial: Three token layers on the Zaklad blog walks through this in depth.

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.500

They 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.

Tutorial: Responsive without breakpoints on the Zaklad blog walks through this in depth.

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.

TokenExpressionValue
dimension.25base × 0.254px
dimension.50base × 0.58px
dimension.75base × 0.7512px
dimension.100base × 116px
dimension.150base × 1.524px
dimension.200base × 232px
dimension.300base × 348px

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.

Tutorial: Computational tokens on the Zaklad blog walks through this in depth.

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 ms or s (for example, 150ms). The Motion Builder generates a named ramp of five steps: instant, fast, normal, slow, slower. These live at motion.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), and inOut (balanced, for most UI transitions). These live at motion.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 in curve is cubic-bezier(0, 0, 0, 1), out is cubic-bezier(0.3, 0, 1, 1), inOut is 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.

Motion is a code-side concern only. Duration, easing, and transition tokens are emitted into the generated package and generate a 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.