feat: add light/dark theme support with DB-persisted setting #17

Merged
addison merged 3 commits from exe-dev-bot/kiosk:feat/light-mode into main 2026-02-13 19:20:44 -05:00
Contributor

Summary

Adds full light/dark theme support across both the admin UI and kiosk display. Theme preference is stored in the database and shared between both interfaces.

Changes

Backend

  • New setting table (key/value store) with GetSetting/SetSetting functions
  • GET /api/settings/{key} and PUT /api/settings/{key} endpoints
  • QR code colors adapt dynamically based on theme setting

Admin UI

  • Theme toggle button (☀️/🌙) in the header
  • Full light theme via CSS custom property overrides ([data-theme="light"])
  • Toasts, dialogs, and color swatches all adapt to theme
  • Theme fetched on init before rendering to prevent flash

Kiosk Display

  • All hardcoded colors extracted into CSS custom properties
  • Light theme: clean white background, subtle borders, dark text
  • Events use colored left border instead of filled background in light mode
  • Background is a subtle 8% tint of the event color via color-mix()
  • Dark theme remains unchanged (filled color backgrounds)
  • Theme fetched from settings API on page load

Design decisions

  • Default theme is light (set via data-theme="light" on <html> to prevent FOUC)
  • Settings API is generic (any key/value) — not theme-specific
  • Dark mode is backwards-compatible — no visual changes

Screenshots

Light mode (kiosk)

Events show colored left borders with subtle tinted backgrounds.

Dark mode (kiosk)

Unchanged — events show filled color backgrounds.

Admin light mode

Clean white cards with theme toggle in header.

Admin dark mode

Unchanged from previous design.

## Summary Adds full light/dark theme support across both the admin UI and kiosk display. Theme preference is stored in the database and shared between both interfaces. ## Changes ### Backend - New `setting` table (key/value store) with `GetSetting`/`SetSetting` functions - `GET /api/settings/{key}` and `PUT /api/settings/{key}` endpoints - QR code colors adapt dynamically based on theme setting ### Admin UI - Theme toggle button (☀️/🌙) in the header - Full light theme via CSS custom property overrides (`[data-theme="light"]`) - Toasts, dialogs, and color swatches all adapt to theme - Theme fetched on init before rendering to prevent flash ### Kiosk Display - All hardcoded colors extracted into CSS custom properties - Light theme: clean white background, subtle borders, dark text - **Events use colored left border** instead of filled background in light mode - Background is a subtle 8% tint of the event color via `color-mix()` - Dark theme remains unchanged (filled color backgrounds) - Theme fetched from settings API on page load ### Design decisions - Default theme is **light** (set via `data-theme="light"` on `<html>` to prevent FOUC) - Settings API is generic (any key/value) — not theme-specific - Dark mode is backwards-compatible — no visual changes ## Screenshots ### Light mode (kiosk) Events show colored left borders with subtle tinted backgrounds. ### Dark mode (kiosk) Unchanged — events show filled color backgrounds. ### Admin light mode Clean white cards with theme toggle in header. ### Admin dark mode Unchanged from previous design.
- Add setting table and generic GET/PUT settings API
- Admin UI: theme toggle button (sun/moon icons) in header
- Kiosk display: fetches theme on init, applies before rendering
- Light mode (default): clean white theme with colored left-border
  events instead of filled backgrounds
- Dark mode: unchanged from previous behavior
- QR code colors adapt to current theme
- Both admin and kiosk pages default to light via data-theme attribute
  on <html> to prevent flash of wrong theme

Co-authored-by: Shelley <shelley@exe.dev>
Co-authored-by: Shelley <shelley@exe.dev>
exe-dev-bot force-pushed feat/light-mode from ed270a5b60 to 0194855208 2026-02-13 19:12:58 -05:00 Compare
exe-dev-bot force-pushed feat/light-mode from 0194855208 to abbbd761d6 2026-02-13 19:13:54 -05:00 Compare
Remove scattered [data-theme="light"] selector blocks from both admin
and kiosk stylesheets. All theme differences are now controlled entirely
by CSS custom properties defined in :root (dark) and [data-theme="light"]
(light) blocks.

Kiosk events use --event-border-width, --event-color-mix-pct, and
fallback chains for text colors to switch between filled backgrounds
(dark) and left-border accent (light) without additional selectors.

Co-authored-by: Shelley <shelley@exe.dev>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kwila/kiosk!17
No description provided.