Theming

LatticeUI is themed entirely through CSS custom properties compiled from W3C design tokens. There is no theme object, no provider, and no runtime cost - overriding a theme is just CSS.

The token layers

Change the brand color

One rule re-themes every button, badge, focus ring, and accent in the system:

:root {
  --ts-accent-default: oklch(0.65 0.2 300); /* purple instead of teal */
  --ts-accent-emphasis: oklch(0.58 0.21 300);
  --ts-accent-fg: oklch(0.78 0.16 300);
  --ts-accent-subtle: oklch(0.3 0.08 300 / 0.35);
}

Dark / light mode

Themes are keyed off data-theme on <html>. Both themes ship in tokens.css; switching is instant and SSR-safe.

<html data-theme="light">  <!-- or "dark" (default) -->

Restyle a single component

Components expose stable data-scope/data-part attributes - a versioned styling API. Because all library CSS sits in @layer latticeui, your unlayered CSS always wins. No specificity wars, no !important:

/* square buttons, app-wide */
[data-scope="button"][data-part="root"] {
  border-radius: 0;
}

/* or tweak one component token */
[data-scope="button"][data-part="root"][data-variant="solid"] {
  --btn-bg: var(--ts-success-default);
}

Scoped themes

Because everything is CSS variables, you can theme a subtree - useful for marketing sections or embedded widgets:

.promo-section {
  --ts-accent-default: #f59e0b;
  --ts-radius-md: 2px;
}

Build your own token set

The source of truth is W3C design-token JSON in latticeui-tokens. Fork the JSON, run the build script, and you get a complete tokens.css plus typed TypeScript maps for your own brand.