0004. Theming with CSS custom properties, no styled-components
Generated from docs/decisions/0004-css-custom-properties-theming.md
- Status: Accepted (2026-10-08)
- Date: 2026-10-08
Context and problem statement
Section titled “Context and problem statement”The front-end and its component library used styled-components with a JS theme object
(ThemeProvider, about 540 styled declarations, 289 getStylesBasedOnTheme calls). The roadmap needs
per-tenant themes from presets plus an accent colour (Course Builder, Phase 2.3), framework-agnostic
web components themeable with CSS custom properties (Phase 5.2) and design tokens exported from the
design tool. A runtime CSS-in-JS library makes all of these harder and adds bundle weight.
Decision
Section titled “Decision”- Themes are
ThemeTokensobjects (same keys as the formerDefaultTheme). One mapping (front/src/lib/components/theme/cssVars.ts) turns them into--ulams-*custom properties: light values on:root, dark values (dm__*keys) under[data-mode="dark"]. applyTheme()replacesThemeProviderand also applies custom colours from API settings.- Components use CSS Modules and read only
var(--ulams-…). Presets include the three experience themescoffee,oncallandnightsky. - styled-components is removed from every workspace and blocked by a lint rule.
Consequences
Section titled “Consequences”- Good: themes work in any framework and in web components; design tokens map directly to variables.
- Good: no runtime style injection; smaller bundles.
- Bad: a large one-time conversion of the component library and the front application.