Add theming infrastructure (task 08)

CSS-variable multi-theme system (default + warm) × {light, dark, system}; per-user theme/theme_mode columns; no-flash pre-paint script; useTheme hook + ThemePicker component on /settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ginnoir
2026-05-06 02:50:05 -05:00
co-authored by Claude Sonnet 4.6
parent 6710c8b231
commit 8cc2ef0732
12 changed files with 540 additions and 3 deletions
+71
View File
@@ -116,6 +116,77 @@
--sidebar-ring: oklch(0.556 0 0);
}
/* Warm theme — light */
[data-theme="warm"] {
--background: oklch(0.98 0.012 60);
--foreground: oklch(0.18 0.03 50);
--card: oklch(0.97 0.014 58);
--card-foreground: oklch(0.18 0.03 50);
--popover: oklch(0.97 0.014 58);
--popover-foreground: oklch(0.18 0.03 50);
--primary: oklch(0.52 0.18 40);
--primary-foreground: oklch(0.98 0.01 60);
--secondary: oklch(0.92 0.02 60);
--secondary-foreground: oklch(0.25 0.04 45);
--muted: oklch(0.93 0.018 58);
--muted-foreground: oklch(0.52 0.04 50);
--accent: oklch(0.90 0.03 55);
--accent-foreground: oklch(0.22 0.04 45);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.88 0.025 60);
--input: oklch(0.88 0.025 60);
--ring: oklch(0.65 0.12 45);
--chart-1: oklch(0.72 0.16 40);
--chart-2: oklch(0.62 0.14 55);
--chart-3: oklch(0.52 0.12 45);
--chart-4: oklch(0.45 0.10 40);
--chart-5: oklch(0.35 0.08 35);
--radius: 0.625rem;
--sidebar: oklch(0.94 0.018 58);
--sidebar-foreground: oklch(0.18 0.03 50);
--sidebar-primary: oklch(0.52 0.18 40);
--sidebar-primary-foreground: oklch(0.98 0.01 60);
--sidebar-accent: oklch(0.90 0.03 55);
--sidebar-accent-foreground: oklch(0.22 0.04 45);
--sidebar-border: oklch(0.88 0.025 60);
--sidebar-ring: oklch(0.65 0.12 45);
}
/* Warm theme — dark */
[data-theme="warm"].dark {
--background: oklch(0.16 0.025 45);
--foreground: oklch(0.95 0.015 60);
--card: oklch(0.22 0.03 48);
--card-foreground: oklch(0.95 0.015 60);
--popover: oklch(0.22 0.03 48);
--popover-foreground: oklch(0.95 0.015 60);
--primary: oklch(0.78 0.14 50);
--primary-foreground: oklch(0.16 0.025 45);
--secondary: oklch(0.28 0.04 50);
--secondary-foreground: oklch(0.95 0.015 60);
--muted: oklch(0.28 0.035 48);
--muted-foreground: oklch(0.68 0.04 55);
--accent: oklch(0.30 0.045 50);
--accent-foreground: oklch(0.95 0.015 60);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.55 0.08 50);
--chart-1: oklch(0.78 0.14 50);
--chart-2: oklch(0.65 0.12 55);
--chart-3: oklch(0.52 0.10 48);
--chart-4: oklch(0.42 0.08 42);
--chart-5: oklch(0.32 0.06 38);
--sidebar: oklch(0.20 0.03 47);
--sidebar-foreground: oklch(0.95 0.015 60);
--sidebar-primary: oklch(0.78 0.14 50);
--sidebar-primary-foreground: oklch(0.16 0.025 45);
--sidebar-accent: oklch(0.30 0.045 50);
--sidebar-accent-foreground: oklch(0.95 0.015 60);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.55 0.08 50);
}
@layer base {
* {
@apply border-border outline-ring/50;