Tokens
Design tokens flow from a single DTCG source through Style Dictionary into four consumable artifacts.
Source of truth
tokens.json at the repo root — DTCG-formatted, hand-curated cinematic palette in OKLCh.
Generated outputs
| File | Format | Consumed by |
|---|---|---|
packages/tokens/dist/tokens.css | CSS custom properties (--ploxum-color-*, --ploxum-font-*, --ploxum-motion-*, --ploxum-density-*, --ploxum-radius-*, --ploxum-layout-*) | Any app — @import "@roger-emerson/ploxum-tokens/css" |
packages/tokens/dist/tailwind.preset.mjs | Tailwind v4 preset (extends theme.colors, theme.fontFamily, theme.fontSize, theme.borderRadius) | Tailwind v4 apps |
packages/tokens/dist/tokens.mjs | Runtime JS object | Components needing non-CSS access |
packages/tokens/dist/themes/<name>.css | Per-theme [data-theme="<id>"] blocks | Switched via <PloxumProvider theme> |
Two-layer token model
Wave 9 introduced a hybrid token namespace so every shipping component keeps reading the rich --ploxum-color-* hierarchy AND any tweakcn-style theme CSS drops in without translation.
Layer 1 — shadcn semantic aliases
Every theme defines the standard shadcn vocabulary. Tailwind v4's @theme inline picks these up so bg-card, text-foreground, border-border, text-primary-foreground all work alongside the older text-[var(--ploxum-color-text-primary)] style.
--background --foreground
--card --card-foreground
--popover --popover-foreground
--primary --primary-foreground
--secondary --secondary-foreground
--muted --muted-foreground
--accent --accent-foreground
--destructive --destructive-foreground
--border --input --ring
--chart-1 --chart-2 --chart-3 --chart-4 --chart-5
--sidebar --sidebar-foreground
--sidebar-primary --sidebar-primary-foreground
--sidebar-accent --sidebar-accent-foreground
--sidebar-border --sidebar-ringThe shadcn layer caps chart colours at --chart-1..5. ploxum's derivation layer exposes --ploxum-color-chart-series1..8 — an 8-colour data-viz palette read directly by charts (PieChart, ChartFrame) so series don't collide on up-to-8-category charts.
Layer 2 — ploxum derivations
The richer ploxum hierarchy is re-expressed in terms of the shadcn names within the same [data-theme] block. For example, the cinematic theme maps:
[data-theme="cinematic"] {
/* shadcn layer */
--background: oklch(10% 0.010 35);
--foreground: oklch(94% 0.012 60);
--primary: oklch(72% 0.160 63);
--accent: oklch(20% 0.040 58 / 50%);
/* …16 more shadcn names… */
/* ploxum derivation */
--ploxum-color-background-canvas: var(--background);
--ploxum-color-text-primary: var(--foreground);
--ploxum-color-amber-default: var(--primary);
--ploxum-color-text-tertiary: oklch(52% 0.012 50); /* not in shadcn — bespoke */
/* …rest of the ploxum tree… */
}This is why an Amber Minimal swap repaints the entire surface area: each component reads ploxum vars, and those vars now point at the active theme's shadcn-aliased values.
OKLCh palette (cinematic, the reference)
Surfaces
| Token | Value | Use |
|---|---|---|
--ploxum-color-background-canvas | oklch(10% 0.010 35) (#1A1612) | App background, focal canvas |
--ploxum-color-background-surface | oklch(13% 0.012 33) | Card, sidebar |
--ploxum-color-background-elevated | oklch(17% 0.014 32) | Popover, dropdown |
--ploxum-color-background-overlay | oklch(21% 0.015 31) | HUD pills, badges over canvas |
--ploxum-color-background-scrim | oklch(8% 0.008 35 / 80%) | Modal scrim |
Text
| Token | Value | Contrast on canvas |
|---|---|---|
--ploxum-color-text-primary | oklch(94% 0.012 60) | 13.8:1 |
--ploxum-color-text-secondary | oklch(72% 0.014 55) | 7.2:1 |
--ploxum-color-text-tertiary | oklch(52% 0.012 50) | 4.6:1 |
--ploxum-color-text-amber | oklch(78% 0.160 62) | 7.8:1 |
Amber (4 tones)
| Token | Value | Use |
|---|---|---|
--ploxum-color-amber-bright | oklch(80% 0.175 65) | Hover, focus highlight |
--ploxum-color-amber-default | oklch(72% 0.160 63) (#D4902A) | Primary accent — ≤20% of chrome surface |
--ploxum-color-amber-dim | oklch(58% 0.120 60) | Secondary amber detail |
--ploxum-color-amber-tint | oklch(20% 0.040 58 / 50%) | Active row background, badge fill |
Status
| Family | Default | Mid | Tint |
|---|---|---|---|
| Success | oklch(62% 0.140 152) | oklch(48% 0.110 152) | oklch(18% 0.040 148 / 55%) |
| Warning | oklch(74% 0.140 85) | oklch(58% 0.110 82) | oklch(18% 0.038 80 / 55%) |
| Danger | oklch(58% 0.200 22) | oklch(44% 0.170 22) | oklch(16% 0.060 20 / 55%) |
| Info | oklch(64% 0.140 240) | oklch(50% 0.110 242) | oklch(16% 0.040 238 / 55%) |
Status colors NEVER convey state alone — always paired with a <StatusPip> shape (circle / square / triangle / x).
Density
Two modes via <PloxumProvider density>:
| Token | Compact | Comfortable |
|---|---|---|
--ploxum-density-rowHeight | 28px | 40px |
--ploxum-density-gutter | 8px | 16px |
--ploxum-density-cardPadX | 12px | 20px |
--ploxum-density-cardPadY | 8px | 16px |
--ploxum-density-iconSize | 16px | 20px |
--ploxum-density-inputHeight | 28px | 36px |
compact is tuned for NOC walls; comfortable for laptops. Density persists per operator account, not session.
Scrollbars
theme.css restyles every scroll container to flow with the UI — a transparent track and a subtle border-default thumb that brightens to text-tertiary on hover, via scrollbar-width/scrollbar-color (Firefox) and ::-webkit-scrollbar (WebKit/Blink). No markup needed; it applies globally.
.scrollbar-none— opt out (hide the scrollbar while keeping scroll); wins by specificity.- For overlay/hover-reveal scrollbars or horizontal scrolling, wrap the region in the
ScrollAreaprimitive.
See also
- Themes — switching between cinematic + amber-minimal at runtime and the tweakcn adapter.
- Motion — duration + easing tokens and the cinematic-flourish budget.
- Principles — the 10 UX heuristics that constrain how tokens are spent.
