Palettes
A palette is a hue/chroma recipe. It generates a continuous range of tones (0–100) in HCT space. Semantic color tokens such as primary and surface then choose a tone from that palette.
Standard palettes
Each built-in variant derives these five palettes from sourceColor:
| Palette | Role |
|---|---|
primary | Main brand color |
secondary | Complementary accent |
tertiary | Additional accent with a variant-specific hue transformation |
neutral | Surfaces, backgrounds, borders and secondary text |
error | Error states |
The standard variants choose the hue and chroma differently. Leave these palettes untouched when you want the selected variant to retain its intended relationships.
Overriding a standard palette
The palettes key in theme.config.ts can replace a standard palette or add a custom one. A callback receives the current Context and returns a hue and chroma. When it replaces an existing palette, its second argument is the inherited palette recipe for the current context:
// theme.config.ts
import { defineConfig } from '@udixio/tailwind';
export default defineConfig({
sourceColor: '#6750A4',
palettes: {
primary: ({ sourceColor }) => ({
hue: sourceColor.hue + 30,
chroma: 60,
}),
tertiary: (_context, base) => ({
...base!,
chroma: base!.chroma + 10,
}),
neutral: () => ({
hue: 200,
chroma: 6,
}),
},
});The callback is evaluated again when a context property it reads changes. A palette has no tone of its own: the tone of a Color returned by a callback is not used for palette generation.
PaletteCallback
type PaletteCallback = (
context: Context,
base?: { hue: number; chroma: number },
) => { hue: number; chroma: number };The Context exposes sourceColor, isDark, contrastLevel and variant. The callbacks used by the built-in variants are ordinary PaletteCallback values and do not receive a base. For a standard palette override, base is recalculated from the active variant whenever the context changes. Return both coordinates when no inherited base exists.
Custom palettes (Udixio variant)
With the Udixio variant, a palette added under a custom key automatically generates semantic tokens for that key:
// theme.config.ts
import { defineConfig } from '@udixio/tailwind';
import { Variants } from '@udixio/theme';
export default defineConfig({
sourceColor: '#6750A4',
variant: Variants.Udixio,
palettes: {
brand: '#FF5722',
info: ({ sourceColor }) => ({
hue: sourceColor.hue + 90,
chroma: 50,
}),
},
});For brand, the system generates:
--color-brand/.bg-brand--color-on-brand/.text-on-brand--color-brand-container/.bg-brand-container--color-on-brand-container/.text-on-brand-container
The fixed roles are generated too. See Color tokens for the available token names.
Simple palette values
A fixed custom palette can be a hex string:
palettes: {
accent: '#E91E63',
}At the lower level, Color is also accepted as a palette input. Its tone is ignored because a palette spans every tone:
import { Color } from '@udixio/theme';
palettes: {
accent: Color.fromHex('#E91E63'),
}Use a callback when the palette depends on the current context:
palettes: {
accent: ({ sourceColor }) => ({
hue: sourceColor.hue + 30,
chroma: sourceColor.chroma,
}),
}These snippets are fragments of the palettes field; place them in theme.config.ts as shown above.
Example: two-color theme
// theme.config.ts
import { defineConfig } from '@udixio/tailwind';
import { Variants } from '@udixio/theme';
export default defineConfig({
sourceColor: '#1565C0',
variant: Variants.Udixio,
palettes: {
secondary: ({ sourceColor }) => ({
hue: sourceColor.hue + 180,
chroma: sourceColor.chroma,
}),
accent: '#FF6D00',
},
});For direct palette manipulation through api.palettes.get(), api.palettes.sync() or api.palettes.override(), see Palettes API.