Skip to content

Theming

One set of components, many eras. A theme is a CSS file; your markup never changes.

Eras

  • Y2K · aqua (default): gel, pinstripes, the blue popup button, midnight dark mode.
  • Now · liquid: frosted glass, rim light, deep soft shadows.
  • Vintage · platinum: Mac OS 8 and 9 gray, bevels, hard shadows, square corners, no motion. Dark mode is graphite.
  • Vintage · system: 1-bit black and white, dither instead of gray, inverted selection.
  • Y2K · aero: Frutiger Aero glass, wet highlights, sky blue.

Styles

Looks that were never an era. Same system, same components.

  • brutalist: thick outlines, hard offset shadows, zero radius, flat loud color.
  • minimal: hairlines, no shadows, space and one ink color.
  • urban: near black with grain, acid accent, heavy uppercase type.
  • paper: warm stock, serif headings, clay accent, ruled inputs.
  • terminal: monospace, bracketed buttons, phosphor glow, blinking caret.
  • neon: violet black, magenta and cyan glow, lit controls.

Themes name a typeface through --mi-font-sans but cannot load it: Archivo for brutalist, urban and neon, Inter for minimal and paper, JetBrains Mono for terminal. paper also reads --mi-paper-serif for its headings. Load the fonts yourself, or override the variables.

Modes

Without data-mode, themes follow the device. Set data-mode="light" or "dark" to lock one.

Tokens

Every theme defines the same CSS variables, designed in Figma and generated into CSS. Change them anywhere:

[data-theme="aqua"] {
  --mi-accent: #e8559b;      /* pink gel, why not */
  --mi-radius-lg: 16px;
}
  • Color: --mi-bg, fg, fg-muted, accent, accent-fg, danger, success, warning, border
  • Glass: --mi-glass-tint, tint-strong, blur, saturate, highlight, edge, shadow
  • Shape and type: --mi-radius-sm…full, --mi-space-1…8, --mi-text-xs…xl, --mi-font-sans, mono
  • Motion: --mi-duration-fast, --mi-duration

Slots and state

Every part of every component has a data-slot, like select-trigger, menu-item or dialog-panel. State lives in data attributes. Style them from anywhere:

[data-slot="tabs-trigger"][data-state="active"] { font-weight: 700; }
[data-slot="toast"][data-variant="error"] { border-color: red; }

Overriding with classes

Theme styles live in @layer components. Your classes, Tailwind or not, always win without !important:

<Button className="rounded-none px-8">Square</Button>