Custom CSS
Override CSS variables to retune colors, spacing, and individual surfaces.
purplemux is built on a CSS variable system. You can change almost anything visual without touching the source — paste rules into the Appearance tab, click Apply, and they take effect immediately on every connected client.
Where to put it
Open Settings (⌘,) and pick Appearance. You'll see a single textarea labeled Custom CSS.
- Write your rules.
- Click Apply. The CSS is injected into a
<style>tag on every page. - Click Reset to clear all overrides.
The CSS is stored on the server in ~/.purplemux/config.json (customCSS), so it applies on every device that connects.
How it works
Most colors, surfaces, and accents in purplemux are exposed as CSS variables under :root (light) and .dark. Overriding the variable cascades the change everywhere that variable is used — sidebar, dialogs, charts, status badges.
Changing a single variable is almost always better than overriding component selectors directly. Component classes are not a stable API; variables are.
A minimal example
Tone the sidebar a touch warmer in light mode and push the dark surface darker:
:root {
--sidebar: oklch(0.96 0.012 80);
}
.dark {
--background: oklch(0.05 0 0);
}
Or recolor the brand without touching anything else:
:root {
--primary: oklch(0.55 0.16 280);
}
.dark {
--primary: oklch(0.78 0.14 280);
}
Variable groups
The Appearance panel exposes the full list under Available Variables. The major buckets are:
- Surface —
--background,--card,--popover,--muted,--secondary,--accent,--sidebar - Text —
--foregroundand the matching*-foregroundvariants - Interactive —
--primary,--primary-foreground,--destructive - Border —
--border,--input,--ring - Palette —
--ui-blue,--ui-teal,--ui-coral,--ui-amber,--ui-purple,--ui-pink,--ui-green,--ui-gray,--ui-red - Semantic —
--positive,--negative,--accent-color,--brand,--focus-indicator,--claude-active
For the full token list with default oklch values and the design rationale, see docs/STYLE.md in the repo. That document is the source of truth.
Targeting only one mode
Wrap rules in :root for light and .dark for dark. The class is set on <html> by next-themes.
:root {
--muted: oklch(0.95 0.01 287);
}
.dark {
--muted: oklch(0.18 0 0);
}
If you only need to change one mode, leave the other untouched.
What about the terminal?
The xterm.js terminal uses its own palette, picked from a curated list — it's not driven by these CSS variables. Switch it on the Terminal tab. See Terminal themes.
What's next
- Themes & fonts — light, dark, system; font-size presets.
- Terminal themes — separate palette for the terminal area.
- Sidebar & Claude options — reorder items, toggle Claude flags.