Customizing UI Themes
Relevant source files
The following files were used as context for generating this wiki page:
StatusBeam utilizes a modern CSS-in-JS and utility-first approach to UI theming, leveraging Tailwind CSS, shadcn/ui, and Astro. The system is designed to be "dark-mode-ready" out of the box, employing a single severity token system to maintain visual consistency across different statuses and themes. The theming architecture ensures that the user interface remains performant by rendering at the edge and minimizing client-side JavaScript flashes during theme transitions.
Sources: README.md:120-130, ARCHITECTURE.md:40-45
Core Theming Architecture
The theming system is built upon CSS variables and the light-dark() CSS function, allowing for a unified token set that automatically resolves based on the computed color-scheme. This approach eliminates the need for duplicated dark-mode CSS blocks and enables native UI elements like scrollbars to adapt automatically to the chosen theme.
Design Tokens and CSS Variables
The project maps design tokens to Tailwind's theme via the @theme block in global.css. These variables cover background, foreground, primary, secondary, and destructive colors, as well as a specific palette for system status severities.
| Token Type | CSS Variables | Description |
|---|---|---|
| Base Colors | --background, --foreground, --card | Foundational colors for the application layout. |
| UI Components | --primary, --secondary, --accent | Colors used for interactive elements and highlights. |
| Severity Palette | --status-operational, --status-degraded, --status-major | Specific colors tied to service health states. |
| Layout | --radius | Border radius values for components. |
Sources: apps/web/src/styles/global.css:12-70, README.md:130-140
Severity Token System
StatusBeam defines five distinct states as CSS variables using the OKLCH color space. This system ensures that colors remain vivid and stable regardless of whether the user is in light or dark mode.
/* Severity palette — oklch based */
--status-operational: oklch(0.72 0.17 149); /* green */
--status-degraded: oklch(0.82 0.16 86); /* yellow */
--status-partial: oklch(0.75 0.17 55); /* orange */
--status-major: oklch(0.63 0.22 25); /* red */
--status-maintenance: oklch(0.65 0.15 250);/* blue */
Sources: apps/web/src/styles/global.css:73-78, README.md:135-140
Theme Management and Persistence
StatusBeam supports three theme states: light, dark, and system. The system theme follows the operating system's preference using color-scheme: light dark.
Theme Switching Logic
The theme is managed by the ThemeToggle.tsx component, which cycles through the available states. It uses localStorage for persistence and manipulates the classList of the <html> element to apply explicit light or dark overrides.
The following sequence diagram illustrates the theme application process:
Anti-FOUC (Flash of Unstyled Content)
To prevent a flash of unstyled content, an inline script (referenced in StatusPage.astro) reads the theme from localStorage before the first paint. The ThemeToggle component then reconciles its state during the useEffect hook after hydration.
Sources: apps/web/src/components/ThemeToggle.tsx:60-75
Configuration and Customization
Users can customize the theme via the status.config.yml file. This configuration is validated by the core domain layer and used during the SSR process.
| Option | Type | Description |
|---|---|---|
logoUrl | string | URL to the status page logo. |
darkMode | boolean | Enables or disables dark mode support globally. |
locale | string | Fallback UI language (en, zh, ja, ko). |
Configuration Example
theme:
logoUrl: /logo.svg
darkMode: true
locale: en
Sources: status.config.example.yml:65-75, ARCHITECTURE.md:130-135
Visual Consistency Across Themes
The system utilizes custom Tailwind variants to ensure icons and components render correctly based on the root class.
/* apps/web/src/styles/global.css */
@custom-variant dark (&:is(.dark, .dark *));
@custom-variant light (&:is(.light, .light *));
This allows components like ThemeToggle.tsx to hide or show specific icons (Sun, Moon, Monitor) based on the presence of .dark or .light classes on the <html> element without waiting for React hydration.
Sources: apps/web/src/styles/global.css:6-8, apps/web/src/components/ThemeToggle.tsx:90-100
Summary
The UI customization in StatusBeam is centered on a robust CSS variable architecture that prioritizes performance and consistency. By using OKLCH colors and the light-dark() function, the project provides a seamless transition between themes while ensuring that critical status indicators remain accessible and clear. The integration between YAML-based user configuration and edge-rendered Astro components allows for a highly customizable yet stable status page.