Color variables
Semantic color tokens map palette shades to specific UI roles. Each token automatically resolves to a different shade in light and dark mode, so you never hardcode colors.
All groups are registered as ThemeExtension and accessible via context extensions like context.textColors.primary.
Text colors23 tokens
Manage all text fill colors across light and dark modes via TextColors.
| Name | Light mode | Dark mode | Usage |
|---|---|---|---|
text.primary | gray-900 | grayDark-50 | page headings, high emphasis content |
text.secondary | gray-700 | grayDark-300 | labels, section headings |
text.secondary.hover | gray-800 | grayDark-200 | Secondary text hover state |
text.tertiary | gray-600 | grayDark-400 | supporting text, paragraphs |
text.tertiary.hover | gray-700 | grayDark-300 | Tertiary text hover state |
text.quaternary | gray-500 | grayDark-400 | subtle, low-contrast text (footer headings) |
text.disabled | gray-500 | grayDark-500 | disabled fields, buttons |
text.placeholder | gray-500 | grayDark-500 | input placeholders |
text.placeholder.subtle | gray-300 | grayDark-700 | lower contrast (e.g. verification inputs) |
text.white | white | white | always white regardless of mode |
text.primary.on.brand | white | grayDark-50 | Primary text on solid brand backgrounds (CTA sections) |
text.secondary.on.brand | brand-200 | grayDark-300 | Secondary text on solid brand backgrounds |
text.tertiary.on.brand | brand-200 | grayDark-400 | Tertiary text on solid brand backgrounds |
text.quaternary.on.brand | brand-300 | grayDark-400 | Quaternary text on solid brand backgrounds |
text.brand.primary | brand-900 | grayDark-50 | brand headings (e.g. pricing cards) |
text.brand.secondary | brand-700 | grayDark-300 | brand buttons, accented text |
text.brand.secondary.hover | brand-800 | grayDark-200 | Brand secondary text hover state |
text.brand.tertiary | brand-600 | grayDark-400 | lighter accented text (metric numbers) |
text.brand.tertiary.alt | brand-600 | grayDark-50 | lighter in dark mode |
text.error.primary | error-600 | error-400 | error messages, validation |
text.error.primary.hover | error-700 | error-300 | Error text hover state |
text.warning.primary | warning-600 | warning-400 | warning messages |
text.success.primary | success-600 | success-400 | success messages |
Background colors32 tokens
Surface and container colors via BackgroundColors.
| Name | Light mode | Dark mode | Usage |
|---|---|---|---|
bg.primary | white | grayDark-950 | white in light, near-black in dark |
bg.primary.solid | gray-950 | grayDark-900 | dark background for tooltips, etc. |
bg.primary.alt | white | grayDark-900 | switches to secondary in dark mode |
bg.primary.hover | gray-50 | grayDark-800 | default hover for white-bg components |
bg.secondary | gray-50 | grayDark-900 | subtle contrast against primary (section bgs) |
bg.secondary.solid | gray-600 | grayDark-600 | mid-tone dark fill (featured icons) |
bg.secondary.subtle | gray-25 | grayDark-900 | slightly lighter secondary |
bg.secondary.hover | gray-100 | grayDark-800 | hover on gray-50 bg components |
bg.secondary.alt | gray-50 | grayDark-950 | switches to primary in dark mode |
bg.tertiary | gray-100 | grayDark-800 | stronger contrast (toggles) |
bg.quaternary | gray-200 | grayDark-700 | even stronger contrast (sliders, progress) |
bg.active | gray-50 | grayDark-800 | selected items |
bg.disabled | gray-100 | grayDark-800 | disabled primary buttons, toggles |
bg.disabled.subtle | gray-50 | grayDark-900 | disabled inputs, checkboxes |
bg.overlay | gray-950 | grayDark-800 | modal overlays |
bg.brand.primary | brand-50 | brand-500 | brand tinted (check icons) |
bg.brand.primary.alt | brand-50 | grayDark-900 | switches to secondary bg in dark mode |
bg.brand.secondary | brand-100 | brand-600 | slightly stronger brand tint (featured icons) |
bg.brand.solid | brand-600 | brand-600 | strong brand fill (toggles, messages) |
bg.brand.solid.hover | brand-700 | brand-500 | hover state for brand solid |
bg.brand.section | brand-800 | grayDark-900 | dark brand bg for website sections (CTAs) |
bg.brand.section.subtle | brand-700 | grayDark-950 | lighter brand section bg (FAQ sections) |
bg.error.primary | error-50 | error-950 | light error bg (error states) |
bg.error.secondary | error-100 | error-600 | slightly stronger error bg (featured icons) |
bg.error.solid | error-600 | error-600 | strong error fill (buttons) |
bg.error.solid.hover | error-700 | error-500 | Error solid hover |
bg.warning.primary | warning-50 | warning-950 | Warning primary background |
bg.warning.secondary | warning-100 | warning-600 | Warning secondary background (featured icons) |
bg.warning.solid | warning-600 | warning-600 | strong warning fill |
bg.success.primary | success-50 | success-950 | Success primary background |
bg.success.secondary | success-100 | success-600 | Success secondary background (featured icons) |
bg.success.solid | success-600 | success-600 | strong success fill |
Border colors10 tokens
Divider and border colors via BorderColors.
| Name | Light mode | Dark mode | Usage |
|---|---|---|---|
border.primary | gray-300 | grayDark-700 | inputs, button groups, checkboxes |
border.secondary | gray-200 | grayDark-800 | most common default (tables, cards, dividers) |
border.secondary.alt | rgba(#000000, 8%) | grayDark-800 | floating menus, notifications |
border.tertiary | gray-100 | grayDark-800 | subtle dividers, chart axes |
border.disabled | gray-300 | grayDark-700 | disabled inputs, checkboxes |
border.disabled.subtle | gray-200 | grayDark-800 | disabled buttons |
border.brand | brand-500 | brand-400 | active input fields |
border.brand.alt | brand-600 | grayDark-700 | switches to gray in dark mode (banners, footers) |
border.error | error-500 | error-400 | error state inputs, uploaders |
border.error.subtle | error-300 | error-500 | less prominent error indication |
Foreground colors21 tokens
Icon and indicator colors via ForegroundColors.
| Name | Light mode | Dark mode | Usage |
|---|---|---|---|
fg.primary | gray-900 | white | primary icons |
fg.secondary | gray-700 | grayDark-300 | secondary icons |
fg.secondary.hover | gray-800 | grayDark-200 | Secondary hover state |
fg.tertiary | gray-600 | grayDark-400 | supporting icons |
fg.tertiary.hover | gray-700 | grayDark-300 | Tertiary hover state |
fg.quaternary | gray-400 | grayDark-600 | button icons, help icons, input icons |
fg.quaternary.hover | gray-500 | grayDark-500 | Quaternary hover state |
fg.white | white | white | Always white foreground |
fg.disabled | gray-400 | grayDark-500 | disabled button group icons, dropdown items |
fg.disabled.subtle | gray-300 | grayDark-600 | disabled active checkboxes |
fg.brand.primary | brand-600 | brand-500 | featured icons, progress bars |
fg.brand.primary.alt | brand-600 | grayDark-300 | switches to gray in dark mode (active tabs) |
fg.brand.secondary | brand-500 | brand-500 | accents, arrows in marketing |
fg.brand.secondary.alt | brand-500 | grayDark-600 | switches to gray in dark mode (brand buttons) |
fg.brand.secondary.hover | brand-600 | grayDark-500 | Brand secondary hover state |
fg.error.primary | error-600 | error-500 | error featured icons |
fg.error.secondary | error-500 | error-400 | error input icons, negative metrics |
fg.warning.primary | warning-600 | warning-500 | warning featured icons |
fg.warning.secondary | warning-500 | warning-400 | Warning secondary foreground |
fg.success.primary | success-600 | success-500 | success featured icons |
fg.success.secondary | success-500 | success-400 | button dots, avatar online dots, positive metrics |
Component colors29 tokens
Component-specific tokens (avatars, toggles, sliders, etc.) via ComponentColors.
| Name | Light mode | Dark mode | Usage |
|---|---|---|---|
comp.avatar.bg | gray-100 | grayDark-800 | |
comp.avatar.contrast.border | rgba(#000000, 8%) | rgba(#FFFFFF, 12%) | |
comp.avatar.profile.photo.border | white | grayDark-950 | |
comp.avatar.styles.bg.neutral | #E0E0E0 | #E0E0E0 | |
comp.button.primary.icon | brand-300 | brand-300 | |
comp.button.primary.icon.hover | brand-200 | brand-200 | |
comp.button.destructive.primary.icon | error-300 | error-300 | |
comp.button.destructive.primary.icon.hover | error-200 | error-200 | |
comp.featured.icon.light.fg.brand | brand-600 | brand-200 | |
comp.featured.icon.light.fg.error | error-600 | error-200 | |
comp.featured.icon.light.fg.gray | gray-500 | grayDark-200 | |
comp.featured.icon.light.fg.success | success-600 | success-200 | |
comp.featured.icon.light.fg.warning | warning-600 | warning-200 | |
comp.focus.ring | brand-500 | brand-500 | |
comp.focus.ring.error | error-500 | error-500 | |
comp.footer.button.fg | brand-200 | grayDark-300 | |
comp.footer.button.fg.hover | white | grayDark-100 | |
comp.icon.fg.brand | brand-600 | grayDark-400 | |
comp.icon.fg.brand.on.brand | brand-200 | grayDark-400 | |
comp.screen.mockup.border | gray-900 | grayDark-700 | |
comp.slider.handle.bg | white | brand-500 | |
comp.slider.handle.border | brand-600 | grayDark-950 | |
comp.toggle.border | gray-300 | transparent | |
comp.toggle.button.fg.disabled | gray-50 | grayDark-600 | |
comp.toggle.slim.border.pressed.hover | brand-700 | transparent | |
comp.toggle.slim.border.pressed | brand-600 | transparent | |
comp.tooltip.supporting.text | gray-300 | grayDark-300 | |
comp.text.editor.icon.fg | gray-400 | grayDark-400 | |
comp.text.editor.icon.fg.active | gray-500 | white |
Utility colors18 palettes
UtilityColors provides 18 palettes, each a UtilityScale with shades 50 through 900. In light mode shades map directly; in dark mode the scale is inverted so darker shades become lighter.
| Token | Light source | Dark source | Shades |
|---|---|---|---|
gray | directExtended(gray) | grayDarkInverted(grayDark) | 50–900 |
brand | directExtended(brand) | brandInverted(brand) | 50–900 |
brandAlt | directExtended(brand) | grayDarkInverted(gray) | 50–900 |
blue | direct(AccentColors.blue) | inverted(AccentColors.blue) | 50–700 |
blueDark | direct(AccentColors.blueDark) | inverted(AccentColors.blueDark) | 50–700 |
blueLight | direct(AccentColors.blueLight) | inverted(AccentColors.blueLight) | 50–700 |
indigo | direct(AccentColors.indigo) | inverted(AccentColors.indigo) | 50–700 |
purple | direct(AccentColors.purple) | inverted(AccentColors.purple) | 50–700 |
fuchsia | direct(AccentColors.fuchsia) | inverted(AccentColors.fuchsia) | 50–700 |
pink | direct(AccentColors.pink) | inverted(AccentColors.pink) | 50–700 |
error | direct(MihrColors.error) | inverted(MihrColors.error) | 50–700 |
warning | direct(MihrColors.warning) | inverted(MihrColors.warning) | 50–700 |
success | direct(MihrColors.success) | inverted(MihrColors.success) | 50–700 |
orange | direct(AccentColors.orange) | inverted(AccentColors.orange) | 50–700 |
orangeDark | direct(AccentColors.orangeDark) | inverted(AccentColors.orangeDark) | 50–700 |
grayBlue | direct(grayBlue) | inverted(grayBlue) | 50–700 |
green | direct(AccentColors.green) | inverted(AccentColors.green) | 50–700 |
yellow | direct(AccentColors.yellow) | inverted(AccentColors.yellow) | 50–700 |
Alpha colors20 tokens
AlphaColors provides 20 opacity-based tokens that adapt to the current theme. In light mode, white tokens use #FFFFFF and black tokens use #000000. In dark mode the base colors are swapped: white tokens use #0C0E12 (gray-950) and black tokens use #FFFFFF.
| Token | Opacity | Light mode | Dark mode |
|---|---|---|---|
white10 | 10% | #FFFFFF @ 10% | #0C0E12 @ 10% |
white20 | 20% | #FFFFFF @ 20% | #0C0E12 @ 20% |
white30 | 30% | #FFFFFF @ 30% | #0C0E12 @ 30% |
white40 | 40% | #FFFFFF @ 40% | #0C0E12 @ 40% |
white50 | 50% | #FFFFFF @ 50% | #0C0E12 @ 50% |
white60 | 60% | #FFFFFF @ 60% | #0C0E12 @ 60% |
white70 | 70% | #FFFFFF @ 70% | #0C0E12 @ 70% |
white80 | 80% | #FFFFFF @ 80% | #0C0E12 @ 80% |
white90 | 90% | #FFFFFF @ 90% | #0C0E12 @ 90% |
white100 | 100% | #FFFFFF @ 100% | #0C0E12 @ 100% |
black10 | 10% | #000000 @ 10% | #FFFFFF @ 10% |
black20 | 20% | #000000 @ 20% | #FFFFFF @ 20% |
black30 | 30% | #000000 @ 30% | #FFFFFF @ 30% |
black40 | 40% | #000000 @ 40% | #FFFFFF @ 40% |
black50 | 50% | #000000 @ 50% | #FFFFFF @ 50% |
black60 | 60% | #000000 @ 60% | #FFFFFF @ 60% |
black70 | 70% | #000000 @ 70% | #FFFFFF @ 70% |
black80 | 80% | #000000 @ 80% | #FFFFFF @ 80% |
black90 | 90% | #000000 @ 90% | #FFFFFF @ 90% |
black100 | 100% | #000000 @ 100% | #FFFFFF @ 100% |