Add theme system with color presets, fix login page styling, persist auth session

Theme system with 5 color presets (Slate, Emerald, Violet, Amber, Rose)
and light/dark/system mode. User menu in sidebar with theme picker and
sign out. Login page uses standalone dark branded styling with autofill
override. Auth persists in sessionStorage across refreshes.
This commit is contained in:
Ryan Moon
2026-03-28 08:30:24 -05:00
parent 9abdf6c050
commit 7c64a928e1
10 changed files with 691 additions and 145 deletions

View File

@@ -1,94 +1,29 @@
@import "tailwindcss";
@custom-variant dark (&:is(.dark *));
@variant dark (&:is(.dark, .dark *));
@theme {
--color-background: hsl(0 0% 100%);
--color-foreground: hsl(240 10% 3.9%);
/* Defaults — overridden at runtime by theme store */
--color-background: hsl(210 20% 97%);
--color-foreground: hsl(222 47% 11%);
--color-card: hsl(0 0% 100%);
--color-card-foreground: hsl(240 10% 3.9%);
--color-card-foreground: hsl(222 47% 11%);
--color-popover: hsl(0 0% 100%);
--color-popover-foreground: hsl(240 10% 3.9%);
--color-primary: hsl(240 5.9% 10%);
--color-primary-foreground: hsl(0 0% 98%);
--color-secondary: hsl(240 4.8% 95.9%);
--color-secondary-foreground: hsl(240 5.9% 10%);
--color-muted: hsl(240 4.8% 95.9%);
--color-muted-foreground: hsl(240 3.8% 46.1%);
--color-accent: hsl(240 4.8% 95.9%);
--color-accent-foreground: hsl(240 5.9% 10%);
--color-destructive: hsl(0 84.2% 60.2%);
--color-destructive-foreground: hsl(0 0% 98%);
--color-border: hsl(240 5.9% 90%);
--color-input: hsl(240 5.9% 90%);
--color-ring: hsl(240 5.9% 10%);
--color-sidebar: hsl(0 0% 98%);
--color-sidebar-foreground: hsl(240 5.3% 26.1%);
--color-sidebar-primary: hsl(240 5.9% 10%);
--color-sidebar-primary-foreground: hsl(0 0% 98%);
--color-sidebar-accent: hsl(240 4.8% 95.9%);
--color-sidebar-accent-foreground: hsl(240 5.9% 10%);
--color-sidebar-border: hsl(220 13% 91%);
--color-sidebar-ring: hsl(217.2 91.2% 59.8%);
--radius: 0.625rem;
}
.dark {
--color-background: hsl(240 10% 3.9%);
--color-foreground: hsl(0 0% 98%);
--color-card: hsl(240 10% 3.9%);
--color-card-foreground: hsl(0 0% 98%);
--color-popover: hsl(240 10% 3.9%);
--color-popover-foreground: hsl(0 0% 98%);
--color-primary: hsl(0 0% 98%);
--color-primary-foreground: hsl(240 5.9% 10%);
--color-secondary: hsl(240 3.7% 15.9%);
--color-secondary-foreground: hsl(0 0% 98%);
--color-muted: hsl(240 3.7% 15.9%);
--color-muted-foreground: hsl(240 5% 64.9%);
--color-accent: hsl(240 3.7% 15.9%);
--color-accent-foreground: hsl(0 0% 98%);
--color-destructive: hsl(0 62.8% 30.6%);
--color-destructive-foreground: hsl(0 0% 98%);
--color-border: hsl(240 3.7% 15.9%);
--color-input: hsl(240 3.7% 15.9%);
--color-ring: hsl(240 4.9% 83.9%);
--color-sidebar: hsl(240 5.9% 10%);
--color-sidebar-foreground: hsl(240 4.8% 95.9%);
--color-sidebar-primary: hsl(224.3 76.3% 48%);
--color-sidebar-primary-foreground: hsl(0 0% 100%);
--color-sidebar-accent: hsl(240 3.7% 15.9%);
--color-sidebar-accent-foreground: hsl(240 4.8% 95.9%);
--color-sidebar-border: hsl(240 3.7% 15.9%);
--color-sidebar-ring: hsl(217.2 91.2% 59.8%);
--sidebar: hsl(240 5.9% 10%);
--sidebar-foreground: hsl(240 4.8% 95.9%);
--sidebar-primary: hsl(224.3 76.3% 48%);
--sidebar-primary-foreground: hsl(0 0% 100%);
--sidebar-accent: hsl(240 3.7% 15.9%);
--sidebar-accent-foreground: hsl(240 4.8% 95.9%);
--sidebar-border: hsl(240 3.7% 15.9%);
--sidebar-ring: hsl(217.2 91.2% 59.8%);
}
body {
font-family:
"Inter",
ui-sans-serif,
system-ui,
-apple-system,
sans-serif;
}
:root {
--sidebar: hsl(0 0% 98%);
--sidebar-foreground: hsl(240 5.3% 26.1%);
--sidebar-primary: hsl(240 5.9% 10%);
--sidebar-primary-foreground: hsl(0 0% 98%);
--sidebar-accent: hsl(240 4.8% 95.9%);
--sidebar-accent-foreground: hsl(240 5.9% 10%);
--sidebar-border: hsl(220 13% 91%);
--sidebar-ring: hsl(217.2 91.2% 59.8%);
--color-popover-foreground: hsl(222 47% 11%);
--color-primary: hsl(215 25% 27%);
--color-primary-foreground: hsl(210 40% 98%);
--color-secondary: hsl(210 40% 94%);
--color-secondary-foreground: hsl(222 47% 11%);
--color-muted: hsl(210 40% 94%);
--color-muted-foreground: hsl(215 16% 47%);
--color-accent: hsl(210 40% 94%);
--color-accent-foreground: hsl(222 47% 11%);
--color-destructive: hsl(0 72% 51%);
--color-destructive-foreground: hsl(210 40% 98%);
--color-border: hsl(214 32% 89%);
--color-input: hsl(214 32% 89%);
--color-ring: hsl(215 25% 27%);
--radius: 0.5rem;
}
@theme inline {
@@ -101,3 +36,38 @@ body {
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}
:root {
--sidebar: hsl(210 25% 95%);
--sidebar-foreground: hsl(215 16% 47%);
--sidebar-primary: hsl(215 25% 27%);
--sidebar-primary-foreground: hsl(210 40% 98%);
--sidebar-accent: hsl(210 40% 92%);
--sidebar-accent-foreground: hsl(222 47% 11%);
--sidebar-border: hsl(214 32% 89%);
--sidebar-ring: hsl(215 25% 27%);
}
body {
font-family:
"Inter",
ui-sans-serif,
system-ui,
-apple-system,
sans-serif;
}
.login-input {
background-color: #1a2740 !important;
border-color: #2a3a52 !important;
color: #d0d8e0 !important;
}
.login-input:-webkit-autofill,
.login-input:-webkit-autofill:hover,
.login-input:-webkit-autofill:focus {
-webkit-box-shadow: 0 0 0 1000px #1a2740 inset !important;
-webkit-text-fill-color: #d0d8e0 !important;
border-color: #2a3a52 !important;
transition: background-color 5000s ease-in-out 0s;
}