Figma → code token sync (QBDS)
Scope: Run only when designers have updated Figma variables and tokens need to flow into code. Skip for component-only work — use the figma-parity skill instead.
Figma source
- File: QBDS v2.0.0
- Variable sets to read:
DS_Themes, Radius, DS-Primitives
- Modes: light and dark (both must be synced)
Use the Figma MCP get_variable_defs tool to read resolved values. Note: search_design_system returns metadata only (no values) — do not use it for syncing.
Code targets (read before editing)
| File |
Role |
docs/TOKENS.md |
Figma ↔ CSS mapping — the Design name column is the canonical Figma variable path for each --* token; read this before syncing |
src/styles/globals.css |
CSS source of truth — primitive + semantic variable definitions and var() bindings |
globals.css structure (preserve layout)
@theme inline — primitives (--mist-*, --slate-*, opacity ladders, brand accents), Tailwind bridge (--color-fill-*, --color-fg-*, --color-surface-*, …), shadcn aliases, radius utilities (--radius-* → --rad-*).
:root — light-mode semantic tokens (--text-*, --border-*, --fill-*, --surface-*, --status-*, --stateslayer-*, --elevations-*) and sharp radius defaults (--rad-*).
.dark — dark-mode semantic tokens (same families as :root).
.radius-mode — rounded radius overrides (--rad-reg, --rad-sm, --rad-md, --rad-lg; --rad-round stays 9999px).
@utility shadow-elevation-* and typography utilities — update only if elevation or type tokens changed in Figma.
Do not remove @custom-variant dark, @custom-variant radius-mode, or the @theme inline → semantic → Tailwind bridge pattern.
Workflow (run in order)
1 — Read Figma variables
Read docs/TOKENS.md — note each token's Design name column (e.g. --fill-active → Fill/Content/Active). These are the canonical Figma paths to match against.
Call the Figma MCP get_variable_defs tool pointing at the QBDS v2.0.0 file and node 1878:17156.
- If the tool responds "nothing selected": this is a known limitation of the Figma plugin sandbox — it checks for an active selection before running, even though
fileKey and nodeId are provided explicitly. Ask the user to open the QBDS v2.0.0 variables page in the Figma desktop app, click any layer, and retry. The selection does not affect the data returned.
- The response contains all file variables with
valuesByMode entries. Most semantic tokens will be VARIABLE_ALIAS references — follow the id to the primitive variable (also in the response) to get the resolved name (e.g. Slate 900/opacity-88).
- Focus on the three local collections:
| Collection |
Modes |
DS_Themes |
Dark and Light |
DS-Primitives |
Value |
Radius |
Sharp and Round |
For each DS_Themes token, resolve both Light and Dark mode aliases to their primitive name and compare against the current var() binding in globals.css.
Build a diff table: Design name (from TOKENS.md) → CSS variable → current var() binding → new binding. Flag renames and removed tokens.
2 — Update globals.css
- Update primitives in
@theme inline if DS-Primitives changed (oklch values, opacity steps).
- Update semantic mappings in
:root (light) and .dark (dark) from DS_Themes.
- Update radius in
:root / .dark (sharp defaults) and .radius-mode (rounded overrides) from Radius.
- Keep semantic tokens referencing primitives via
var(...) — do not inline raw oklch in semantic blocks unless Figma aliases require it.
- Verify the
@theme inline bridge still maps every semantic token to a --color-* utility.
3 — Update docs/TOKENS.md
Only when the token model changed (new/removed/renamed semantic tokens or Figma design names):
- Every
--* semantic variable in globals.css must have a row in the matching TOKENS.md section.
- Design name column = the Figma variable path used in step 1.
- Add/remove/rename rows as needed. Keep "How to choose" and "Quick rules" intact unless the token model itself changed.
If only primitive var() bindings changed in globals.css, TOKENS.md usually needs no edit.
4 — Fix downstream references (if names changed)
If any CSS variable or Tailwind utility was renamed or removed:
# Example greps — extend for each renamed token
rg 'old-token-name' src/
rg '--old-var' src/
Update components, demos, and tests that reference old names. Prefer semantic utilities (bg-fill-active, text-fg-primary) over raw var(...).
Out of scope unless asked: Code Connect publish, registry rebuild, component visual parity (figma-parity).
5 — Verify
npm run build
npm run lint
Report a summary: tokens added/changed/removed, files touched, grep hits fixed, build/lint result.
Acceptance checklist
1---2name: figma-token-sync3description: Sync QBDS Figma variables (DS_Themes, Radius, DS-Primitives) into globals.css and TOKENS.md. Use only when designers have updated Figma variables and tokens need to flow into code (light + dark modes). Triggers — "sync tokens", "figma token sync", "designers updated variables", or a Figma variables URL for the QBDS v2.0.0 file. For component-only work use figma-parity instead.4---56# Figma → code token sync (QBDS)78**Scope:** Run only when designers have updated Figma variables and tokens need to flow into code. Skip for component-only work — use the **figma-parity** skill instead.910## Figma source1112- **File:** [QBDS v2.0.0](https://www.figma.com/design/iuMWqCsIohoKAUB0tBS0xr/QBDS-v2.0.0?node-id=1878-17156&view=variables&p=f&t=z4NTULUiQsv5yiJM-0)13- **Variable sets to read:** `DS_Themes`, `Radius`, `DS-Primitives`14- **Modes:** light and dark (both must be synced)1516Use the Figma MCP `get_variable_defs` tool to read resolved values. Note: `search_design_system` returns metadata only (no values) — do not use it for syncing.1718## Code targets (read before editing)1920| File | Role |21| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |22| [`docs/TOKENS.md`](../../../docs/TOKENS.md) | **Figma ↔ CSS mapping** — the **Design name** column is the canonical Figma variable path for each `--*` token; read this before syncing |23| [`src/styles/globals.css`](../../../src/styles/globals.css) | **CSS source of truth** — primitive + semantic variable definitions and `var()` bindings |2425### `globals.css` structure (preserve layout)26271. **`@theme inline`** — primitives (`--mist-*`, `--slate-*`, opacity ladders, brand accents), Tailwind bridge (`--color-fill-*`, `--color-fg-*`, `--color-surface-*`, …), shadcn aliases, radius utilities (`--radius-*` → `--rad-*`).282. **`:root`** — light-mode semantic tokens (`--text-*`, `--border-*`, `--fill-*`, `--surface-*`, `--status-*`, `--stateslayer-*`, `--elevations-*`) and sharp radius defaults (`--rad-*`).293. **`.dark`** — dark-mode semantic tokens (same families as `:root`).304. **`.radius-mode`** — rounded radius overrides (`--rad-reg`, `--rad-sm`, `--rad-md`, `--rad-lg`; `--rad-round` stays `9999px`).315. **`@utility shadow-elevation-*`** and typography utilities — update only if elevation or type tokens changed in Figma.3233**Do not** remove `@custom-variant dark`, `@custom-variant radius-mode`, or the `@theme inline` → semantic → Tailwind bridge pattern.3435## Workflow (run in order)3637### 1 — Read Figma variables38391. Read [`docs/TOKENS.md`](../../../docs/TOKENS.md) — note each token's **Design name** column (e.g. `--fill-active` → `Fill/Content/Active`). These are the canonical Figma paths to match against.40412. Call the Figma MCP `get_variable_defs` tool pointing at the QBDS v2.0.0 file and node `1878:17156`.42 - If the tool responds "nothing selected": this is a known limitation of the Figma plugin sandbox — it checks for an active selection before running, even though `fileKey` and `nodeId` are provided explicitly. Ask the user to open the [QBDS v2.0.0 variables page](https://www.figma.com/design/iuMWqCsIohoKAUB0tBS0xr/QBDS-v2.0.0?node-id=1878-17156&view=variables&p=f&t=z4NTULUiQsv5yiJM-0) in the Figma desktop app, click any layer, and retry. The selection does not affect the data returned.43 - The response contains all file variables with `valuesByMode` entries. Most semantic tokens will be `VARIABLE_ALIAS` references — follow the `id` to the primitive variable (also in the response) to get the resolved name (e.g. `Slate 900/opacity-88`).44 - Focus on the three local collections:4546 | Collection | Modes |47 | --------------- | --------------- |48 | `DS_Themes` | Dark and Light |49 | `DS-Primitives` | Value |50 | `Radius` | Sharp and Round |51523. For each `DS_Themes` token, resolve both Light and Dark mode aliases to their primitive name and compare against the current `var()` binding in `globals.css`.53544. Build a diff table: Design name (from TOKENS.md) → CSS variable → current `var()` binding → new binding. Flag **renames** and **removed** tokens.5556### 2 — Update `globals.css`57581. Update **primitives** in `@theme inline` if `DS-Primitives` changed (oklch values, opacity steps).592. Update **semantic mappings** in `:root` (light) and `.dark` (dark) from `DS_Themes`.603. Update **radius** in `:root` / `.dark` (sharp defaults) and `.radius-mode` (rounded overrides) from `Radius`.614. Keep semantic tokens referencing primitives via `var(...)` — do not inline raw oklch in semantic blocks unless Figma aliases require it.625. Verify the `@theme inline` bridge still maps every semantic token to a `--color-*` utility.6364### 3 — Update `docs/TOKENS.md`6566Only when the token **model** changed (new/removed/renamed semantic tokens or Figma design names):67681. Every `--*` semantic variable in `globals.css` must have a row in the matching TOKENS.md section.692. **Design name** column = the Figma variable path used in step 1.703. Add/remove/rename rows as needed. Keep "How to choose" and "Quick rules" intact unless the token model itself changed.7172If only primitive `var()` bindings changed in `globals.css`, TOKENS.md usually needs no edit.7374### 4 — Fix downstream references (if names changed)7576If any CSS variable or Tailwind utility was renamed or removed:7778```bash79# Example greps — extend for each renamed token80rg 'old-token-name' src/81rg '--old-var' src/82```8384Update components, demos, and tests that reference old names. Prefer semantic utilities (`bg-fill-active`, `text-fg-primary`) over raw `var(...)`.8586**Out of scope unless asked:** Code Connect publish, registry rebuild, component visual parity (**figma-parity**).8788### 5 — Verify8990```bash91npm run build92npm run lint93```9495Report a summary: tokens added/changed/removed, files touched, grep hits fixed, build/lint result.9697## Acceptance checklist9899- [ ] Figma variables read from `DS_Themes`, `Radius`, `DS-Primitives` (light + dark)100- [ ] `globals.css` updated: primitives, `:root`, `.dark`, `.radius-mode` as needed101- [ ] `@theme inline` bridge intact; no broken `var()` chains102- [ ] `docs/TOKENS.md` matches `globals.css` (including Design name column)103- [ ] Renamed/removed tokens grepped and fixed in `src/`104- [ ] `npm run build` and `npm run lint` pass