Usage

The principles behind Mizu, how to drop components in and make them yours, and how to keep things coherent as you compose. The components are the vocabulary; this is the grammar.

Principles

Five ideas hold the whole system together. When a decision is unclear, these break the tie.

Quiet by default Hierarchy comes from space, tonal fills, and type. White surfaces and soft shadows carry the structure; nothing shines.
You own the code Components are copied into your project, not imported from a black box. Rename them, restyle them, delete what you do not use.
Recolor from one token Change --primary and the whole system retints. Reach for tokens first and one-off overrides second.
Accessible by default Interactive components wrap bits-ui, so keyboard and screen-reader behavior come for free. Keep it that way.
Restraint over decoration The content does the talking. One blue accent, one glow, and generous space go further than any effect.

Using a component

Add a component with the CLI, or copy the source straight from its page. Either way the files land in src/lib/components/ui/ and belong to you. Style any part through its class prop. Classes merge with tailwind-merge, so your overrides win without !important.

  • Compose with the exported parts, like Dialog.Root, Dialog.Trigger, and Dialog.Content.
  • Prefer tokens and utilities (bg-primary, shadow-sm, rounded-lg) over raw values.
  • Delete the components you do not use. Nothing is loaded that you did not add.

Composition

Mizu ships a few surface utilities: glass for flat frosted panels that float above content, and the orb-* and aurora-* pastel washes for the moments where the AI is present. Two rules keep them looking right:

  • One frost per layer. Translucency is for the single floating panel above the page, never for panels stacked on panels. Everything else is solid white or slate.
  • Concentric radius. A child's corner radius should equal its parent's radius minus the padding between them, or the corners read as misaligned.

Do and don't

Do

  • Theme by editing tokens in app.css, not hex values in markup
  • Reserve the pastel auras for AI moments, not chrome
  • Compose with the exported parts (Dialog.Root, Dialog.Trigger, …)
  • Label dialogs, inputs, and icon-only buttons
  • Match a child radius to its parent minus padding

Don't

  • Hard-code colors that ignore the theme
  • Stack heavy shadows where a quiet tonal shift would do
  • Remove focus rings to make it look cleaner
  • Ship an icon-only control with no accessible name
  • Animate without honoring prefers-reduced-motion

Accessibility

Behavior is delegated to bits-ui, so focus traps, roving focus, escape handling, and ARIA wiring are handled for you. Your job is to keep the names and contrast intact.

  • Give every dialog a Dialog.Title (use sr-only if it is visually hidden) and every input a Label.
  • Icon-only buttons need an sr-only label so screen readers can announce them.
  • Motion respects prefers-reduced-motion globally; keep any custom animation behind the same guard.
  • On light surfaces, use mizu-600 or darker for small text to keep contrast comfortable.

Choosing the right component

A few pairings come up constantly. When two components could work, this is the default call.

Dialog vs Sheet vs Popover Dialog for a focused, blocking task. Sheet for side panels and mobile navigation. Popover for a lightweight, non-blocking overlay anchored to a trigger.
Button variants primary for the one main action on a view, secondary for everything else, ghost for low-emphasis actions, and destructive only for something irreversible.
Badge tones primary to highlight, success / warning / destructive for status, and outline for quiet metadata.