Themes

Five palettes over one set of components. Each theme authors 30 values; the 69 semantic names every component reads stay the same, so swapping a theme never touches component source. Below is every shipped palette, light and dark.

Compare

Solace

$ npx @beaket/ui init --theme solace

Warm paper, cool ink. The default: equal-weight signals under one vivid blue.

Light
Page#fdfcfa
Raised#f4f3f2
Overlay#ecebea
Ink#24232a
Rule#868688
Accent#2657d0
Danger#961733
Success#498c67
Warning#ddb54c
Info#275085
Dark
Page#0f171e
Raised#1b2229
Overlay#242c33
Ink#dfdeda
Rule#73787d
Accent#6c9bfe
Danger#e36f79
Success#88c598
Warning#f2cd6f
Info#5f8bc6

Porcelain

$ npx @beaket/ui init --theme porcelain

Near-white paper and cool graphite, with the deepest accent in the set.

Light
Page#fdfdfe
Raised#f4f4f5
Overlay#ececed
Ink#222428
Rule#858688
Accent#172889
Danger#c24b40
Success#489a68
Warning#f5c165
Info#234e82
Dark
Page#151617
Raised#202123
Overlay#2a2b2c
Ink#dcdee2
Rule#76777a
Accent#5379fe
Danger#f27e70
Success#7ed09c
Warning#ffcf7d
Info#6b84c3

Tobacco

$ npx @beaket/ui init --theme tobacco

Warm earthen paper and quiet low-chroma signals. Its sheets step lighter than the page.

Light
Page#f6f3f0
Raised#fbf7f4
Overlay#fefbf7
Ink#27231f
Rule#898582
Accent#a8372a
Danger#7f0329
Success#6e896e
Warning#ddc89d
Info#405870
Dark
Page#1b150e
Raised#262019
Overlay#302923
Ink#e3ddd7
Rule#7d766f
Accent#e87a69
Danger#d05a6a
Success#a4c0a4
Warning#e6d2a8
Info#738ca7

Marigold

$ npx @beaket/ui init --theme marigold

Pure-grey paper and ink carrying deliberately loud signals.

Light
Page#faf9fc
Raised#f1eff5
Overlay#e9e8ed
Ink#272032
Rule#88848e
Accent#7145d2
Danger#c42359
Success#099d78
Warning#fbc629
Info#423eaf
Dark
Page#18141f
Raised#231f2a
Overlay#2d2834
Ink#e0ded9
Rule#79767d
Accent#a287fe
Danger#f76689
Success#20daa7
Warning#ffd25c
Info#747aed

Eucalyptus

$ npx @beaket/ui init --theme eucalyptus

Cool-blue paper and blue-black ink, vivid throughout. Its sheets also step lighter.

Light
Page#f4f7f9
Raised#f8fcfe
Overlay#feffff
Ink#202528
Rule#838789
Accent#0470b6
Danger#a5342b
Success#439859
Warning#f1bf4e
Info#264f8b
Dark
Page#222527
Raised#2c2f31
Overlay#34373a
Ink#e0e1e3
Rule#7e8083
Accent#37b1ec
Danger#e66f62
Success#83d494
Warning#fbcd68
Info#638fd0

Try one here

This picker repaints the whole documentation site, including the specimen below, so you can read a theme in a real interface before installing it.

Acme
LiveAM

Revenue

$12,840

Users

1,284

Monthly target64%
OrderCustomerStatus
#1042Sofia MartinezShipped
#1041Liam O'ConnorPending
#1040Aisha RahmanFailed
#1039Noah WilliamsShipped

Overview

Account
LiveAM
Plan
Email receipts

Settings

Every theme supplies 30 palette values and inherits the same 69 semantic names. The CLI also installs the shared type, spacing, border, and radius foundation. Components consume 28 palette values through the semantic layer; --tone-8 and --tone-9 are reserved for neutral-ramp compatibility and future deep-ink roles.

The CLI writes the foundation, semantic layer, and selected palette directly into the CSS file you choose during setup.

npx @beaket/ui init --theme solace
# Later, switch the saved project to another theme
npx @beaket/ui theme --theme tobacco

Dark mode

Every theme ships with a dark twin. Once the CLI has written the tokens, dark mode works automatically — no flags, no extra imports, no toggle configuration required.

How it works

The CSS written by the CLI contains both light and dark values. With no data-theme attribute on <html>, @media (prefers-color-scheme: dark) follows the OS. Set data-theme="light" or data-theme="dark" to force a scheme; remove the attribute for system mode. Your app owns persistence and applying the attribute before first paint, for example through a cookie read by your server layout.

document.documentElement.dataset.theme = "dark";
document.documentElement.dataset.theme = "light";
delete document.documentElement.dataset.theme; // system

Customize safely

The marked block is managed: theme regenerates it. Put brand overrides in the generated stub after beaket:theme:end. Keep its explicit light, system-dark and forced-dark selectors: plain :root has lower specificity than the generated dark selectors. The stub is emitted once and preserved on later syncs.

npx @beaket/ui theme --theme tobacco --diff
npx @beaket/ui theme --theme tobacco --dry-run
# Review, then apply (confirmation defaults to No)
npx @beaket/ui theme --theme tobacco

Both preview flags leave CSS, config and backups untouched. A stored managed-block hash detects local edits; replacement saves a numbered backup. --overwrite explicitly skips confirmation. Generated CSS also honors prefers-reduced-motion, shortening animations and transitions, including pseudo-elements. Spacing uses Tailwind's existing 4px utility scale, not a separate custom scale.

Docs preview controls

The theme picker in this documentation site is a local preview implementation, not an @beaket/ui CSS API. It reads theme from the URL and beaket-theme / beaket-color-scheme from this site's localStorage, then injects the generated token values onto the document before paint. Those keys affect this documentation site only; importing a package palette does not read them.

The consumer contract is the root data-theme attribute in CLI-generated CSS, not this site's storage keys. Raw source palettes remain the light/dark authoring inputs.