Color roles
Text, surface and line roles with one value for light and one for dark.
On this page
Classes
| Class | Declarations |
|---|---|
fg-text-<name> | color: var(--color-text-<name>); |
bg-surface-<name> | background-color: var(--color-surface-<name>); |
b-line-<name> | border-color: var(--color-line-<name>); |
19 other color families
| Class | Declarations |
|---|---|
b-<role>-<name> | border-color: var(--color-<role>-<name>); |
bb-<role>-<name> | border-bottom-color: var(--color-<role>-<name>); |
bg-<role>-<name> | background-color: var(--color-<role>-<name>); |
bl-<role>-<name> | border-left-color: var(--color-<role>-<name>); |
br-<role>-<name> | border-right-color: var(--color-<role>-<name>); |
bt-<role>-<name> | border-top-color: var(--color-<role>-<name>); |
bx-<role>-<name> | border-inline-color: var(--color-<role>-<name>); |
by-<role>-<name> | border-block-color: var(--color-<role>-<name>); |
fg-<role>-<name> | color: var(--color-<role>-<name>); |
bxe-<role>-<name> | border-inline-end-color: var(--color-<role>-<name>); |
bxs-<role>-<name> | border-inline-start-color: var(--color-<role>-<name>); |
bye-<role>-<name> | border-block-end-color: var(--color-<role>-<name>); |
bys-<role>-<name> | border-block-start-color: var(--color-<role>-<name>); |
fill-<role>-<name> | fill: var(--color-<role>-<name>); |
caret-<role>-<name> | caret-color: var(--color-<role>-<name>); |
accent-<role>-<name> | accent-color: var(--color-<role>-<name>); |
stroke-<role>-<name> | stroke: var(--color-<role>-<name>); |
outline-<role>-<name> | outline-color: var(--color-<role>-<name>); |
text-fill-color-<role>-<name> | -webkit-text-fill-color: var(--color-<role>-<name>); |
A role is part of the color key: fg-text-muted reads --color-text-muted through the color namespace. Every color family accepts role keys, including bg-text-link and outline-line-control; the role name does not restrict the property.
Values
Light and Dark are the two arguments of each preset light-dark() value. They are selected by the element’s used color scheme, not by the class prefix or the operating system alone.
Text
| Class | Light | Dark |
|---|---|---|
fg-text-body | var(--color-zinc-70) | var(--color-zinc-30) |
fg-text-strong | var(--color-zinc-100) | var(--color-white) |
fg-text-muted | var(--color-zinc-60) | var(--color-zinc-40) |
fg-text-disabled | var(--color-zinc-40) | var(--color-zinc-60) |
fg-text-inverse | var(--color-white) | var(--color-black) |
fg-text-link | var(--color-blue-60) | var(--color-blue-30) |
fg-text-link-hover | var(--color-blue-70) | var(--color-blue-20) |
fg-text-stone | var(--color-stone-60) | var(--color-stone-30) |
fg-text-gray | var(--color-gray-60) | var(--color-gray-30) |
fg-text-zinc | var(--color-zinc-60) | var(--color-zinc-30) |
fg-text-neutral | var(--color-neutral-60) | var(--color-neutral-30) |
fg-text-slate | var(--color-slate-60) | var(--color-slate-30) |
fg-text-brown | var(--color-brown-60) | var(--color-brown-30) |
fg-text-orange | var(--color-orange-70) | var(--color-orange-30) |
fg-text-amber | var(--color-amber-80) | var(--color-amber-40) |
fg-text-yellow | var(--color-yellow-90) | var(--color-yellow-40) |
fg-text-lime | var(--color-lime-80) | var(--color-lime-40) |
fg-text-green | var(--color-green-80) | var(--color-green-40) |
fg-text-beryl | var(--color-beryl-90) | var(--color-beryl-40) |
fg-text-teal | var(--color-teal-90) | var(--color-teal-40) |
fg-text-cyan | var(--color-cyan-90) | var(--color-cyan-40) |
fg-text-sky | var(--color-sky-70) | var(--color-sky-30) |
fg-text-blue | var(--color-blue-60) | var(--color-blue-30) |
fg-text-indigo | var(--color-indigo-60) | var(--color-indigo-30) |
fg-text-violet | var(--color-violet-60) | var(--color-violet-30) |
fg-text-purple | var(--color-purple-60) | var(--color-purple-30) |
fg-text-fuchsia | var(--color-fuchsia-70) | var(--color-fuchsia-30) |
fg-text-pink | var(--color-pink-80) | var(--color-pink-30) |
fg-text-crimson | var(--color-crimson-80) | var(--color-crimson-30) |
fg-text-red | var(--color-red-80) | var(--color-red-30) |
Surface
| Class | Light | Dark |
|---|---|---|
bg-surface-base | var(--color-zinc-0) | var(--color-zinc-95) |
bg-surface-inset | var(--color-zinc-5) | var(--color-zinc-100) |
bg-surface-raised | var(--color-white) | var(--color-zinc-90) |
bg-surface-floating | var(--color-white) | var(--color-zinc-80) |
bg-surface-inverse | var(--color-black) | var(--color-white) |
Line
| Class | Light | Dark |
|---|---|---|
b-line-divider | oklch(0% 0 none / .12) | oklch(100% 0 none / .12) |
b-line-control | var(--color-zinc-50) | var(--color-zinc-40) |
b-line-subtle | oklch(0% 0 none / .06) | oklch(100% 0 none / .06) |
The local color scheme selects the value
fg-text-muted emits color: var(--color-text-muted). Its preset value uses light-dark(var(--color-zinc-60), var(--color-zinc-40)): light selects the first color, dark the second. The class and generated rule stay the same.
One role, two local color schemes
The used color scheme selects the first or second color. Both specimens keep fg-text-muted and bg-surface-base; the local scheme changes their computed colors.
Text description
- fg-text-muted generates color: var(--color-text-muted). Its preset token contains light-dark(var(--color-zinc-60), var(--color-zinc-40)).
- The light specimen uses the first argument, --color-zinc-60. The dark specimen uses the second, --color-zinc-40.
- Both specimens use bg-surface-base and the same text class. The colored leaders identify the two arguments; they are annotations, not the resulting text colors.
- The local used color scheme selects the branch. The comparison does not imply that system media queries follow a manual local theme.
The preset enables color-scheme: light dark on the root. Its data-theme="light" and data-theme="dark" selectors can choose a scheme on the root, a nested region or a shadow host. Native CSS performs the selection; switching schemes does not require regenerating this utility.
The @dark and @light class suffixes test the system preference. A manual data-theme choice does not activate those media queries. Use the mode contract for selector-based conditions.
A role supplies a color, not a component or a contrast guarantee for every background. Inverse surfaces have a paired inverse text role. Divider and subtle lines are decorative; control lines identify boundaries. Recheck the actual pair when changing a surface, opacity or token value.
See Variables and modes and native light-dark() selection.
Usage
Build a card from roles: a raised surface, a divider line, and strong, body and muted text.
Make space for ideas
A steady rhythm keeps the focus on the content.
4 min read
<article class="… b(1) b-solid b-line-divider bg-surface-raised"> <h3 class="… fg-text-strong">Make space for ideas</h3> <p class="… fg-text-body">A steady rhythm keeps the focus on the content.</p> <p class="… bt(1) bt-solid bt-line-divider fg-text-muted">4 min read</p></article>Generated CSS
@layer theme { :root, :host { --color-zinc-30: oklch(78% .0025 265); --color-zinc-40: oklch(68.6% .0028 265); --color-zinc-60: oklch(48.6% .003 265); --color-zinc-70: oklch(39.8% .0028 265); --color-zinc-90: oklch(24.6% .0022 265); --color-zinc-100: oklch(15% .0016 265) } :root, :host { --color-surface-raised: light-dark(var(--color-white), var(--color-zinc-90)); --color-line-divider: light-dark(oklch(0% 0 none / .12), oklch(100% 0 none / .12)); --color-text-body: light-dark(var(--color-zinc-70), var(--color-zinc-30)); --color-text-strong: light-dark(var(--color-zinc-100), var(--color-white)); --color-text-muted: light-dark(var(--color-zinc-60), var(--color-zinc-40)) } :root, :host { --color-white: oklch(100% 0 none) }}@layer utilities { .bg-surface-raised { background-color: var(--color-surface-raised) } .b-line-divider { border-color: var(--color-line-divider) } .bt-line-divider { border-top-color: var(--color-line-divider) } .b-solid { border-style: solid } .bt-solid { border-top-style: solid } .b\(1\) { border-width: calc(1 * 1px) } .bt\(1\) { border-top-width: calc(1 * 1px) } .fg-text-body { color: var(--color-text-body) } .fg-text-muted { color: var(--color-text-muted) } .fg-text-strong { color: var(--color-text-strong) }}Customize
Add a role with one value per color scheme: --color-text-brand creates fg-text-brand.
@theme { --color-text-brand: light-dark( var(--color-indigo-60), var(--color-indigo-30) );}Generated CSS
@layer theme { :root, :host { --color-indigo-30: oklch(70.2% .1611 282.9); --color-indigo-60: oklch(50.06% .2906 282) } :root, :host { --color-text-brand: light-dark(var(--color-indigo-60), var(--color-indigo-30)) }}@layer utilities { .fg-text-brand { color: var(--color-text-brand) }}See theme directives and Color.

