Color tokens

The system generates semantic tokens from palettes. Each token has a tone optimized for the configured light/dark mode and contrast level.

Usage in Tailwind CSS

Tokens are exposed as CSS variables and Tailwind utility classes:

html
<!-- Surface background -->
<div class="bg-surface text-on-surface">...</div>

<!-- Primary button -->
<button class="bg-primary text-on-primary">Action</button>

<!-- Secondary container -->
<div class="bg-secondary-container text-on-secondary-container">...</div>

Token reference

Surfaces

Surfaces form the layers of the interface. They range from darkest (surfaceContainerLowest) to lightest (surfaceContainerHighest) in light mode, and inversely in dark mode.

TokenTailwind classUsage
surfacebg-surfaceMain background
surfaceDimbg-surface-dimSlightly dimmed surface
surfaceBrightbg-surface-brightSlightly brightened surface
surfaceContainerLowestbg-surface-container-lowestLayer 0 (lowest)
surfaceContainerLowbg-surface-container-lowLayer 1
surfaceContainerbg-surface-containerLayer 2 (cards, dialogs)
surfaceContainerHighbg-surface-container-highLayer 3
surfaceContainerHighestbg-surface-container-highestLayer 4 (highest)
onSurfacetext-on-surfacePrimary text on surface
onSurfaceVarianttext-on-surface-variantSecondary text on surface
outlineborder-outlineVisible borders
outlineVariantborder-outline-variantSubtle dividers
inverseSurfacebg-inverse-surfaceInverted surface (snackbar, tooltip)
inverseOnSurfacetext-inverse-on-surfaceText on inverted surface

Primary

TokenTailwind classUsage
primarybg-primaryMain actions, CTAs
onPrimarytext-on-primaryText on primary
primaryContainerbg-primary-containerSoft colored areas
onPrimaryContainertext-on-primary-containerText on primaryContainer
inversePrimarytext-inverse-primaryLink on inverted surface

Secondary

TokenTailwind classUsage
secondarybg-secondarySecondary accents
onSecondarytext-on-secondaryText on secondary
secondaryContainerbg-secondary-containerChips, badges
onSecondaryContainertext-on-secondary-containerText on secondaryContainer

Tertiary

TokenTailwind classUsage
tertiarybg-tertiaryAdditional accents
onTertiarytext-on-tertiaryText on tertiary
tertiaryContainerbg-tertiary-containerSoft tertiary areas
onTertiaryContainertext-on-tertiary-containerText on tertiaryContainer

Error

TokenTailwind classUsage
errorbg-errorError state
onErrortext-on-errorText on error
errorContainerbg-error-containerSoft error area
onErrorContainertext-on-error-containerText on errorContainer

Aliases

These tokens are aliases for Material Design compatibility:

AliasPoints to
backgroundsurface
onBackgroundonSurface
surfaceVariantsurfaceContainerHighest
surfaceTintprimary

Raw CSS variables

Variables are generated as --color-{token} with camelCase converted to kebab-case:

css
:root {
  --color-primary: #6750A4;
  --color-on-primary: #FFFFFF;
  --color-primary-container: #EADDFF;
  --color-surface: #FEF7FF;
  /* … */
}

.dark {
  --color-primary: #D0BCFF;
  --color-on-primary: #381E72;
  /* … */
}

Custom color tokens (Udixio variant)

With variant: Variants.Udixio and custom palettes, these tokens are generated for each {name} palette:

css
--color-{name}
--color-on-{name}
--color-{name}-container
--color-on-{name}-container
html
<!-- Example with "brand" palette -->
<div class="bg-brand text-on-brand">...</div>
<div class="bg-brand-container text-on-brand-container">...</div>

Adding custom tokens

The colors option in ConfigInterface lets you define additional tokens:

ts
import type { AddColorsOptions } from '@udixio/theme';

const colors: AddColorsOptions = ({ palettes, colors, context }) => ({
  highlight: {
    palette: () => palettes.get('tertiary'),
    tone: () => context.isDark ? 70 : 40,
    isBackground: true,
  },
  onHighlight: {
    palette: () => palettes.get('tertiary'),
    background: () => colors.get('highlight'),
    contrastCurve: () => getCurve(4.5),
  },
});

Reading tokens from the API

ts
const api = await loader(config);
await api.load();

const primary = api.colors.get('primary');
console.log(primary.getTone());   // e.g. 40 in light mode
console.log(primary.toHex());     // e.g. "#6750A4"