Wireframe Theme Selector Pattern
Both wa-dark/wa-light and data-wf-theme are set on the same <html> element. Themes must define variables in two compound selector blocks so they cooperate with Web Awesome’s dark/light class mechanism:
/* ── Light (default) ──────────────────────────────────────── *//* Applies when wa-light is present, and also before any WA *//* class is set (prevents flash of unstyled content at paint). */:root[data-wf-theme="{id}"],:root.wa-light[data-wf-theme="{id}"] { --wf-color-primary: #…; --wf-color-primary-text: #…; --wf-color-bg: #…; --wf-color-bg-light: #…; --wf-color-bg-elevated: #…; --wf-color-text: #…; --wf-color-text-muted: #…; --wf-color-border: #…; --wf-color-border-dark: #…; --wf-color-success: #…; --wf-color-warning: #…; --wf-color-danger: #…; --wf-radius-card: …px; --wf-radius-button: …px; --wf-border-width: 1px; --wf-spacing-gap: 1rem; /* Optional: --wf-font-body, --wf-font-heading, --wf-font-mono */}
/* ── Dark ─────────────────────────────────────────────────── *//* Overrides when wa-dark is present on <html>. */:root.wa-dark[data-wf-theme="{id}"] { --wf-color-primary: #…; /* often a lighter tint than light mode */ --wf-color-bg: #…; --wf-color-bg-light: #…; --wf-color-bg-elevated: #…; --wf-color-text: #…; --wf-color-text-muted: #…; --wf-color-border: #…; --wf-color-border-dark: #…;}
/* ── Component overrides ─────────────────────────────────── *//* Scope to the theme to avoid polluting other themes. *//* Use :root[data-wf-theme="{id}"] .wf-{component} for *//* overrides that apply in both modes; narrow further with *//* .wa-light / .wa-dark when mode-specific shapes are needed. */:root[data-wf-theme="{id}"] .wf-card { … }:root.wa-dark[data-wf-theme="{id}"] .wf-card { … }Specificity notes
| Selector | Specificity | When it wins |
|---|---|---|
:root[data-wf-theme="{id}"] | (0,1,1) | Default / light mode |
:root.wa-light[data-wf-theme="{id}"] | (0,2,1) | Explicit light mode (same result) |
:root.wa-dark[data-wf-theme="{id}"] | (0,2,1) | Dark mode — beats the single-selector default |
The dark block wins by specificity alone — no !important or load-order tricks required. The plain :root[data-wf-theme] block handles the moment before any WA class is applied (pre-paint flash prevention).