Skip to main content
Mantı UI logoMantı UIv0.12.1
Studio

Theming with tokens

Use the broadest token that matches the design decision.

Before writing any of this, check whether a shipped preset already gets you there — adopting one is a single import. Reach for the tokens below to retune a preset, or to build a theme none of them cover.

Prefer to see it before you write it? The Theme Studio tunes these same tokens live on a full product surface, then hands the result back as CSS, as an agent prompt, or as a shareable link.

NeedUse
Replace a palette or scalePrimitive token
Change a system-wide purposeSemantic token
Change color and emphasisVariant roles
Make one component intentionally differComponent token

Start with semantic roles

:root {
  --manti-bg: light-dark(#fafafb, #0c0c10);
  --manti-surface: light-dark(#ffffff, #15151b);
  --manti-surface-raised: light-dark(#ffffff, #1b1b22);
  --manti-text: light-dark(#16161a, #f4f4f6);
  --manti-text-muted: light-dark(#5c5c66, #b6b6c0);
  --manti-border: light-dark(#e6e6ea, #2a2a33);
  --manti-radius-factor: 0.8;
  --manti-duration-base: 180ms;
}

Keep theme-aware colors in light-dark(light, dark) form.

Use variants for color

Remap a built-in variant on the whole app or within a subtree:

.marketing [data-variant='primary'] {
  --variant-solid: var(--manti-blue-9);
  --variant-solid-hover: var(--manti-blue-10);
  --variant-ring: var(--manti-blue-8);
}

See Color & variants for the full role list.

Use component tokens for exceptions

:root {
  --manti-button-radius: var(--manti-radius-full);
}

If the same override appears on several components, move it to a semantic token instead. Do not override private --_* variables.

Retune a size step

sm | md | lg is one shared rhythm. A control and the surface it opens resolve the same --manti-size-* channel, so a sm Select opens a sm listbox and a lg Menu lays out lg rows. Popups are portalled, so each adapter re-stamps data-size on its positioner rather than relying on inheritance.

Retune a step once and every control and popup on it follows:

[data-size='sm'] {
  --manti-size-item-padding-y: 0.125rem;
  --manti-size-text: 0.8125rem;
}

The channel carries text, text-sub, icon, control-height, control-padding-x, panel-padding, panel-gap, item-padding-y, item-padding-x, item-gap, item-radius, and cell. Every component token above defaults to one of them, so a per-component override still wins.

Continue to plain CSS for anatomy selectors or Tailwind for utility integration.

Last updated

Built end-to-end with Manti UI components and design tokens. Manti UI is a framework-agnostic design system on Zag.js.

GitHub