Status: CONCEPT Β· Created March 2026
Parent: GLOBAL_concept-ecosystem.md
Supersedes: COMP_ui_spec.md, COMP_ui_concept.md (theme layer)
Companion document: GLOBAL_concept-brand.md
Overview
CSS design system for all xPulse tools β structure, colours, effects and
animations in a single package. No separate @xpulse/theme β everything lives in
@xpulse/theme.
A theme is a CSS file that defines custom properties, component styles,
hover/focus effects and animations. Themes are found automatically via discovery β
no manual registration required.
Theme names are extracted from the bundled CSS via regex β
no filename parsing, no manual registration:
1
[data-theme="dark"] β 'dark'
2
[data-theme="light"] β 'light'
3
[data-theme="app"] β 'app'
Only themes that appear as selectors in the CSS are considered known.
App Theme Overrides
App CSS under src/themes/ is appended to the end of the bundle.
The app theme link is additionally included as a separate <link> (via themeAssets()).
xpulse.json Configuration
1
{
2
"theme":{
3
"default":"dark",
4
"allow":["dark","light"],
5
"cache":{
6
"enabled":true,
7
"ttl":0
8
}
9
}
10
}
Key
Description
Default
theme.default
Active theme on startup
"dark"
theme.allow
Which themes the user may choose. [] = all discovered themes allowed
[]
theme.cache.enabled
Cache the CSS bundle (see caching section)
true
theme.cache.ttl
Cache expiry in seconds. 0 = no expiry
0
If allow is empty or not set β all discovered themes are permitted.
If allow contains exactly ["dark", "light"] β toggle button instead of select.
If allow contains more than 2 themes β select dropdown.
If allow contains only one theme β no switcher in the UI.
// root β where to look for src/themes/ (default: cwd)
9
// force β ignore cache and rebuild bundle
10
11
// Active default theme (from config)
12
theme.current(); // β 'dark'
13
14
// All themes discovered in the CSS
15
theme.available(); // β ['dark', 'light']
16
17
// Permitted themes (filtered by theme.allow)
18
theme.allowed(); // β ['dark', 'light']
19
20
// Existence check
21
theme.has('dark'); // β true
22
23
// Theme switch (server-side)
24
theme.set('light');
25
26
// Toggle (only when exactly 2 themes in allowed())
27
theme.toggle();
28
29
// URLs
30
theme.href(); // β '/_theme/css/xpulse.css'
31
theme.scriptHref(); // β '/_theme/theme.js'
How the Toggle Works
Theme switching is controlled by the data-theme attribute on <html> β
CSS selectors html[data-theme="dark"] take effect without any JS-side DOM styling.
As a safeguard, the class theme-${name} is also set.
Existing xPulse projects still use the old unprefixed properties.
Migration at v1.4.0 (component based):
Old
New
--bg
--xpulse-bg
--surface
--xpulse-surface
--border
--xpulse-border
--muted
--xpulse-muted
--text
--xpulse-text
--text-dim
--xpulse-text-dim
--accent
--xpulse-accent
--accent2
--xpulse-accent2
--danger
--xpulse-danger
--mono
--xpulse-font-mono
--serif
--xpulse-font-serif
.btn-primary
.xpulse-btn-primary
.btn-secondary
.xpulse-btn-secondary
.btn-danger
.xpulse-btn-danger
.btn-icon
.xpulse-btn-icon
.field
.xpulse-field
.field-label
.xpulse-field-label
.field-hint
.xpulse-field-hint
@keyframes fadeIn
@keyframes xpulse-fadeIn
@keyframes spin
@keyframes xpulse-spin
Chat-specific properties (--sidebar-width, --topbar-height) and
classes (.status-dot, .status-badge, .waiting-dots) remain in the
chat CSS without renaming.
Documentation
The component documentation is rendered as a standalone HTML page β
analogous to Bootstrap/Tailwind: live preview + code snippet side by side.
1
xpulse.one/doc/component/theme/
Structure:
Each component has a block with:
Rendered preview (real HTML with the active theme)
Code snippet (copy-pasteable)
Variants (e.g. all button types)
Theme toggle visible directly in the docs β switch dark/light live
Custom properties overview as a table with live colour preview
Animations as live demo
The docs HTML lives in docs/de/components.html + docs/en/components.html
as standalone HTML docs β rendered directly in the docs section of xpulse.one
via <iframe> or embedded inline (see GLOBAL_concept-docs.md).
Consumers
Project
Status
Note
chat.xpulse.one
β Source
Migration at v1.4.0
xpulse.one
π First smoke test
Determines whether the package is truly generic
board.xpulse.one
π‘ Planned
Starts after smoke test
Future: ui.xpulse.one
Visual theme generator β a standalone xPulse tool on its own subdomain:
Live preview of all components with the active theme
Colour picker + sliders for all --xpulse-* properties
Selectable dark/light base
Export as a ready-to-use mytheme.css
Directly includable via discovery in any xPart
1
xpulse.one/doc/component/theme/ β documentation + live preview
2
ui.xpulse.one β theme generator + export
Status: idea β conceivable after board.xpulse.one.