Cycles
Design · c52

Dark Mode (Subtle) — Iteration & Theming

archivedcreated 2026-07-16· last activity 2026-09-11

Build a dark-mode color system for the qcontrol app consolidation (qdash, qglass, Nuxt UI), with a design-app-based color picker and theme-file persistence for rapid iteration.

Why

The c51 consolidation names "subtle dark mode — human-driven" as an objective but doesn't have the tooling to explore it. Designing in the browser with live pickers is faster than Figma comps; saving themes as files (JSON/YAML/TypeScript) lets us try variants without losing previous attempts. A shared theme format also grounds the conversation with engineering about token implementation.

Objective

Three deliverables:

  1. Color picker UI in the design app — add an interactive tool to the /brand pages that lets you pick and preview a third theme (dark-subtle) live, alongside light and the legacy dark (zinc/emerald).
  2. Theme file format — define a text-based schema (JSON recommended) that captures a full theme: semantic token values (surface, content, stroke, signal colors), tailwind color scale overrides, opacity rules.
  3. Theme persistence — save/load/list theme files so iterations don't evaporate; allow trying multiple dark-subtle variants in parallel (e.g., dark-subtle-v1.json, dark-subtle-v2.json, dark-subtle-experimental.json).

Scope

In:

  • Color picker component(s) added to design app
  • Theme file format (schema + examples)
  • Save/load UI + file browser
  • A baseline dark-subtle theme as proof of concept (not final)

Out:

  • Implementation in the Nuxt qdash/qglass UI (that's c51's follow-on work)
  • Figma sync or cross-project theming
  • Accessibility audit (save that as a separate decision)

Key Changes

  • app/composables/useThemeEditor.ts — extended to support three-column themes (light/dark/subtle), live Dark/Subtle preview toggle, save/load via API
  • app/components/ThemeEditor.vue — added subtle column, Dark/Subtle preview toggle in header, saved themes selector in footer
  • public/themes/ — baseline theme files (dark-subtle-baseline.ts, light-default.ts)
  • server/routes/api/themes.ts + [id].ts — existing file-backed theme API (reused for save/load)
  • cycles/c52.dark-mode-subtle/theme-format.md — documented hex format for themes
  • cycles/c52.dark-mode-subtle/IMPLEMENTATION.md — implementation details

Outcome

✅ Complete.

  • Three-column theme editor drawer — added subtle column alongside light/dark in the existing ThemeEditor.vue component (floating trigger, bottom-right on every page)
  • Live Dark/Subtle preview toggle — swap which theme values render on the page's .dark class to compare visually
  • Save/load mechanism — themes persisted as JSON files in public/themes/, loaded via existing /api/themes endpoints
  • Baseline themesdark-subtle-baseline and light-default saved and ready to iterate on
  • Ready for rapid browser-based iteration: edit swatches, toggle Dark/Subtle, save variants, reload to re-load

Artifacts

  • IMPLEMENTATION.md
  • theme-format.md

Qpoint Brand Style Guide