Themes

Every component reads semantic design tokens, never raw colours. Swap the token set and everything restyles, even inside shadow DOM.

Pixel corners, notched frames, stepped motion and the pixel display font in capitals. Turn them off with data-sb-style="smooth", or set only --sb-notch: 0 to keep everything but the corners.

Button

Blast off

Input

Slider

Alert

Your component is live.

Toggle

Tabs

Card

A violet planet rising over pixel hills

Tooltip

Info

Modal

Are you ready to launch?CancelLaunch

Use it

Scope a theme to any element with data-sb-theme, or copy the overrides into your own stylesheet. Components only ever read --sb-* semantic tokens.

The 8-bit details are tokens too: data-sb-style="smooth" on any element sets --sb-notch: 0 (plain corners with a normal radius), --sb-frame-step: 1px (hairline frames), the UI font for display text and --sb-display-case: none (display text as written, not in capitals). At --sb-notch: 0 stepped arrows become triangles, stepped motion runs smoothly, and pixel charts draw at the screen's resolution. It combines with every theme.

[data-sb-theme="deep-space"] {
  color-scheme: dark;
  
  --sb-bg: var(--sb-ink-12);
  --sb-bg-glow: oklch(30% 0.12 285 / 0.35);
  --sb-surface-raised: var(--sb-ink-10);
  --sb-surface-card: var(--sb-ink-9);
  --sb-surface-inset: var(--sb-ink-11);
  --sb-surface-hover: oklch(from var(--sb-ink-9) calc(l + 0.03) c h);
  --sb-surface-overlay: oklch(12% 0.03 268 / 0.72);
  
  --sb-border: var(--sb-ink-7);
  --sb-border-subtle: oklch(from var(--sb-ink-7) l c h / 0.6);
  --sb-border-strong: var(--sb-ink-6);
  
  --sb-text-1: var(--sb-ink-0);
  --sb-text-2: var(--sb-ink-2);
  --sb-text-muted: var(--sb-ink-4);
  --sb-text-on-brand: var(--sb-ink-0);
  
  --sb-brand: var(--sb-violet-5);
  --sb-brand-hover: var(--sb-violet-4);
  --sb-brand-light: var(--sb-violet-3);
  --sb-brand-subtle: oklch(from var(--sb-violet-5) l c h / 0.14);
  --sb-accent: var(--sb-cyan-3);
  --sb-datastar: var(--sb-green-3);
  
  --sb-ok: var(--sb-green-3);
  --sb-ok-subtle: oklch(from var(--sb-green-3) l c h / 0.12);
  --sb-warn: var(--sb-amber-3);
  --sb-warn-subtle: oklch(from var(--sb-amber-3) l c h / 0.12);
  --sb-danger: var(--sb-red-3);
  --sb-danger-subtle: oklch(from var(--sb-red-3) l c h / 0.12);
  --sb-info: var(--sb-cyan-3);
  --sb-info-subtle: oklch(from var(--sb-cyan-3) l c h / 0.12);
  
  --sb-control-bg: var(--sb-ink-11);
  --sb-control-border: var(--sb-ink-7);
  --sb-control-border-hover: var(--sb-ink-6);
  --sb-control-text: var(--sb-ink-0);
  --sb-control-placeholder: var(--sb-ink-4);
  --sb-control-radius: var(--sb-radius-sm);
  
  --sb-radius: var(--sb-radius-md);
  --sb-frame-color: var(--sb-violet-3);
  --sb-glow-brand: 0 0 0 1px oklch(from var(--sb-violet-5) l c h / 0.35), 0 8px 32px -8px oklch(from var(--sb-violet-5) l c h / 0.45);
  --sb-focus-ring: 0 0 0 2px var(--sb-bg), 0 0 0 4px var(--sb-brand-light);
  --sb-selection: oklch(from var(--sb-violet-5) l c h / 0.4);
  
  --sb-font-body: var(--sb-font-ui);
  --sb-font-heading: var(--sb-font-ui);
  
  /* Syntax highlighting (code blocks and sb-code-editor). */
  --sb-code-keyword: var(--sb-violet-3);
  --sb-code-function: var(--sb-violet-2);
  --sb-code-tag: var(--sb-cyan-3);
  --sb-code-string: var(--sb-green-3);
  --sb-code-number: var(--sb-amber-3);
  --sb-text-on-danger: #1B0A0C;
}