Colors
Colors are semantic: named by role, not by hue. This means the same token adapts automatically to light and dark mode without any code changes.
Using colors
Section titled “Using colors”There are three ways to apply color. Pick whichever fits your context.
Utility class: the simplest option for backgrounds and text:
<div class="bg-secondary text-primary">…</div>CSS custom property: use in custom CSS when utility classes don’t cover your needs:
.my-element { color: var(--v-color-foreground-primary); background: var(--v-color-background-secondary);}TypeScript helper: for inline styles in React, values update automatically with color mode:
import tokens from '@volvo-cars/css/tokens';
<div style={{ color: tokens.colorForegroundPrimary }} />;Background
Section titled “Background”Page-level backgrounds for content areas, sections, and feedback banners.
--v-color-background-primaryUse as a primary background color.
--v-color-background-secondaryUse as a secondary background color for elevated sections.
--v-color-background-feedback-grayUse as a background color to indicate informational messages.
--v-color-background-feedback-greenUse as a background color to highlight successful and positive states.
--v-color-background-feedback-redUse as a background color to highlight errors, invalid data, and destructive states.
--v-color-background-feedback-orangeUse as a background color to highlight warnings, invalid or missing data, and states that require caution.
| Class | Token or value |
|---|---|
bg-primary | --v-color-background-primary |
bg-secondary | --v-color-background-secondary |
bg-feedback-gray | --v-color-background-feedback-gray |
bg-feedback-green | --v-color-background-feedback-green |
bg-feedback-orange | --v-color-background-feedback-orange |
bg-feedback-red | --v-color-background-feedback-red |
bg-always-black | --v-color-always-black |
bg-always-white | --v-color-always-white |
bg-inherit | background-color: inherit |
bg-transparent | background-color: transparent |
Foreground
Section titled “Foreground”Text, icons, and border colors. Pick primary for most content, secondary for supporting text, and the feedback variants for validation states.
--v-color-foreground-primaryUse for primary text, icons and borders.
--v-color-foreground-secondaryUse for secondary text, icons and borders.
--v-color-foreground-tertiaryThe lightest possible foreground color acceptable for UI fills. Should not be used for body text.
--v-color-foreground-invertedThe inverse of the primary foreground color. For use on filled surfaces.
--v-color-foreground-accent-blueFor emphasized selection borders and graphic accents (icons, illustrations).
--v-color-foreground-feedback-greenUse as a foreground or border color to highlight successful states and positive actions.
--v-color-foreground-feedback-redUse as a foreground or border color to highlight errors, invalid data, and destructive actions.
--v-color-foreground-feedback-orangeUse as a foreground or border color to highlight warnings, invalid or missing data, and actions that require caution.
These classes set color, which is also used by icons that follow the current text color.
| Class | Token or value |
|---|---|
text-primary | --v-color-foreground-primary |
text-secondary | --v-color-foreground-secondary |
text-inverted | --v-color-foreground-inverted |
text-accent-blue | --v-color-foreground-accent-blue |
text-feedback-green | --v-color-foreground-feedback-green |
text-feedback-orange | --v-color-foreground-feedback-orange |
text-feedback-red | --v-color-foreground-feedback-red |
text-always-black | --v-color-always-black |
text-always-white | --v-color-always-white |
text-inherit | color: inherit |
Only text-primary and text-secondary support md:, lg:, and xl: prefixes, for example text-secondary md:text-primary. There is no text-tertiary utility. The tertiary foreground token is available through border-tertiary for control borders, or as a custom property in component CSS.
Surface
Section titled “Surface”Fills for interactive UI elements like buttons and form controls. Always pair a surface color with a foreground color that has enough contrast. For example, use text-inverted on bg-surface-neutral, or text-always-white on bg-surface-accent-blue.
--v-color-surface-neutralUsed as a surface fill for UI elements like buttons and form controls. Combine with Foreground / Inverted foreground color.
--v-color-surface-grayUsed as surface fill.
--v-color-surface-accent-blueUsed as an emphasized surface fill for UI elements like buttons and form controls.
--v-color-surface-accent-safetyUsed as an emphasized surface fill for UI elements like buttons and form controls.
--v-color-surface-feedback-greenUsed as a surface fill for UI elements like buttons and form controls to signify positive actions. Combine with Always White foreground color.
--v-color-surface-feedback-orange[Deprecated]
--v-color-surface-feedback-redUsed as a surface fill for UI elements like buttons and form controls to signify destructive actions. Combine with Always White foreground color.
| Class | Token |
|---|---|
bg-surface-neutral | --v-color-surface-neutral |
bg-surface-accent-blue | --v-color-surface-accent-blue |
bg-surface-feedback-green | --v-color-surface-feedback-green |
bg-surface-feedback-orange | --v-color-surface-feedback-orange |
bg-surface-feedback-red | --v-color-surface-feedback-red |
Background and surface color utilities have no responsive prefixes. Their tokens already follow the current color mode.
Ornament
Section titled “Ornament”Borders, dividers, and backdrops that separate or group content.
--v-color-ornament-primaryUse for strokes or dividers to visually group or separate elements.
--v-color-ornament-scrimUsed as a backdrop that usually sits behind a Side sheet or Dialog component.
--v-color-ornament-overlayUse as strokes or dividers for overlaying UI, like Listbox, Dropdown menu components.
Border colors
Section titled “Border colors”Combine a color class with a border width or inset ring, for example border border-primary or border-ring-2 border-accent-blue. A color class alone does not add a visible border. The default border color is --v-color-ornament-primary.
| Class | Token or value |
|---|---|
border-ornament | --v-color-ornament-primary |
border-primary | --v-color-foreground-primary |
border-secondary | --v-color-foreground-secondary |
border-tertiary | --v-color-foreground-tertiary |
border-accent-blue | --v-color-foreground-accent-blue |
border-feedback-green | --v-color-foreground-feedback-green |
border-feedback-orange | --v-color-foreground-feedback-orange |
border-feedback-red | --v-color-foreground-feedback-red |
border-always-black | --v-color-always-black |
border-always-white | --v-color-always-white |
border-transparent | Transparent border color |
border-inherit | Inherits the parent’s border-color custom property (--_border-color) |
Border color classes have no responsive prefixes. border-inherit inherits the design system’s color setting, rather than a parent’s arbitrary CSS border-color; if that setting is absent, the ornament default applies.
Ornament overlay and scrim have no color utilities. Use --v-color-ornament-overlay and --v-color-ornament-scrim in component CSS when needed.
Always
Section titled “Always”Fixed colors that ignore color mode. Use when an element must look the same in both light and dark contexts. For example, text on an image or a branded surface.
--v-color-always-whiteAlways white regardless of color mode.
--v-color-always-blackAlways black regardless of colour mode.
State layers
Section titled “State layers”Semi-transparent overlays applied on hover, focus, and pressed states. Each base color has three intensities: subtle, medium, and strong. These are mainly used internally by components. You rarely need them directly.
--v-color-state-primary-strongUse for state layers with foreground/primary.
--v-color-state-primary-mediumUse for state layers with foreground/primary.
--v-color-state-primary-subtleUse for state layers with foreground/primary.
--v-color-state-inverted-strongUse for state layers with foreground/inverted.
--v-color-state-inverted-mediumUse for state layers with foreground/inverted.
--v-color-state-inverted-subtleUse for state layers with foreground/inverted.
--v-color-state-accent-blue-strongUse for state layers with foreground/accent/blue.
--v-color-state-accent-blue-mediumUse for state layers with foreground/accent/blue.
--v-color-state-accent-blue-subtleUse for state layers with foreground/accent/blue.
--v-color-state-feedback-red-strongUse for state layers with foreground/feedback/red.
--v-color-state-feedback-red-mediumUse for state layers with foreground/feedback/red.
--v-color-state-feedback-red-subtleUse for state layers with foreground/feedback/red.
--v-color-state-always-black-strongUse for state layers with an always/black foreground color.
--v-color-state-always-black-mediumUse for state layers with an always/black foreground color.
--v-color-state-always-black-subtleUse for state layers with an always/black foreground color.
--v-color-state-always-white-strongUse for state layers with an always/white foreground color.
--v-color-state-always-white-mediumUse for state layers with an always/white foreground color.
--v-color-state-always-white-subtleUse for state layers with an always/white foreground color.
Color state variants
Section titled “Color state variants”Only the variants listed below are available. Their state modifiers target HTML and ARIA attributes on the element or an ancestor. Hover variants require the hover stylesheet, included by @volvo-cars/css/styles_all-media.css, and apply only on devices with hover support.
Backgrounds:
| Class | Token |
|---|---|
current:bg-surface-neutral | --v-color-surface-neutral |
checked:bg-surface-neutral | --v-color-surface-neutral |
selected:bg-surface-neutral | --v-color-surface-neutral |
odd:bg-secondary | --v-color-background-secondary |
selected:bg-accent-blue-medium | --v-color-state-accent-blue-medium |
expanded:bg-accent-blue-medium | --v-color-state-accent-blue-medium |
hover:bg-primary-subtle | --v-color-state-primary-subtle |
hover:bg-primary-subtle does not apply while the element has aria-selected="true". The state-layer backgrounds above exist only with their listed prefixes; there is no unprefixed bg-accent-blue-medium or bg-primary-subtle. Use custom properties for other state layers.
Text and icons:
| Class | Token |
|---|---|
current:text-primary | --v-color-foreground-primary |
checked:text-primary | --v-color-foreground-primary |
selected:text-primary | --v-color-foreground-primary |
current:text-inverted | --v-color-foreground-inverted |
checked:text-inverted | --v-color-foreground-inverted |
selected:text-inverted | --v-color-foreground-inverted |
hover:text-primary | --v-color-foreground-primary |
Borders:
| Class | Token |
|---|---|
hover:border-primary | --v-color-foreground-primary |
open:border-primary | --v-color-foreground-primary |
current:border-primary | --v-color-foreground-primary |
checked:border-primary | --v-color-foreground-primary |
selected:border-primary | --v-color-foreground-primary |
expanded:border-primary | --v-color-foreground-primary |
link-current:border-primary | --v-color-foreground-primary |
radio-checked:border-primary | --v-color-foreground-primary |
checkbox-checked:border-primary | --v-color-foreground-primary |
tab-selected:border-primary | --v-color-foreground-primary |
button-expanded:border-primary | --v-color-foreground-primary |
focus:border-accent-blue | --v-color-foreground-accent-blue |
current:border-accent-blue | --v-color-foreground-accent-blue |
checked:border-accent-blue | --v-color-foreground-accent-blue |
selected:border-accent-blue | --v-color-foreground-accent-blue |
expanded:border-accent-blue | --v-color-foreground-accent-blue |
link-current:border-accent-blue | --v-color-foreground-accent-blue |
radio-checked:border-accent-blue | --v-color-foreground-accent-blue |
checkbox-checked:border-accent-blue | --v-color-foreground-accent-blue |
tab-selected:border-accent-blue | --v-color-foreground-accent-blue |
button-expanded:border-accent-blue | --v-color-foreground-accent-blue |
focus:border-accent-blue uses :focus-visible, preserving the standard keyboard focus outline. See supported state utilities for border widths and rings that can also respond to state.
Dark mode
Section titled “Dark mode”Semantic color tokens adapt automatically when you switch color mode; Always colors stay fixed. Light mode is the default.
Activate dark mode by adding the data-color-mode attribute to any element. Everything inside inherits the mode, and you can nest them as deeply as you like. Set data-color-mode="auto" to follow the device system preference instead.
Show code
<div class="grid grid-cols-2"> <div data-color-mode="auto" class="border p-24 bg-primary text-primary"> Auto </div> <div data-color-mode="dark" class="border p-24 bg-primary text-primary"> Dark <div data-color-mode="light" class="border p-24 bg-primary text-primary"> Light </div> </div></div>Naming convention
Section titled “Naming convention”All color tokens follow the pattern --v-color-{property}-{category?}-{variant}:
- Property: what the color targets:
foreground,background,surface,ornament,state, oralways. - Category: optional sub-group:
feedback,accent. - Variant: distinguishes alternatives:
primary,secondary,red,blue, etc.
Type --v-color in your editor to get autocomplete for all available tokens.
Token reference
Section titled “Token reference”A complete list of every color token with its resolved value in light and dark mode.
| Token | Light | Dark |
|---|---|---|
--v-color-foreground-primary | #ffffff | #000000 |
--v-color-foreground-secondary | #969696 | #5e5e5e |
--v-color-foreground-tertiary | #787878 | #787878 |
--v-color-foreground-inverted | #000000 | #ffffff |
--v-color-foreground-accent-blue | #3354ff | #0b2ded |
--v-color-foreground-feedback-green | #07ca31 | #04771d |
--v-color-foreground-feedback-red | #ef6658 | #cd2314 |
--v-color-foreground-feedback-orange | #ff9933 | #ce6700 |
--v-color-surface-neutral | #ffffff | #000000 |
--v-color-surface-gray | #3b3b3b | #e3e3e3 |
--v-color-surface-accent-blue | #3354ff | #0b2ded |
--v-color-surface-accent-safety | #fc6408 | #fc6408 |
--v-color-surface-feedback-green | #048220 | #048220 |
--v-color-surface-feedback-orange | #ce6700 | #ce6700 |
--v-color-surface-feedback-red | #e52715 | #e52715 |
--v-color-background-primary | #000000 | #ffffff |
--v-color-background-secondary | #171717 | #fafafa |
--v-color-background-feedback-gray | #242424 | #f0f0f0 |
--v-color-background-feedback-green | #02310c | #d7f9df |
--v-color-background-feedback-red | #4a0d07 | #fce5e3 |
--v-color-background-feedback-orange | #522900 | #ffe8d1 |
--v-color-always-white | #ffffff | #ffffff |
--v-color-always-black | #000000 | #000000 |
--v-color-ornament-primary | rgb(100% 100% 100% / 0.16) | rgb(0% 0% 0% / 0.12) |
--v-color-ornament-scrim | rgb(9.0196% 9.0196% 9.0196% / 0.64) | rgb(9.0196% 9.0196% 9.0196% / 0.64) |
--v-color-ornament-overlay | rgb(100% 100% 100% / 0.08) | rgb(0% 0% 0% / 0.04) |
--v-color-state-primary-strong | rgb(100% 100% 100% / 0.24) | rgb(0% 0% 0% / 0.2) |
--v-color-state-primary-medium | rgb(100% 100% 100% / 0.16) | rgb(0% 0% 0% / 0.12) |
--v-color-state-primary-subtle | rgb(100% 100% 100% / 0.08) | rgb(0% 0% 0% / 0.04) |
--v-color-state-inverted-strong | rgb(0% 0% 0% / 0.24) | rgb(100% 100% 100% / 0.2) |
--v-color-state-inverted-medium | rgb(0% 0% 0% / 0.16) | rgb(100% 100% 100% / 0.12) |
--v-color-state-inverted-subtle | rgb(0% 0% 0% / 0.08) | rgb(100% 100% 100% / 0.04) |
--v-color-state-accent-blue-strong | rgb(20% 32.941% 100% / 0.24) | rgb(4.3137% 17.647% 92.941% / 0.2) |
--v-color-state-accent-blue-medium | rgb(20% 32.941% 100% / 0.16) | rgb(4.3137% 17.647% 92.941% / 0.12) |
--v-color-state-accent-blue-subtle | rgb(20% 32.941% 100% / 0.08) | rgb(4.3137% 17.647% 92.941% / 0.04) |
--v-color-state-feedback-red-strong | rgb(89.804% 15.294% 8.2353% / 0.24) | rgb(89.804% 15.294% 8.2353% / 0.2) |
--v-color-state-feedback-red-medium | rgb(89.804% 15.294% 8.2353% / 0.16) | rgb(89.804% 15.294% 8.2353% / 0.12) |
--v-color-state-feedback-red-subtle | rgb(89.804% 15.294% 8.2353% / 0.08) | rgb(89.804% 15.294% 8.2353% / 0.04) |
--v-color-state-always-black-strong | rgb(0% 0% 0% / 0.24) | rgb(0% 0% 0% / 0.2) |
--v-color-state-always-black-medium | rgb(0% 0% 0% / 0.16) | rgb(0% 0% 0% / 0.12) |
--v-color-state-always-black-subtle | rgb(0% 0% 0% / 0.08) | rgb(0% 0% 0% / 0.04) |
--v-color-state-always-white-strong | rgb(100% 100% 100% / 0.24) | rgb(100% 100% 100% / 0.2) |
--v-color-state-always-white-medium | rgb(100% 100% 100% / 0.16) | rgb(100% 100% 100% / 0.12) |
--v-color-state-always-white-subtle | rgb(100% 100% 100% / 0.08) | rgb(100% 100% 100% / 0.04) |