Tokens · Token families
Tokens in Figma
The tokens as one design-tokens file for Figma variables and other design tools, with the same names and the three modes.
Files: dist/luz-tokens.dtcg.json, dist/luz-tokens.resolver.json
Not tested in Figma yet
Nobody has imported this file into Figma or Tokens Studio yet. The limits below come from Figma's help and from reports, checked on 9 October 2026. What a test does check is that the file matches the CSS. If you import it, tell us what happened.
Get the file
@luz-ds/tokens includes every token in the W3C Design Tokens (DTCG) JSON format, in one file. pnpm tokens:build generates it from the same sources as the CSS, so the two always match.
node_modules/@luz-ds/tokens/dist/luz-tokens.dtcg.json
- From a bundler or a script:
import tokens from "@luz-ds/tokens/dtcg"(the./dtcgexport). - Without installing anything:
https://cdn.jsdelivr.net/npm/@luz-ds/tokens@0.3.0/dist/luz-tokens.dtcg.json. Download it, then import the downloaded file.
The file has two groups, one for each Figma collection you want:
| Group in the file | Meant as the collection | Modes | Comes from |
|---|---|---|---|
primitives | LUZ primitives | One: Value | tokens.json: colour scales, space, control sizes, type, radius, shadows, font roles, breakpoints, motion |
semantic | LUZ semantic | Light, Dark, High contrast | src/semantic.css: the 63 colours that change with the mode |
A semantic token points at a primitive whenever the CSS does: --luz-divider is var(--luz-gray-20) in light mode, so divider is an alias of {primitives.gray.20}. A font role is an alias of its face: font/body is {primitives.font.serif}. Durations are DTCG durations and easings are cubic Béziers. Layers (z-index) and layout widths ship with @luz-ds/core, so they are not in the file.
One rule for every name
Remove --luz-. The first word becomes the group and the rest becomes the name, joined by a slash.
| CSS custom property | Figma variable | Collection |
|---|---|---|
--luz-surface-page | surface/page | LUZ semantic |
--luz-text-secondary | text/secondary | LUZ semantic |
--luz-color-danger-bg | color/danger-bg | LUZ semantic |
--luz-space-md | space/md | LUZ primitives |
--luz-blue-60 | blue/60 | LUZ primitives |
One exception: --luz-surface is also the name of a group, so in the file it is surface/$root. Figma joins nested groups with slashes, so a tool that keeps the top group writes semantic/surface/page: the rest of the name does not change.
Figma modes and color modes
Each mode of the semantic collection matches one value of data-theme on <html>. So a frame set to Dark in Figma shows what the page shows with data-theme="dark".
| Figma mode | data-theme | Where it is in the file |
|---|---|---|
Light | light, or none | $value, and $extensions.mode.Light |
Dark | dark | $extensions.mode.Dark |
High contrast | high-contrast | $extensions.mode["High contrast"] |
A look of your own, made as that page shows, is not in the file. To have it in Figma, add it as an extra mode and copy its values from its CSS file. This step is optional.
Import it
Two ways in. Neither has been tried with this file yet.
- Tokens Studio or Terrazzo: they read DTCG files, so load this one as it is. The Dark and High contrast values are in
$extensions.mode, a LUZ extension that is not part of the DTCG standard, so check that your tool turns them into modes. - Figma, without a plugin: the Variables panel imports DTCG files, but it makes one mode for each file, and an alias to another collection needs Figma's own
com.figma.aliasDataextension. This file therefore needs a conversion step first, described below. Imported as it is, you get the Light values only.
To convert the file for Figma's own import, with a short script or by hand:
- Write the
primitivesgroup to a file of its own, and import it as the LUZ primitives collection. - For each mode (Light, Dark, High contrast), write a file with the
semanticgroup, where each token's$valueis its value under$extensions.modefor that mode. - In those files, give each alias to a primitive (
{primitives.gray.90}) thecom.figma.aliasDataextension that names the variable in LUZ primitives, or write the colour instead of the alias. - Import the Light file to create the LUZ semantic collection, then each of the other two files with Import mode, named Dark and High contrast.
Files ready for each mode may ship in the package later, once an import has been checked in a real Figma file.
The specification, and where modes live in it
Both files follow the Design Tokens specification 2025.10, a Final Community Group Report of 28 October 2025. It is stable, and it is not a W3C Standard or on the W3C Standards Track.
- The format module describes tokens, groups, types and aliases, and has no modes: a token file holds one value for each token.
luz-tokens.dtcg.jsonis in this format. The$valueof a semantic token is its light value, and the other two modes are in$extensions.mode, a convention that Tokens Studio and Terrazzo read. It is an extension, not part of the specification. - The resolver module is where the specification puts modes, as a modifier: a set of contexts, each listing the token sources to apply after the base.
luz-tokens.resolver.json(the./dtcg/resolverexport) is in this format: the base set is the token file, and the modifiermodehas the contextslight,darkandhigh-contrast, each with the whole semantic group for that mode. The default islight, as:rootis.
node_modules/@luz-ds/tokens/dist/luz-tokens.resolver.json
- Checked against the official schemas. A test validates both files against the JSON Schemas the Community Group publishes for 2025.10 (copied into the repository, no network needed), and that every context gives each token the value the token file keeps for that mode.
- Not checked with a tool. No resolver implementation has loaded the resolver file, and neither Figma nor Tokens Studio has been tried with it. The validation says the file is well formed, not that a given tool understands it.
- The two looks that ship with core are in neither file, as explained above.
Known limits
From Figma's help on modes and import (read on 9 October 2026) or from other users' reports, and not checked against this file:
- Import the primitives before the semantic tokens, which point at them, if your tool makes two collections. Otherwise the aliases cannot resolve.
- Descriptions are lost. Figma's help does not mention them, and users report that they do not arrive. Each token's job is on the Color page.
- Sizes in
remare skipped. Figma takes dimensions inpxonly, and the type scale is inrem. - Font stacks are skipped. Figma takes a single font name, not a list. Set the fonts in Figma's text styles.
- Modes need a paid Figma plan (Professional, Organization, Enterprise or Education), and the number of modes per collection depends on the plan.
Keep Figma and the code in step
- Import again whenever
@luz-ds/tokenschanges version. The file is regenerated with every release. - Never change a value in Figma alone: change the token in the code, and Figma follows on the next import.
- Name your own variables with the same rule, so a designer and a developer use the same words.