Colors
The color tokens every component draws with, by role, in light and dark.
A color token is a named role, such as --bt-text-secondary or --bt-bg-section, that holds one value for the light theme and one for the dark theme. Use a token for every color an app draws, and the app follows light and dark, a theme made with createTheme, and the contrast rules without any code of its own.
Use a token, never a value
Each token is a CSS variable that ButteryProvider sets on the page. Read it with var():
.order-total {
color: var(--bt-text-strong);
background-color: var(--bt-bg-section);
}The tokens change with the theme.
.order-total {
color: #1a1a1a;
background-color: #f7f7f7;
}Hex values stay the same in dark mode, and buttery's stylelint config fails them.
In TypeScript and Tailwind
The same tokens are in TypeScript as colors from @butteryui/core, each with its light value, its dark value and what it's for. Use them in code that needs a value rather than a variable, such as a chart drawn on a canvas.
With Tailwind v4, import @butteryui/ after Tailwind in your stylesheet:
@import "tailwindcss";
@import "@butteryui/core/tailwind.css";Utilities such as bg-surface, text-fg-secondary and border-border then read the same tokens. Keep importing @butteryui/ at your app's entry, because it defines the variables they read.
Surfaces
The backgrounds pages, panels and cards sit on. A surface's text and borders are chosen to read on it, so pair them as the components do.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-bg-app | #f3f3f4 | #0f0f10 | Page and stage background behind everything. | |
| --bt-bg-surface | #ffffff | #19191b | Header bar, inspector panel, inner cards, dialogs. | |
| --bt-bg-raised | #ffffff | #2c2c30 | Elements raised above a surface or a control track: the active segment, secondary buttons. | |
| --bt-bg-floating | #ffffff | #1f1f22 | Floating layers: menus, popovers, floating toolbars. | |
| --bt-bg-section | #f7f7f7 | #141416 | The well behind a section's card. | |
| --bt-bg-inset | #fefefe | #161618 | Small recessed controls: tilt pad, anchor grid. | |
| --bt-bg-control | #f1f1f1 | #232326 | Segmented track, value badge, soft button, hover fill. | |
| --bt-bg-control-subtle | #f9f9f9 | #1e1e20 | Disabled soft button and chip. | |
| --bt-bg-item-hover | #f7f7f7 | #202023 | Highlighted menu item. | |
| --bt-bg-control-active | #ececec | #2a2a2d | Ghost trigger while its menu is open. | |
| --bt-bg-tint | #fbf4da | #2d1e14 | A tinted card or page band: the cream gradient's first stop in light, the espresso family at OKLCH L 0.25 in dark, so every text color holds 4.5:1 on it and every chart series 3:1. |
Text and icons
text-strong is for titles and numbers that lead, text for labels and body text, text-secondary for descriptions and inactive items, and text-tertiary for the quietest hints.
Contrast. All four meet WCAG AA contrast on the surfaces above. Disabled text is exempt, as inactive UI is.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-text-strong | #1a1a1a | #f5f5f6 | Dialog titles and page headings. | |
| --bt-text | #303030 | #ececed | Labels, primary text, the active segment. | |
| --bt-text-secondary | #616161 | #a0a0a6 | Section titles, body copy, value badges, icons, inactive segments. | |
| --bt-text-tertiary | #6b6b6b | #93939a | Captions and hints. | |
| --bt-text-disabled | #acacac | #55555b | Disabled text. Exempt from contrast rules, like all inactive UI. | |
| --bt-text-disabled-subtle | #b8b8b8 | #4d4d53 | Disabled chip text, one step quieter than text-disabled. | |
| --bt-icon-disabled | #c0c0c0 | #4a4a50 | Disabled icons. |
Borders
Edges and dividers. control-border marks the edge of a control where nothing else does, such as a text input's box or a switch's track, at 3:1 on every surface.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-border | #ebebeb | #2a2a2e | Row dividers, section borders, separators. | |
| --bt-border-strong | #e3e3e3 | #333338 | Slider track, anchor grid, tilt pad, and the edge of a disabled input. | |
| --bt-control-border | #858585 | #75757c | The edge that marks a control where nothing else does: a text input's box, a checkbox's box, a switch's track. 3:1 on every surface. | |
| --bt-divider-on-primary | rgba(255, 255, 255, 0.18) | rgba(17, 17, 17, 0.18) | The hairline between a split button's halves. |
Primary and accent
primary fills the one main action on a screen. accent marks focus rings, selection and links; accent-text is the accent's shade for text, which meets contrast where accent itself wouldn't.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-primary | #1a1a1a | #f2f2f3 | Primary button and split button. | |
| --bt-primary-hover | #2b2b2b | #ffffff | Primary hover. Lightens in light mode rather than darkening. | |
| --bt-primary-disabled | #a3a3a3 | #4a4a50 | Disabled primary background; the text keeps on-primary. | |
| --bt-on-primary | #ffffff | #111111 | Text on primary. | |
| --bt-accent | #2862e0 | #4f89ff | Focus ring, tilt arc, selection highlights. | |
| --bt-accent-subtle | #e9f0fd | #16223b | Background of an info callout. | |
| --bt-accent-text | #2862e0 | #4f89ff | The accent as text: links and icons in an info callout. 4.5:1 on the surface and on accent-subtle, even when a theme's accent is lighter. | |
| --bt-selection | rgba(40, 98, 224, 0.2) | rgba(79, 137, 255, 0.3) | Text selection highlight. | |
| --bt-ring-selected | #cacaca | #4a4a50 | Selected swatch ring, crop handle border, drop-zone dashes. |
Status
danger, success and warning are for text and icons that say how something went. Their -subtle shades are the backgrounds of callouts and badges that carry them.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-danger | #c72a1c | #ff7a6e | Errors: a field's border and message, error icons. | |
| --bt-danger-subtle | #fdeceb | #3a1916 | Background of an error callout. | |
| --bt-success | #177245 | #4cc38a | Success text and icons, a met requirement. | |
| --bt-success-subtle | #e7f5ed | #132c20 | Background of a success callout. | |
| --bt-warning | #9a4d00 | #f2a33a | Warning text and icons. | |
| --bt-warning-subtle | #fdf1e2 | #33230f | Background of a warning callout. |
Inverse
For the few things drawn dark on a light page and light on a dark one, such as a toast.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-inverse-bg | #1a1a1a | #f2f2f3 | Tooltip and toast background. | |
| --bt-inverse-text | #ffffff | #111111 | Tooltip and toast text. | |
| --bt-inverse-text-secondary | #a3a3a3 | #6b6b6b | Secondary text and actions in tooltips and toasts. | |
| --bt-inverse-success | #4cc38a | #177245 | Success on the inverse surface: a success toast's icon. Each theme takes the other theme's success, which reads on its inverse surface. | |
| --bt-inverse-warning | #f2a33a | #9a4d00 | Warning on the inverse surface: a warning toast's icon. | |
| --bt-inverse-danger | #ff7a6e | #c72a1c | Danger on the inverse surface: a danger toast's icon. | |
| --bt-inverse-success-bg | #26342c | #d5e0d9 | A success toast: the inverse surface mixed toward inverse-success in OKLab, 18% (14% in dark). | |
| --bt-inverse-warning-bg | #3b3024 | #e7dad3 | A warning toast: the inverse surface mixed toward inverse-warning, 18% (14% in dark). | |
| --bt-inverse-danger-bg | #3e2b28 | #f0d9d5 | A danger toast: the inverse surface mixed toward inverse-danger, 18% (14% in dark). |
Charts
The colors of a chart's series. chart-1 is the accent, the next four are other hue families at the accent's lightness, and chart-muted is for a series to compare against, such as the previous period.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-chart-1 | #2862e0 | #4f89ff | A chart's first series: the accent. | |
| --bt-chart-2 | #008254 | #1ea971 | A chart's second series: the mint family at the accent's OKLCH lightness, chroma 0.14 or the most sRGB allows. | |
| --bt-chart-3 | #a65400 | #cf752d | A chart's third series: the apricot family at the accent's OKLCH lightness, chroma 0.14 or the most sRGB allows. | |
| --bt-chart-4 | #7b57b2 | #9d7ad7 | A chart's fourth series: the lilac family at the accent's OKLCH lightness, chroma 0.14. | |
| --bt-chart-5 | #ae445b | #d6677c | A chart's fifth series: the rose family at the accent's OKLCH lightness, chroma 0.14. | |
| --bt-chart-muted | #8b8b8b | #6e6e74 | A comparison series, such as the previous period: the lightest gray still 3:1 on every chart background. |
Scrims and marks
The scrim behind a dialog, the wash behind a menu, page dots, and a Skeleton's fills.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-overlay | rgba(0, 0, 0, 0.32) | rgba(0, 0, 0, 0.55) | Dialog scrim, with no blur. | |
| --bt-wash | rgba(255, 255, 255, 0.55) | rgba(15, 15, 16, 0.55) | Wash over the blurred page behind a menu. | |
| --bt-dot | #e8e8e8 | #2e2e32 | Page dots and idle anchor dots. | |
| --bt-dot-active | #303030 | #ececed | The active page dot. | |
| --bt-skeleton | #f2f2f4 | #232326 | A Skeleton's fill, and skeleton blocks in illustrations. | |
| --bt-skeleton-strong | #ececee | #2a2a2d | The band that sweeps across a Skeleton, and skeleton lines in illustrations. |
Decorative
Colors for illustrations, buttery's own mark and the knobs of sliders and other controls. They're never used for UI that has to be read.
| Token | Light | Dark | Use | |
|---|---|---|---|---|
| --bt-knob-top | #535353 | #535353 | Top of the slider thumb's vertical gradient. | |
| --bt-knob-bottom | #2e2e2e | #2e2e2e | Bottom of the slider thumb's vertical gradient. | |
| --bt-knob-center | #5c5c5c | #5c5c5c | Lit point of the radial knob gradient (tilt knob, active anchor dot), 30% down from the top. | |
| --bt-knob-edge | #262626 | #262626 | Where the radial knob gradient ends: the bottom edge, the side farthest from the lit point. | |
| --bt-knob-border | #1c1c1c | #000000 | Knob border. | |
| --bt-knob-highlight | #7a7a7a | #7a7a7a | One-pixel inset highlight along the top of a knob. | |
| --bt-knob-grip | #b2b2b2 | #b2b2b2 | The two grip lines on the slider thumb. | |
| --bt-knob-ring | #ffffff | #ffffff | The ring around a thumb drawn over picked colors (the color picker's), the same in both themes so it shows on any color. | |
| --bt-traffic-red | #ed6c61 | #ed6c61 | Window-chrome dot in illustrations. | |
| --bt-traffic-yellow | #f5c05c | #f5c05c | Window-chrome dot in illustrations. | |
| --bt-traffic-green | #5ac55e | #5ac55e | Window-chrome dot in illustrations. | |
| --bt-brand-butter | #f5d06f | #f5d06f | buttery's brand color. Decorative only: the mark, docs, marketing. | |
| --bt-brand-butter-deep | #e8b64a | #e8b64a | The brand mark's side and shadow. | |
| --bt-brand-cream | #fff4d6 | #fff4d6 | The brand mark's top face. | |
| --bt-brand-gloss | #ffffff | #ffffff | The brand mark's highlight, white on any background. | |
| --bt-brand-shadow | #8a5a12 | #8a5a12 | The brand mark's contact shadow, drawn faint and blurred. |