Theme
Diwa ships two themes — Noir (dark, default) and Light. Semantic tokens automatically resolve to the correct value for the active theme. Switching is done by toggling data-theme="light" on any ancestor element.
Example
Theme Noir
Background
Contrast
Notification
State
Theme Light
Background
Contrast
Notification
State
Accent Scale(theme-invariant)
Usage
Noir is the primary design expression. Use Light only where context demands it — for example, in print-oriented views, high-ambient-light environments, or sub-sections embedded in external light-themed surfaces.
Do
- ✓Choose Noir as the first choice for Diwa AI interfaces — it reduces visual fatigue in long sessions.
- ✓Use accessibility-safe semantic tokens: contrast-high for primary text, contrast-medium for secondary, contrast-low only for decorative dividers.
- ✓Play with bg-base / bg-surface layers to create hierarchy — surface sits one step above base.
- ✓Scope light theme to a subtree with data-theme="light" on a container element when mixing is intentional.
Don't
- ✕Don't use contrast-low for text or critical information — it fails WCAG AA contrast.
- ✕Don't mix tokens from different themes (e.g. using a Noir color value in a Light context).
- ✕Don't add new raw color values to components. Always reference a semantic token.
- ✕Don't override semantic tokens with primitives in ad-hoc inline styles.
Theme switching: Toggle by setting data-theme="light" on <html>. Removing the attribute returns to Noir. Themes can be scoped to any subtree.
// Switch to Light
document.documentElement.setAttribute('data-theme', 'light');
// Return to Noir
document.documentElement.removeAttribute('data-theme');
// Scope to a subtree
<section data-theme="light">…</section>Styles
Import JS tokens for CSS-in-JS frameworks. Hover any tile above to see its full token name. Use CSS custom properties directly in stylesheets — they resolve automatically for the active theme.
import {
// Theme objects (resolved values for current theme)
themeNoir,
themeLight,
// Noir semantic tokens
themeNoirPrimary,
themeNoirBackgroundBase, themeNoirBackgroundSurface,
themeNoirBackgroundShading, themeNoirBackgroundFrosted,
themeNoirContrastLow, themeNoirContrastMedium, themeNoirContrastHigh,
themeNoirNotificationSuccess, themeNoirNotificationSuccessSoft,
themeNoirNotificationWarning, themeNoirNotificationWarningSoft,
themeNoirNotificationError, themeNoirNotificationErrorSoft,
themeNoirNotificationInfo, themeNoirNotificationInfoSoft,
themeNoirStateHover, themeNoirStateActive,
themeNoirStateFocus, themeNoirStateDisabled,
// Light semantic tokens
themeLightPrimary,
themeLightBackgroundBase, themeLightBackgroundSurface,
themeLightBackgroundShading, themeLightBackgroundFrosted,
themeLightContrastLow, themeLightContrastMedium, themeLightContrastHigh,
themeLightNotificationSuccess, themeLightNotificationSuccessSoft,
themeLightNotificationWarning, themeLightNotificationWarningSoft,
themeLightNotificationError, themeLightNotificationErrorSoft,
themeLightNotificationInfo, themeLightNotificationInfoSoft,
themeLightStateHover, themeLightStateActive,
themeLightStateFocus, themeLightStateDisabled,
// Accent scale (theme-invariant)
colorAccent50, colorAccent100, colorAccent200, colorAccent300,
colorAccent400, colorAccent500, colorAccent600, colorAccent700,
} from '@diwacopilot/components/styles';
/* ─── CSS — always resolve via semantic tokens ────────────────────── */
.card {
background: var(--diwa-bg-surface); /* adapts to active theme */
color: var(--diwa-primary);
border: 1px solid var(--diwa-contrast-low);
}
.badge-accent {
background: var(--diwa-color-accent-100);
color: var(--diwa-color-accent-400);
}
/* ─── Scoped light theme region ──────────────────────────────────── */
[data-theme="light"] .card {
/* tokens above already resolve correctly — no extra overrides needed */
}@use '@diwacopilot/components/styles' as *;
/* Scoped theme override for a region */
.dark-panel { @include diwa-theme-noir; }
.light-panel { @include diwa-theme-light; }
/* Use semantic tokens directly in component styles */
.card {
background: $diwa-bg-surface;
border: 1px solid $diwa-border;
color: $diwa-text-primary;
}
.badge-accent {
background: $diwa-color-accent-100;
color: $diwa-color-accent-400;
}