Theming

Components read CSS variables. Change tokens for system-wide look, or override a single component with classes and selectors.

Where tokens live

Package installs use @sivir-ui/svelte/ui.css. CLI installs use src/lib/sivir/ui.css. Both define the same public axes: color, type, radius, and motion.

Theme Studio

The Theme Studio is the visual way to build a theme. Start from a built-in preset and adjust the shared axes — brand, neutral temperature, radius, density, motion, and fonts — plus typography (header size and per-role weights for body, label, button, badge, and description), per-mode foundation colors, and chrome flags (surface, control, and dialog shadows, the traveling highlight, primary stroke, and the interactive cursor). The Advanced section overrides individual color, spacing, and animation tokens per light and dark mode.

Copy the generated theme.css to use the theme in your app, or copy the theme JSON to share it. The studio keeps your draft in local storage between visits.

Override tokens

Set values in your app CSS after importing Sivir’s sheet. Light defaults go in @theme. Dark values go under .dark.

@theme {
  --color-primary: #155eef;
  --color-background: #fcfcfd;
  --color-foreground: #101828;
  --radius-lg: 0.55rem;
    --font-sans: 'DM Sans', sans-serif;
}

.dark {
  --color-background: #0d1118;
  --color-foreground: #f5f7fb;
  --color-primary: #7aa2ff;
}

Useful public tokens

  • Color: --color-background, --color-card, --color-panel, --color-secondary, --color-foreground, --color-foreground-muted, --color-primary, --color-on-primary, --color-button-foreground, --color-border, --color-input, --color-ring
  • Type: --font-sans, --font-mono, --font-header, --font-size-header, and role weights like --font-weight-body, --font-weight-label, --font-weight-button
  • Radius and density: --radius-sm, --radius-md, --radius-lg, --radius-xl, and the base spacing unit --sivir-space-unit
  • Motion: --motion-duration-hover, --motion-duration-menu, --motion-duration-panel, --motion-duration-sheet
  • Elevation: --elevation-1, --elevation-float, --elevation-control, --elevation-modal

Built-in presets

Five presets ship with Sivir: default, magic, bitsy, open, and functional. Preview them live on the themes page, where you can copy each preset’s CSS or JSON.

With the CLI, install a preset into theme.css:

bunx --package @sivir-ui/svelte sivir add theme open

Import it after ui.css so it wins:

@import './lib/sivir/ui.css';
@import './lib/sivir/theme.css';

sivir list shows available built-in theme slugs. Community theme registry hosting is not part of v1.

Dark mode

Toggle a .dark class on <html>. Components do not manage the class for you.

Theme JSON

Theme JSON (version 4) captures a theme as data, so the studio, the CLI, and the theme registry all speak the same format. Beyond the shared axes, theme JSON accepts per-mode surfaces in foundation.light / foundation.dark (base, border, background, secondary, foreground, foregroundMuted, onPrimary), typography under typography (headerSize, headerWeight, and roleWeights for body, label, button, badge, and description), raw token overrides under tokens.shared / tokens.light / tokens.dark (for example per-mode primary colors overriding --color-primary), and chrome flags under chrome: surfaceShadows, controlShadows, dialogShadows, travelingHighlight: false (item fill stays, the slide does not), primaryStroke, and interactiveCursor. Setting motion: "none" disables every animation, including dialogs, menus, and the traveling highlight.

class prop

Every primitive accepts class. Use Tailwind utilities or your own classes for one-off tweaks.

<Button class="w-full rounded-2xl">Continue</Button>

data-ui selectors

Components render data-ui (and often data-variant / data-size). Scope CSS to a family without forking files.

[data-ui='button'][data-variant='primary'] {
  border-radius: 999px;
}

[data-ui='badge'][data-variant='secondary'] {
  text-transform: uppercase;
}

Edit the source

With the CLI path, files live under src/lib/sivir/components/<name>/. Edit them when you need behavior changes, not just style.

# after: bunx --package @sivir-ui/svelte sivir add button
src/lib/sivir/components/button/
├── button.svelte
└── index.ts

Next

Components