2. Design tokens
Each role has a short name used by themeColor() in code and as a Figma variable ud/<role> in the Theme collection (§9.2).
Esta página está em inglês; a tradução está a caminho.
2.1 Chrome colour roles#
Each role has a short name used by themeColor() in code and as a Figma variable ud/<role> in the Theme collection (§9.2). Reference values are VS Code Dark Modern. Before building the Figma variables, confirm all values with the VS Code command “Developer: Generate Color Theme From Current Settings” in each of the four reference themes: Dark Modern, Light Modern, Dark High Contrast, Light High Contrast.
Role (themeColor name) |
VS Code token | Dark Modern | Used for |
|---|---|---|---|
| background | editor.background |
#1F1F1F |
Default canvas background when the page has none; modal bodies |
| foreground | foreground |
#CCCCCC |
Default text and icons |
| muted | descriptionForeground |
#9D9D9D |
Secondary text, scrub labels, placeholders in lists, frame titles |
| disabled | disabledForeground |
#CCCCCC80 |
Disabled text and icons |
| icon | icon.foreground |
#CCCCCC |
Codicons in chrome |
| surface | sideBar.background |
#181818 |
Left and right panels |
| surfaceBorder | sideBar.border |
#2B2B2B |
Panel edge next to the canvas |
| header | sideBarSectionHeader.background |
#181818 |
Section headers |
| raised | editorWidget.background |
#202020 |
Floating tool bar, popovers, agent pill, review bar |
| border | widget.border |
#313131 |
Raised surfaces, cards, tiles |
| divider | panel.border |
#2B2B2B |
Lines between sections and regions |
| shadow | widget.shadow |
#0000005C |
Shadows of raised surfaces |
| tab | tab.inactiveBackground |
#181818 |
Panel tab row |
| tabForeground | tab.inactiveForeground |
#9D9D9D |
Inactive tab label |
| tabActive | tab.activeBackground |
#1F1F1F |
Not used for panel tabs (they are text tabs); used in the preview player tab strip |
| tabActiveForeground | tab.activeForeground |
#FFFFFF |
Active tab label |
| tabBorder | tab.activeBorderTop |
#0078D4 |
2 px underline of the active tab |
| hover | list.hoverBackground |
#2A2D2E |
Row hover in trees and lists |
| toolbarHover | toolbar.hoverBackground |
#5A5D5E50 |
Icon button hover |
| toolbarActive | toolbar.activeBackground |
#63666750 |
Icon button pressed |
| selected | list.activeSelectionBackground |
#04395E |
Selected row, focused tree |
| selectedForeground | list.activeSelectionForeground |
#FFFFFF |
Text on selected row |
| inactiveSelected | list.inactiveSelectionBackground |
#37373D |
Selected row when the tree has no focus |
| highlight | list.highlightForeground |
#2AAAFF |
Matched characters in search results |
| drop | list.dropBackground |
#383B3D |
Drop target container row |
| indentGuide | tree.indentGuidesStroke |
#585858 |
Layer tree indent guides |
| input | input.background |
#313131 |
Fields |
| inputBorder | input.border |
#3C3C3C |
Field border |
| placeholder | input.placeholderForeground |
#989898 |
Placeholder text |
| dropdown | dropdown.background |
#313131 |
Dropdown closed |
| dropdownBorder | dropdown.border |
#3C3C3C |
Dropdown border |
| dropdownList | dropdown.listBackground |
#1F1F1F |
Dropdown open list |
| checkbox | checkbox.background |
#313131 |
Checkbox box |
| checkboxBorder | checkbox.border |
#3C3C3C |
Checkbox border |
| optionActive | inputOption.activeBackground |
#2489DB82 |
Selected segment, toggled icon button (e.g. “Clip content”) |
| optionActiveBorder | inputOption.activeBorder |
#2488DB |
Border of selected segment |
| optionActiveForeground | inputOption.activeForeground |
#FFFFFF |
Icon on selected segment |
| focus | focusBorder |
#0078D4 |
Focus ring; canvas selection, hover outline, noodles |
| button | button.background |
#0078D4 |
Primary button |
| buttonForeground | button.foreground |
#FFFFFF |
Primary button label |
| buttonHover | button.hoverBackground |
#026EC1 |
Primary button hover |
| buttonBorder | button.border |
#FFFFFF12 |
Button border |
| buttonSecondary | button.secondaryBackground |
#313131 |
Secondary button |
| buttonSecondaryForeground | button.secondaryForeground |
#CCCCCC |
Secondary button label |
| buttonSecondaryHover | button.secondaryHoverBackground |
#3C3C3C |
Secondary button hover |
| link | textLink.foreground |
#4DAAFC |
Links, “Go to main component” |
| menu | menu.background |
#1F1F1F |
Context menus |
| menuBorder | menu.border |
#454545 |
Menu border |
| menuSelection | menu.selectionBackground |
#0078D4 |
Highlighted menu item |
| menuSelectionForeground | menu.selectionForeground |
#FFFFFF |
Highlighted menu item text |
| menuSeparator | menu.separatorBackground |
#454545 |
Menu separators |
| tooltip | editorHoverWidget.background |
#252526 |
Tooltips |
| tooltipBorder | editorHoverWidget.border |
#454545 |
Tooltip border |
| keycap | keybindingLabel.background |
#8080802B |
Shortcut key caps |
| keycapForeground | keybindingLabel.foreground |
#CCCCCC |
Key cap text |
| keycapBorder | keybindingLabel.border |
#33333399 |
Key cap border |
| keycapBottom | keybindingLabel.bottomBorder |
#44444499 |
Key cap bottom edge |
| quickInput | quickInput.background |
#222222 |
Quick actions palette |
| notification | notifications.background |
#1F1F1F |
Toasts |
| status | statusBar.background |
#181818 |
Editor status strip |
| statusForeground | statusBar.foreground |
#CCCCCC |
Status strip text |
| statusBorder | statusBar.border |
#2B2B2B |
Status strip top line |
| statusHover | statusBarItem.hoverBackground |
#F1F1F133 |
Status item hover |
| badge | badge.background |
#616161 |
Counts |
| badgeForeground | badge.foreground |
#F8F8F8 |
Count text |
| progress | progressBar.background |
#0078D4 |
Progress bars, AI step progress |
| scrollbar | scrollbarSlider.background |
#79797966 |
Panel scroll bars |
| sash | sash.hoverBorder |
#0078D4 |
Panel splitter hover and drag |
| code | textCodeBlock.background |
#2B2B2B |
Code snippets in Inspect, script console |
| danger | errorForeground |
#F85149 |
Error text |
| errorBorder | inputValidation.errorBorder |
#BE1100 |
Field with invalid expression |
| errorBackground | inputValidation.errorBackground |
#5A1D1D |
Error message under a field |
| editorError | editorError.foreground |
#F14C4C |
Error icon |
| warning | editorWarning.foreground |
#CCA700 |
Warnings, missing font |
| info | editorInfo.foreground |
#3794FF |
Info icon |
| success | charts.green |
#89D185 |
Success, accepted, “Ready for dev” |
| red | charts.red |
#F14C4C |
Measurements, smart guides, layout grids, auto layout spacing |
| purple | charts.purple |
#B180D7 |
Components and instances |
| blue | charts.blue |
#3794FF |
Info, prototype flow start |
| orange | charts.orange |
#D18616 |
Changed overrides, modified marker |
| yellow | charts.yellow |
#CCA700 |
Comments pins (unresolved) |
| contrastBorder | contrastBorder |
none (HC: #6FC3DF) |
Extra border on every surface in high contrast |
| contrastActiveBorder | contrastActiveBorder |
none (HC: #F38518) |
Focus and selection in high contrast |
Scrim behind modals is a literal rgba(0, 0, 0, 0.45) in every theme. It is not chrome colour; it dims the canvas.
2.2 Canvas overlay colours#
The canvas renderer (Canvas 2D) draws overlays above the document. It reads the computed values of these roles from the webview’s CSS variables and repaints on theme change (§8).
| Overlay | Role | Weight / opacity |
|---|---|---|
| Hover outline | focus | 1 px |
| Selection box and handles stroke | focus | 1 px; HC: contrastActiveBorder 2 px |
| Handle fill | literal #FFFFFF |
8 × 8 squares |
| Size label pill | fill focus, text #FFFFFF |
16 px tall |
| Component / instance outline, frame title, handles | purple | 1 px |
| Smart guides, distance labels, measurement redlines | red | 1 px, labels filled red, white text |
| Auto layout padding and gap | red at 18 % with 45° hatch at 30 % on hover | Shown on hover of padding/gap fields or handles |
| Layout guides (grids) | red at 10 % | User colour if the guide sets one |
| Prototype noodles | focus | 1.5 px with arrow head |
| Text edit caret and range | focus, range at 30 % | 1 px caret |
| Pixel grid | foreground at 8 % | Above 400 % zoom (CAN-5) |
| Agent flash | actor colour | 2 px outline, name tag |
| Comment pins | yellow (unresolved), muted (resolved) | §4.24 |
2.3 Actor colours#
Actor colours are document data, not theme colours, so they are literals. They mark who changed a node (flash, history, avatars).
| Actor | Colour | Rule |
|---|---|---|
| You (the local user) | role focus | Your own changes do not flash. |
Claude (AI panel or Claude Code via ud) |
#D97757 |
Reserved. Never hashed to another actor. |
Other ud clients and git authors |
From a fixed palette of 8: #3794FF, #89D185, #B180D7, #D18616, #4EC9B0, #F14C4C, #CCA700, #C586C0 |
colorFor(actorName) hashes the name to the palette, the same function the CLI uses. |
Avatars are 20 px circles with the actor colour and the first letter in #FFFFFF, caption font. Claude’s avatar shows the Claude spark mark instead of a letter.
2.4 Type scale#
The family is var(--vscode-font-family) and the mono family is var(--vscode-editor-font-family). In Figma, use Inter for the UI family and JetBrains Mono for mono as stand-ins; both are bundled fonts (TXT-6).
themeFont role |
Value | Used for |
|---|---|---|
| display | 600 26px/1.2 | Empty file title only |
| heading | 600 20px/1.3 | Modal titles at 640 px and wider |
| subheading | 600 15px/1.35 | Modal titles under 640 px, template card titles |
| body | 400 13px/1.5 | Default text, layer names, menu items, tab labels |
| strong | 600 13px/1.5 | Selection name in the right panel header, file name, active tab |
| small | 400 12px/1.4 | Field values (with font-variant-numeric: tabular-nums), dropdown values, row secondary text |
| caption | 600 11px/1.3 | Section headers (sentence case, not upper case), badges |
| tiny | 400 11px/1.3 | Scrub labels inside fields, status strip, frame titles on canvas, size labels, tooltips’ shortcut |
| code | 400 12px/1.5 mono | Code snippets, script console, hex values in colour picker, ud commands |
2.5 Spacing#
The scale is 4/8: 4, 8, 12, 16, 24, 32, 40, 48. Values 2 and 6 are allowed only inside a control (icon to label gap, key cap padding).
| Spacing | Use |
|---|---|
| 4 | Gap between icon buttons in a group; tool bar inner padding vertical (6 inside) |
| 8 | Gap between two fields in a row; gap between rows; panel right padding |
| 12 | Indent per layer level; section bottom padding |
| 16 | Panel left padding; modal padding of small modals; distance of floating bars from canvas edges |
| 24 | Modal padding at 640 px and wider; gap between template cards |
| 32 | Empty state blocks |
2.6 Radii#
| Radius | Use |
|---|---|
| 2 | Colour swatches, checkbox |
| 4 | Fields, dropdowns, buttons, icon buttons, rows, segments, key caps (3 inside) |
| 6 | Menus, tooltips, toasts, asset tiles, template cards |
| 8 | Popovers (colour picker, interaction editor, comment thread), modals |
| 12 | Floating tool bar, quick actions palette |
| h/2 | Pills: agent pill, size label (radius 3 at 16 px, as Figma), badges, avatars |
2.7 Sizes#
| Element | Size |
|---|---|
| Row (tree, list, menu), field, dropdown, icon button, segmented control | 24 tall |
| Tool bar button | 32 × 32 |
| Section header | 32 tall |
| Panel tab row | 36 tall |
| Panel header | 40 tall |
| Status strip | 22 tall |
| Codicon | 16 × 16 in a 24 or 32 box |
| Avatar | 20 |
| Colour swatch | 16 × 16 in a 24 slot |
| Focus ring | 1 px focus, offset −1 inside fields and rows, +1 around buttons |
2.8 Elevation and stacking#
| Layer | z-index | Shadow |
|---|---|---|
| Canvas | 0 | none |
| Canvas overlays (selection, guides, pins) | 10 | none |
| Floating tool bar, agent pill, review bar, minimap | 50 | 0 2px 8px shadow |
| Panels | 60 | none (divider line) |
| Modals and scrim | 900 | 0 8px 32px shadow |
| Popovers and menus | 1000 | 0 4px 16px shadow |
| Toasts | 1100 | 0 4px 16px shadow |
| Tooltips | 1200 | 0 2px 8px shadow |
2.9 Icons#
Codicons at 16 px, coloured by icon through createIcon(name, 16) (mask image). Where codicons have no fitting glyph, custom icons are drawn on the 16 px codicon grid (1 px stroke on a 14 px live area, square caps) and stored in media/resources/icons/. They render through the same mask-image path, so they take theme colours.
| Need | Codicon | Custom icon (media/resources/icons/) |
|---|---|---|
| Move, Scale | — | ud-move.svg, ud-scale.svg |
| Frame | symbol-numeric as fallback |
ud-frame.svg (hash frame) |
| Section | — | ud-section.svg |
| Slice | — | ud-slice.svg |
| Rectangle, Ellipse, Line, Arrow, Polygon, Star | primitive-square, circle-large, — |
ud-line.svg, ud-arrow.svg, ud-polygon.svg, ud-star.svg |
| Image | file-media |
— |
| Pen, Pencil | edit (pencil) |
ud-pen.svg |
| Text | text-size |
— |
| Hand | — | ud-hand.svg |
| Comment | comment |
— |
| Quick actions | search |
— |
| AI | sparkle |
— |
| Inspect | code |
— |
| Component, instance | symbol-class as fallback |
ud-component.svg, ud-instance.svg |
| Auto layout direction, wrap, grid | arrow-down, arrow-right |
ud-al-wrap.svg, ud-al-grid.svg |
| Align and distribute (6 + 2) | — | ud-align-*.svg, ud-distribute-*.svg |
| Boolean ops (4) | — | ud-bool-*.svg |
| Corner radius, independent corners | — | ud-radius.svg, ud-corners.svg |
| Padding H/V, gap | — | ud-pad-h.svg, ud-pad-v.svg, ud-gap.svg |
| Stroke weight, sides | — | ud-stroke-weight.svg, ud-stroke-sides.svg |
| Blend mode | — | ud-blend.svg |
| Visibility, lock | eye, eye-closed, lock, unlock |
— |
| Variables, styles | symbol-variable, symbol-color |
— |
| Layers, assets, pages | layers, library, files |
— |
| History | history |
— |
| Export | export |
— |
| Play / preview | play |
— |
| Zoom | zoom-in, zoom-out, screen-full |
— |
| Rulers | symbol-ruler |
— |
| Snap | magnet |
— |
| Target / go to main | target, go-to-file |
— |
| Drag grip | gripper |
— |
| Stop | debug-stop |
— |
2.10 Motion#
| Motion | Duration | Easing |
|---|---|---|
| Hover, pressed | 0 ms (instant, as VS Code) | — |
| Popover, menu open | 100 ms fade | ease-out |
| Panel collapse | 150 ms width | ease-out |
| Toast in / out | 150 ms slide 8 px + fade | ease-out |
| Agent flash | 1200 ms outline fade | linear after 600 ms hold |
| Zoom to selection | 200 ms | ease-in-out |
With prefers-reduced-motion: reduce, all durations are 0 and the agent flash becomes a static outline for 2 s.