workday/canvas-kit/sana-canvas-kit-tokens
Claude Code and agent skill by workday/canvas-kit
- community
Checking that the SKILL.md file is still in the repository.
Choose Canvas design tokens from @workday/canvas-tokens-web. Use when picking system.color, system.gap, system.padding, system.size, system.shape, or system.type paths; choosing accessible color pairings; migrating deprecated token names (bg.*, text.*, space.*); or deciding base vs system vs brand. For how to apply tokens in CSS see /sana-canvas-kit-styling; for deprecated components/props see /sana-canvas-kit-component-selection.
Install
npx vskill@latest install workday/canvas-kit/sana-canvas-kit-tokensSKILL.md
Canvas Kit Tokens
Which token to use, by role — not a single version's path list. For how to apply tokens (createStyles, createStencil, cs), see /sana-canvas-kit-styling.
REQUIRED SUB-SKILL: /sana-canvas-kit-version. Run it first. This skill's path tables and family names assume current generation (@workday/canvas-kit-react 16.x + @workday/canvas-tokens-web 4.4+, Sana Canvas). If the version skill reports an older install, do not apply the tables below as current truth — use MCP get-canvas-kit-tokens plus the matching upgrade guide instead.
When to apply
- Choosing a color, spacing, shape, size, or typography value
- Pairing a background/foreground/border combination and needing it to stay accessible
- Migrating
@workday/canvas-kit-react/tokensor deprecatedsystem.*paths - Translating Figma variables into token paths
- Reviewing token usage after a codemod (
/sana-canvas-kit-migration)
For full inventories and old→new mapping tables (current-generation only), see references.md. For deeper token docs, call MCP get-canvas-kit-tokens and start with docs://tokens/v4/v4.4-token-reference.
Core rules
- Run `/sana-canvas-kit-version` first — these tables are current-generation only.
- Default to `system.*` — semantic, themeable tokens for almost everything.
- Match the CSS property to the spacing family — wrong family is a semantic error even when
the pixel value matches.
- Pick color by role, then pair by role — don't pick a foreground/background combination by
eyeballing contrast; use the pairing rules below so contrast is guaranteed.
- Never use internal namespaces in application code — see Off-limits.
- Verify in installed `node_modules` —
@deprecatedJSDoc on token paths always wins over
static tables.
Namespaces
| Namespace | Contains | Use for | |
|---|---|---|---|
system | Semantic tokens | Default for everything | |
base | Raw palette and size steps | Escape hatch when no system token fits | |
brand | Tenant-themeable ramps | Brand color outside system.color.brand.* | |
component | Per-component hooks | Overriding one component's internals (systemIcon) |
Each token is a CSS variable name, not a raw value. createStyles wraps whole property values in var() automatically. In template literals, wrap manually: ` 1px solid var(${token}) `.
Off-limits
Do not use these in application code:
system.legacy.*,base.legacy,base.sana,brand.legacy,component.legacy— internal
backward-compat namespace for Canvas Kit's own library source, not for app code
system.sana.*— internal Sana theme implementation detail@workday/canvas-kit-react/tokens(canvas,colors,space,type,depth,borderRadius)
Canvas Kit uses .legacy internally so published components keep working for consumers on older token packages. Write plain system.* and let theme CSS resolve the value.
Color — pick by role
Five families, split by the role the color plays:
| Family | Role | Examples | |
|---|---|---|---|
surface.* | Container/page backgrounds | surface.default, surface.alt.default, surface.modal | |
fg.* | Text, icons, foreground marks | fg.default, fg.muted.default, fg.inverse | |
border.* | Strokes, dividers, outlines | border.default, border.strong, border.input.default | |
accent.* | Solid non-brand emphasis | accent.info, accent.success, accent.ai | |
brand.* | Tenant-brandable semantics | brand.accent.primary, brand.fg.primary.default |
Modifier ladder
Within a family, intensity is short: default, strong, and stronger (on fg only). There is no soft/softer/softest ladder on surface.* — that belonged to removed bg.*.
| Need | Token direction | ||||
|---|---|---|---|---|---|
| Page/card background | system.color.surface.default | ||||
| Subtle alternate surface | system.color.surface.alt.default | ||||
| Body text | system.color.fg.default | ||||
| Secondary/helper text | system.color.fg.muted.default | ||||
| Emphasized text | system.color.fg.strong / fg.stronger | ||||
| Text on dark surfaces | system.color.fg.inverse | ||||
| Divider between sections | system.color.border.default | ||||
| Strong container border | system.color.border.strong | ||||
| Input field border | system.color.border.input.default | ||||
| Status (neutral words) | `fg.danger\ | warning\ | success\ | info + matching surface.*` | |
| Tenant primary actions | system.color.brand.accent.primary | ||||
| Elevation | boxShadow: system.depth[1]–[6] (whole token) |
Deprecated color families
| Don't write | Write | |
|---|---|---|
system.color.bg.* | system.color.surface.* | |
system.color.text.* | system.color.fg.* (brand text → brand.fg.*) | |
system.color.icon.* | system.color.fg.* | |
system.color.border.divider | system.color.border.default | |
system.color.border.container | system.color.border.strong | |
system.color.fg.primary.* | system.color.brand.fg.primary.* | |
system.color.static.* | A base palette ramp |
Only bg.default and bg.alt.default survive; prefer surface.default / surface.alt.default.
Accessible color pairings
Contrast is baked into the semantic token pairs below — pick a pairing, don't compose colors freely. WCAG 2.1 AA requires 4.5:1 for text ≤ 18pt (3:1 for larger/bold text), 3:1 for non-text UI (icons, control borders, focus rings).
Semantic pairs (default — always guaranteed)
| Background / surface | Foreground | Notes | |||||||
|---|---|---|---|---|---|---|---|---|---|
surface.default, surface.alt.default | fg.default, fg.muted.default, fg.strong/stronger | The default pairing for body content | |||||||
| `surface.info\ | danger\ | warning\ | success.default` | matching `fg.info\ | danger\ | warning\ | success.default` | Status surfaces pair with status foregrounds | |
brand.accent.primary (and other solid brand accents) | fg.inverse | Default on solid brand/accent fills | |||||||
brand.accent.caution (and other light brand accents) | fg.contrast — not fg.inverse | Light accents fail with inverse foreground | |||||||
surface.contrast.default | fg.inverse | Dark/contrast surfaces |
Rules
- Match `fg` intensity to its surface/background modifier.
bg.default/surface.defaultuse
fg.default, fg.muted.default, or the stronger foregrounds listed in the semantic-pair table; brand.surface.primary.* uses brand.fg.primary.*. Don't use a foreground from another family.
- `fg.inverse` is for solid accent/brand fills — except light brand accents such as
brand.accent.caution, which use fg.contrast instead.
- Don't put accent fills on alt surfaces — never
accent.*onsurface.alt/bg.alt, even if
a contrast calculator says it passes. This is a design-system rule, not just a math check.
- Don't mix overlay families —
surface.overlay.*is for neutral surfaces;accent.overlay.*
is for accent surfaces. Don't cross them.
- Don't stack translucent `surface.*` fills — many
surface.*tokens use alpha values; nesting
them compounds the wash and can silently drop contrast below the guaranteed ratio.
- Never use color alone to convey state (error, required, success). Pair with an icon and text,
not color alone — see /sana-canvas-kit-accessibility for the full accessible-names guidance.
Escape hatch: composing from base when no semantic pair fits
If you're forced off system.* colors entirely (rare — usually only for data-visualization palettes), use the step-difference framework instead of eyeballing hex values:
| Content type | WCAG level | Target ratio | Required step difference | |
|---|---|---|---|---|
| Text | AA | 4.5:1 | 500+ | |
| Text | AAA | 7:1 | 700+ | |
| Non-text | AA | 3:1 | 400+ (when both steps > 200) | |
| Non-text | AAA | 4.5:1 | 500+ |
The base palette is a 0 (lightest) → 1000 (darkest) tonal scale per color family. Compare step numbers between foreground and background; the difference must meet the table above. Do not invent or estimate a contrast ratio from a hex value — use the step framework or a calculator, and prefer a system.* semantic pair whenever one exists.
MCP: get-canvas-kit-tokens → docs://tokens/color-contrast. Full WCAG scenario guidance (forms, focus indicators, status messaging) lives in /sana-canvas-kit-accessibility — this skill only covers which tokens to pair.
Spacing — three families
| CSS property | Family | |
|---|---|---|
gap, rowGap, columnGap, margin* | system.gap.* | |
padding* | system.padding.* | |
width, height, min/max, inlineSize, blockSize | system.size.* |
system.space.x1–x20 are deprecated. There is no system.space in new code.
Quick reference
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/sana-canvas-kit-tokens/SKILL.md
Popularity
- Repository stars
- 367
- Repository forks
- 270
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/workday/canvas-kit/sana-canvas-kit-tokens)