Theming

Updated: Sep 24, 2026
The toolkit has one theme tuned for the additive-light display. Customize an application by re-pointing supported semantic roles, not by replacing the palette or restyling component internals. The toolkit does not provide a theme provider, JavaScript theme object, or light and dark modes.

Apply an override

Apply application-wide overrides to [data-app-root], the attribute that App places on its root element:
[data-app-root] {
  --uit-color-text-accent: var(--app-color-accent);
  --uit-color-persistent-action: var(--app-color-action);
}
Use a smaller application-owned ancestor when only one subtree needs an override:
.transcript-panel {
  --uit-color-text-accent: var(--app-color-transcript-accent);
}
Custom properties inherit. Menus, tooltips, and toasts render in the floating portal root, so they inherit from [data-app-root] rather than the element that opened them. Put an override on [data-app-root] when an overlay also needs it.
If the document or mount root uses --uit-color-background-window, re-point that role on :root as well so the document and application backgrounds match.

Choose supported roles

Use Semantic tokens to find the role that represents the intended meaning. Common customization families include foreground, background, interactive state, status, spacing, icon size, opacity, and elevation.
Keep overrides within the supported semantic-token surface:
  • Do not redefine component-anatomy variables or corner-radius tokens. Components own their geometry, focus bounds, drawing, and hit areas.
  • Do not target generated class names, internal elements, or other private component structure.
  • Keep the document on --uit-color-background-window. Use a documented surface component when content needs a separate legibility surface.
  • Use the secondary foreground utility classes with their corresponding color roles so the required blend behavior is preserved.
  • Use TextView or a uit-text-* appearance class for typography. A text appearance owns its family, size, weight, line height, and block metrics as one contract.
See Theme API for the complete override contract and token boundaries.

When a token is not enough

A token override changes a semantic role wherever it is used. If a custom interactive surface needs different stateful paint across idle, targeted, and pressed states, use a documented material instead. Start with a MaterialLibrary factory and pass the material to a supported host rather than reaching into an existing component’s layers.
See Theming and customization for advanced composition, materials, and validation guidance.

Validate the result

Check every reachable state, including idle, targeted, pressed, disabled, selected, partial focus, and loading. Also check overlays, route transitions, and handoffs between focus regions. Evaluate the complete rendered material because colors that remain legible at idle can fail at focused or pressed extremes.