Foundation
Theming
style.cssDOM Studio uses css variable design tokens: base tokens paint skins, and matching -fg tokens keep text readable.
Model
Colour and fg pairs
Use the base token when you are painting a background. Use the matching *-fg token when text or icons need to sit on it.
Filled action
bg-primary
text-primary-fg
Quiet panel
bg-secondary
text-secondary-fg or text-canvas-fg
Token naming convention
- Bg token
- DOM Studio --primary
- Fg token
- DOM Studio --primary-fg
- Added pairs
- primary, secondary, muted, accent, status
At a glance
Read the theme as product UI
Project dashboard
Example composition using only semantic tokens.
Revenue
GBP 42,860
Quiet panel
Secondary skins group nearby controls without demanding attention.
Review needed
Warning tokens should feel noticeable, not alarming.
Command menu
Editor
Tune CSS variable colours
Primary - light
--primary: oklch(0.205 0 0)
Corners
The base radius that feeds the rounded scale.
Shape preview
Radius is still global because it affects every rounded utility.
Rounded frame
Uses the same radius scale as components.
Skin recipes
These Tailwind-like utilities carry material, border, shadow, blur, and gradient from variables.
Card
skin-card
Cards, panels, calendars, and grouped content.
--skin-card-bg
--skin-card-fg
--skin-card-shadow
Drop shadow
--skin-card-backdrop
--skin-card-bg-image
Popover
skin-popover
Dropdowns, popovers, combobox menus, and context menus.
--skin-popover-bg
--skin-popover-fg
--skin-popover-shadow
Drop shadow
Drop shadow
--skin-popover-backdrop
--skin-popover-bg-image
Dialogs, drawers, command palettes, and action sheets.
--skin-overlay-bg
--skin-overlay-fg
--skin-overlay-shadow
Drop shadow
Drop shadow
--skin-overlay-backdrop
--skin-overlay-bg-image
Input
skin-input
Inputs, textareas, selects, and editable controls.
--skin-input-bg
--skin-input-fg
--skin-input-shadow
Inner shadow
--skin-input-backdrop
--skin-input-bg-image
Control
skin-control
Secondary buttons, quiet triggers, and neutral controls.
--skin-control-bg
--skin-control-fg
--skin-control-shadow
Drop shadow
--skin-control-backdrop
--skin-control-bg-image
Action
skin-action
Primary actions and high-emphasis commands.
--skin-action-bg
--skin-action-fg
--skin-action-shadow
Drop shadow
--skin-action-backdrop
--skin-action-bg-image
Fill 1
Light mode
:root
Canvas
Page background and ordinary text.
Canvas
Page background and ordinary text.
Primary
Primary actions and high emphasis selected states.
Primary
Primary actions and high emphasis selected states.
Secondary
Quiet buttons, subtle panels, inactive controls, and helper UI.
Secondary
Quiet buttons, subtle panels, inactive controls, and helper UI.
Muted
Low-emphasis backgrounds and supporting copy.
Muted
Low-emphasis backgrounds and supporting copy.
Accent
Hover, focus, active rows, and soft selected states.
Accent
Hover, focus, active rows, and soft selected states.
Destructive
Delete, remove, error, and irreversible actions.
Destructive
Delete, remove, error, and irreversible actions.
Success
Saved, complete, connected, and positive confirmation states.
Success
Saved, complete, connected, and positive confirmation states.
Warning
Attention, pending review, expiring, and recoverable risk states.
Warning
Attention, pending review, expiring, and recoverable risk states.
Edges and focus
Borders, input chrome, and keyboard focus rings.
Dark mode
[data-theme="dark"]
Canvas
Page background and ordinary text.
Canvas
Page background and ordinary text.
Primary
Primary actions and high emphasis selected states.
Primary
Primary actions and high emphasis selected states.
Secondary
Quiet buttons, subtle panels, inactive controls, and helper UI.
Secondary
Quiet buttons, subtle panels, inactive controls, and helper UI.
Muted
Low-emphasis backgrounds and supporting copy.
Muted
Low-emphasis backgrounds and supporting copy.
Accent
Hover, focus, active rows, and soft selected states.
Accent
Hover, focus, active rows, and soft selected states.
Destructive
Delete, remove, error, and irreversible actions.
Destructive
Delete, remove, error, and irreversible actions.
Success
Saved, complete, connected, and positive confirmation states.
Success
Saved, complete, connected, and positive confirmation states.
Warning
Attention, pending review, expiring, and recoverable risk states.
Warning
Attention, pending review, expiring, and recoverable risk states.
Edges and focus
Borders, input chrome, and keyboard focus rings.
:root {
--radius: 0.625rem;
}
:root {
--canvas: oklch(1 0 0);
--canvas-fg: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-fg: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-fg: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-fg: oklch(0.5 0 0);
--accent: oklch(0.97 0 0);
--accent-fg: oklch(0.205 0 0);
--destructive: oklch(0.583 0.239 28.476);
--destructive-fg: oklch(0.985 0 0);
--success: oklch(0.632 0.186 147.369);
--success-fg: oklch(0.985 0 0);
--warning: oklch(0.839 0.16 84.07);
--warning-fg: oklch(0.281 0.07 46.31);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.709 0 0);
}
[data-theme="dark"] {
--canvas: oklch(0.145 0 0);
--canvas-fg: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-fg: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-fg: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-fg: oklch(0.709 0 0);
--accent: oklch(0.269 0 0);
--accent-fg: oklch(0.985 0 0);
--destructive: oklch(0.702 0.189 22.228);
--destructive-fg: oklch(0.985 0 0);
--success: oklch(0.702 0.158 160.438);
--success-fg: oklch(0.145 0 0);
--warning: oklch(0.772 0.173 65.367);
--warning-fg: oklch(0.145 0 0);
--border: oklch(0.269 0 0);
--input: oklch(0.321 0 0);
--ring: oklch(0.556 0 0);
}Tokens
Palette and pairs
Background
bg-canvas text-canvas-fg
The app canvas and ordinary page text.
Primary
bg-primary text-primary-fg
Primary actions and high emphasis selected states.
Secondary
bg-secondary text-secondary-fg
Quiet buttons, subtle panels, inactive controls, and helper UI.
Muted
bg-muted text-muted-fg
Low-emphasis backgrounds and supporting copy.
Accent
bg-accent text-accent-fg
Hover, focus, active rows, and soft selected states.
Destructive
bg-destructive text-destructive-fg
Delete, remove, error, and irreversible actions.
Success
bg-success text-success-fg
Saved, complete, connected, and positive confirmation states.
Warning
bg-warning text-warning-fg
Attention, pending review, expiring, and recoverable risk states.
Border
--borderEdges, separators, low-emphasis rings, and component outlines.
border-border ring-border divide-border
Input
--inputInput borders and control tracks that should read as editable.
border-input bg-canvas
Ring
--ringKeyboard focus, inspector selection, and strong focus affordances.
focus-visible:ring-ring outline-ring
Decision guide
Which token should I use?
| Intent | Utility | Rule of thumb |
|---|---|---|
| Page canvas | bg-canvas text-canvas-fg | Use for the actual app canvas; it is driven directly by --canvas and --canvas-fg. |
| Card or panel | skin-card | Use for grouped content that needs the standard card material. |
| Popover or menu | skin-popover | Use for layers attached to a trigger. |
| Dialog or drawer | skin-overlay | Use for modal and app-level overlay panels. |
| Input chrome | skin-input | Use for editable controls and select-like triggers. |
| Primary button | skin-action | Use for high-emphasis commands. |
| Secondary button | skin-control | Use for quiet controls and neutral triggers. |
| Menu item hover | hover:bg-accent hover:text-accent-fg | Use accent for temporary interaction states. |
| Helper copy | text-muted-fg | Use for hints, captions, placeholders, and metadata. |
| Danger action | text-destructive or bg-destructive text-destructive-fg | Text-only for subtle danger, filled for destructive confirmation. |
| Success status | bg-success text-success-fg | Use for positive, completed, or saved states. |
| Warning status | bg-warning text-warning-fg | Use when attention is needed but the action is recoverable. |
| Focus state | focus-visible:ring-ring | Use for keyboard focus, usually with a transparent offset. |
Code
Define and consume tokens
:root {
--radius: 0.625rem;
--canvas: oklch(0.984 0.003 247);
--canvas-fg: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-fg: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-fg: oklch(0.205 0 0);
--success: oklch(0.57 0.794 149.350);
--success-fg: oklch(0.985 0 0);
--warning: oklch(0.7 0.2 84);
--warning-fg: oklch(0.28 0.07 46);
}
:root {
--skin-popover-bg: color-mix(in oklch, var(--canvas) 88%, transparent);
}<button class="skin-action rounded-full px-4 py-2">
Save changes
</button>
<div class="skin-card rounded-2xl p-4">
<p class="text-sm text-muted-fg">Use secondary text inside a card.</p>
</div>
<div class="skin-popover rounded-2xl p-2">
<button class="rounded-xl px-3 py-2 hover:bg-accent hover:text-accent-fg">
Open project
</button>
</div>