Design tokens
Variables for a canvas — colours, spacing, radii and type that every frame and agent shares.
A design token is a named value a canvas owns: color-primary, radius-card,
font-heading. Frames use it as an ordinary CSS variable, var(--color-primary), so changing
the token once restyles every frame that names it — the person who edits in the Design panel and the agent that
writes HTML over MCP are reading the same list. Tokens carry a value per theme, so one frame can
switch to dark, compact or a brand variant without a second copy of the design. If you have used variables in
Figma or tokens in Paper, this is the same idea.
What a token is
Every token has a type, a name, a value and an optional note on when to reach for it. There are eleven types, in three groups:
- Colour — color, opacity, radius.
- Layout — spacing, container, breakpoint.
- Type — font family, font weight, font size, line height, letter spacing.
Names are typed without the leading dashes (color-primary) and used in CSS with them
(var(--color-primary)). Letters, digits, hyphens and underscores are allowed; spaces become hyphens.
A name is unique on its canvas, and a canvas holds up to 500 tokens.
A value is one CSS value — #0177d3, 12px, 'Inter', sans-serif, 1.4.
It can also be var(--other-token), which aliases another token on the same canvas:
color-button pointing at color-primary, say. Aliases must resolve, and a token another
token aliases cannot be deleted until the alias is repointed.
Create and edit tokens
Open the Layers panel and switch to its Tokens tab (the braces icon; the collapsed
rail has the same button). The tab lists the canvas's tokens folded by type, like frames in the layer tree. Press
+ beside the Tokens heading, pick a type, and the new token opens with a suggested name
(color-2, radius-1) and a default value for its type. Each type gets a fitting control: a
swatch and hex field for colours, font and weight lists for type, a number with its unit for everything else — drag
the glyph at the left of a number to scrub it, as in the Design panel. Enter saves.
Click a token to edit it, rename it, add a note, or delete it. A rename rewrites every
var(--old-name) in every frame and in any token that aliased it, so nothing breaks. A
delete leaves frames naming the token; they fall back to whatever default they wrote until a token
of that name exists again.
Bind a field in the Design panel
You rarely need the Tokens tab to use a token. Select an element and the Design panel's fill,
stroke and text colour, corner radius, font size,
font family and font weight fields each carry a braces button — it appears over
the field's unit on hover, or beside the font selects. Click it to pick from the canvas's tokens of that kind; the
field now writes var(--name) and shows the token as a chip with its resolved swatch. The broken-chain
button beside the chip detaches it back to the literal value.
The same menu has a +: it takes the field's current value, asks for a name, and creates the token and binds the field in one step — Figma's "create variable from this fill", for any of the seven fields.
Themes
Every canvas has a default theme, the value you set first. Up to eight more — dark,
compact, brand-b, any lowercase slug — give a token a second value where it should
differ. In the token editor a segmented switch flips between default and each theme; a dot marks a
theme that overrides, and the reset beside the field puts it back to following the default. A theme is declared
the first time a token names it, or from the Themes heading's + in the Tokens tab.
Right-click a theme row to rename it (its values follow) or delete it (its values go with it).
A frame picks its theme with one attribute on its root: <html data-doop-theme="dark">. Put the
same attribute on a subtree to theme only part of a frame. On the canvas, selecting a theme row in the Tokens tab
switches the selected frames to it — or every frame on the page when nothing is selected — one undo step per frame.
How frames carry tokens
A frame is always a self-contained HTML document, so Doop writes the values of the tokens a frame names into a
managed <style data-doop-tokens> block at the top of its <head>: a
:root { … } rule with the defaults, then one rule per theme with its overrides. Screenshots, exports
and anything else that reads the frame's HTML get the right values with no extra lookup.
When a token changes, Doop rewrites that block in every frame on the canvas that names it. This is a restyle, not a redesign: a frame marked ready for dev keeps its sign-off, no version is filed, and the activity feed gets one line naming the token and how many frames followed. Leave the block alone — it is regenerated on every save.
Tokens for agents
An agent connected over MCP sees the canvas's tokens and themes in
get_canvas, with a brief telling it to use var(--name) rather than literal values, and has
four tools of its own. The Doop Agent has the same four.
-
get_tokens— the list, filtered bytypesor aname_patternglob, as JSON or rendered ascss,tailwindormarkdown. -
create_tokens— add one or many tokens at once; the payload matches Paper'screate_tokens, so an agent that knows Paper's tokens knows Doop's. -
set_tokens— change values, descriptions and per-theme values, rename withnew_name, ordelete. set_token_themes— the canvas's theme list: add, rename or remove themes in one call.
A brief that leans on tokens tends to produce consistent work across many frames and agents:
Set up tokens for this canvas from the imported homepage — a colour scale, a 4px spacing scale, two radii and the type ramp — with a dark theme. Then rebuild the pricing page using only tokens, no literal colours or sizes.
Export tokens to code
Tokens are meant to leave the canvas. Three formats are available from the REST API and from
get_tokens:
- CSS — the same
:rootand theme rules the frames carry, ready to paste into a stylesheet. - Tailwind — a Tailwind v4
@themeblock. Token names follow Tailwind's namespaces (--color-*,--spacing-*,--radius-*,--font-*…), so the export is a pass-through andbg-primaryorrounded-cardjust work. - Markdown — tables per type with every theme's value and the note, for a design doc or a PR.
# JSON by default; ?format=css | tailwind | md $ curl https://doop.design/api/canvases/<canvas-id>/tokens?format=tailwind # tokens as tables + the :root CSS, followed by every style guide on the canvas $ curl https://doop.design/api/canvases/<canvas-id>/styleguide.md
styleguide.md is the one file a coding agent needs: the tokens as tables, the CSS block, then every
style guide written on the canvas. Drop it into a repo as
its DESIGN.md and the implementation starts from the same values the design used.
Tips
- Name by role, not by value.
color-surfacesurvives a rebrand;color-grey-100does not. Keep raw scales as aliased targets if you want both. - Use a font-family token for your brand face. A library font named only through a token is still embedded in every frame that uses it.
- Theme the few tokens that differ. A dark theme is usually ten colour overrides; everything else inherits the default and stays greyed in the Tokens tab.
- Pair tokens with a style guide. Tokens say what the values are; a guideline says when to use them. Agents read both before they design.