Installation & Usage
Add @wintermuted/ui-theme to any project in two steps: install the package
and import the stylesheet. The theme ships as a single CSS file with design tokens and
component classes — no build step required.
Entry files: index.css, styles/tokens.css, styles/base.css, styles/components.css
Install
Install from npm:
npm install @wintermuted/ui-theme
Or with yarn:
yarn add @wintermuted/ui-theme
Import the Stylesheet
Import once at your app entry point. In a Vite / bundler project:
import '@wintermuted/ui-theme';
Or reference directly in HTML:
<link rel="stylesheet" href="node_modules/@wintermuted/ui-theme/index.css" />
Dark Mode
Dark tokens activate when the data-theme="dark" attribute is set on
document.documentElement. Remove the attribute to restore light mode.
// Enable dark mode
document.documentElement.setAttribute('data-theme', 'dark');
// Restore light mode
document.documentElement.removeAttribute('data-theme');
Persist the preference across sessions:
const saved = localStorage.getItem('theme');
if (saved === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
}
Design Tokens
All tokens are CSS custom properties on :root. Dark overrides live on
[data-theme="dark"]. Use them directly in your own CSS:
.my-card {
background: var(--wm-color-surface-solid);
border: 1px solid var(--wm-color-border);
border-radius: var(--wm-radius-sm);
color: var(--wm-color-text);
font-family: var(--wm-font-sans);
}
Color tokens
--wm-color-bg— page background--wm-color-surface-solid/--wm-color-surface-strong/--wm-color-surface-muted— layered surface levels--wm-color-text/--wm-color-text-secondary/--wm-color-text-muted— text hierarchy--wm-color-border/--wm-color-border-strong— border levels--wm-color-accent/--wm-color-accent-soft/--wm-color-accent-border— brand accent--wm-color-success/--wm-color-warning/--wm-color-danger— semantic states (each with-softand-bordervariants)
Spacing & shape tokens
--wm-radius-xs--wm-radius-base--wm-radius-sm--wm-radius-md--wm-radius-lg--wm-radius-pill— border radius scale--wm-font-sans— system font stack (Inter + fallbacks)--wm-shadow-soft— card/modal elevation shadow
Component Classes
The stylesheet includes opt-in component classes. All classes ship with both a
wm- prefixed alias and a short alias for convenience.
| Class | Alias | Description |
|---|---|---|
.wm-card | .card | Surface card with border, radius, and optional shadow |
.wm-btn | .btn | Base button reset — combine with modifier below |
.btn-primary | — | Tonal primary action button |
.btn-secondary | — | Tonal secondary button |
.btn-ghost | — | Transparent with hover fill |
.btn-danger | — | Tonal destructive action |
.btn-sm | .wm-btn-sm | Compact size modifier for .btn |
.wm-tag | .tag | Neutral pill — for keyword / skill lists |
.wm-tag-accent | .tag-accent | Accent-tinted pill — for linked references |
.badge | — | Inline status badge (combine with semantic modifier) |
.wm-list | — | Custom dot-bullet list (no default list styling) |
.wm-separator | — | Themed <hr> |
.wm-side-nav | — | Sticky sidebar nav with left-bar active indicator |
Local Development
To iterate on the theme without publishing to npm, use npm link to symlink
the local package into a consumer project:
# In the ui-theme repo
npm link
# In your consumer project
npm link @wintermuted/ui-theme
Bundler projects (Vite, webpack) may need to be told to allow symlinked files outside
the project root. In Vite, set server.fs.allow and exclude the package
from dep pre-bundling:
// vite.config.ts
export default defineConfig({
server: {
fs: { allow: ['..'] },
},
optimizeDeps: {
exclude: ['@wintermuted/ui-theme'],
},
});