feat: simplify theme system to single Warm Sage brand palette
Consolidate from 11 themes to one cohesive Warm Sage palette across landing page, auth layout, dashboard components, kanban columns, demo banner, theme picker, and CSS variables. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+20
-291
@@ -19,305 +19,34 @@ export interface ThemeDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* All 11 themes matching the KMM/iOS theme system.
|
||||
* Hex values are taken directly from ThemeColors.kt.
|
||||
* Single "Warm Sage" theme — the Casera brand palette.
|
||||
*/
|
||||
export const themes: ThemeDefinition[] = [
|
||||
{
|
||||
id: "default",
|
||||
name: "Default",
|
||||
description: "Warm orange with teal accents",
|
||||
name: "Warm Sage",
|
||||
description: "Calming sage with warm clay accents",
|
||||
light: {
|
||||
primary: "#E07A3A",
|
||||
secondary: "#0D7C66",
|
||||
accent: "#D4A574",
|
||||
error: "#DC2626",
|
||||
bgPrimary: "#FFFFFF",
|
||||
bgSecondary: "#F7F7F7",
|
||||
textPrimary: "#1C1917",
|
||||
textSecondary: "#78716C",
|
||||
primary: "#6B8F71",
|
||||
secondary: "#C4856A",
|
||||
accent: "#C4856A",
|
||||
error: "#C75B4A",
|
||||
bgPrimary: "#FAFAF7",
|
||||
bgSecondary: "#F2EFE9",
|
||||
textPrimary: "#2D3436",
|
||||
textSecondary: "#8A8F87",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#F0A070",
|
||||
secondary: "#4FC9AF",
|
||||
accent: "#DDB892",
|
||||
error: "#EF4444",
|
||||
bgPrimary: "#0A0A0A",
|
||||
bgSecondary: "#161616",
|
||||
textPrimary: "#FAFAFA",
|
||||
textSecondary: "#A1A1A1",
|
||||
textOnPrimary: "#0A0A0A",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "teal",
|
||||
name: "Teal",
|
||||
description: "Blue-green with warm accents",
|
||||
light: {
|
||||
primary: "#069FC3",
|
||||
secondary: "#0054A4",
|
||||
accent: "#EFC707",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#FFF0D0",
|
||||
bgSecondary: "#FFFFFF",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#60CCE2",
|
||||
secondary: "#60A5D8",
|
||||
accent: "#EFC707",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#091829",
|
||||
bgSecondary: "#1A2E3E",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "ocean",
|
||||
name: "Ocean",
|
||||
description: "Deep blues and coral tones",
|
||||
light: {
|
||||
primary: "#006B8F",
|
||||
secondary: "#008A8A",
|
||||
accent: "#FF7E50",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#E4EBF1",
|
||||
bgSecondary: "#BCCAD5",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#49B5D1",
|
||||
secondary: "#60D1C6",
|
||||
accent: "#FF7E50",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#161B22",
|
||||
bgSecondary: "#313A4B",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "forest",
|
||||
name: "Forest",
|
||||
description: "Earth greens and golden hues",
|
||||
light: {
|
||||
primary: "#2C5015",
|
||||
secondary: "#6B8E22",
|
||||
accent: "#FFD600",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#EBEEE2",
|
||||
bgSecondary: "#C1C8AD",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#93C66B",
|
||||
secondary: "#AFD182",
|
||||
accent: "#FFD600",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#181E17",
|
||||
bgSecondary: "#384436",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "sunset",
|
||||
name: "Sunset",
|
||||
description: "Warm oranges and reds",
|
||||
light: {
|
||||
primary: "#FF4500",
|
||||
secondary: "#FF6246",
|
||||
accent: "#FFD600",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#F7F0E8",
|
||||
bgSecondary: "#DCD0BA",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#FF9E60",
|
||||
secondary: "#FFAD7C",
|
||||
accent: "#FFD600",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#201813",
|
||||
bgSecondary: "#433329",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "monochrome",
|
||||
name: "Monochrome",
|
||||
description: "Elegant grayscale",
|
||||
light: {
|
||||
primary: "#333333",
|
||||
secondary: "#666666",
|
||||
accent: "#999999",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#F0F0F0",
|
||||
bgSecondary: "#D4D4D4",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#E5E5E5",
|
||||
secondary: "#BFBFBF",
|
||||
accent: "#D1D1D1",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#161616",
|
||||
bgSecondary: "#3B3B3B",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "lavender",
|
||||
name: "Lavender",
|
||||
description: "Soft purple with pink accents",
|
||||
light: {
|
||||
primary: "#6B418A",
|
||||
secondary: "#8A60AF",
|
||||
accent: "#E24982",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#F1EFF5",
|
||||
bgSecondary: "#D9D1DF",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#D1AFE2",
|
||||
secondary: "#DDBFEA",
|
||||
accent: "#FF9EC6",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#17131E",
|
||||
bgSecondary: "#393042",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "crimson",
|
||||
name: "Crimson",
|
||||
description: "Bold red with warm highlights",
|
||||
light: {
|
||||
primary: "#B51E28",
|
||||
secondary: "#992D38",
|
||||
accent: "#E26000",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#F6EDEB",
|
||||
bgSecondary: "#DECFCC",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#FF827C",
|
||||
secondary: "#F99993",
|
||||
accent: "#FFB56B",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#1B1215",
|
||||
bgSecondary: "#412E39",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "midnight",
|
||||
name: "Midnight",
|
||||
description: "Deep navy with sky blue",
|
||||
light: {
|
||||
primary: "#1E4993",
|
||||
secondary: "#2D60AF",
|
||||
accent: "#4993E2",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#EDF0F7",
|
||||
bgSecondary: "#CCD5E2",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#82B5EA",
|
||||
secondary: "#93C6F2",
|
||||
accent: "#9ED8FF",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#12161F",
|
||||
bgSecondary: "#2F3848",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "desert",
|
||||
name: "Desert",
|
||||
description: "Warm terracotta and sand tones",
|
||||
light: {
|
||||
primary: "#AF6049",
|
||||
secondary: "#9E7C60",
|
||||
accent: "#D1932D",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#F6F0EA",
|
||||
bgSecondary: "#E5D8C6",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#F2B593",
|
||||
secondary: "#EAD1AF",
|
||||
accent: "#FFD86B",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#1F1C16",
|
||||
bgSecondary: "#494138",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "mint",
|
||||
name: "Mint",
|
||||
description: "Fresh green with turquoise",
|
||||
light: {
|
||||
primary: "#38AF93",
|
||||
secondary: "#60C6AF",
|
||||
accent: "#2D9EAF",
|
||||
error: "#DD1C1A",
|
||||
bgPrimary: "#EDF6F0",
|
||||
bgSecondary: "#D1E2D8",
|
||||
textPrimary: "#111111",
|
||||
textSecondary: "#444444",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
},
|
||||
dark: {
|
||||
primary: "#93F2D8",
|
||||
secondary: "#BFF9EA",
|
||||
accent: "#6BEAF2",
|
||||
error: "#FF5244",
|
||||
bgPrimary: "#161F1F",
|
||||
bgSecondary: "#384949",
|
||||
textPrimary: "#F5F5F5",
|
||||
textSecondary: "#C6C6C6",
|
||||
textOnPrimary: "#FFFFFF",
|
||||
primary: "#8FB896",
|
||||
secondary: "#D4A08A",
|
||||
accent: "#D4A08A",
|
||||
error: "#E07A6B",
|
||||
bgPrimary: "#1A1D1A",
|
||||
bgSecondary: "#2A2E2A",
|
||||
textPrimary: "#E8E5DF",
|
||||
textSecondary: "#9A9E97",
|
||||
textOnPrimary: "#1A1D1A",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -4,14 +4,8 @@ import { useEffect } from "react";
|
||||
import { useThemeStore } from "@/stores/theme";
|
||||
|
||||
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
const themeId = useThemeStore((s) => s.themeId);
|
||||
const mode = useThemeStore((s) => s.mode);
|
||||
|
||||
// Sync data-theme attribute
|
||||
useEffect(() => {
|
||||
document.documentElement.setAttribute("data-theme", themeId);
|
||||
}, [themeId]);
|
||||
|
||||
// Sync dark class based on mode + system preference
|
||||
useEffect(() => {
|
||||
const applyDarkClass = (isDark: boolean) => {
|
||||
@@ -41,22 +35,5 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
return () => mql.removeEventListener("change", handler);
|
||||
}, [mode]);
|
||||
|
||||
// On mount, migrate any stale persisted state to light mode
|
||||
useEffect(() => {
|
||||
const stored = localStorage.getItem("casera-theme");
|
||||
if (stored) {
|
||||
try {
|
||||
const parsed = JSON.parse(stored);
|
||||
if (parsed?.state?.mode === "system") {
|
||||
parsed.state.mode = "light";
|
||||
localStorage.setItem("casera-theme", JSON.stringify(parsed));
|
||||
useThemeStore.getState().setMode("light");
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { themes, getThemeById, type ThemeDefinition } from "./theme-config";
|
||||
* (accounting for system preference), and setters.
|
||||
*/
|
||||
export function useTheme() {
|
||||
const { themeId, mode, setTheme, setMode } = useThemeStore();
|
||||
const { mode, setMode } = useThemeStore();
|
||||
|
||||
const [effectiveMode, setEffectiveMode] = useState<"light" | "dark">("light");
|
||||
|
||||
@@ -28,11 +28,9 @@ export function useTheme() {
|
||||
return () => mql.removeEventListener("change", handler);
|
||||
}, [mode]);
|
||||
|
||||
const currentTheme: ThemeDefinition = getThemeById(themeId);
|
||||
const currentTheme: ThemeDefinition = getThemeById("default");
|
||||
|
||||
return {
|
||||
/** Current theme ID string */
|
||||
themeId,
|
||||
/** Current mode setting (light | dark | system) */
|
||||
mode,
|
||||
/** Resolved mode after considering system preference */
|
||||
@@ -41,8 +39,6 @@ export function useTheme() {
|
||||
currentTheme,
|
||||
/** All available theme definitions */
|
||||
themes,
|
||||
/** Set the active theme by ID */
|
||||
setTheme,
|
||||
/** Set the color mode */
|
||||
setMode,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user