diff --git a/admin/src/app/theme.ts b/admin/src/app/theme.ts index 8ba825a..76a851e 100644 --- a/admin/src/app/theme.ts +++ b/admin/src/app/theme.ts @@ -1,15 +1,32 @@ -// Colour scheme (D-06, flagged assumption A6): the admin follows the system -// preference only, with no toggle. The .dark class on the document element -// swaps the design's dark tokens in main.css; the sidebar stays dark in both -// modes and gains its #222b40 right border in dark mode. +// Colour scheme (D-06; assumption A6 superseded). The admin follows the +// system preference by default; light and dark are manual choices the admin +// makes on the rail's top button and keeps per account (usePreferences). The +// .dark class on the document element swaps the design's dark tokens in +// main.css; the sidebar stays dark in both modes and gains its #222b40 right +// border in dark mode. export const DARK_QUERY = '(prefers-color-scheme: dark)' +/** The admin's theme: follow the system, or always light or dark. */ +export type ThemeChoice = 'system' | 'light' | 'dark' + +/** The theme choices in the order the rail button cycles through them. */ +export const THEME_CHOICES: readonly ThemeChoice[] = ['system', 'light', 'dark'] + +export function isThemeChoice(value: unknown): value is ThemeChoice { + return typeof value === 'string' && (THEME_CHOICES as readonly string[]).includes(value) +} + /** - * Applies the current preference and follows changes. Returns the - * unsubscribe function. + * Applies a theme choice. light and dark set the class once and subscribe + * to nothing; system applies the current preference and follows changes. + * Returns the unsubscribe function. */ -export function applyColorScheme(win: Window = window): () => void { +export function applyColorScheme(win: Window = window, choice: ThemeChoice = 'system'): () => void { const root = win.document.documentElement + if (choice !== 'system') { + root.classList.toggle('dark', choice === 'dark') + return () => undefined + } if (typeof win.matchMedia !== 'function') { root.classList.remove('dark') return () => undefined diff --git a/admin/src/components/shell/PluginRail.vue b/admin/src/components/shell/PluginRail.vue index 14a1c48..8cb36fc 100644 --- a/admin/src/components/shell/PluginRail.vue +++ b/admin/src/components/shell/PluginRail.vue @@ -1,11 +1,12 @@