Repo

ZUI ships first-party wrappers for React, Astro, Solid, Svelte, and Vue. For other frameworks, use the CSS classes directly.

Install ZUI and import the stylesheet however your framework handles CSS

CSS class reference

All ZUI components use BEM-style classes prefixed with zui-. Apply them directly in any template language.

Button

Class Purpose
zui-button Base button styles
zui-button-variant-fill Solid filled button (default)
zui-button-variant-subtle Subtle background
zui-button-variant-outline Outlined border
zui-button-variant-ghost No background until hover
zui-button-variant-link Looks like a text link
zui-button-color-theme Theme colour (default)
zui-button-color-accent Accent colour
zui-button-color-destructive Destructive/danger colour
zui-button-size-xs Extra small
zui-button-size-sm Small
zui-button-size-lg Large
zui-button-size-xl Extra large
zui-button-shape-hard Sharp corners
zui-button-shape-soft Extra rounded corners
zui-button-shape-squircle Squircle shape
zui-button-icon Icon-only button (square)

Badge

Class Purpose
zui-badge Base badge styles
zui-badge-variant-fill Solid filled badge
zui-badge-variant-outline Outlined badge
zui-badge-color-{color} Color variant (red, green, blue, violet, amber, orange, yellow, lime, emerald, teal, cyan, sky, indigo, purple, fuchsia, pink, rose, gray)

Card

Class Purpose
zui-card Base card container
zui-card-elevated Elevated shadow style
zui-card-interactive Adds hover/focus styles for clickable cards
zui-card-header Card header section
zui-card-title Card title text
zui-card-description Card description text
zui-card-body Card body content
zui-card-footer Card footer section

Form elements

Class Purpose
zui-input Text input
zui-textarea Textarea
zui-select Select dropdown
zui-label Form label
zui-label-required Adds a required indicator after the label
zui-label-description Descriptive/hint text below a label
zui-checkbox Checkbox
zui-checkbox-list Vertical list of checkboxes
zui-radio Radio button
zui-radio-list Vertical list of radio buttons

Table

Class Purpose
zui-table Base table styles
zui-table-head Table header cell (<th>)
zui-table-row Table row
zui-table-cell Table body cell (<td>)
zui-table-footer Table footer row/section
zui-table-caption Table caption

Dialog

Class Purpose
zui-dialog Dialog container
zui-dialog-header Dialog header section
zui-dialog-title Dialog title text
zui-dialog-description Dialog description text
zui-dialog-body Dialog body content
zui-dialog-footer Dialog footer section
zui-dialog-close Close button
zui-dialog-size-sm Small dialog
zui-dialog-size-lg Large dialog
zui-dialog-size-full Full-screen dialog

Tooltip

Class Purpose
zui-tooltip Tooltip wrapper
zui-tooltip-content Tooltip content bubble
zui-tooltip-placement-top Position above the trigger
zui-tooltip-placement-bottom Position below the trigger
zui-tooltip-placement-left Position left of the trigger
zui-tooltip-placement-right Position right of the trigger

Accordion

Class Purpose
zui-accordion Accordion container
zui-accordion-item Individual accordion item (<details>)
zui-accordion-trigger Accordion toggle (<summary>)
zui-accordion-content Accordion content panel
zui-accordion-flush Flush (borderless) variant

Collapsible

Class Purpose
zui-collapsible Collapsible container (<details>)
zui-collapsible-trigger Toggle trigger (<summary>)
zui-collapsible-content Collapsible content panel

Popover

Class Purpose
zui-popover Popover container

Framework examples

Plain HTML

<button class="zui-button zui-button-variant-fill zui-button-color-theme">
  Save
</button>

<span class="zui-badge zui-badge-color-green">Active</span>

<div class="zui-card">
  <div class="zui-card-header">
    <h2 class="zui-card-title">Card title</h2>
    <p class="zui-card-description">Card description</p>
  </div>
  <div class="zui-card-body">
    <div class="zui-field">
      <label class="zui-label" for="email">Email</label>
      <input class="zui-input" id="email" type="email" />
    </div>
    <button class="zui-button zui-button-variant-outline">Submit</button>
  </div>
</div>

Utility classes

ZUI ships utility classes you can use in any framework. Note that spacing, flex, flow, and prose utilities do not use the zui- prefix.

Spacing

<!-- Margin -->
<div class="mt-md mx-lg">...</div>

<!-- Padding -->
<div class="px-lg py-sm">...</div>

<!-- Gap (for flex/grid) -->
<div class="flex flex-row gap-md">...</div>

Flex

<div class="flex flex-row gap-md items-center">...</div>
<div class="flex flex-column gap-sm">...</div>
<div class="inline-flex items-center gap-xs">...</div>

Layout

<!-- Flow (vertical rhythm) -->
<div class="flow">...</div>

<!-- Prose (long-form content) -->
<div class="prose">...</div>

Typography

<!-- Font size scale -->
<p class="zui-text-sm">Small text</p>
<p class="zui-text-base">Base text</p>
<p class="zui-text-1">Larger text</p>

<!-- Muted text -->
<p class="zui-color-muted">Secondary text</p>
<p class="zui-color-faint">Faint text</p>

<!-- Link styling -->
<a href="#" class="zui-link">Styled link</a>

<!-- Code -->
<code class="zui-code">inline code</code>
<pre class="zui-pre"><code>block code</code></pre>

Accessibility

<!-- Visually hidden (screen reader only) -->
<span class="sr-only">Screen reader label</span>

Building wrapper components

You can create thin wrapper components in any framework using the CSS classes. Here's a generic example using a hypothetical template language:

<!-- Button.template -->
<button class="zui-button zui-button-variant-{variant} zui-button-color-{color}">
  {label}
</button>

Tip: ZUI already ships first-party wrappers for React, Astro, Solid, Svelte, and Vue.

CSS Layers

ZUI uses CSS @layer to organize styles. Your unlayered styles will always take precedence, making overrides straightforward in any framework:

/* Your framework's styles — always wins over ZUI layers */
.my-custom-button {
  background-color: hotpink;
}

Theming

Theming is framework-agnostic — just override CSS custom properties. See the Theming page for full details.

:root {
  --color-theme: light-dark(var(--color-violet-600), var(--color-violet-400));
  --radius-scale: 1.5;
}

Theme

Copy this CSS to your project: