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:
Trey t
2026-03-03 18:26:40 -06:00
parent 264107e3bf
commit 44993ae601
17 changed files with 187 additions and 1381 deletions
+6 -6
View File
@@ -7,10 +7,10 @@ export default function AuthLayout({ children }: { children: React.ReactNode })
return ( return (
<div className="min-h-screen flex bg-[#FAFAF7]"> <div className="min-h-screen flex bg-[#FAFAF7]">
{/* Left brand panel — hidden on mobile */} {/* Left brand panel — hidden on mobile */}
<div className="hidden lg:flex lg:w-[480px] xl:w-[540px] relative flex-col justify-between bg-[#1C1917] p-10 overflow-hidden"> <div className="hidden lg:flex lg:w-[480px] xl:w-[540px] relative flex-col justify-between bg-[#2D3436] p-10 overflow-hidden">
{/* Decorative blurs */} {/* Decorative blurs */}
<div className="absolute top-0 right-0 w-80 h-80 rounded-full bg-[#E07A3A]/15 blur-[100px] pointer-events-none" /> <div className="absolute top-0 right-0 w-80 h-80 rounded-full bg-[#6B8F71]/15 blur-[100px] pointer-events-none" />
<div className="absolute bottom-0 left-0 w-64 h-64 rounded-full bg-[#0D7C66]/10 blur-[80px] pointer-events-none" /> <div className="absolute bottom-0 left-0 w-64 h-64 rounded-full bg-[#C4856A]/10 blur-[80px] pointer-events-none" />
{/* Subtle grid */} {/* Subtle grid */}
<div <div
@@ -40,15 +40,15 @@ export default function AuthLayout({ children }: { children: React.ReactNode })
<div className="relative"> <div className="relative">
<h2 className="font-heading text-3xl font-bold text-white leading-snug mb-4"> <h2 className="font-heading text-3xl font-bold text-white leading-snug mb-4">
Home maintenance,<br /> Home maintenance,<br />
<span className="text-[#E07A3A]">simplified.</span> <span className="text-[#8FB896]">simplified.</span>
</h2> </h2>
<p className="text-[#A8A29E] leading-relaxed max-w-sm"> <p className="text-[#9A9E97] leading-relaxed max-w-sm">
Track tasks, organize contractors, and store important Track tasks, organize contractors, and store important
documents all in one place built for homeowners. documents all in one place built for homeowners.
</p> </p>
</div> </div>
<p className="relative text-xs text-[#78716C]"> <p className="relative text-xs text-[#8A8F87]">
&copy; {new Date().getFullYear()} Casera &copy; {new Date().getFullYear()} Casera
</p> </p>
</div> </div>
+8 -8
View File
@@ -8,8 +8,8 @@ export default function DemoLandingPage() {
return ( return (
<div className="flex min-h-screen flex-col items-center justify-center bg-[#FAFAF7] px-6 relative overflow-hidden"> <div className="flex min-h-screen flex-col items-center justify-center bg-[#FAFAF7] px-6 relative overflow-hidden">
{/* Decorative background */} {/* Decorative background */}
<div className="absolute top-20 right-[-10%] w-[500px] h-[500px] rounded-full bg-[#E07A3A]/[0.04] blur-3xl pointer-events-none" /> <div className="absolute top-20 right-[-10%] w-[500px] h-[500px] rounded-full bg-[#6B8F71]/[0.04] blur-3xl pointer-events-none" />
<div className="absolute bottom-0 left-[-5%] w-[300px] h-[300px] rounded-full bg-[#0D7C66]/[0.03] blur-3xl pointer-events-none" /> <div className="absolute bottom-0 left-[-5%] w-[300px] h-[300px] rounded-full bg-[#C4856A]/[0.03] blur-3xl pointer-events-none" />
<div className="relative mx-auto max-w-lg text-center"> <div className="relative mx-auto max-w-lg text-center">
{/* Logo */} {/* Logo */}
@@ -21,16 +21,16 @@ export default function DemoLandingPage() {
height={36} height={36}
className="rounded-lg" className="rounded-lg"
/> />
<span className="font-heading text-2xl font-bold tracking-tight text-[#1C1917]"> <span className="font-heading text-2xl font-bold tracking-tight text-[#2D3436]">
Casera Casera
</span> </span>
</Link> </Link>
{/* Hero */} {/* Hero */}
<h1 className="font-heading text-4xl font-bold tracking-tight text-[#1C1917]"> <h1 className="font-heading text-4xl font-bold tracking-tight text-[#2D3436]">
See Casera in action See Casera in action
</h1> </h1>
<p className="mt-4 text-lg text-[#78716C] leading-relaxed"> <p className="mt-4 text-lg text-[#8A8F87] leading-relaxed">
Explore the full app with sample data. No account needed Explore the full app with sample data. No account needed
just click and start exploring. just click and start exploring.
</p> </p>
@@ -39,7 +39,7 @@ export default function DemoLandingPage() {
<div className="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4"> <div className="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4">
<Link <Link
href="/demo/app" href="/demo/app"
className="group inline-flex items-center gap-2.5 rounded-full bg-[#E07A3A] px-8 py-4 text-base font-semibold text-white shadow-lg shadow-[#E07A3A]/20 hover:bg-[#C4632A] transition-all" className="group inline-flex items-center gap-2.5 rounded-full bg-[#C4856A] px-8 py-4 text-base font-semibold text-white shadow-lg shadow-[#C4856A]/20 hover:bg-[#A86B52] transition-all"
> >
<Play className="size-4" /> <Play className="size-4" />
Launch Demo Launch Demo
@@ -48,9 +48,9 @@ export default function DemoLandingPage() {
</div> </div>
{/* Login link */} {/* Login link */}
<p className="mt-8 text-sm text-[#A8A29E]"> <p className="mt-8 text-sm text-[#9A9E97]">
Already have an account?{" "} Already have an account?{" "}
<Link href="/login" className="text-[#E07A3A] font-medium hover:underline"> <Link href="/login" className="text-[#6B8F71] font-medium hover:underline">
Sign In Sign In
</Link> </Link>
</p> </p>
+28 -13
View File
@@ -49,25 +49,40 @@
--radius-4xl: calc(var(--radius) + 16px); --radius-4xl: calc(var(--radius) + 16px);
/* App-specific theme-aware Tailwind utilities */ /* App-specific theme-aware Tailwind utilities */
--color-bg-primary: #FFFFFF; --color-bg-primary: var(--color-bg-primary);
--color-bg-secondary: #F7F7F7; --color-bg-secondary: var(--color-bg-secondary);
--color-text-primary: #1C1917; --color-text-primary: var(--color-text-primary);
--color-text-secondary: #78716C; --color-text-secondary: var(--color-text-secondary);
--color-text-on-primary: #FFFFFF; --color-text-on-primary: var(--color-text-on-primary);
--color-app-primary: var(--color-primary); --color-app-primary: var(--color-primary);
--color-app-secondary: var(--color-secondary); --color-app-secondary: var(--color-secondary);
--color-app-accent: var(--color-accent); --color-app-accent: var(--color-accent);
--color-app-error: var(--color-error); --color-app-error: var(--color-error);
/* Landing page brand colors (theme-independent) */ /* Brand colors — Warm Sage palette */
--color-brand-orange: #E07A3A; --color-brand-sage: #6B8F71;
--color-brand-orange-dark: #C4632A; --color-brand-sage-light: #EDF2ED;
--color-brand-orange-light: #FFF3EB; --color-brand-clay: #C4856A;
--color-brand-teal: #0D7C66; --color-brand-clay-light: #FDF3EE;
--color-brand-teal-light: #ECFDF5; --color-brand-charcoal: #2D3436;
--color-brand-slate: #1C1917; --color-brand-cream: #FAFAF7;
--color-brand-linen: #F2EFE9;
--color-brand-stone: #E8E3DC;
/* Legacy brand aliases (for any remaining references) */
--color-brand-orange: #C4856A;
--color-brand-orange-dark: #A86B52;
--color-brand-orange-light: #FDF3EE;
--color-brand-teal: #6B8F71;
--color-brand-teal-light: #EDF2ED;
--color-brand-slate: #2D3436;
--color-brand-warm: #FFFFFF; --color-brand-warm: #FFFFFF;
/* Warm shadow tokens */
--shadow-warm-sm: 0 1px 3px rgba(45, 52, 54, 0.06), 0 1px 2px rgba(45, 52, 54, 0.04);
--shadow-warm-md: 0 4px 12px rgba(45, 52, 54, 0.07), 0 2px 4px rgba(45, 52, 54, 0.04);
--shadow-warm-lg: 0 8px 24px rgba(45, 52, 54, 0.08), 0 4px 8px rgba(45, 52, 54, 0.04);
/* Animation tokens */ /* Animation tokens */
--animate-fade-up: fade-up 0.7s cubic-bezier(0.22, 1, 0.36, 1) both; --animate-fade-up: fade-up 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
--animate-fade-in: fade-in 0.6s ease both; --animate-fade-in: fade-in 0.6s ease both;
@@ -76,7 +91,7 @@
} }
:root { :root {
--radius: 0.625rem; --radius: 0.75rem;
} }
@layer base { @layer base {
+53 -53
View File
@@ -18,14 +18,14 @@ const features = [
title: "Smart Task Tracking", title: "Smart Task Tracking",
description: description:
"Kanban boards, recurring schedules, and due date reminders keep every repair and project on track.", "Kanban boards, recurring schedules, and due date reminders keep every repair and project on track.",
color: "bg-[#FFF3EB] text-[#E07A3A]", color: "bg-[#EDF2ED] text-[#6B8F71]",
}, },
{ {
icon: HardHat, icon: HardHat,
title: "Contractor Rolodex", title: "Contractor Rolodex",
description: description:
"Store contact details, specialties, and notes for every service provider. Never lose a plumber's number again.", "Store contact details, specialties, and notes for every service provider. Never lose a plumber's number again.",
color: "bg-[#ECFDF5] text-[#0D7C66]", color: "bg-[#FDF3EE] text-[#C4856A]",
}, },
{ {
icon: FileText, icon: FileText,
@@ -82,9 +82,9 @@ const highlights = [
export default function HomePage() { export default function HomePage() {
return ( return (
<div className="min-h-screen bg-white text-[#1C1917] font-sans selection:bg-[#E07A3A]/20"> <div className="min-h-screen bg-[#FAFAF7] text-[#2D3436] font-sans selection:bg-[#6B8F71]/20">
{/* ─── Navigation ─── */} {/* ─── Navigation ─── */}
<nav className="fixed top-0 w-full z-50 bg-white/80 backdrop-blur-xl border-b border-[#E7E5E4]/60"> <nav className="fixed top-0 w-full z-50 bg-[#FAFAF7]/80 backdrop-blur-xl border-b border-[#E8E3DC]/60">
<div className="max-w-7xl mx-auto px-6 flex items-center justify-between h-16"> <div className="max-w-7xl mx-auto px-6 flex items-center justify-between h-16">
<Link href="/" className="flex items-center gap-2.5"> <Link href="/" className="flex items-center gap-2.5">
<Image <Image
@@ -94,7 +94,7 @@ export default function HomePage() {
height={32} height={32}
className="rounded-lg" className="rounded-lg"
/> />
<span className="font-heading text-xl font-bold tracking-tight text-[#1C1917]"> <span className="font-heading text-xl font-bold tracking-tight text-[#2D3436]">
Casera Casera
</span> </span>
</Link> </Link>
@@ -102,19 +102,19 @@ export default function HomePage() {
<div className="hidden md:flex items-center gap-8"> <div className="hidden md:flex items-center gap-8">
<a <a
href="#features" href="#features"
className="text-sm font-medium text-[#78716C] hover:text-[#1C1917] transition-colors" className="text-sm font-medium text-[#8A8F87] hover:text-[#2D3436] transition-colors"
> >
Features Features
</a> </a>
<a <a
href="#how-it-works" href="#how-it-works"
className="text-sm font-medium text-[#78716C] hover:text-[#1C1917] transition-colors" className="text-sm font-medium text-[#8A8F87] hover:text-[#2D3436] transition-colors"
> >
How It Works How It Works
</a> </a>
<Link <Link
href="/demo" href="/demo"
className="text-sm font-medium text-[#78716C] hover:text-[#1C1917] transition-colors" className="text-sm font-medium text-[#8A8F87] hover:text-[#2D3436] transition-colors"
> >
Demo Demo
</Link> </Link>
@@ -123,13 +123,13 @@ export default function HomePage() {
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Link <Link
href="/login" href="/login"
className="text-sm font-medium text-[#78716C] hover:text-[#1C1917] transition-colors hidden sm:inline-flex" className="text-sm font-medium text-[#8A8F87] hover:text-[#2D3436] transition-colors hidden sm:inline-flex"
> >
Sign In Sign In
</Link> </Link>
<Link <Link
href="/register" href="/register"
className="inline-flex items-center gap-1.5 rounded-full bg-[#1C1917] px-5 py-2 text-sm font-semibold text-white hover:bg-[#292524] transition-colors" className="inline-flex items-center gap-1.5 rounded-full bg-[#2D3436] px-5 py-2 text-sm font-semibold text-white hover:bg-[#3D4446] transition-colors"
> >
Get Started Get Started
<ArrowRight className="size-3.5" /> <ArrowRight className="size-3.5" />
@@ -142,14 +142,14 @@ export default function HomePage() {
<section className="relative pt-32 pb-24 md:pt-40 md:pb-32 overflow-hidden"> <section className="relative pt-32 pb-24 md:pt-40 md:pb-32 overflow-hidden">
{/* Decorative background */} {/* Decorative background */}
<div className="absolute inset-0 pointer-events-none"> <div className="absolute inset-0 pointer-events-none">
<div className="absolute top-20 right-[-10%] w-[600px] h-[600px] rounded-full bg-[#E07A3A]/[0.04] blur-3xl" /> <div className="absolute top-20 right-[-10%] w-[600px] h-[600px] rounded-full bg-[#6B8F71]/[0.04] blur-3xl" />
<div className="absolute bottom-0 left-[-5%] w-[400px] h-[400px] rounded-full bg-[#0D7C66]/[0.03] blur-3xl" /> <div className="absolute bottom-0 left-[-5%] w-[400px] h-[400px] rounded-full bg-[#C4856A]/[0.03] blur-3xl" />
{/* Subtle grid pattern */} {/* Subtle grid pattern */}
<div <div
className="absolute inset-0 opacity-[0.03]" className="absolute inset-0 opacity-[0.03]"
style={{ style={{
backgroundImage: backgroundImage:
"linear-gradient(#1C1917 1px, transparent 1px), linear-gradient(90deg, #1C1917 1px, transparent 1px)", "linear-gradient(#2D3436 1px, transparent 1px), linear-gradient(90deg, #2D3436 1px, transparent 1px)",
backgroundSize: "64px 64px", backgroundSize: "64px 64px",
}} }}
/> />
@@ -158,17 +158,17 @@ export default function HomePage() {
<div className="max-w-7xl mx-auto px-6 relative"> <div className="max-w-7xl mx-auto px-6 relative">
<div className="max-w-3xl"> <div className="max-w-3xl">
{/* Badge */} {/* Badge */}
<div className="animate-fade-up stagger-1 inline-flex items-center gap-2 rounded-full border border-[#E7E5E4] bg-white px-4 py-1.5 text-sm text-[#78716C] mb-8 shadow-sm"> <div className="animate-fade-up stagger-1 inline-flex items-center gap-2 rounded-full border border-[#E8E3DC] bg-white px-4 py-1.5 text-sm text-[#8A8F87] mb-8 shadow-sm">
<span className="inline-block size-2 rounded-full bg-[#0D7C66] animate-pulse" /> <span className="inline-block size-2 rounded-full bg-[#6B8F71] animate-pulse" />
Now available for homeowners Now available for homeowners
</div> </div>
<h1 className="animate-fade-up stagger-2 font-heading text-5xl sm:text-6xl md:text-7xl font-bold tracking-tight leading-[1.08]"> <h1 className="animate-fade-up stagger-2 font-heading text-5xl sm:text-6xl md:text-7xl font-bold tracking-tight leading-[1.08]">
Your home,{" "} Your home,{" "}
<span className="text-[#E07A3A]">perfectly maintained.</span> <span className="text-[#6B8F71]">perfectly maintained.</span>
</h1> </h1>
<p className="animate-fade-up stagger-3 mt-6 text-lg md:text-xl text-[#78716C] max-w-xl leading-relaxed"> <p className="animate-fade-up stagger-3 mt-6 text-lg md:text-xl text-[#8A8F87] max-w-xl leading-relaxed">
Track tasks, organize contractors, and store important Track tasks, organize contractors, and store important
documents. Everything you need to keep your home running documents. Everything you need to keep your home running
smoothly in one place. smoothly in one place.
@@ -177,17 +177,17 @@ export default function HomePage() {
<div className="animate-fade-up stagger-4 mt-10 flex flex-wrap gap-4"> <div className="animate-fade-up stagger-4 mt-10 flex flex-wrap gap-4">
<Link <Link
href="/register" href="/register"
className="group inline-flex items-center gap-2 rounded-full bg-[#E07A3A] px-7 py-3.5 text-base font-semibold text-white shadow-lg shadow-[#E07A3A]/20 hover:bg-[#C4632A] transition-all hover:shadow-xl hover:shadow-[#E07A3A]/25" className="group inline-flex items-center gap-2 rounded-full bg-[#C4856A] px-7 py-3.5 text-base font-semibold text-white shadow-lg shadow-[#C4856A]/20 hover:bg-[#A86B52] transition-all hover:shadow-xl hover:shadow-[#C4856A]/25"
> >
Get Started Free Get Started Free
<ArrowRight className="size-4 transition-transform group-hover:translate-x-0.5" /> <ArrowRight className="size-4 transition-transform group-hover:translate-x-0.5" />
</Link> </Link>
<Link <Link
href="/demo" href="/demo"
className="group inline-flex items-center gap-2 rounded-full border-2 border-[#E7E5E4] bg-white px-7 py-3.5 text-base font-semibold text-[#1C1917] hover:border-[#D6D3D1] hover:bg-[#F5F5F4] transition-all" className="group inline-flex items-center gap-2 rounded-full border-2 border-[#E8E3DC] bg-white px-7 py-3.5 text-base font-semibold text-[#2D3436] hover:border-[#D6D1CA] hover:bg-[#F2EFE9] transition-all"
> >
Try the Demo Try the Demo
<ChevronRight className="size-4 text-[#A8A29E] transition-transform group-hover:translate-x-0.5" /> <ChevronRight className="size-4 text-[#8A8F87] transition-transform group-hover:translate-x-0.5" />
</Link> </Link>
</div> </div>
</div> </div>
@@ -196,21 +196,21 @@ export default function HomePage() {
<div className="animate-fade-up stagger-5 hidden lg:block absolute top-12 right-6 w-[420px]"> <div className="animate-fade-up stagger-5 hidden lg:block absolute top-12 right-6 w-[420px]">
<div className="relative"> <div className="relative">
{/* Main card */} {/* Main card */}
<div className="rounded-2xl bg-white border border-[#E7E5E4] shadow-xl shadow-black/[0.04] p-5"> <div className="rounded-2xl bg-white border border-[#E8E3DC] shadow-xl shadow-[#2D3436]/[0.04] p-5">
<div className="flex items-center gap-3 mb-4"> <div className="flex items-center gap-3 mb-4">
<div className="size-8 rounded-lg bg-[#FFF3EB] flex items-center justify-center"> <div className="size-8 rounded-lg bg-[#EDF2ED] flex items-center justify-center">
<CheckSquare className="size-4 text-[#E07A3A]" /> <CheckSquare className="size-4 text-[#6B8F71]" />
</div> </div>
<div> <div>
<div className="text-sm font-semibold">Upcoming Tasks</div> <div className="text-sm font-semibold">Upcoming Tasks</div>
<div className="text-xs text-[#A8A29E]">3 due this week</div> <div className="text-xs text-[#8A8F87]">3 due this week</div>
</div> </div>
</div> </div>
<div className="space-y-2.5"> <div className="space-y-2.5">
{[ {[
{ task: "Replace HVAC filter", due: "Tomorrow", status: "bg-[#FEF3C7] text-[#92400E]" }, { task: "Replace HVAC filter", due: "Tomorrow", status: "bg-[#FEF3C7] text-[#92400E]" },
{ task: "Schedule gutter cleaning", due: "Wed", status: "bg-[#ECFDF5] text-[#0D7C66]" }, { task: "Schedule gutter cleaning", due: "Wed", status: "bg-[#EDF2ED] text-[#6B8F71]" },
{ task: "Check smoke detectors", due: "Fri", status: "bg-[#FFF3EB] text-[#E07A3A]" }, { task: "Check smoke detectors", due: "Fri", status: "bg-[#FDF3EE] text-[#C4856A]" },
].map((item) => ( ].map((item) => (
<div <div
key={item.task} key={item.task}
@@ -229,13 +229,13 @@ export default function HomePage() {
{/* Floating stat card */} {/* Floating stat card */}
<div <div
className="absolute -bottom-8 -left-8 rounded-xl bg-white border border-[#E7E5E4] shadow-lg shadow-black/[0.04] p-4 w-48" className="absolute -bottom-8 -left-8 rounded-xl bg-white border border-[#E8E3DC] shadow-lg shadow-[#2D3436]/[0.04] p-4 w-48"
style={{ animation: "float 6s ease-in-out infinite" }} style={{ animation: "float 6s ease-in-out infinite" }}
> >
<div className="text-xs text-[#A8A29E] mb-1">This Month</div> <div className="text-xs text-[#8A8F87] mb-1">This Month</div>
<div className="text-2xl font-bold font-heading text-[#0D7C66]">12 Done</div> <div className="text-2xl font-bold font-heading text-[#6B8F71]">12 Done</div>
<div className="mt-2 h-1.5 rounded-full bg-[#F7F7F7] overflow-hidden"> <div className="mt-2 h-1.5 rounded-full bg-[#F2EFE9] overflow-hidden">
<div className="h-full w-3/4 rounded-full bg-[#0D7C66]" /> <div className="h-full w-3/4 rounded-full bg-[#6B8F71]" />
</div> </div>
</div> </div>
</div> </div>
@@ -244,7 +244,7 @@ export default function HomePage() {
</section> </section>
{/* ─── Social proof strip ─── */} {/* ─── Social proof strip ─── */}
<section className="border-y border-[#E7E5E4] bg-white/50"> <section className="border-y border-[#E8E3DC] bg-white/50">
<div className="max-w-7xl mx-auto px-6 py-8 flex flex-wrap items-center justify-center gap-x-12 gap-y-4 text-center"> <div className="max-w-7xl mx-auto px-6 py-8 flex flex-wrap items-center justify-center gap-x-12 gap-y-4 text-center">
{[ {[
{ value: "Free", label: "to get started" }, { value: "Free", label: "to get started" },
@@ -252,10 +252,10 @@ export default function HomePage() {
{ value: "All-in-one", label: "home management" }, { value: "All-in-one", label: "home management" },
].map((stat) => ( ].map((stat) => (
<div key={stat.label} className="flex items-baseline gap-2"> <div key={stat.label} className="flex items-baseline gap-2">
<span className="text-lg font-bold font-heading text-[#1C1917]"> <span className="text-lg font-bold font-heading text-[#2D3436]">
{stat.value} {stat.value}
</span> </span>
<span className="text-sm text-[#A8A29E]">{stat.label}</span> <span className="text-sm text-[#8A8F87]">{stat.label}</span>
</div> </div>
))} ))}
</div> </div>
@@ -265,13 +265,13 @@ export default function HomePage() {
<section id="features" className="py-24 md:py-32"> <section id="features" className="py-24 md:py-32">
<div className="max-w-7xl mx-auto px-6"> <div className="max-w-7xl mx-auto px-6">
<div className="max-w-2xl mb-16"> <div className="max-w-2xl mb-16">
<p className="text-sm font-semibold text-[#E07A3A] uppercase tracking-wider mb-3"> <p className="text-sm font-semibold text-[#6B8F71] uppercase tracking-wider mb-3">
Features Features
</p> </p>
<h2 className="font-heading text-3xl md:text-4xl font-bold tracking-tight"> <h2 className="font-heading text-3xl md:text-4xl font-bold tracking-tight">
Everything your home needs, nothing it doesn&apos;t. Everything your home needs, nothing it doesn&apos;t.
</h2> </h2>
<p className="mt-4 text-lg text-[#78716C] leading-relaxed"> <p className="mt-4 text-lg text-[#8A8F87] leading-relaxed">
Casera brings all your home maintenance into one clear, Casera brings all your home maintenance into one clear,
organized space. No bloat, no learning curve. organized space. No bloat, no learning curve.
</p> </p>
@@ -281,7 +281,7 @@ export default function HomePage() {
{features.map((feature, i) => ( {features.map((feature, i) => (
<div <div
key={feature.title} key={feature.title}
className={`group relative rounded-2xl border border-[#E7E5E4] bg-white p-8 transition-all hover:shadow-lg hover:shadow-black/[0.04] hover:-translate-y-0.5 stagger-${i + 1}`} className={`group relative rounded-2xl border border-[#E8E3DC] bg-white p-8 transition-all hover:shadow-lg hover:shadow-[#2D3436]/[0.04] hover:-translate-y-0.5 stagger-${i + 1}`}
> >
<div <div
className={`inline-flex items-center justify-center size-12 rounded-xl ${feature.color} mb-5`} className={`inline-flex items-center justify-center size-12 rounded-xl ${feature.color} mb-5`}
@@ -291,7 +291,7 @@ export default function HomePage() {
<h3 className="font-heading text-xl font-bold mb-2"> <h3 className="font-heading text-xl font-bold mb-2">
{feature.title} {feature.title}
</h3> </h3>
<p className="text-[#78716C] leading-relaxed"> <p className="text-[#8A8F87] leading-relaxed">
{feature.description} {feature.description}
</p> </p>
</div> </div>
@@ -303,11 +303,11 @@ export default function HomePage() {
{/* ─── How It Works ─── */} {/* ─── How It Works ─── */}
<section <section
id="how-it-works" id="how-it-works"
className="py-24 md:py-32 bg-[#F7F7F7] relative noise-overlay" className="py-24 md:py-32 bg-[#F2EFE9] relative noise-overlay"
> >
<div className="max-w-7xl mx-auto px-6 relative"> <div className="max-w-7xl mx-auto px-6 relative">
<div className="text-center max-w-2xl mx-auto mb-16"> <div className="text-center max-w-2xl mx-auto mb-16">
<p className="text-sm font-semibold text-[#0D7C66] uppercase tracking-wider mb-3"> <p className="text-sm font-semibold text-[#6B8F71] uppercase tracking-wider mb-3">
How It Works How It Works
</p> </p>
<h2 className="font-heading text-3xl md:text-4xl font-bold tracking-tight"> <h2 className="font-heading text-3xl md:text-4xl font-bold tracking-tight">
@@ -318,13 +318,13 @@ export default function HomePage() {
<div className="grid md:grid-cols-3 gap-8 md:gap-12"> <div className="grid md:grid-cols-3 gap-8 md:gap-12">
{steps.map((step) => ( {steps.map((step) => (
<div key={step.number} className="text-center md:text-left"> <div key={step.number} className="text-center md:text-left">
<div className="inline-flex items-center justify-center size-14 rounded-2xl bg-[#1C1917] text-white font-heading font-bold text-lg mb-5"> <div className="inline-flex items-center justify-center size-14 rounded-2xl bg-[#2D3436] text-white font-heading font-bold text-lg mb-5">
{step.number} {step.number}
</div> </div>
<h3 className="font-heading text-xl font-bold mb-2"> <h3 className="font-heading text-xl font-bold mb-2">
{step.title} {step.title}
</h3> </h3>
<p className="text-[#78716C] leading-relaxed"> <p className="text-[#8A8F87] leading-relaxed">
{step.description} {step.description}
</p> </p>
</div> </div>
@@ -340,7 +340,7 @@ export default function HomePage() {
<h2 className="font-heading text-3xl md:text-4xl font-bold tracking-tight"> <h2 className="font-heading text-3xl md:text-4xl font-bold tracking-tight">
Built for real homeowners Built for real homeowners
</h2> </h2>
<p className="mt-4 text-lg text-[#78716C]"> <p className="mt-4 text-lg text-[#8A8F87]">
Thoughtful details that make home maintenance feel manageable. Thoughtful details that make home maintenance feel manageable.
</p> </p>
</div> </div>
@@ -349,13 +349,13 @@ export default function HomePage() {
{highlights.map((item) => ( {highlights.map((item) => (
<div <div
key={item.title} key={item.title}
className="rounded-2xl border border-[#E7E5E4] bg-white p-6 hover:shadow-md hover:shadow-black/[0.03] transition-all" className="rounded-2xl border border-[#E8E3DC] bg-white p-6 hover:shadow-md hover:shadow-[#2D3436]/[0.03] transition-all"
> >
<item.icon className="size-6 text-[#E07A3A] mb-4" /> <item.icon className="size-6 text-[#6B8F71] mb-4" />
<h3 className="font-heading font-bold text-base mb-1.5"> <h3 className="font-heading font-bold text-base mb-1.5">
{item.title} {item.title}
</h3> </h3>
<p className="text-sm text-[#78716C] leading-relaxed"> <p className="text-sm text-[#8A8F87] leading-relaxed">
{item.description} {item.description}
</p> </p>
</div> </div>
@@ -366,23 +366,23 @@ export default function HomePage() {
{/* ─── CTA Section ─── */} {/* ─── CTA Section ─── */}
<section className="py-24 md:py-32 relative overflow-hidden"> <section className="py-24 md:py-32 relative overflow-hidden">
<div className="absolute inset-0 bg-[#1C1917]" /> <div className="absolute inset-0 bg-[#2D3436]" />
{/* Orange glow */} {/* Sage glow */}
<div className="absolute top-0 right-0 w-[500px] h-[500px] rounded-full bg-[#E07A3A]/10 blur-[120px] pointer-events-none" /> <div className="absolute top-0 right-0 w-[500px] h-[500px] rounded-full bg-[#6B8F71]/10 blur-[120px] pointer-events-none" />
<div className="absolute bottom-0 left-0 w-[400px] h-[400px] rounded-full bg-[#0D7C66]/10 blur-[100px] pointer-events-none" /> <div className="absolute bottom-0 left-0 w-[400px] h-[400px] rounded-full bg-[#C4856A]/10 blur-[100px] pointer-events-none" />
<div className="max-w-3xl mx-auto px-6 text-center relative"> <div className="max-w-3xl mx-auto px-6 text-center relative">
<h2 className="font-heading text-3xl md:text-5xl font-bold tracking-tight text-white"> <h2 className="font-heading text-3xl md:text-5xl font-bold tracking-tight text-white">
Ready to take control of your home? Ready to take control of your home?
</h2> </h2>
<p className="mt-5 text-lg text-[#A8A29E] max-w-xl mx-auto leading-relaxed"> <p className="mt-5 text-lg text-[#9A9E97] max-w-xl mx-auto leading-relaxed">
Join homeowners who&apos;ve simplified their maintenance routine. Join homeowners who&apos;ve simplified their maintenance routine.
Free to start, no credit card required. Free to start, no credit card required.
</p> </p>
<div className="mt-10 flex flex-wrap justify-center gap-4"> <div className="mt-10 flex flex-wrap justify-center gap-4">
<Link <Link
href="/register" href="/register"
className="group inline-flex items-center gap-2 rounded-full bg-[#E07A3A] px-8 py-4 text-base font-semibold text-white shadow-lg shadow-[#E07A3A]/20 hover:bg-[#C4632A] transition-all" className="group inline-flex items-center gap-2 rounded-full bg-[#C4856A] px-8 py-4 text-base font-semibold text-white shadow-lg shadow-[#C4856A]/20 hover:bg-[#A86B52] transition-all"
> >
Get Started Free Get Started Free
<ArrowRight className="size-4 transition-transform group-hover:translate-x-0.5" /> <ArrowRight className="size-4 transition-transform group-hover:translate-x-0.5" />
@@ -398,7 +398,7 @@ export default function HomePage() {
</section> </section>
{/* ─── Footer ─── */} {/* ─── Footer ─── */}
<footer className="bg-[#1C1917] border-t border-white/5 text-[#A8A29E]"> <footer className="bg-[#2D3436] border-t border-white/5 text-[#9A9E97]">
<div className="max-w-7xl mx-auto px-6 py-16"> <div className="max-w-7xl mx-auto px-6 py-16">
<div className="grid md:grid-cols-4 gap-10"> <div className="grid md:grid-cols-4 gap-10">
{/* Brand */} {/* Brand */}
+2 -2
View File
@@ -39,8 +39,8 @@ export function RecentActivity() {
</div> </div>
) : notifications.length === 0 ? ( ) : notifications.length === 0 ? (
<div className="flex flex-col items-center justify-center py-10 text-center"> <div className="flex flex-col items-center justify-center py-10 text-center">
<div className="size-11 rounded-xl bg-[#FFF3EB] flex items-center justify-center mb-3"> <div className="size-11 rounded-xl bg-primary/10 flex items-center justify-center mb-3">
<Coffee className="size-5 text-[#E07A3A]" /> <Coffee className="size-5 text-primary" />
</div> </div>
<p className="text-sm font-medium text-foreground">Nothing yet all quiet!</p> <p className="text-sm font-medium text-foreground">Nothing yet all quiet!</p>
<p className="text-xs text-muted-foreground mt-1"> <p className="text-xs text-muted-foreground mt-1">
+5 -5
View File
@@ -32,16 +32,16 @@ const stats = [
key: "active", key: "active",
label: "Active", label: "Active",
icon: ClipboardList, icon: ClipboardList,
iconColor: "text-[#0D7C66]", iconColor: "text-primary",
bgColor: "bg-emerald-50 dark:bg-emerald-500/10", bgColor: "bg-primary/10",
prop: "active" as const, prop: "active" as const,
}, },
{ {
key: "completed", key: "completed",
label: "Completed", label: "Completed",
icon: CheckCircle2, icon: CheckCircle2,
iconColor: "text-[#E07A3A]", iconColor: "text-brand-clay",
bgColor: "bg-orange-50 dark:bg-orange-500/10", bgColor: "bg-brand-clay/10",
prop: "completed" as const, prop: "completed" as const,
}, },
] as const; ] as const;
@@ -54,7 +54,7 @@ export function StatsCards({ overdue, dueSoon, active, completed }: StatsCardsPr
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4"> <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
{stats.map((stat) => ( {stats.map((stat) => (
<Link key={stat.key} href={`${basePath}/tasks`}> <Link key={stat.key} href={`${basePath}/tasks`}>
<div className="group rounded-2xl border border-border bg-card p-5 hover:shadow-md hover:shadow-black/[0.03] transition-all hover:-translate-y-0.5 cursor-pointer"> <div className="group rounded-2xl border border-border bg-card p-5 hover:shadow-[var(--shadow-warm-md)] transition-all hover:-translate-y-0.5 cursor-pointer">
<div className="flex items-center gap-3 mb-3"> <div className="flex items-center gap-3 mb-3">
<div className={`inline-flex items-center justify-center size-9 rounded-xl ${stat.bgColor}`}> <div className={`inline-flex items-center justify-center size-9 rounded-xl ${stat.bgColor}`}>
<stat.icon className={`size-4 ${stat.iconColor}`} /> <stat.icon className={`size-4 ${stat.iconColor}`} />
@@ -43,8 +43,8 @@ export function TaskCompletionChart({ data }: TaskCompletionChartProps) {
<Area <Area
type="monotone" type="monotone"
dataKey="count" dataKey="count"
stroke="#E07A3A" stroke="#6B8F71"
fill="#E07A3A" fill="#6B8F71"
fillOpacity={0.1} fillOpacity={0.1}
strokeWidth={2} strokeWidth={2}
/> />
@@ -52,8 +52,8 @@ export function TaskCompletionChart({ data }: TaskCompletionChartProps) {
</ResponsiveContainer> </ResponsiveContainer>
) : ( ) : (
<div className="flex flex-col items-center justify-center h-[300px] text-center"> <div className="flex flex-col items-center justify-center h-[300px] text-center">
<div className="size-12 rounded-xl bg-[#ECFDF5] flex items-center justify-center mb-3"> <div className="size-12 rounded-xl bg-primary/10 flex items-center justify-center mb-3">
<TrendingUp className="size-5 text-[#0D7C66]" /> <TrendingUp className="size-5 text-primary" />
</div> </div>
<p className="text-sm font-medium text-foreground">Your progress chart lives here</p> <p className="text-sm font-medium text-foreground">Your progress chart lives here</p>
<p className="text-xs text-muted-foreground mt-1 max-w-[260px] leading-relaxed"> <p className="text-xs text-muted-foreground mt-1 max-w-[260px] leading-relaxed">
+2 -2
View File
@@ -11,7 +11,7 @@ export function DemoBanner() {
if (dismissed) return null; if (dismissed) return null;
return ( return (
<div className="sticky top-0 z-50 flex items-center justify-center gap-3 border-b border-[#E07A3A]/20 bg-[#FFF3EB]/80 px-4 py-2.5 text-sm text-[#92400E] backdrop-blur-xl"> <div className="sticky top-0 z-50 flex items-center justify-center gap-3 border-b border-brand-clay/20 bg-brand-clay-light/80 px-4 py-2.5 text-sm text-[#92400E] backdrop-blur-xl">
<p className="font-medium"> <p className="font-medium">
You&apos;re exploring Casera in demo mode. Changes aren&apos;t saved. You&apos;re exploring Casera in demo mode. Changes aren&apos;t saved.
</p> </p>
@@ -21,7 +21,7 @@ export function DemoBanner() {
<Button <Button
variant="ghost" variant="ghost"
size="icon-xs" size="icon-xs"
className="absolute right-2 text-[#92400E] hover:bg-[#E07A3A]/10" className="absolute right-2 text-[#92400E] hover:bg-brand-clay/10"
onClick={() => setDismissed(true)} onClick={() => setDismissed(true)}
aria-label="Dismiss banner" aria-label="Dismiss banner"
> >
+1 -1
View File
@@ -28,7 +28,7 @@ export function AuthFormWrapper({
height={32} height={32}
className="rounded-lg" className="rounded-lg"
/> />
<span className="font-heading text-xl font-bold text-[#1C1917]"> <span className="font-heading text-xl font-bold text-foreground">
Casera Casera
</span> </span>
</Link> </Link>
+3 -38
View File
@@ -4,8 +4,6 @@ import { Monitor, Moon, Sun } from "lucide-react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { cn } from "@/lib/utils";
import { themes } from "@/lib/themes/theme-config";
import { useThemeStore, type ColorMode } from "@/stores/theme"; import { useThemeStore, type ColorMode } from "@/stores/theme";
const modeOptions: { value: ColorMode; label: string; icon: React.ElementType }[] = [ const modeOptions: { value: ColorMode; label: string; icon: React.ElementType }[] = [
@@ -15,48 +13,15 @@ const modeOptions: { value: ColorMode; label: string; icon: React.ElementType }[
]; ];
export function ThemePicker() { export function ThemePicker() {
const { themeId, mode, setTheme, setMode } = useThemeStore(); const { mode, setMode } = useThemeStore();
return ( return (
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle>Appearance</CardTitle> <CardTitle>Appearance</CardTitle>
<CardDescription>Choose a theme and color mode for the app.</CardDescription> <CardDescription>Choose a color mode for the app.</CardDescription>
</CardHeader> </CardHeader>
<CardContent className="space-y-6"> <CardContent>
{/* Theme swatches */}
<div>
<p className="text-sm font-medium mb-3">Theme</p>
<div className="flex flex-wrap gap-3">
{themes.map((theme) => (
<button
key={theme.id}
type="button"
onClick={() => setTheme(theme.id)}
className={cn(
"group relative flex flex-col items-center gap-1.5 rounded-lg p-2 transition-colors hover:bg-accent",
themeId === theme.id && "bg-accent"
)}
title={theme.name}
>
<span
className={cn(
"size-8 rounded-full border-2 transition-all",
themeId === theme.id
? "border-foreground ring-2 ring-foreground ring-offset-2 ring-offset-background"
: "border-transparent"
)}
style={{ backgroundColor: theme.light.primary }}
/>
<span className="text-xs text-muted-foreground group-hover:text-foreground">
{theme.name}
</span>
</button>
))}
</div>
</div>
{/* Mode toggle */}
<div> <div>
<p className="text-sm font-medium mb-3">Mode</p> <p className="text-sm font-medium mb-3">Mode</p>
<div className="inline-flex items-center rounded-lg border bg-muted p-1 gap-1"> <div className="inline-flex items-center rounded-lg border bg-muted p-1 gap-1">
+6 -6
View File
@@ -10,8 +10,8 @@ import type { KanbanColumn as KanbanColumnType } from "@/lib/api/tasks";
const COLUMN_COLORS: Record<string, string> = { const COLUMN_COLORS: Record<string, string> = {
overdue_tasks: "border-red-200 bg-red-50/40 dark:border-red-500/20 dark:bg-red-950/20", overdue_tasks: "border-red-200 bg-red-50/40 dark:border-red-500/20 dark:bg-red-950/20",
due_soon_tasks: "border-amber-200 bg-amber-50/40 dark:border-amber-500/20 dark:bg-amber-950/20", due_soon_tasks: "border-amber-200 bg-amber-50/40 dark:border-amber-500/20 dark:bg-amber-950/20",
upcoming_tasks: "border-blue-200 bg-blue-50/40 dark:border-blue-500/20 dark:bg-blue-950/20", upcoming_tasks: "border-[#6B8F71]/20 bg-[#EDF2ED]/50 dark:border-[#8FB896]/20 dark:bg-[#8FB896]/5",
in_progress_tasks: "border-emerald-200 bg-emerald-50/40 dark:border-emerald-500/20 dark:bg-emerald-950/20", in_progress_tasks: "border-[#C4856A]/20 bg-[#FDF3EE]/50 dark:border-[#D4A08A]/20 dark:bg-[#D4A08A]/5",
completed_tasks: "border-stone-200 bg-stone-50/40 dark:border-stone-500/20 dark:bg-stone-950/20", completed_tasks: "border-stone-200 bg-stone-50/40 dark:border-stone-500/20 dark:bg-stone-950/20",
cancelled_tasks: "border-slate-200 bg-slate-50/40 dark:border-slate-500/20 dark:bg-slate-950/20", cancelled_tasks: "border-slate-200 bg-slate-50/40 dark:border-slate-500/20 dark:bg-slate-950/20",
}; };
@@ -19,8 +19,8 @@ const COLUMN_COLORS: Record<string, string> = {
const COLUMN_HEADER_COLORS: Record<string, string> = { const COLUMN_HEADER_COLORS: Record<string, string> = {
overdue_tasks: "text-red-700 dark:text-red-400", overdue_tasks: "text-red-700 dark:text-red-400",
due_soon_tasks: "text-amber-700 dark:text-amber-400", due_soon_tasks: "text-amber-700 dark:text-amber-400",
upcoming_tasks: "text-blue-700 dark:text-blue-400", upcoming_tasks: "text-[#6B8F71] dark:text-[#8FB896]",
in_progress_tasks: "text-emerald-700 dark:text-emerald-400", in_progress_tasks: "text-[#C4856A] dark:text-[#D4A08A]",
completed_tasks: "text-stone-600 dark:text-stone-400", completed_tasks: "text-stone-600 dark:text-stone-400",
cancelled_tasks: "text-slate-600 dark:text-slate-400", cancelled_tasks: "text-slate-600 dark:text-slate-400",
}; };
@@ -28,8 +28,8 @@ const COLUMN_HEADER_COLORS: Record<string, string> = {
const COUNT_BADGE_COLORS: Record<string, string> = { const COUNT_BADGE_COLORS: Record<string, string> = {
overdue_tasks: "bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300", overdue_tasks: "bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300",
due_soon_tasks: "bg-amber-100 text-amber-700 dark:bg-amber-900/50 dark:text-amber-300", due_soon_tasks: "bg-amber-100 text-amber-700 dark:bg-amber-900/50 dark:text-amber-300",
upcoming_tasks: "bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300", upcoming_tasks: "bg-[#6B8F71]/15 text-[#6B8F71] dark:bg-[#8FB896]/20 dark:text-[#8FB896]",
in_progress_tasks: "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/50 dark:text-emerald-300", in_progress_tasks: "bg-[#C4856A]/15 text-[#C4856A] dark:bg-[#D4A08A]/20 dark:text-[#D4A08A]",
completed_tasks: "bg-stone-100 text-stone-700 dark:bg-stone-900/50 dark:text-stone-300", completed_tasks: "bg-stone-100 text-stone-700 dark:bg-stone-900/50 dark:text-stone-300",
cancelled_tasks: "bg-slate-100 text-slate-700 dark:bg-slate-900/50 dark:text-slate-300", cancelled_tasks: "bg-slate-100 text-slate-700 dark:bg-slate-900/50 dark:text-slate-300",
}; };
+3 -40
View File
@@ -1,6 +1,6 @@
"use client"; "use client";
import { Sun, Moon, Monitor, Check } from "lucide-react"; import { Sun, Moon, Monitor } from "lucide-react";
import { useTheme, type ColorMode } from "@/lib/themes/use-theme"; import { useTheme, type ColorMode } from "@/lib/themes/use-theme";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@@ -13,11 +13,10 @@ const modeOptions: { value: ColorMode; label: string; icon: React.ElementType }[
/** /**
* Theme switcher component. * Theme switcher component.
* *
* Shows a grid of 11 color swatches (one per theme) and a * Light/dark/system segmented toggle.
* light/dark/system segmented toggle.
*/ */
export function ThemeSwitcher({ className }: { className?: string }) { export function ThemeSwitcher({ className }: { className?: string }) {
const { themeId, mode, effectiveMode, themes, setTheme, setMode } = useTheme(); const { mode, setMode } = useTheme();
return ( return (
<div className={cn("flex flex-col gap-4", className)}> <div className={cn("flex flex-col gap-4", className)}>
@@ -40,42 +39,6 @@ export function ThemeSwitcher({ className }: { className?: string }) {
</button> </button>
))} ))}
</div> </div>
{/* Theme swatches */}
<div className="grid grid-cols-6 gap-2 sm:grid-cols-11">
{themes.map((theme) => {
const isActive = theme.id === themeId;
// Show the primary color for the effective mode so the swatch
// preview matches what the user actually sees.
const previewColor =
effectiveMode === "dark"
? theme.dark.primary
: theme.light.primary;
return (
<button
key={theme.id}
type="button"
title={theme.name}
onClick={() => setTheme(theme.id)}
className={cn(
"relative flex h-8 w-8 items-center justify-center rounded-full border-2 transition-all",
isActive
? "border-foreground scale-110"
: "border-transparent hover:scale-105 hover:border-muted-foreground/40"
)}
style={{ backgroundColor: previewColor }}
>
{isActive && (
<Check
className="h-4 w-4"
style={{ color: theme[effectiveMode].textOnPrimary }}
/>
)}
</button>
);
})}
</div>
</div> </div>
); );
} }
+20 -291
View File
@@ -19,305 +19,34 @@ export interface ThemeDefinition {
} }
/** /**
* All 11 themes matching the KMM/iOS theme system. * Single "Warm Sage" theme — the Casera brand palette.
* Hex values are taken directly from ThemeColors.kt.
*/ */
export const themes: ThemeDefinition[] = [ export const themes: ThemeDefinition[] = [
{ {
id: "default", id: "default",
name: "Default", name: "Warm Sage",
description: "Warm orange with teal accents", description: "Calming sage with warm clay accents",
light: { light: {
primary: "#E07A3A", primary: "#6B8F71",
secondary: "#0D7C66", secondary: "#C4856A",
accent: "#D4A574", accent: "#C4856A",
error: "#DC2626", error: "#C75B4A",
bgPrimary: "#FFFFFF", bgPrimary: "#FAFAF7",
bgSecondary: "#F7F7F7", bgSecondary: "#F2EFE9",
textPrimary: "#1C1917", textPrimary: "#2D3436",
textSecondary: "#78716C", textSecondary: "#8A8F87",
textOnPrimary: "#FFFFFF", textOnPrimary: "#FFFFFF",
}, },
dark: { dark: {
primary: "#F0A070", primary: "#8FB896",
secondary: "#4FC9AF", secondary: "#D4A08A",
accent: "#DDB892", accent: "#D4A08A",
error: "#EF4444", error: "#E07A6B",
bgPrimary: "#0A0A0A", bgPrimary: "#1A1D1A",
bgSecondary: "#161616", bgSecondary: "#2A2E2A",
textPrimary: "#FAFAFA", textPrimary: "#E8E5DF",
textSecondary: "#A1A1A1", textSecondary: "#9A9E97",
textOnPrimary: "#0A0A0A", textOnPrimary: "#1A1D1A",
},
},
{
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",
}, },
}, },
]; ];
-23
View File
@@ -4,14 +4,8 @@ import { useEffect } from "react";
import { useThemeStore } from "@/stores/theme"; import { useThemeStore } from "@/stores/theme";
export function ThemeProvider({ children }: { children: React.ReactNode }) { export function ThemeProvider({ children }: { children: React.ReactNode }) {
const themeId = useThemeStore((s) => s.themeId);
const mode = useThemeStore((s) => s.mode); 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 // Sync dark class based on mode + system preference
useEffect(() => { useEffect(() => {
const applyDarkClass = (isDark: boolean) => { const applyDarkClass = (isDark: boolean) => {
@@ -41,22 +35,5 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
return () => mql.removeEventListener("change", handler); return () => mql.removeEventListener("change", handler);
}, [mode]); }, [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}</>; return <>{children}</>;
} }
+2 -6
View File
@@ -9,7 +9,7 @@ import { themes, getThemeById, type ThemeDefinition } from "./theme-config";
* (accounting for system preference), and setters. * (accounting for system preference), and setters.
*/ */
export function useTheme() { export function useTheme() {
const { themeId, mode, setTheme, setMode } = useThemeStore(); const { mode, setMode } = useThemeStore();
const [effectiveMode, setEffectiveMode] = useState<"light" | "dark">("light"); const [effectiveMode, setEffectiveMode] = useState<"light" | "dark">("light");
@@ -28,11 +28,9 @@ export function useTheme() {
return () => mql.removeEventListener("change", handler); return () => mql.removeEventListener("change", handler);
}, [mode]); }, [mode]);
const currentTheme: ThemeDefinition = getThemeById(themeId); const currentTheme: ThemeDefinition = getThemeById("default");
return { return {
/** Current theme ID string */
themeId,
/** Current mode setting (light | dark | system) */ /** Current mode setting (light | dark | system) */
mode, mode,
/** Resolved mode after considering system preference */ /** Resolved mode after considering system preference */
@@ -41,8 +39,6 @@ export function useTheme() {
currentTheme, currentTheme,
/** All available theme definitions */ /** All available theme definitions */
themes, themes,
/** Set the active theme by ID */
setTheme,
/** Set the color mode */ /** Set the color mode */
setMode, setMode,
}; };
-5
View File
@@ -1,22 +1,17 @@
import { create } from "zustand"; import { create } from "zustand";
import { persist } from "zustand/middleware"; import { persist } from "zustand/middleware";
import { DEFAULT_THEME_ID } from "@/lib/themes/theme-config";
export type ColorMode = "light" | "dark" | "system"; export type ColorMode = "light" | "dark" | "system";
interface ThemeState { interface ThemeState {
themeId: string;
mode: ColorMode; mode: ColorMode;
setTheme: (themeId: string) => void;
setMode: (mode: ColorMode) => void; setMode: (mode: ColorMode) => void;
} }
export const useThemeStore = create<ThemeState>()( export const useThemeStore = create<ThemeState>()(
persist( persist(
(set) => ({ (set) => ({
themeId: DEFAULT_THEME_ID,
mode: "light", mode: "light",
setTheme: (themeId: string) => set({ themeId }),
setMode: (mode: ColorMode) => set({ mode }), setMode: (mode: ColorMode) => set({ mode }),
}), }),
{ {
+44 -878
View File
@@ -1,9 +1,7 @@
/* /*
* Casera multi-theme design system * Casera "Warm Sage" design system
* 11 themes x 2 modes (light/dark) = 22 palettes * Single brand palette — light + dark mode
* Maps to shadcn/ui CSS variables and custom app variables * Maps to shadcn/ui CSS variables and custom app variables
*
* Spacing and radius tokens are theme-independent.
*/ */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
@@ -24,27 +22,19 @@
--radius-xxl: 24px; --radius-xxl: 24px;
} }
/* ------------------------------------------------------------------ */
/* Helper: map app vars to shadcn vars */
/* Each theme block sets --color-* vars, then this maps them. */
/* We inline shadcn mapping directly in each theme block for */
/* specificity, so this section documents the pattern. */
/* ------------------------------------------------------------------ */
/* ================================================================== */ /* ================================================================== */
/* THEME: Default — Warm orange brand with teal accents */ /* Light mode (default) */
/* ================================================================== */ /* ================================================================== */
[data-theme="default"],
:root { :root {
/* App color tokens light */ /* App color tokens light */
--color-primary: #E07A3A; --color-primary: #6B8F71;
--color-secondary: #0D7C66; --color-secondary: #C4856A;
--color-accent: #D4A574; --color-accent: #C4856A;
--color-error: #DC2626; --color-error: #C75B4A;
--color-bg-primary: #FFFFFF; --color-bg-primary: #FAFAF7;
--color-bg-secondary: #F7F7F7; --color-bg-secondary: #F2EFE9;
--color-text-primary: #1C1917; --color-text-primary: #2D3436;
--color-text-secondary: #78716C; --color-text-secondary: #8A8F87;
--color-text-on-primary: #FFFFFF; --color-text-on-primary: #FFFFFF;
/* shadcn overrides */ /* shadcn overrides */
@@ -63,8 +53,8 @@
--muted: var(--color-bg-secondary); --muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary); --muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error); --destructive: var(--color-error);
--border: #E8E8E8; --border: #E8E3DC;
--input: #E8E8E8; --input: #E8E3DC;
--ring: var(--color-primary); --ring: var(--color-primary);
--sidebar: #FFFFFF; --sidebar: #FFFFFF;
@@ -73,21 +63,30 @@
--sidebar-primary-foreground: var(--color-text-on-primary); --sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-secondary); --sidebar-accent: var(--color-bg-secondary);
--sidebar-accent-foreground: var(--color-text-primary); --sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: #E7E5E4; --sidebar-border: #E8E3DC;
--sidebar-ring: var(--color-primary); --sidebar-ring: var(--color-primary);
/* Chart palette */
--chart-1: #6B8F71;
--chart-2: #C4856A;
--chart-3: #8FB896;
--chart-4: #D4A08A;
--chart-5: #A3C4A8;
} }
[data-theme="default"].dark, /* ================================================================== */
.dark[data-theme="default"] { /* Dark mode */
--color-primary: #F0A070; /* ================================================================== */
--color-secondary: #4FC9AF; .dark {
--color-accent: #DDB892; --color-primary: #8FB896;
--color-error: #EF4444; --color-secondary: #D4A08A;
--color-bg-primary: #0A0A0A; --color-accent: #D4A08A;
--color-bg-secondary: #161616; --color-error: #E07A6B;
--color-text-primary: #FAFAFA; --color-bg-primary: #1A1D1A;
--color-text-secondary: #A1A1A1; --color-bg-secondary: #2A2E2A;
--color-text-on-primary: #0A0A0A; --color-text-primary: #E8E5DF;
--color-text-secondary: #9A9E97;
--color-text-on-primary: #1A1D1A;
--primary: var(--color-primary); --primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary); --primary-foreground: var(--color-text-on-primary);
@@ -97,9 +96,9 @@
--accent-foreground: var(--color-text-primary); --accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary); --background: var(--color-bg-primary);
--foreground: var(--color-text-primary); --foreground: var(--color-text-primary);
--card: #141414; --card: #232823;
--card-foreground: var(--color-text-primary); --card-foreground: var(--color-text-primary);
--popover: #141414; --popover: #232823;
--popover-foreground: var(--color-text-primary); --popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary); --muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary); --muted-foreground: var(--color-text-secondary);
@@ -108,7 +107,7 @@
--input: rgba(255, 255, 255, 0.12); --input: rgba(255, 255, 255, 0.12);
--ring: var(--color-primary); --ring: var(--color-primary);
--sidebar: #141414; --sidebar: #232823;
--sidebar-foreground: var(--color-text-primary); --sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary); --sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary); --sidebar-primary-foreground: var(--color-text-on-primary);
@@ -116,844 +115,11 @@
--sidebar-accent-foreground: var(--color-text-primary); --sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: rgba(255, 255, 255, 0.1); --sidebar-border: rgba(255, 255, 255, 0.1);
--sidebar-ring: var(--color-primary); --sidebar-ring: var(--color-primary);
}
/* Chart palette */
/* ================================================================== */ --chart-1: #8FB896;
/* THEME: Teal — Blue-green with warm accents */ --chart-2: #D4A08A;
/* ================================================================== */ --chart-3: #6B8F71;
[data-theme="teal"] { --chart-4: #C4856A;
--color-primary: #069FC3; --chart-5: #A3C4A8;
--color-secondary: #0054A4;
--color-accent: #EFC707;
--color-error: #DD1C1A;
--color-bg-primary: #FFF0D0;
--color-bg-secondary: #FFFFFF;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="teal"].dark,
.dark[data-theme="teal"] {
--color-primary: #60CCE2;
--color-secondary: #60A5D8;
--color-accent: #EFC707;
--color-error: #FF5244;
--color-bg-primary: #091829;
--color-bg-secondary: #1A2E3E;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Ocean — Deep blues and coral tones */
/* ================================================================== */
[data-theme="ocean"] {
--color-primary: #006B8F;
--color-secondary: #008A8A;
--color-accent: #FF7E50;
--color-error: #DD1C1A;
--color-bg-primary: #E4EBF1;
--color-bg-secondary: #BCCAD5;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="ocean"].dark,
.dark[data-theme="ocean"] {
--color-primary: #49B5D1;
--color-secondary: #60D1C6;
--color-accent: #FF7E50;
--color-error: #FF5244;
--color-bg-primary: #161B22;
--color-bg-secondary: #313A4B;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Forest — Earth greens and golden hues */
/* ================================================================== */
[data-theme="forest"] {
--color-primary: #2C5015;
--color-secondary: #6B8E22;
--color-accent: #FFD600;
--color-error: #DD1C1A;
--color-bg-primary: #EBEEE2;
--color-bg-secondary: #C1C8AD;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="forest"].dark,
.dark[data-theme="forest"] {
--color-primary: #93C66B;
--color-secondary: #AFD182;
--color-accent: #FFD600;
--color-error: #FF5244;
--color-bg-primary: #181E17;
--color-bg-secondary: #384436;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Sunset — Warm oranges and reds */
/* ================================================================== */
[data-theme="sunset"] {
--color-primary: #FF4500;
--color-secondary: #FF6246;
--color-accent: #FFD600;
--color-error: #DD1C1A;
--color-bg-primary: #F7F0E8;
--color-bg-secondary: #DCD0BA;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="sunset"].dark,
.dark[data-theme="sunset"] {
--color-primary: #FF9E60;
--color-secondary: #FFAD7C;
--color-accent: #FFD600;
--color-error: #FF5244;
--color-bg-primary: #201813;
--color-bg-secondary: #433329;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Monochrome — Elegant grayscale */
/* ================================================================== */
[data-theme="monochrome"] {
--color-primary: #333333;
--color-secondary: #666666;
--color-accent: #999999;
--color-error: #DD1C1A;
--color-bg-primary: #F0F0F0;
--color-bg-secondary: #D4D4D4;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="monochrome"].dark,
.dark[data-theme="monochrome"] {
--color-primary: #E5E5E5;
--color-secondary: #BFBFBF;
--color-accent: #D1D1D1;
--color-error: #FF5244;
--color-bg-primary: #161616;
--color-bg-secondary: #3B3B3B;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Lavender — Soft purple with pink accents */
/* ================================================================== */
[data-theme="lavender"] {
--color-primary: #6B418A;
--color-secondary: #8A60AF;
--color-accent: #E24982;
--color-error: #DD1C1A;
--color-bg-primary: #F1EFF5;
--color-bg-secondary: #D9D1DF;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="lavender"].dark,
.dark[data-theme="lavender"] {
--color-primary: #D1AFE2;
--color-secondary: #DDBFEA;
--color-accent: #FF9EC6;
--color-error: #FF5244;
--color-bg-primary: #17131E;
--color-bg-secondary: #393042;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Crimson — Bold red with warm highlights */
/* ================================================================== */
[data-theme="crimson"] {
--color-primary: #B51E28;
--color-secondary: #992D38;
--color-accent: #E26000;
--color-error: #DD1C1A;
--color-bg-primary: #F6EDEB;
--color-bg-secondary: #DECFCC;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="crimson"].dark,
.dark[data-theme="crimson"] {
--color-primary: #FF827C;
--color-secondary: #F99993;
--color-accent: #FFB56B;
--color-error: #FF5244;
--color-bg-primary: #1B1215;
--color-bg-secondary: #412E39;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Midnight — Deep navy with sky blue */
/* ================================================================== */
[data-theme="midnight"] {
--color-primary: #1E4993;
--color-secondary: #2D60AF;
--color-accent: #4993E2;
--color-error: #DD1C1A;
--color-bg-primary: #EDF0F7;
--color-bg-secondary: #CCD5E2;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="midnight"].dark,
.dark[data-theme="midnight"] {
--color-primary: #82B5EA;
--color-secondary: #93C6F2;
--color-accent: #9ED8FF;
--color-error: #FF5244;
--color-bg-primary: #12161F;
--color-bg-secondary: #2F3848;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Desert — Warm terracotta and sand tones */
/* ================================================================== */
[data-theme="desert"] {
--color-primary: #AF6049;
--color-secondary: #9E7C60;
--color-accent: #D1932D;
--color-error: #DD1C1A;
--color-bg-primary: #F6F0EA;
--color-bg-secondary: #E5D8C6;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="desert"].dark,
.dark[data-theme="desert"] {
--color-primary: #F2B593;
--color-secondary: #EAD1AF;
--color-accent: #FFD86B;
--color-error: #FF5244;
--color-bg-primary: #1F1C16;
--color-bg-secondary: #494138;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
}
/* ================================================================== */
/* THEME: Mint — Fresh green with turquoise */
/* ================================================================== */
[data-theme="mint"] {
--color-primary: #38AF93;
--color-secondary: #60C6AF;
--color-accent: #2D9EAF;
--color-error: #DD1C1A;
--color-bg-primary: #EDF6F0;
--color-bg-secondary: #D1E2D8;
--color-text-primary: #111111;
--color-text-secondary: #444444;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-primary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--sidebar-ring: var(--color-primary);
}
[data-theme="mint"].dark,
.dark[data-theme="mint"] {
--color-primary: #93F2D8;
--color-secondary: #BFF9EA;
--color-accent: #6BEAF2;
--color-error: #FF5244;
--color-bg-primary: #161F1F;
--color-bg-secondary: #384949;
--color-text-primary: #F5F5F5;
--color-text-secondary: #C6C6C6;
--color-text-on-primary: #FFFFFF;
--primary: var(--color-primary);
--primary-foreground: var(--color-text-on-primary);
--secondary: var(--color-bg-secondary);
--secondary-foreground: var(--color-text-primary);
--accent: var(--color-bg-secondary);
--accent-foreground: var(--color-text-primary);
--background: var(--color-bg-primary);
--foreground: var(--color-text-primary);
--card: var(--color-bg-secondary);
--card-foreground: var(--color-text-primary);
--popover: var(--color-bg-secondary);
--popover-foreground: var(--color-text-primary);
--muted: var(--color-bg-secondary);
--muted-foreground: var(--color-text-secondary);
--destructive: var(--color-error);
--border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--input: color-mix(in srgb, var(--color-text-primary) 15%, transparent);
--ring: var(--color-primary);
--sidebar: var(--color-bg-secondary);
--sidebar-foreground: var(--color-text-primary);
--sidebar-primary: var(--color-primary);
--sidebar-primary-foreground: var(--color-text-on-primary);
--sidebar-accent: var(--color-bg-primary);
--sidebar-accent-foreground: var(--color-text-primary);
--sidebar-border: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
--sidebar-ring: var(--color-primary);
} }