Primary
Brand actions and key highlights
- primary-main
- primary-light
- primary-dark
- primary-contrast
UXDSL builds on standard CSS. Colors define the available color values; Palette assigns colors to interface roles. Both are configured in the theme JSON. Prefer palette() when a component expresses a role such as primary action or surface. Use color() when a specific color token is intentional, and standard CSS when finer control is needed.
A palette describes what a color is used for. Primary does not have to mean blue: another theme can assign a different color while components keep the same role.
This reference excerpt defines a color collection and connects palette roles to it using CSS variable references:
{
"colors": {
"blue": { "500": "#3b82f6", "700": "#1d4ed8" },
"white": "#ffffff",
"ink": "#0f172a"
},
"palette": {
"primary": {
"main": "var(--uxdsl__color__blue-700)",
"contrast": "var(--uxdsl__color__white)"
},
"surface": {
"main": "var(--uxdsl__color__white)",
"contrast": "var(--uxdsl__color__ink)"
}
}
}The nested entry colors.blue["700"] produces --uxdsl__color__blue-700. The nested role palette.primary.main produces --uxdsl__palette__primary-main.
References preserve the connection. In this JSON, primary.main references blue-700. Changing that color updates the role once the theme is compiled or applied. A literal hex value in a palette is also valid, but copying a color’s hex value does not create a reference to that color token.
.primary-action {
background: palette(primary.main);
color: palette(primary.contrast);
}
/* Deliberately use a specific color token */
.blue-swatch {
background: color(blue-700);
}:root {
--uxdsl__color__blue-700: #1d4ed8;
--uxdsl__color__white: #ffffff;
--uxdsl__palette__primary-main: var(--uxdsl__color__blue-700);
--uxdsl__palette__primary-contrast: var(--uxdsl__color__white);
}
.primary-action {
background: var(--uxdsl__palette__primary-main);
color: var(--uxdsl__palette__primary-contrast);
}
.blue-swatch {
background: var(--uxdsl__color__blue-700);
}The CSS shows only the variables used by these two selectors. Plain CSS custom properties provide the same reference mechanism; UXDSL connects component syntax to the theme’s shared definitions.
colors.blue["700"] to update direct consumers and palette roles that reference it.palette.primary.main to reference blue-500. Primary actions follow that role; direct color(blue-700) consumers keep their token.Apply changes through the theme build or supported runtime API. Existing overrides and active modes can affect the final value. A variant named contrast is a configured foreground color, not proof of accessible contrast; check the actual foreground/background pair in each relevant state and theme.
Use the examples and palette editors below to inspect roles and their consumers. The reference JSON above stays unchanged. Palette edits may affect other parts of the playground that use the same role. Editor changes update the playground’s theme/runtime state; some controls persist browser overrides. They do not write to your source JSON file.
Token-Aware Colors: Use palette() to access semantic colors (primary, success, surface) and their variants (main, light, dark).
Click any swatch above to edit and apply the selected color.
Brand actions and key highlights
Complementary elements and secondary CTAs
Muted accents and tertiary surfaces
Positive states and confirmations
Informational surfaces and banners
Cautionary or pending actions
Destructive flows and error states
High-contrast backgrounds
Structure, frames, and dividers
Raised backgrounds and cards
Base canvas + sheets
AI implementation guide
UXDSL builds on standard CSS. Colors define the available color values; Palette assigns colors to interface roles. Both are configured in the theme JSON. Prefer palette() when a component expresses a role such as primary action or surface. Use color() when a specific color token is intentional, and standard CSS when finer control is needed.
Responsibility: maintain the semantic roles consumed by UI components. Palette expresses purpose, such as primary action or surface, independently of the current color assigned to it.
palette, relevant mode overrides and component conventions before choosing a role and variant. Primary does not inherently mean blue.palette(role.variant) when styling interface roles. Confirm the role, variant and any referenced Color exist in the intended theme.contrast is not automatic validation.Decision rule: Prefer Palette when styling interface roles. Reassign a Palette role when the meaning stays the same but its visual color should change. Keep components connected to the role.
Preserve intent, not just the current computed value. A Palette role and a Color token can look identical today while responding differently to tomorrow’s theme changes.
{
"colors": {
"blue": { "500": "#3b82f6", "700": "#1d4ed8" },
"white": "#ffffff",
"ink": "#0f172a"
},
"palette": {
"primary": {
"main": "var(--uxdsl__color__blue-700)",
"contrast": "var(--uxdsl__color__white)"
},
"surface": {
"main": "var(--uxdsl__color__white)",
"contrast": "var(--uxdsl__color__ink)"
}
}
}.primary-action {
background: palette(primary.main);
color: palette(primary.contrast);
}The action consumes primary.main, which currently references blue-700. Reassign the role to another defined Color to update its consumers while keeping their semantic declarations intact.
Change primary actions to use the existing blue-500 color.
blue-500 exists and inspect the primary role, its consumers and mode overrides.palette.primary.main to var(--uxdsl__color__blue-500) in the intended theme scope.palette(primary.main); leave direct blue-700 references unchanged.Colors define the values. Palette defines their roles. Components express the intended use.